1use crate::aws_lc::RAND_bytes;
36use crate::error::Unspecified;
37use crate::fips::indicator_check;
38use core::fmt::Debug;
39
40pub trait SecureRandom: sealed::SecureRandom {
42 fn fill(&self, dest: &mut [u8]) -> Result<(), Unspecified>;
47}
48
49impl<T> SecureRandom for T
50where
51 T: sealed::SecureRandom,
52{
53 #[inline]
54 fn fill(&self, dest: &mut [u8]) -> Result<(), Unspecified> {
55 self.fill_impl(dest)
56 }
57}
58
59pub struct Random<T: RandomlyConstructable>(T);
64
65impl<T: RandomlyConstructable> Random<T> {
66 #[inline]
68 pub fn expose(self) -> T {
69 self.0
70 }
71}
72
73#[inline]
78pub fn generate<T: RandomlyConstructable>(
79 rng: &dyn SecureRandom,
80) -> Result<Random<T>, Unspecified> {
81 let mut r = T::zero();
82 rng.fill(r.as_mut_bytes())?;
83 Ok(Random(r))
84}
85
86pub(crate) mod sealed {
87 use crate::error;
88
89 pub trait SecureRandom: core::fmt::Debug {
90 fn fill_impl(&self, dest: &mut [u8]) -> Result<(), error::Unspecified>;
92 }
93
94 pub trait RandomlyConstructable: Sized {
95 fn zero() -> Self;
96 fn as_mut_bytes(&mut self) -> &mut [u8]; }
99
100 impl<const T: usize> RandomlyConstructable for [u8; T] {
101 #[inline]
102 fn zero() -> Self {
103 [0; T]
104 }
105
106 #[inline]
107 fn as_mut_bytes(&mut self) -> &mut [u8] {
108 &mut self[..]
109 }
110 }
111}
112
113pub trait RandomlyConstructable: sealed::RandomlyConstructable {}
115
116impl<T> RandomlyConstructable for T where T: sealed::RandomlyConstructable {}
117
118#[derive(Clone, Debug)]
126pub struct SystemRandom(());
127
128const SYSTEM_RANDOM: SystemRandom = SystemRandom(());
129
130impl SystemRandom {
131 #[inline]
133 #[must_use]
134 pub fn new() -> Self {
135 Self::default()
136 }
137}
138
139impl Default for SystemRandom {
140 fn default() -> Self {
141 SYSTEM_RANDOM
142 }
143}
144
145impl sealed::SecureRandom for SystemRandom {
146 #[inline]
147 fn fill_impl(&self, dest: &mut [u8]) -> Result<(), Unspecified> {
148 fill(dest)
149 }
150}
151
152pub fn fill(dest: &mut [u8]) -> Result<(), Unspecified> {
160 if 1 != indicator_check!(unsafe { RAND_bytes(dest.as_mut_ptr(), dest.len()) }) {
161 return Err(Unspecified);
162 }
163 Ok(())
164}
165
166#[cfg(test)]
167mod tests {
168 use crate::rand;
169 use core::array::IntoIter;
170
171 use crate::rand::{generate, SecureRandom, SystemRandom};
172
173 #[test]
174 fn test_secure_random_fill() {
175 let mut random_array = [0u8; 1009];
177 let rng = SystemRandom::new();
178 rng.fill(&mut random_array).unwrap();
179
180 let (mean, variance) = mean_variance(&mut random_array.into_iter());
181 assert!((106f64..150f64).contains(&mean), "Mean: {mean}");
182 assert!(variance > 8f64);
183 println!("Mean: {mean} Variance: {variance}");
184 }
185
186 #[test]
187 fn test_rand_fill() {
188 let mut random_array = [0u8; 1009];
190 rand::fill(&mut random_array).unwrap();
191
192 let (mean, variance) = mean_variance(&mut random_array.into_iter());
193 assert!((106f64..150f64).contains(&mean), "Mean: {mean}");
194 assert!(variance > 8f64);
195 println!("Mean: {mean} Variance: {variance}");
196 }
197
198 #[test]
199 fn test_randomly_constructable() {
200 let rando = SystemRandom::new();
201 let random_array = generate(&rando).unwrap();
202 let random_array: [u8; 1009] = random_array.expose();
204 let (mean, variance) = mean_variance(&mut random_array.into_iter());
205 assert!((106f64..150f64).contains(&mean), "Mean: {mean}");
206 assert!(variance > 8f64);
207 println!("Mean: {mean} Variance: {variance}");
208 }
209
210 fn mean_variance<T: Into<f64>, const N: usize>(iterable: &mut IntoIter<T, N>) -> (f64, f64) {
211 let iter = iterable;
212 let mean: Option<T> = iter.next();
213 let mut mean = mean.unwrap().into();
214 let mut var_squared = 0f64;
215 let mut count = 1f64;
216 for value in iter.by_ref() {
217 count += 1f64;
218 let value = value.into();
219 let prev_mean = mean;
220 mean = prev_mean + (value - prev_mean) / count;
221 var_squared =
222 var_squared + ((value - prev_mean) * (value - mean) - var_squared) / count;
223 }
224
225 (mean, var_squared.sqrt())
226 }
227}