quantica/slh_dsa/rng.rs
1//! Minimal cryptographic RNG trait and OS-backed implementation.
2//!
3//! SLH-DSA requires a source of cryptographic randomness for key generation and
4//! hedged signing. This module provides a simple trait and a default implementation
5//! backed by the operating system's entropy source.
6
7use super::SlhDsaError;
8
9/// Trait for cryptographic random byte generation.
10///
11/// Implementors must provide bytes that are indistinguishable from uniform random
12/// to any computationally bounded adversary. The default implementation ([`OsRng`])
13/// reads from `/dev/urandom`.
14///
15/// Custom implementations can be provided for testing (deterministic RNG) or for
16/// environments where `/dev/urandom` is unavailable.
17pub trait CryptoRng {
18 /// Fill `dest` with cryptographically secure random bytes.
19 ///
20 /// Returns `Err(SlhDsaError::RngFailure)` if the entropy source is unavailable.
21 fn fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), SlhDsaError>;
22}
23
24/// OS-backed cryptographic RNG reading from `/dev/urandom`.
25///
26/// Only available with the `std` feature. In `no_std` builds, callers
27/// must supply their own [`CryptoRng`] implementation.
28#[cfg(feature = "std")]
29pub struct OsRng;
30
31#[cfg(feature = "std")]
32impl CryptoRng for OsRng {
33 fn fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), SlhDsaError> {
34 use std::io::Read;
35 let mut f = std::fs::File::open("/dev/urandom").map_err(|_| SlhDsaError::RngFailure)?;
36 f.read_exact(dest).map_err(|_| SlhDsaError::RngFailure)
37 }
38}