embassy/embassy-traits/src/rng.rs

77 lines
2.1 KiB
Rust
Raw Normal View History

2021-04-26 15:43:19 +02:00
use core::future::Future;
/// Random-number Generator
pub trait Rng {
type Error;
2021-08-27 22:10:01 +02:00
#[rustfmt::skip]
2021-08-30 15:55:29 +02:00
type RngFuture<'a>: Future<Output = Result<(), Self::Error> > + 'a
2021-04-26 15:43:19 +02:00
where
2021-08-30 15:55:29 +02:00
Self: 'a;
2021-04-26 15:43:19 +02:00
/// Completely fill the provided buffer with random bytes.
///
/// May result in delays if entropy is exhausted prior to completely
/// filling the buffer. Upon completion, the buffer will be completely
/// filled or an error will have been reported.
fn fill_bytes<'a>(&'a mut self, dest: &'a mut [u8]) -> Self::RngFuture<'a>;
2021-08-30 15:55:29 +02:00
}
2021-08-27 22:10:01 +02:00
pub struct Random<T: Rng> {
rng: T,
}
impl<T: Rng> Random<T> {
pub fn new(rng: T) -> Self {
Self { rng }
}
2021-10-18 00:55:43 +02:00
pub async fn next_u8(&mut self, range: u8) -> Result<u8, T::Error> {
// Lemire's method
let t = (-(range as i8) % (range as i8)) as u8;
loop {
let mut buf = [0; 1];
self.rng.fill_bytes(&mut buf).await?;
let x = u8::from_le_bytes(buf);
let m = x as u16 * range as u16;
let l = m as u8;
if l < t {
continue;
}
return Ok((m >> 8) as u8);
}
}
2021-10-18 00:55:43 +02:00
pub async fn next_u16(&mut self, range: u16) -> Result<u16, T::Error> {
// Lemire's method
let t = (-(range as i16) % (range as i16)) as u16;
loop {
let mut buf = [0; 2];
self.rng.fill_bytes(&mut buf).await?;
let x = u16::from_le_bytes(buf);
let m = x as u32 * range as u32;
let l = m as u16;
if l < t {
continue;
}
return Ok((m >> 16) as u16);
}
}
2021-08-27 22:10:01 +02:00
2021-10-18 00:55:43 +02:00
pub async fn next_u32(&mut self, range: u32) -> Result<u32, T::Error> {
// Lemire's method
let t = (-(range as i32) % (range as i32)) as u32;
loop {
let mut buf = [0; 4];
self.rng.fill_bytes(&mut buf).await?;
let x = u32::from_le_bytes(buf);
let m = x as u64 * range as u64;
let l = m as u32;
if l < t {
continue;
}
return Ok((m >> 32) as u32);
}
}
2021-04-26 15:43:19 +02:00
}