use std;
use errors::*;
use ring::error::Unspecified;
use ring::rand::SecureRandom;
pub(crate) const MAX_MESSAGE_SIZE: usize = std::usize::MAX / (std::u8::MAX - 1) as usize;
pub(crate) static MIN_MESSAGE_SIZE: usize = 1;
pub(crate) fn random_bytes_count(threshold: u8, message_size: usize) -> usize {
assert!(threshold >= MIN_THRESHOLD);
assert!(message_size >= MIN_MESSAGE_SIZE);
assert!(message_size <= MAX_MESSAGE_SIZE);
(threshold as usize - 1) * message_size
}
pub(crate) fn random_bytes(random: &SecureRandom, count: usize) -> Result<Vec<u8>> {
if count == 0 {
return Ok(Vec::new());
}
let mut rl = vec![0; count];
random
.fill(&mut rl)
.chain_err(|| ErrorKind::CannotGenerateRandomNumbers)?;
Ok(rl)
}
pub(crate) struct FixedRandom {
src: Vec<u8>,
}
impl FixedRandom {
pub(crate) fn new(src: Vec<u8>) -> Self {
if src.is_empty() {
panic!("The source slice of FixedRandom cannot be empty!");
}
FixedRandom { src }
}
}
impl SecureRandom for FixedRandom {
fn fill(&self, dst: &mut [u8]) -> std::result::Result<(), Unspecified> {
if dst.len() > self.src.len() {
return Err(Unspecified);
}
let len = dst.len();
dst.copy_from_slice(&self.src[0..len]);
Ok(())
}
}