Skip to main content

chio_kernel_core/
rng.rs

1//! Abstract entropy source for receipt IDs and DPoP nonces.
2//!
3//! The kernel core never calls `OsRng` directly. Browser adapters route
4//! to `crypto.getRandomValues()` through `getrandom`'s `js` feature;
5//! WASI adapters route to the host's random API; mobile adapters use
6//! `SecRandomCopyBytes` / `/dev/urandom`.
7
8/// Trait boundary for cryptographically-secure random byte production.
9///
10/// Implementations MUST produce cryptographically strong randomness.
11/// Failing to do so defeats replay protection (DPoP nonces) and
12/// capability-ID unpredictability. The trait deliberately exposes only
13/// `fill_bytes` so adapters can route to CSPRNG primitives native to
14/// their platform without extra shims.
15pub trait Rng {
16    /// Fill `dest` with cryptographically secure random bytes.
17    fn fill_bytes(&self, dest: &mut [u8]);
18}
19
20/// Entropy-free RNG that refuses to produce bytes.
21///
22/// Useful for test paths that should never require randomness (e.g. pure
23/// verdict evaluation with no receipt ID generation). Callers that need
24/// to mint receipt IDs must supply a real RNG, typically via the
25/// `getrandom`-backed adapter shim in `chio-kernel`.
26#[derive(Debug, Clone, Copy, Default)]
27pub struct NullRng;
28
29impl Rng for NullRng {
30    fn fill_bytes(&self, dest: &mut [u8]) {
31        // Fill with zeros so deterministic-but-non-random contexts still
32        // receive a valid slice. Callers that actually need entropy must
33        // plug in a real RNG; NullRng is for tests only.
34        for byte in dest.iter_mut() {
35            *byte = 0;
36        }
37    }
38}
39
40impl<T: Rng + ?Sized> Rng for &T {
41    fn fill_bytes(&self, dest: &mut [u8]) {
42        (**self).fill_bytes(dest)
43    }
44}