#[cfg(feature = "alloc")]
use alloc::vec::Vec;
use crate::sm3::Sm3Hasher;
#[cfg(feature = "alloc")]
pub fn kdf(z: &[u8], klen: usize) -> Vec<u8> {
let mut result = Vec::with_capacity(klen + 32);
let mut counter: u32 = 1;
while result.len() < klen {
let mut h = Sm3Hasher::new();
h.update(z);
h.update(&counter.to_be_bytes());
result.extend_from_slice(&h.finalize());
counter += 1;
}
result.truncate(klen);
result
}
#[cfg(test)]
#[cfg(feature = "alloc")]
mod tests {
use super::*;
#[test]
fn test_kdf_length() {
let z = b"test input";
assert_eq!(kdf(z, 32).len(), 32);
assert_eq!(kdf(z, 48).len(), 48);
assert_eq!(kdf(z, 1).len(), 1);
}
#[test]
fn test_kdf_deterministic() {
let z = b"shared secret";
assert_eq!(kdf(z, 32), kdf(z, 32));
}
#[test]
fn test_kdf_different_lengths() {
let z = b"input";
let k32 = kdf(z, 32);
let k64 = kdf(z, 64);
assert_eq!(&k64[..32], &k32[..]);
}
}