1use crate::rng::*;
2use chachacha::*;
3use core::mem::MaybeUninit;
4
5pub struct SecureRng {
11 index: usize,
12 buf: [u64; BUF_LEN_U64],
13 internal: ChaCha8Djb,
14}
15
16impl SecureYARandGenerator for SecureRng {
17 #[inline]
18 fn fill_bytes(&mut self, dst: &mut [u8]) {
19 self.internal.fill(dst);
21 }
22}
23
24impl YARandGenerator for SecureRng {
25 #[inline]
26 fn try_new() -> Result<Self, getrandom::Error> {
27 #[allow(invalid_value)]
31 let mut state = unsafe { MaybeUninit::<[u8; SEED_LEN_U8]>::uninit().assume_init() };
32 getrandom::fill(&mut state)?;
33 let mut internal = ChaCha8Djb::new(state);
34 let buf = internal.get_block_u64();
35 let index = 0;
36 Ok(SecureRng {
37 index,
38 buf,
39 internal,
40 })
41 }
42
43 #[cfg_attr(feature = "inline", inline)]
44 fn u64(&mut self) -> u64 {
45 if self.index >= self.buf.len() {
46 self.internal.fill_block_u64(&mut self.buf);
47 self.index = 0;
48 }
49 let result = self.buf[self.index];
50 self.index += 1;
51 result
52 }
53}