use anyhow::{anyhow, Error, Result};
#[derive(Clone, Copy)]
pub struct D {
pub d: u64,
log_log_d_plus_1: usize,
}
impl D {
pub fn new(d: u64) -> Self {
D::try_from(d).unwrap()
}
pub fn bits_to_combine(&self) -> usize {
1 << self.log_log_d_plus_1
}
pub fn bits_c(&self) -> usize {
let bits_c = self.bits_to_combine() + 8 - self.log_log_d_plus_1;
let bits_c = (((bits_c as f32) / (self.bits_to_combine() as f32)).ceil() as usize)
* self.bits_to_combine();
bits_c
}
pub fn signature_and_key_size(&self) -> usize {
(256 + self.bits_c()) / self.bits_to_combine()
}
}
impl TryFrom<u64> for D {
type Error = Error;
fn try_from(d: u64) -> Result<D> {
let log_log_d_plus_1 = ((d + 1) as f64).log2().log2() as usize;
if d + 1 != (1 << (1 << log_log_d_plus_1)) {
Err(anyhow!(
"d is not of the form 2^(2^x) - 1! Try one of 1, 3, 15, or 255."
))
} else {
Ok(D {
d,
log_log_d_plus_1,
})
}
}
}