Init
This commit is contained in:
54
lorawan-device-patch/src/rng.rs
Normal file
54
lorawan-device-patch/src/rng.rs
Normal file
@@ -0,0 +1,54 @@
|
||||
//! RNG based on the `wyrand` pseudorandom number generator.
|
||||
//!
|
||||
//! This crate uses the random number generator for exactly two things:
|
||||
//!
|
||||
//! * Generating DevNonces for join requests
|
||||
//! * Selecting random channels when transmitting uplinks.
|
||||
//!
|
||||
//! The good news is that both these operations don't require true
|
||||
//! cryptographic randomness. In fact, in both cases, we don't even care about
|
||||
//! predictability! A pseudorandom number generator initialized with a seed
|
||||
//! generated by a true random number generator is plenty enough:
|
||||
//!
|
||||
//! * DevNonces must only be unique with a low chance of collision.
|
||||
//! The 1.0.4 LoRaWAN spec even explicitly requires the DevNonces to be
|
||||
//! a sequence of incrementing integers, which is obviously predictable.
|
||||
//! * No one cares if the channel selected for the next uplink is predictable,
|
||||
//! as long as the channel selection yields an uniform distribution.
|
||||
//!
|
||||
//! By providing a PRNG `RngCore` implementation, we enable the crate users the
|
||||
//! flexibility of choosing whether they want to provide their own RNG, or just
|
||||
//! a seed to instantiate this PRNG to generate the random numbers for them.
|
||||
|
||||
use fastrand::Rng;
|
||||
use rand_core::RngCore;
|
||||
|
||||
#[derive(Clone)]
|
||||
/// A pseudorandom number generator utilizing Wyrand algorithm via
|
||||
/// the `fastrand` crate.
|
||||
pub struct Prng(Rng);
|
||||
|
||||
impl Prng {
|
||||
pub(crate) fn new(seed: u64) -> Self {
|
||||
Self(Rng::with_seed(seed))
|
||||
}
|
||||
}
|
||||
|
||||
impl RngCore for Prng {
|
||||
fn next_u32(&mut self) -> u32 {
|
||||
self.0.u32(..)
|
||||
}
|
||||
|
||||
fn next_u64(&mut self) -> u64 {
|
||||
self.0.u64(..)
|
||||
}
|
||||
|
||||
fn fill_bytes(&mut self, dest: &mut [u8]) {
|
||||
rand_core::impls::fill_bytes_via_next(self, dest)
|
||||
}
|
||||
|
||||
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> {
|
||||
self.fill_bytes(dest);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user