lorawan-device 0.12.2

A Rust LoRaWAN device stack implementation
Documentation
//! 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(())
    }
}