use rand::{rngs::adapter::ReseedingRng, RngCore, SeedableRng};
use rand_chacha::ChaChaCore;
pub use s2n_quic_core::random::*;
struct AwsLc;
impl RngCore for AwsLc {
#[inline]
fn next_u32(&mut self) -> u32 {
let mut v = [0; 4];
self.fill_bytes(&mut v);
u32::from_ne_bytes(v)
}
#[inline]
fn next_u64(&mut self) -> u64 {
let mut v = [0; 8];
self.fill_bytes(&mut v);
u64::from_ne_bytes(v)
}
#[inline]
fn fill_bytes(&mut self, dest: &mut [u8]) {
self.try_fill_bytes(dest).unwrap()
}
#[inline]
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
aws_lc_rs::rand::fill(dest).map_err(rand::Error::new)
}
}
pub struct Random {
public: ReseedingRng<ChaChaCore, AwsLc>,
private: ReseedingRng<ChaChaCore, AwsLc>,
}
impl Default for Random {
#[inline]
fn default() -> Self {
Self {
public: build_rng(),
private: build_rng(),
}
}
}
fn build_rng() -> ReseedingRng<ChaChaCore, AwsLc> {
const RESEED_THRESHOLD: u64 = 1024 * 64;
let prng = ChaChaCore::from_rng(AwsLc)
.unwrap_or_else(|err| panic!("could not initialize random generator: {err}"));
ReseedingRng::new(prng, RESEED_THRESHOLD, AwsLc)
}
impl Generator for Random {
#[inline]
fn public_random_fill(&mut self, dest: &mut [u8]) {
self.public.fill_bytes(dest);
}
#[inline]
fn private_random_fill(&mut self, dest: &mut [u8]) {
self.private.fill_bytes(dest);
}
}