cap_rand/lib.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
//! Capability-based random number generators
//!
//! This corresponds to [`rand`].
//!
//! Capability-based APIs represent access to external resources as values
//! which can be passed around between different parts of a program.
//!
//! Two notable features are the [`OsRng`] and [`CapRng`] types, which
//! wrap up access to the operating system entropy source in capability
//! values.
//!
//! This crate uses the existing `rand::SeedableRng` trait rather than having
//! its own version, however while `rand::SeedableRng` is mostly just a pure
//! interface, it provides a `from_entropy` function which directly reads
//! from the operating system entropy source. To preserve the
//! capability-based interface, avoid using `rand::SeedableRng`'s
//! `from_entropy` function on any of the types that implement that trait; use
//! [`std_rng_from_entropy`] instead.
//!
//! [`OsRng`]: crate::rngs::OsRng
//! [`CapRng`]: crate::rngs::CapRng
#![deny(missing_docs)]
#![forbid(unsafe_code)]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/bytecodealliance/cap-std/main/media/cap-std.svg"
)]
#![doc(
html_favicon_url = "https://raw.githubusercontent.com/bytecodealliance/cap-std/main/media/cap-std.ico"
)]
#[doc(hidden)]
pub use ambient_authority::ambient_authority_known_at_compile_time;
pub use ambient_authority::{ambient_authority, AmbientAuthority};
pub use rand::{distributions, seq, CryptoRng, Error, Fill, Rng, RngCore, SeedableRng};
/// Convenience re-export of common members.
///
/// This corresponds to [`rand::prelude`].
pub mod prelude {
pub use crate::distributions::Distribution;
#[cfg(feature = "small_rng")]
pub use crate::rngs::SmallRng;
pub use crate::rngs::{CapRng, StdRng};
pub use crate::seq::{IteratorRandom, SliceRandom};
pub use crate::{random, thread_rng, CryptoRng, Rng, RngCore, SeedableRng};
}
/// Random number generators and adapters.
///
/// This corresponds to [`rand::rngs`].
pub mod rngs {
use super::AmbientAuthority;
pub use rand::rngs::{adapter, mock, StdRng};
#[cfg(feature = "small_rng")]
pub use rand::rngs::SmallRng;
/// A random number generator that retrieves randomness from the operating
/// system.
///
/// This corresponds to [`rand::rngs::OsRng`], except instead of
/// implementing `Default` it has an ambient-authority `default` function
/// to access the operating system.
#[derive(Clone, Copy, Debug)]
pub struct OsRng(());
impl OsRng {
/// Returns an `OsRng` instance.
///
/// # Ambient Authority
///
/// This function makes use of ambient authority to access the platform
/// entropy source.
#[inline]
pub const fn default(ambient_authority: AmbientAuthority) -> Self {
let _ = ambient_authority;
Self(())
}
}
impl crate::RngCore for OsRng {
#[inline]
fn next_u32(&mut self) -> u32 {
rand::rngs::OsRng.next_u32()
}
#[inline]
fn next_u64(&mut self) -> u64 {
rand::rngs::OsRng.next_u64()
}
#[inline]
fn fill_bytes(&mut self, bytes: &mut [u8]) {
rand::rngs::OsRng.fill_bytes(bytes)
}
#[inline]
fn try_fill_bytes(&mut self, bytes: &mut [u8]) -> Result<(), crate::Error> {
rand::rngs::OsRng.try_fill_bytes(bytes)
}
}
impl crate::CryptoRng for OsRng {}
/// The type returned by `thread_rng`, essentially just a reference to a
/// PRNG in memory.
///
/// This corresponds to [`rand::rngs::ThreadRng`], except that it isn't
/// tied to thread-local memory.
#[derive(Clone, Debug)]
pub struct CapRng {
pub(super) inner: rand::rngs::ThreadRng,
}
impl CapRng {
/// A convenience alias for calling `thread_rng`.
///
/// # Ambient Authority
///
/// This function makes use of ambient authority to access the platform
/// entropy source.
#[inline]
pub fn default(ambient_authority: AmbientAuthority) -> Self {
crate::thread_rng(ambient_authority)
}
}
impl crate::RngCore for CapRng {
#[inline]
fn next_u32(&mut self) -> u32 {
self.inner.next_u32()
}
#[inline]
fn next_u64(&mut self) -> u64 {
self.inner.next_u64()
}
#[inline]
fn fill_bytes(&mut self, bytes: &mut [u8]) {
self.inner.fill_bytes(bytes)
}
#[inline]
fn try_fill_bytes(&mut self, bytes: &mut [u8]) -> Result<(), crate::Error> {
self.inner.try_fill_bytes(bytes)
}
}
impl crate::CryptoRng for CapRng {}
}
/// Retrieve the lazily-initialized thread-local random number generator,
/// seeded by the system.
///
/// This corresponds to [`rand::thread_rng`].
///
/// # Ambient Authority
///
/// This function makes use of ambient authority to access the platform entropy
/// source.
#[inline]
pub fn thread_rng(ambient_authority: AmbientAuthority) -> rngs::CapRng {
let _ = ambient_authority;
rngs::CapRng {
inner: rand::thread_rng(),
}
}
/// Retrieve the standard random number generator, seeded by the system.
///
/// This corresponds to [`rand::rngs::StdRng::from_entropy`].
///
/// # Ambient Authority
///
/// This function makes use of ambient authority to access the platform entropy
/// source.
#[inline]
pub fn std_rng_from_entropy(ambient_authority: AmbientAuthority) -> rngs::StdRng {
let _ = ambient_authority;
rand::rngs::StdRng::from_entropy()
}
/// Generates a random value using the thread-local random number generator.
///
/// This corresponds to [`rand::random`].
///
/// # Ambient Authority
///
/// This function makes use of ambient authority to access the platform entropy
/// source.
#[inline]
pub fn random<T>(ambient_authority: AmbientAuthority) -> T
where
crate::distributions::Standard: crate::distributions::Distribution<T>,
{
let _ = ambient_authority;
rand::random()
}