relay-crypto 0.1.0

The crypto library for the Relay Ecosystem.
Documentation
use rand_core::{CryptoRng, OsRng, RngCore, SeedableRng as _};

/// Hashes an os ranadom seed with the nonce provided. Provices a sense of security against OS RNG failures.
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);

        // There is a very small chance this could fail if both RNGs produce the same output :DDD
        assert_ne!(buf1, buf2);
    }
}