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