quantica/ml_dsa/rng.rs
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Cédric Mesnil <cslashm@pm.me>
3
4//! Minimal cryptographic RNG trait and OS-backed implementation.
5//!
6//! Provides the [`CryptoRng`] trait used by ML-DSA for key generation and
7//! hedged signing, along with [`OsRng`], a simple implementation backed by
8//! the operating system's entropy source.
9
10use super::MlDsaError;
11
12/// Trait for cryptographic random byte generation.
13///
14/// Implementors must fill the destination buffer with cryptographically
15/// secure random bytes. This trait is used as a trait object (`&mut dyn CryptoRng`)
16/// throughout the ML-DSA API to allow callers to supply their own RNG.
17pub trait CryptoRng {
18 /// Fill `dest` with cryptographically secure random bytes.
19 ///
20 /// # Errors
21 ///
22 /// Returns [`MlDsaError::RngFailure`] if the underlying entropy source
23 /// is unavailable or fails.
24 fn fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), MlDsaError>;
25}
26
27/// OS-backed cryptographic RNG reading from `/dev/urandom`.
28///
29/// Only available with the `std` feature. In `no_std` builds, callers
30/// must supply their own [`CryptoRng`] implementation.
31#[cfg(feature = "std")]
32pub struct OsRng;
33
34#[cfg(feature = "std")]
35impl CryptoRng for OsRng {
36 fn fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), MlDsaError> {
37 use std::io::Read;
38 let mut f = std::fs::File::open("/dev/urandom").map_err(|_| MlDsaError::RngFailure)?;
39 f.read_exact(dest).map_err(|_| MlDsaError::RngFailure)
40 }
41}