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::{distributions, seq, CryptoRng, Error, Fill, Rng, RngCore, SeedableRng};
36
37/// Convenience re-export of common members.
38///
39/// This corresponds to [`rand::prelude`].
40pub mod prelude {
41    pub use crate::distributions::Distribution;
42    #[cfg(feature = "small_rng")]
43    pub use crate::rngs::SmallRng;
44    pub use crate::rngs::{CapRng, StdRng};
45    pub use crate::seq::{IteratorRandom, SliceRandom};
46    pub use crate::{random, thread_rng, CryptoRng, Rng, RngCore, SeedableRng};
47}
48
49/// Random number generators and adapters.
50///
51/// This corresponds to [`rand::rngs`].
52pub mod rngs {
53    use super::AmbientAuthority;
54
55    pub use rand::rngs::{adapter, mock, StdRng};
56
57    #[cfg(feature = "small_rng")]
58    pub use rand::rngs::SmallRng;
59
60    /// A random number generator that retrieves randomness from the operating
61    /// system.
62    ///
63    /// This corresponds to [`rand::rngs::OsRng`], except instead of
64    /// implementing `Default` it has an ambient-authority `default` function
65    /// to access the operating system.
66    #[derive(Clone, Copy, Debug)]
67    pub struct OsRng(());
68
69    impl OsRng {
70        /// Returns an `OsRng` instance.
71        ///
72        /// # Ambient Authority
73        ///
74        /// This function makes use of ambient authority to access the platform
75        /// entropy source.
76        #[inline]
77        pub const fn default(ambient_authority: AmbientAuthority) -> Self {
78            let _ = ambient_authority;
79            Self(())
80        }
81    }
82
83    impl crate::RngCore for OsRng {
84        #[inline]
85        fn next_u32(&mut self) -> u32 {
86            rand::rngs::OsRng.next_u32()
87        }
88
89        #[inline]
90        fn next_u64(&mut self) -> u64 {
91            rand::rngs::OsRng.next_u64()
92        }
93
94        #[inline]
95        fn fill_bytes(&mut self, bytes: &mut [u8]) {
96            rand::rngs::OsRng.fill_bytes(bytes)
97        }
98
99        #[inline]
100        fn try_fill_bytes(&mut self, bytes: &mut [u8]) -> Result<(), crate::Error> {
101            rand::rngs::OsRng.try_fill_bytes(bytes)
102        }
103    }
104
105    impl crate::CryptoRng for OsRng {}
106
107    /// The type returned by `thread_rng`, essentially just a reference to a
108    /// PRNG in memory.
109    ///
110    /// This corresponds to [`rand::rngs::ThreadRng`], except that it isn't
111    /// tied to thread-local memory.
112    #[derive(Clone, Debug)]
113    pub struct CapRng {
114        pub(super) inner: rand::rngs::ThreadRng,
115    }
116
117    impl CapRng {
118        /// A convenience alias for calling `thread_rng`.
119        ///
120        /// # Ambient Authority
121        ///
122        /// This function makes use of ambient authority to access the platform
123        /// entropy source.
124        #[inline]
125        pub fn default(ambient_authority: AmbientAuthority) -> Self {
126            crate::thread_rng(ambient_authority)
127        }
128    }
129
130    impl crate::RngCore for CapRng {
131        #[inline]
132        fn next_u32(&mut self) -> u32 {
133            self.inner.next_u32()
134        }
135
136        #[inline]
137        fn next_u64(&mut self) -> u64 {
138            self.inner.next_u64()
139        }
140
141        #[inline]
142        fn fill_bytes(&mut self, bytes: &mut [u8]) {
143            self.inner.fill_bytes(bytes)
144        }
145
146        #[inline]
147        fn try_fill_bytes(&mut self, bytes: &mut [u8]) -> Result<(), crate::Error> {
148            self.inner.try_fill_bytes(bytes)
149        }
150    }
151
152    impl crate::CryptoRng for CapRng {}
153}
154
155/// Retrieve the lazily-initialized thread-local random number generator,
156/// seeded by the system.
157///
158/// This corresponds to [`rand::thread_rng`].
159///
160/// # Ambient Authority
161///
162/// This function makes use of ambient authority to access the platform entropy
163/// source.
164#[inline]
165pub fn thread_rng(ambient_authority: AmbientAuthority) -> rngs::CapRng {
166    let _ = ambient_authority;
167    rngs::CapRng {
168        inner: rand::thread_rng(),
169    }
170}
171
172/// Retrieve the standard random number generator, seeded by the system.
173///
174/// This corresponds to [`rand::rngs::StdRng::from_entropy`].
175///
176/// # Ambient Authority
177///
178/// This function makes use of ambient authority to access the platform entropy
179/// source.
180#[inline]
181pub fn std_rng_from_entropy(ambient_authority: AmbientAuthority) -> rngs::StdRng {
182    let _ = ambient_authority;
183    rand::rngs::StdRng::from_entropy()
184}
185
186/// Generates a random value using the thread-local random number generator.
187///
188/// This corresponds to [`rand::random`].
189///
190/// # Ambient Authority
191///
192/// This function makes use of ambient authority to access the platform entropy
193/// source.
194#[inline]
195pub fn random<T>(ambient_authority: AmbientAuthority) -> T
196where
197    crate::distributions::Standard: crate::distributions::Distribution<T>,
198{
199    let _ = ambient_authority;
200    rand::random()
201}