use crate::error::{Error, Result};
use constant_time_eq::constant_time_eq_n;
pub fn num_bits(slice: &[u8]) -> u64 {
let len = slice.len() as u64;
assert!(len <= isize::MAX as u64); len * 8
}
#[cfg(feature = "rand")]
pub fn random_bytes<const BYTES: usize>() -> Result<[u8; BYTES]> {
use rand::TryRng;
let mut data = [0; BYTES];
let mut rng = rand::rngs::SysRng;
rng
.try_fill_bytes(&mut data)
.map_err(|_| Error::RandError)?;
Ok(data)
}
#[inline(always)]
pub fn validate_non_zero<const BYTES: usize>(
data: [u8; BYTES],
) -> Result<[u8; BYTES]> {
let all_zero = [0; BYTES];
if constant_time_eq_n(&all_zero, &data) {
Err(Error::AllZeroNotAllowed)
} else {
Ok(data)
}
}
macro_rules! const_assert {
($cond:expr) => {
const _: () = assert!($cond);
};
($cond:expr, $msg:literal) => {
const _: () = assert!($cond, $msg);
};
}
pub(crate) use const_assert;