osom_lib_entropy_cprng/
cprng_entropy.rs1use core::convert::Infallible;
4
5use osom_lib_entropy::{
6 std::StdEntropyGenerator,
7 traits::{EntropyConcreteGenerator, EntropyGenerator},
8};
9use osom_lib_prng::traits::{CryptographicallySecure, PRNGenerator, Seedable};
10use osom_lib_reprc::macros::reprc;
11
12#[reprc]
16#[repr(transparent)]
17#[derive(Clone)]
18pub struct CPRNGEntropy<TPrng>
19where
20 TPrng: PRNGenerator + CryptographicallySecure + Seedable<u128>,
21{
22 cprng: TPrng,
23}
24
25impl<TPrng> CPRNGEntropy<TPrng>
26where
27 TPrng: PRNGenerator + CryptographicallySecure + Seedable<u128>,
28{
29 pub fn new() -> Result<Self, <StdEntropyGenerator as EntropyGenerator>::Error> {
36 let mut entropy = StdEntropyGenerator::new();
37 let seed = entropy.generate::<u128>()?;
38 let cprng = TPrng::with_seed(seed);
39 Ok(Self { cprng })
40 }
41
42 #[allow(clippy::missing_panics_doc)]
44 #[inline(always)]
45 pub fn generate<T: EntropyConcreteGenerator<CPRNGEntropy<TPrng>>>(&mut self) -> T {
46 let result: Result<T, Infallible> = <Self as EntropyGenerator>::generate::<T>(self);
49 result.unwrap()
50 }
51}
52
53impl<TPrng> EntropyGenerator for CPRNGEntropy<TPrng>
54where
55 TPrng: PRNGenerator + CryptographicallySecure + Seedable<u128>,
56{
57 type Error = Infallible;
59
60 unsafe fn fill_raw(&mut self, buffer_ptr: *mut u8, buffer_len: usize) -> Result<(), Infallible> {
61 unsafe {
62 self.cprng.fill_raw(buffer_ptr, buffer_len);
63 }
64 Ok(())
65 }
66}
67
68#[inline]
69fn generate_random_t<T: Copy, TGen: EntropyGenerator>(gene: &mut TGen) -> Result<T, TGen::Error> {
70 let mut item = core::mem::MaybeUninit::<T>::uninit();
71 let item_ptr = item.as_mut_ptr();
72 let slice = unsafe { core::slice::from_raw_parts_mut(item_ptr.cast::<u8>(), size_of::<T>()) };
73 gene.fill(slice)?;
74 Ok(unsafe { item.assume_init() })
75}
76
77impl<const N: usize, TPrng> EntropyConcreteGenerator<CPRNGEntropy<TPrng>> for [u8; N]
78where
79 TPrng: PRNGenerator + CryptographicallySecure + Seedable<u128>,
80{
81 #[inline(always)]
82 fn generate(generator: &mut CPRNGEntropy<TPrng>) -> Result<Self, <CPRNGEntropy<TPrng> as EntropyGenerator>::Error> {
83 if N == 0 {
84 return Ok([0u8; N]);
85 }
86 generate_random_t(generator)
87 }
88}
89
90macro_rules! concrete {
91 ( $t: ty ) => {
92 impl<TPrng> EntropyConcreteGenerator<CPRNGEntropy<TPrng>> for $t
93 where
94 TPrng: PRNGenerator + CryptographicallySecure + Seedable<u128>
95 {
96 #[inline(always)]
97 fn generate(generator: &mut CPRNGEntropy<TPrng>) -> Result<Self, <CPRNGEntropy<TPrng> as EntropyGenerator>::Error>
98 {
99 generate_random_t(generator)
100 }
101 }
102 };
103 ( $t: ty, $($ts:ty),* $(,)?) => {
104 concrete!($t);
105 concrete!($($ts),*);
106 };
107}
108
109concrete!(i16, u16, i32, u32, i64, u64, i128, u128, usize, isize);