1use crate::aws_lc::RAND_bytes;
29use crate::error::Unspecified;
30use crate::fips::indicator_check;
31use core::fmt::Debug;
32
33#[cfg(dev_tests_only)]
35#[allow(unused_imports)]
36pub mod unsealed {
37 pub use super::sealed::*;
38}
39
40pub trait SecureRandom: sealed::SecureRandom {
42 fn fill(&self, dest: &mut [u8]) -> Result<(), Unspecified>;
47
48 #[cfg(any(test, dev_tests_only))]
53 fn mut_fill(&mut self, dest: &mut [u8]) -> Result<(), Unspecified>;
54}
55
56impl<T> SecureRandom for T
57where
58 T: sealed::SecureRandom,
59{
60 #[inline]
61 fn fill(&self, dest: &mut [u8]) -> Result<(), Unspecified> {
62 self.fill_impl(dest)
63 }
64
65 #[inline]
66 #[cfg(any(test, dev_tests_only))]
67 fn mut_fill(&mut self, dest: &mut [u8]) -> Result<(), Unspecified> {
68 self.fill_impl(dest)
69 }
70}
71
72pub struct Random<T: RandomlyConstructable>(T);
77
78impl<T: RandomlyConstructable> Random<T> {
79 #[inline]
81 pub fn expose(self) -> T {
82 self.0
83 }
84}
85
86#[inline]
91pub fn generate<T: RandomlyConstructable>(
92 rng: &dyn SecureRandom,
93) -> Result<Random<T>, Unspecified> {
94 let mut r = T::zero();
95 rng.fill(r.as_mut_bytes())?;
96 Ok(Random(r))
97}
98
99pub(crate) mod sealed {
100 use crate::error;
101
102 pub trait SecureRandom: core::fmt::Debug {
104 fn fill_impl(&self, dest: &mut [u8]) -> Result<(), error::Unspecified>;
109 }
110
111 pub trait RandomlyConstructable: Sized {
113 fn zero() -> Self;
115 fn as_mut_bytes(&mut self) -> &mut [u8];
117 }
118
119 impl<const T: usize> RandomlyConstructable for [u8; T] {
120 #[inline]
121 fn zero() -> Self {
122 [0; T]
123 }
124
125 #[inline]
126 fn as_mut_bytes(&mut self) -> &mut [u8] {
127 &mut self[..]
128 }
129 }
130}
131
132pub trait RandomlyConstructable: sealed::RandomlyConstructable {}
134
135impl<T> RandomlyConstructable for T where T: sealed::RandomlyConstructable {}
136
137#[derive(Clone, Debug)]
145pub struct SystemRandom(());
146
147const SYSTEM_RANDOM: SystemRandom = SystemRandom(());
148
149impl SystemRandom {
150 #[inline]
152 #[must_use]
153 pub fn new() -> Self {
154 Self::default()
155 }
156}
157
158impl Default for SystemRandom {
159 fn default() -> Self {
160 SYSTEM_RANDOM
161 }
162}
163
164impl sealed::SecureRandom for SystemRandom {
165 #[inline]
166 fn fill_impl(&self, dest: &mut [u8]) -> Result<(), Unspecified> {
167 fill(dest)
168 }
169}
170
171pub fn fill(dest: &mut [u8]) -> Result<(), Unspecified> {
179 if 1 != indicator_check!(unsafe { RAND_bytes(dest.as_mut_ptr(), dest.len()) }) {
180 return Err(Unspecified);
181 }
182 Ok(())
183}
184
185#[cfg(test)]
186mod tests {
187 use crate::rand;
188 use core::array::IntoIter;
189
190 use crate::rand::{generate, SecureRandom, SystemRandom};
191
192 #[test]
193 fn test_secure_random_fill() {
194 let mut random_array = [0u8; 1009];
196 let rng = SystemRandom::new();
197 rng.fill(&mut random_array).unwrap();
198
199 let (mean, variance) = mean_variance(&mut random_array.into_iter());
200 assert!((106f64..150f64).contains(&mean), "Mean: {mean}");
201 assert!(variance > 8f64);
202 println!("Mean: {mean} Variance: {variance}");
203 }
204
205 #[test]
206 fn test_rand_fill() {
207 let mut random_array = [0u8; 1009];
209 rand::fill(&mut random_array).unwrap();
210
211 let (mean, variance) = mean_variance(&mut random_array.into_iter());
212 assert!((106f64..150f64).contains(&mean), "Mean: {mean}");
213 assert!(variance > 8f64);
214 println!("Mean: {mean} Variance: {variance}");
215 }
216
217 #[test]
218 fn test_randomly_constructable() {
219 let rando = SystemRandom::new();
220 let random_array = generate(&rando).unwrap();
221 let random_array: [u8; 1009] = random_array.expose();
223 let (mean, variance) = mean_variance(&mut random_array.into_iter());
224 assert!((106f64..150f64).contains(&mean), "Mean: {mean}");
225 assert!(variance > 8f64);
226 println!("Mean: {mean} Variance: {variance}");
227 }
228
229 fn mean_variance<T: Into<f64>, const N: usize>(iterable: &mut IntoIter<T, N>) -> (f64, f64) {
230 let iter = iterable;
231 let mean: Option<T> = iter.next();
232 let mut mean = mean.unwrap().into();
233 let mut var_squared = 0f64;
234 let mut count = 1f64;
235 for value in iter.by_ref() {
236 count += 1f64;
237 let value = value.into();
238 let prev_mean = mean;
239 mean = prev_mean + (value - prev_mean) / count;
240 var_squared =
241 var_squared + ((value - prev_mean) * (value - mean) - var_squared) / count;
242 }
243
244 (mean, var_squared.sqrt())
245 }
246}