std only.Expand description
RngProvider — the indirection through which Phantom Protocol obtains
cryptographic randomness. Default is OsRng, which delegates to
getrandom::getrandom and therefore picks up the platform’s CSPRNG on
every supported target (Linux getrandom(2), macOS / iOS
CCRandomGenerateBytes, Windows BCryptGenRandom, wasm32 via the js
feature → crypto.getRandomValues, etc.).
Embedders can swap in their own provider by implementing this trait and
threading it into the relevant _with_provider entry points (e.g.
HybridSigningKey::generate_with_provider, which mints a keypair from an
injected RNG). The trait is the seam; all in-crate production code uses
the OsRng default, and target-specific embedders (embedded HALs without
a getrandom-shaped entropy source) supply their own provider.
§Module scope
Trait + default OsRng impl + tests. The OsRng substrate forks on the
build: getrandom on the default build, AWS-LC’s CTR_DRBG under
--features fips (see the two impl RngProvider for OsRng blocks below).
Beyond those, the module deliberately ships no other providers:
- A software NIST SP 800-90A DRBG of our own (e.g. HMAC-DRBG). Not needed:
the
fipsbuild delegates to AWS-LC’s FIPS-validated CTR_DRBG rather than carrying an in-tree DRBG. The trait is still shaped to accept one — see the illustrative skeleton below — for embedders who want a custom DRBG. - A hardware-RNG impl. Those are inherently target-specific and belong
in a downstream HAL adapter crate, not in
phantom_protocolitself.
§Slotting in alternative providers
§Hardware TRNG on embedded
On microcontrollers exposing a true-RNG peripheral (e.g., the STM32
RNG, the nRF52 RNG, RP2040 ROSC, …), the HAL crate typically
exposes a blocking reader (embedded_hal::blocking::rng::Read or the
rand_core::RngCore impl that newer HALs wrap it in). A downstream
adapter looks roughly like:
use phantom_protocol::crypto::rng::RngProvider;
use core::sync::atomic::AtomicBool;
use spin::Mutex; // or critical_section::Mutex on no_std-no-alloc
pub struct HwRng<R> {
inner: Mutex<R>,
}
impl<R> HwRng<R> {
pub fn new(peripheral: R) -> Self {
Self { inner: Mutex::new(peripheral) }
}
}
impl<R> RngProvider for HwRng<R>
where
R: rand_core::RngCore + Send + 'static,
{
fn fill_bytes(&self, dest: &mut [u8]) {
self.inner.lock().fill_bytes(dest);
}
}The Mutex is needed because fill_bytes takes &self. A real HAL
adapter should also surface health-test failures from the peripheral
(most TRNGs have a stuck-bit / continuous-test register) rather than
returning silently-biased bytes.
§Software DRBG provider (illustration)
The shipped --features fips build does NOT use an in-tree DRBG — it
delegates OsRng to AWS-LC’s FIPS-validated CTR_DRBG (see the fips
impl RngProvider for OsRng below). An embedder who wants their own
software DRBG (e.g. an HmacDrbg, SP 800-90A § 10.1.2, keyed from
getrandom at boot and re-seeded per SP 800-90A § 9) can shape it as a
provider like this:
use phantom_protocol::crypto::rng::RngProvider;
use std::sync::Mutex;
pub struct HmacDrbg { /* V, Key, reseed_counter, ... */ }
impl HmacDrbg {
pub fn from_entropy() -> Self { /* seed from getrandom */ todo!() }
fn generate(&mut self, out: &mut [u8]) { /* SP 800-90A 10.1.2.5 */ todo!() }
}
pub struct FipsDrbg(Mutex<HmacDrbg>);
impl RngProvider for FipsDrbg {
fn fill_bytes(&self, dest: &mut [u8]) {
self.0.lock().expect("DRBG poisoned").generate(dest);
}
}See docs/compliance/fips-readiness.md for the larger picture.
§Deterministic test fixture
See tests::CounterRng below for a tiny in-tree example.
Structs§
- OsRng
- Default
RngProvider— delegates togetrandomand therefore to the OS’s CSPRNG on every supported target.
Traits§
- RngProvider
- Source of cryptographically secure random bytes.