Skip to main content

quantica/ml_kem/
rng.rs

1/// Minimal cryptographic RNG trait and OS-backed implementation.
2///
3/// Provides the [`CryptoRng`] trait used throughout ML-KEM for obtaining
4/// random bytes, and [`OsRng`], a zero-dependency implementation backed
5/// by the operating system's entropy source.
6use super::MlKemError;
7
8/// Trait for cryptographic-quality random byte generation.
9///
10/// Implementations must provide bytes suitable for key material and nonces.
11/// The trait is intentionally minimal (a single method) to allow easy
12/// integration with external RNG libraries or hardware RNGs.
13///
14/// # Errors
15///
16/// Returns [`MlKemError::RngFailure`] if the underlying entropy source
17/// is unavailable or fails.
18pub trait CryptoRng {
19    /// Fill `dest` with cryptographically secure random bytes.
20    ///
21    /// # Errors
22    ///
23    /// Returns [`MlKemError::RngFailure`] on failure.
24    fn fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), MlKemError>;
25}
26
27/// OS-backed cryptographic RNG reading from `/dev/urandom` on Unix.
28///
29/// Only available with the `std` feature. In `no_std` builds, callers
30/// must supply their own [`CryptoRng`] implementation (typically
31/// wrapping a hardware RNG on embedded targets).
32#[cfg(feature = "std")]
33pub struct OsRng;
34
35#[cfg(feature = "std")]
36impl CryptoRng for OsRng {
37    /// Fill `dest` with random bytes from `/dev/urandom`.
38    fn fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), MlKemError> {
39        use std::io::Read;
40        let mut f = std::fs::File::open("/dev/urandom").map_err(|_| MlKemError::RngFailure)?;
41        f.read_exact(dest).map_err(|_| MlKemError::RngFailure)
42    }
43}