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}