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}