1use crate::rng::{SecureYARandGenerator, YARandGenerator};
2use chacha20::{
3 rand_core::{RngCore, SeedableRng},
4 ChaCha8Rng,
5};
6
7#[derive(Debug)]
12pub struct SecureRng {
13 internal: ChaCha8Rng,
14}
15
16impl SecureYARandGenerator for SecureRng {
17 #[inline(never)]
18 fn fill_bytes(&mut self, dest: &mut [u8]) {
19 self.internal.fill_bytes(dest);
20 }
21}
22
23impl YARandGenerator for SecureRng {
24 fn try_new() -> Result<Self, getrandom::Error> {
25 const SEED_LEN: usize = 32;
26 const STREAM_LEN: usize = 12;
27 let mut data = [0; SEED_LEN + STREAM_LEN];
29 getrandom::fill(&mut data)?;
30 let seed: [u8; SEED_LEN] = data[..SEED_LEN].try_into().unwrap();
32 let stream: [u8; STREAM_LEN] = data[SEED_LEN..].try_into().unwrap();
33 let mut internal = ChaCha8Rng::from_seed(seed);
34 internal.set_stream(stream);
37 Ok(Self { internal })
38 }
39
40 #[cfg_attr(feature = "inline", inline)]
41 fn u64(&mut self) -> u64 {
42 self.internal.next_u64()
43 }
44}