use rand_core::{CryptoRng, OsRng, RngCore, SeedableRng as _};
pub fn os_rng_hkdf(
nonce: Option<&[u8]>,
context: &[u8],
) -> Result<impl RngCore + CryptoRng, hkdf::InvalidLength> {
let mut ikm = [0u8; 32];
OsRng.fill_bytes(&mut ikm);
let hk = hkdf::Hkdf::<sha2::Sha256>::new(nonce, &ikm);
let mut seed = [0u8; 32];
hk.expand(context, &mut seed)?;
Ok(rand_chacha::ChaCha20Rng::from_seed(seed))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_os_rng_hkdf() {
let mut rng1 = os_rng_hkdf(None, b"test-context").unwrap();
let mut rng2 = os_rng_hkdf(Some(b"hey there!"), b"test-context").unwrap();
let mut buf1 = [0u8; 256];
let mut buf2 = [0u8; 256];
rng1.fill_bytes(&mut buf1);
rng2.fill_bytes(&mut buf2);
assert_ne!(buf1, buf2);
}
}