cap_rand/
lib.rs

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