use crate::ots::modes::LmsOtsMode;
use crate::types::Typecode;
use digest::Digest;
use digest::Output;
use generic_array::ArrayLength;
use std::ops::Add;
use std::{
marker::PhantomData,
ops::{Shl, Sub},
};
use typenum::{bit::B1, Add1, Shleft, Sub1, U1, U10, U15, U20, U25, U5};
pub trait LmsMode: Typecode + Clone {
type Hasher: Digest;
type OtsMode: LmsOtsMode;
type TreeLen: ArrayLength<Output<Self::Hasher>>;
type HLen: ArrayLength<Output<Self::Hasher>>;
const M: usize;
const H: usize;
const LEAVES: u32; const TREE_NODES: u32; }
#[derive(Debug)]
pub struct LmsModeInternal<
OtsMode: LmsOtsMode,
Hasher: Digest,
HLen: ArrayLength<Output<Hasher>>,
const M: usize,
const H: usize,
const TC: u32,
> {
_ots_mode: PhantomData<OtsMode>,
_hasher: PhantomData<Hasher>,
_h_len: PhantomData<HLen>,
}
impl<
OtsMode: LmsOtsMode,
Hasher: Digest,
TreeLen: ArrayLength<Output<Hasher>>,
const M: usize,
const H: usize,
const TC: u32,
> Clone for LmsModeInternal<OtsMode, Hasher, TreeLen, M, H, TC>
{
fn clone(&self) -> Self {
*self
}
}
impl<
OtsMode: LmsOtsMode,
Hasher: Digest,
TreeLen: ArrayLength<Output<Hasher>>,
const M: usize,
const H: usize,
const TC: u32,
> Copy for LmsModeInternal<OtsMode, Hasher, TreeLen, M, H, TC>
{
}
impl<
OtsMode: LmsOtsMode,
Hasher: Digest,
HLen: ArrayLength<Output<Hasher>>,
const M: usize,
const H: usize,
const TC: u32,
> LmsMode for LmsModeInternal<OtsMode, Hasher, HLen, M, H, TC>
where
HLen: Add<typenum::B1>,
U1: Shl<<HLen as Add<B1>>::Output>,
Shleft<U1, <HLen as Add<B1>>::Output>: Sub<B1>,
Sub1<Shleft<U1, <HLen as Add<B1>>::Output>>: ArrayLength<Output<Hasher>>,
{
type OtsMode = OtsMode;
type Hasher = Hasher;
type TreeLen = Sub1<Shleft<U1, Add1<HLen>>>;
type HLen = HLen;
const M: usize = M;
const H: usize = H;
const LEAVES: u32 = 1 << H; const TREE_NODES: u32 = (1 << (H + 1)) - 1; }
impl<
Hasher: Digest,
OtsMode: LmsOtsMode,
TreeLen: ArrayLength<Output<Hasher>>,
const M: usize,
const H: usize,
const TC: u32,
> Typecode for LmsModeInternal<OtsMode, Hasher, TreeLen, M, H, TC>
{
const TYPECODE: u32 = TC;
}
pub type LmsSha256M32H5<OtsMode> = LmsModeInternal<OtsMode, sha2::Sha256, U5, 32, 5, 5>;
pub type LmsSha256M32H10<OtsMode> = LmsModeInternal<OtsMode, sha2::Sha256, U10, 32, 10, 6>;
pub type LmsSha256M32H15<OtsMode> = LmsModeInternal<OtsMode, sha2::Sha256, U15, 32, 15, 7>;
pub type LmsSha256M32H20<OtsMode> = LmsModeInternal<OtsMode, sha2::Sha256, U20, 32, 20, 8>;
pub type LmsSha256M32H25<OtsMode> = LmsModeInternal<OtsMode, sha2::Sha256, U25, 32, 25, 9>;