Skip to main content

osom_lib_prng/
defaults.rs

1//! Holds the implementation of the default PRNGs, recommended for general use.
2
3use core::ops::RangeBounds;
4
5use osom_lib_reprc::macros::reprc;
6use osom_lib_try_clone::TryClone;
7
8use crate::{
9    prngs::{ChaCha, LinearCongruentialGenerator128},
10    traits::{
11        CryptographicallySecure, PRNConcreteBoundedGenerator, PRNConcreteGenerator, PRNGenerator, Seedable, Splittable,
12    },
13};
14
15/// The recommended [`PRNGenerator`] for fast PRNG.
16///
17/// At the moment it uses [`LinearCongruentialGenerator128`] as an underlying PRNG.
18#[derive(Debug, PartialEq, Eq, Clone, Copy)]
19#[reprc]
20#[repr(transparent)]
21#[must_use]
22pub struct DefaultFastPRNG {
23    prng: LinearCongruentialGenerator128,
24}
25
26impl TryClone for DefaultFastPRNG {
27    type Error = <LinearCongruentialGenerator128 as TryClone>::Error;
28
29    fn try_clone(&self) -> Result<Self, Self::Error> {
30        let prng = self.prng.try_clone()?;
31        Ok(Self { prng })
32    }
33}
34
35impl PRNGenerator for DefaultFastPRNG {
36    unsafe fn fill_raw(&mut self, dst_ptr: *mut u8, dst_len: usize) {
37        unsafe { self.prng.fill_raw(dst_ptr, dst_len) };
38    }
39}
40
41impl<const N: usize> PRNConcreteGenerator<DefaultFastPRNG> for [u8; N] {
42    #[inline(always)]
43    fn generate(generator: &mut DefaultFastPRNG) -> Self {
44        generator.prng.generate::<Self>()
45    }
46}
47
48impl PRNConcreteGenerator<DefaultFastPRNG> for bool {
49    fn generate(generator: &mut DefaultFastPRNG) -> Self {
50        generator.prng.generate::<bool>()
51    }
52}
53
54impl PRNConcreteGenerator<DefaultFastPRNG> for u8 {
55    fn generate(generator: &mut DefaultFastPRNG) -> Self {
56        generator.prng.generate::<u8>()
57    }
58}
59
60impl PRNConcreteGenerator<DefaultFastPRNG> for i8 {
61    fn generate(generator: &mut DefaultFastPRNG) -> Self {
62        generator.prng.generate::<i8>()
63    }
64}
65
66impl PRNConcreteGenerator<DefaultFastPRNG> for u32 {
67    fn generate(generator: &mut DefaultFastPRNG) -> Self {
68        generator.prng.generate::<u32>()
69    }
70}
71
72impl PRNConcreteGenerator<DefaultFastPRNG> for i32 {
73    fn generate(generator: &mut DefaultFastPRNG) -> Self {
74        generator.prng.generate::<i32>()
75    }
76}
77
78impl PRNConcreteGenerator<DefaultFastPRNG> for u64 {
79    fn generate(generator: &mut DefaultFastPRNG) -> Self {
80        generator.prng.generate::<u64>()
81    }
82}
83
84impl PRNConcreteGenerator<DefaultFastPRNG> for i64 {
85    fn generate(generator: &mut DefaultFastPRNG) -> Self {
86        generator.prng.generate::<i64>()
87    }
88}
89
90impl PRNConcreteGenerator<DefaultFastPRNG> for u128 {
91    fn generate(generator: &mut DefaultFastPRNG) -> Self {
92        generator.prng.generate::<u128>()
93    }
94}
95
96impl PRNConcreteGenerator<DefaultFastPRNG> for i128 {
97    fn generate(generator: &mut DefaultFastPRNG) -> Self {
98        generator.prng.generate::<i128>()
99    }
100}
101
102impl PRNConcreteBoundedGenerator<DefaultFastPRNG> for u32 {
103    fn generate<TBounds: RangeBounds<Self>>(generator: &mut DefaultFastPRNG, range: TBounds) -> Self {
104        generator.prng.generate_in_range(range)
105    }
106}
107
108impl PRNConcreteBoundedGenerator<DefaultFastPRNG> for u64 {
109    fn generate<TBounds: RangeBounds<Self>>(generator: &mut DefaultFastPRNG, range: TBounds) -> Self {
110        generator.prng.generate_in_range(range)
111    }
112}
113
114impl PRNConcreteBoundedGenerator<DefaultFastPRNG> for i32 {
115    fn generate<TBounds: RangeBounds<Self>>(generator: &mut DefaultFastPRNG, range: TBounds) -> Self {
116        generator.prng.generate_in_range(range)
117    }
118}
119
120impl PRNConcreteBoundedGenerator<DefaultFastPRNG> for i64 {
121    fn generate<TBounds: RangeBounds<Self>>(generator: &mut DefaultFastPRNG, range: TBounds) -> Self {
122        generator.prng.generate_in_range(range)
123    }
124}
125
126impl PRNConcreteBoundedGenerator<DefaultFastPRNG> for f32 {
127    fn generate<TBounds: RangeBounds<Self>>(generator: &mut DefaultFastPRNG, range: TBounds) -> Self {
128        generator.prng.generate_in_range(range)
129    }
130}
131
132impl PRNConcreteBoundedGenerator<DefaultFastPRNG> for f64 {
133    fn generate<TBounds: RangeBounds<Self>>(generator: &mut DefaultFastPRNG, range: TBounds) -> Self {
134        generator.prng.generate_in_range(range)
135    }
136}
137
138impl Seedable<u128> for DefaultFastPRNG {
139    fn with_seed(seed: u128) -> Self {
140        Self {
141            prng: LinearCongruentialGenerator128::with_seed(seed),
142        }
143    }
144}
145
146impl Seedable<u64> for DefaultFastPRNG {
147    fn with_seed(seed: u64) -> Self {
148        Self {
149            prng: LinearCongruentialGenerator128::with_seed(seed),
150        }
151    }
152}
153
154impl Splittable for DefaultFastPRNG {
155    fn split(&mut self) -> Self {
156        Self {
157            prng: self.prng.split(),
158        }
159    }
160}
161
162/// The recommended [`PRNGenerator`] PRNG for cryptographically secure purposes.
163///
164/// At the moment it uses [`ChaCha<20>`] as an underlying PRNG.
165#[derive(Debug, PartialEq, Eq, Clone)]
166#[reprc]
167#[repr(transparent)]
168#[must_use]
169pub struct DefaultSecurePRNG {
170    prng: ChaCha<20>,
171}
172
173unsafe impl CryptographicallySecure for DefaultSecurePRNG {}
174
175impl PRNGenerator for DefaultSecurePRNG {
176    unsafe fn fill_raw(&mut self, dst_ptr: *mut u8, dst_len: usize) {
177        unsafe { self.prng.fill_raw(dst_ptr, dst_len) };
178    }
179}
180
181impl<const N: usize> PRNConcreteGenerator<DefaultSecurePRNG> for [u8; N] {
182    #[inline(always)]
183    fn generate(generator: &mut DefaultSecurePRNG) -> Self {
184        generator.prng.generate::<Self>()
185    }
186}
187
188impl PRNConcreteGenerator<DefaultSecurePRNG> for bool {
189    fn generate(generator: &mut DefaultSecurePRNG) -> Self {
190        generator.prng.generate::<bool>()
191    }
192}
193
194impl PRNConcreteGenerator<DefaultSecurePRNG> for u8 {
195    fn generate(generator: &mut DefaultSecurePRNG) -> Self {
196        generator.prng.generate::<u8>()
197    }
198}
199
200impl PRNConcreteGenerator<DefaultSecurePRNG> for i8 {
201    fn generate(generator: &mut DefaultSecurePRNG) -> Self {
202        generator.prng.generate::<i8>()
203    }
204}
205
206impl PRNConcreteGenerator<DefaultSecurePRNG> for u32 {
207    fn generate(generator: &mut DefaultSecurePRNG) -> Self {
208        generator.prng.generate::<u32>()
209    }
210}
211
212impl PRNConcreteGenerator<DefaultSecurePRNG> for i32 {
213    fn generate(generator: &mut DefaultSecurePRNG) -> Self {
214        generator.prng.generate::<i32>()
215    }
216}
217
218impl PRNConcreteGenerator<DefaultSecurePRNG> for u64 {
219    fn generate(generator: &mut DefaultSecurePRNG) -> Self {
220        generator.prng.generate::<u64>()
221    }
222}
223
224impl PRNConcreteGenerator<DefaultSecurePRNG> for i64 {
225    fn generate(generator: &mut DefaultSecurePRNG) -> Self {
226        generator.prng.generate::<i64>()
227    }
228}
229
230impl PRNConcreteGenerator<DefaultSecurePRNG> for u128 {
231    fn generate(generator: &mut DefaultSecurePRNG) -> Self {
232        generator.prng.generate::<u128>()
233    }
234}
235
236impl PRNConcreteGenerator<DefaultSecurePRNG> for i128 {
237    fn generate(generator: &mut DefaultSecurePRNG) -> Self {
238        generator.prng.generate::<i128>()
239    }
240}
241
242impl PRNConcreteBoundedGenerator<DefaultSecurePRNG> for u32 {
243    fn generate<TBounds: RangeBounds<Self>>(generator: &mut DefaultSecurePRNG, range: TBounds) -> Self {
244        generator.prng.generate_in_range(range)
245    }
246}
247
248impl PRNConcreteBoundedGenerator<DefaultSecurePRNG> for u64 {
249    fn generate<TBounds: RangeBounds<Self>>(generator: &mut DefaultSecurePRNG, range: TBounds) -> Self {
250        generator.prng.generate_in_range(range)
251    }
252}
253
254impl PRNConcreteBoundedGenerator<DefaultSecurePRNG> for i32 {
255    fn generate<TBounds: RangeBounds<Self>>(generator: &mut DefaultSecurePRNG, range: TBounds) -> Self {
256        generator.prng.generate_in_range(range)
257    }
258}
259
260impl PRNConcreteBoundedGenerator<DefaultSecurePRNG> for i64 {
261    fn generate<TBounds: RangeBounds<Self>>(generator: &mut DefaultSecurePRNG, range: TBounds) -> Self {
262        generator.prng.generate_in_range(range)
263    }
264}
265
266impl PRNConcreteBoundedGenerator<DefaultSecurePRNG> for f32 {
267    fn generate<TBounds: RangeBounds<Self>>(generator: &mut DefaultSecurePRNG, range: TBounds) -> Self {
268        generator.prng.generate_in_range(range)
269    }
270}
271
272impl PRNConcreteBoundedGenerator<DefaultSecurePRNG> for f64 {
273    fn generate<TBounds: RangeBounds<Self>>(generator: &mut DefaultSecurePRNG, range: TBounds) -> Self {
274        generator.prng.generate_in_range(range)
275    }
276}
277
278impl Seedable<u128> for DefaultSecurePRNG {
279    fn with_seed(seed: u128) -> Self {
280        Self {
281            prng: ChaCha::with_seed(seed),
282        }
283    }
284}
285
286impl Seedable<u64> for DefaultSecurePRNG {
287    fn with_seed(seed: u64) -> Self {
288        Self {
289            prng: ChaCha::with_seed(seed),
290        }
291    }
292}
293
294impl Splittable for DefaultSecurePRNG {
295    fn split(&mut self) -> Self {
296        Self {
297            prng: self.prng.split(),
298        }
299    }
300}