diff --git a/src/hashs/mod.rs b/src/hashs/mod.rs index 8b06d9efc439008a850404f2877a8a4656d5e82a..8268083162db83d6ccd68cc136bb7803ace80082 100644 --- a/src/hashs/mod.rs +++ b/src/hashs/mod.rs @@ -17,7 +17,7 @@ use crate::bases::*; use crate::rand::UnspecifiedRandError; -use ring::{digest, rand}; +use ring::digest; #[cfg(feature = "ser")] use serde::{Deserialize, Serialize}; use std::fmt::{Debug, Display, Error, Formatter}; @@ -60,9 +60,8 @@ impl Hash { /// Generate a random Hash #[inline] pub fn random() -> Result<Self, UnspecifiedRandError> { - let random_bytes = rand::generate::<[u8; 32]>(&rand::SystemRandom::new()) - .map_err(|_| UnspecifiedRandError)?; - Ok(Hash(random_bytes.expose())) + let random_bytes = crate::rand::gen_32_bytes().map_err(|_| UnspecifiedRandError)?; + Ok(Hash(random_bytes)) } /// Compute hash of any binary datas diff --git a/src/rand.rs b/src/rand.rs index c30c712e9da3fd3bfb2c1667df6deb4e79788f4d..b1046ff7e0b30aa07a309023e3be65af8fe44088 100644 --- a/src/rand.rs +++ b/src/rand.rs @@ -16,7 +16,7 @@ //! Manage random generation. use byteorder::ByteOrder; -use ring::rand; +use ring::rand::{generate, SystemRandom}; /// An error with absolutely no details. /// @@ -37,21 +37,72 @@ use ring::rand; #[derive(Copy, Clone, Debug, PartialEq)] pub struct UnspecifiedRandError; +/// Secure random bytes generator +pub fn gen_random_bytes(buffer: &mut [u8]) -> Result<(), UnspecifiedRandError> { + let mut cursor = 0; + let mut remaining_len = buffer.len(); + + while remaining_len >= 32 { + buffer[cursor..(cursor + 32)].copy_from_slice(&gen_32_bytes()?[..]); + cursor += 32; + remaining_len -= 32; + } + while remaining_len >= 16 { + buffer[cursor..(cursor + 16)].copy_from_slice(&gen_16_bytes()?[..]); + cursor += 16; + remaining_len -= 16; + } + if remaining_len > 0 { + buffer[cursor..].copy_from_slice(&gen_16_bytes()?[..remaining_len]); + } + + Ok(()) +} + #[inline] /// Generate random u32 pub fn gen_u32() -> Result<u32, UnspecifiedRandError> { - let rng = rand::SystemRandom::new(); - let random_bytes = rand::generate::<[u8; 4]>(&rng).map_err(|_| UnspecifiedRandError)?; + let random_bytes = + generate::<[u8; 4]>(&SystemRandom::new()).map_err(|_| UnspecifiedRandError)?; + Ok(byteorder::BigEndian::read_u32(&random_bytes.expose())) } +#[inline] +/// Generate random 16 bytes +pub fn gen_16_bytes() -> Result<[u8; 16], UnspecifiedRandError> { + let random_bytes = + generate::<[u8; 16]>(&SystemRandom::new()).map_err(|_| UnspecifiedRandError)?; + + Ok(random_bytes.expose()) +} + +#[inline] +/// Generate random 32 bytes +pub fn gen_32_bytes() -> Result<[u8; 32], UnspecifiedRandError> { + let random_bytes = + generate::<[u8; 32]>(&SystemRandom::new()).map_err(|_| UnspecifiedRandError)?; + + Ok(random_bytes.expose()) +} + #[cfg(test)] mod tests { use super::*; #[test] - fn test_gen_u32() { - assert_ne!(gen_u32(), gen_u32()) + fn test_gen_u32() -> Result<(), UnspecifiedRandError> { + assert_ne!(gen_u32()?, gen_u32()?); + Ok(()) + } + + #[test] + fn test_gen_random_bytes() -> Result<(), UnspecifiedRandError> { + let mut buffer = [0u8; 51]; + gen_random_bytes(buffer.as_mut())?; + let mut buffer = [0u8; 48]; + gen_random_bytes(buffer.as_mut())?; + Ok(()) } } diff --git a/src/seeds.rs b/src/seeds.rs index 923054f56eb30f6191569a4a4f238de1d307aef0..089c26c73df2c0bfb4df47e30fe3e61b12ead6bc 100644 --- a/src/seeds.rs +++ b/src/seeds.rs @@ -18,7 +18,6 @@ use crate::bases::b58::{bytes_to_str_base58, ToBase58}; use crate::bases::*; use crate::rand::UnspecifiedRandError; -use ring::rand; #[cfg(feature = "ser")] use serde::{Deserialize, Serialize}; use std::fmt::{self, Debug, Display, Formatter}; @@ -68,9 +67,8 @@ impl Seed32 { #[inline] /// Generate random seed pub fn random() -> Result<Seed32, UnspecifiedRandError> { - let random_bytes = rand::generate::<[u8; 32]>(&rand::SystemRandom::new()) - .map_err(|_| UnspecifiedRandError)?; - Ok(Seed32::new(random_bytes.expose())) + let random_bytes = crate::rand::gen_32_bytes().map_err(|_| UnspecifiedRandError)?; + Ok(Seed32::new(random_bytes)) } }