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}