crate::ix!();
pub fn proc_rand(
out: &mut [u8],
num: i32,
level: RNGLevel
) {
let rng: &mut RNGState = &mut G_RNG.lock();
assert!{num <= 32};
let mut hasher = Sha512::default();
match level {
RNGLevel::FAST => {
seed_fast(&mut hasher);
}
RNGLevel::SLOW => {
seed_slow(&mut hasher, rng);
}
RNGLevel::PERIODIC => {
seed_periodic(&mut hasher, rng);
}
}
let num: usize = num.try_into().unwrap();
if !rng.mix_extract(out, num, hasher, false) {
let mut startup_hasher = Sha512::default();
seed_startup(&mut startup_hasher, rng);
rng.mix_extract(out, num, startup_hasher, true);
}
}
#[cfg(test)]
mod proc_rand_spec {
use super::*;
#[traced_test]
fn proc_rand_fast_and_slow_produce_up_to_32_bytes() {
let mut out = [0u8; 32];
proc_rand(&mut out, 32, RNGLevel::FAST);
assert!(out.iter().any(|&x| x != 0));
let mut out2 = [0u8; 32];
proc_rand(&mut out2, 32, RNGLevel::SLOW);
assert!(out2.iter().any(|&x| x != 0));
}
#[traced_test]
fn proc_rand_zero_len_is_allowed_and_does_not_panic() {
let mut out = [0u8; 0];
proc_rand(&mut out, 0, RNGLevel::FAST);
}
}