hbs_lms/lms/
parameters.rs

1use core::marker::PhantomData;
2
3use crate::hasher::{sha256::Sha256_256, HashChain};
4
5/// Specifies the used Tree height.
6#[derive(Clone, Copy)]
7pub enum LmsAlgorithm {
8    LmsReserved = 0,
9    #[cfg(test)]
10    LmsH2 = 1,
11    LmsH5 = 5,
12    LmsH10 = 6,
13    LmsH15 = 7,
14    LmsH20 = 8,
15    LmsH25 = 9,
16}
17
18impl Default for LmsAlgorithm {
19    fn default() -> Self {
20        LmsAlgorithm::LmsReserved
21    }
22}
23
24impl From<u32> for LmsAlgorithm {
25    fn from(_type: u32) -> Self {
26        match _type {
27            #[cfg(test)]
28            1 => LmsAlgorithm::LmsH2,
29            5 => LmsAlgorithm::LmsH5,
30            6 => LmsAlgorithm::LmsH10,
31            7 => LmsAlgorithm::LmsH15,
32            8 => LmsAlgorithm::LmsH20,
33            9 => LmsAlgorithm::LmsH25,
34            _ => LmsAlgorithm::LmsReserved,
35        }
36    }
37}
38
39impl LmsAlgorithm {
40    pub fn construct_default_parameter() -> LmsParameter<Sha256_256> {
41        LmsAlgorithm::LmsH5.construct_parameter().unwrap()
42    }
43
44    pub fn construct_parameter<H: HashChain>(&self) -> Option<LmsParameter<H>> {
45        match *self {
46            LmsAlgorithm::LmsReserved => None,
47            #[cfg(test)]
48            LmsAlgorithm::LmsH2 => Some(LmsParameter::new(1, 2)),
49            LmsAlgorithm::LmsH5 => Some(LmsParameter::new(5, 5)),
50            LmsAlgorithm::LmsH10 => Some(LmsParameter::new(6, 10)),
51            LmsAlgorithm::LmsH15 => Some(LmsParameter::new(7, 15)),
52            LmsAlgorithm::LmsH20 => Some(LmsParameter::new(8, 20)),
53            LmsAlgorithm::LmsH25 => Some(LmsParameter::new(9, 25)),
54        }
55    }
56
57    pub fn get_from_type<H: HashChain>(_type: u32) -> Option<LmsParameter<H>> {
58        match _type {
59            #[cfg(test)]
60            1 => LmsAlgorithm::LmsH2.construct_parameter(),
61            5 => LmsAlgorithm::LmsH5.construct_parameter(),
62            6 => LmsAlgorithm::LmsH10.construct_parameter(),
63            7 => LmsAlgorithm::LmsH15.construct_parameter(),
64            8 => LmsAlgorithm::LmsH20.construct_parameter(),
65            9 => LmsAlgorithm::LmsH25.construct_parameter(),
66            _ => None,
67        }
68    }
69}
70
71#[derive(Debug, Clone, PartialEq, Eq)]
72pub struct LmsParameter<H: HashChain> {
73    type_id: u32,
74    tree_height: u8,
75    phantom_data: PhantomData<H>,
76}
77
78// Manually implement Copy because HashChain trait does not.
79// However, it does not make a difference, because we don't hold a instance for HashChain.
80impl<H: HashChain> Copy for LmsParameter<H> {}
81
82impl<H: HashChain> LmsParameter<H> {
83    const HASH_FUNCTION_OUTPUT_SIZE: usize = H::OUTPUT_SIZE as usize;
84
85    pub fn new(type_id: u32, tree_height: u8) -> Self {
86        Self {
87            type_id,
88            tree_height,
89            phantom_data: PhantomData,
90        }
91    }
92
93    pub fn get_type_id(&self) -> u32 {
94        self.type_id
95    }
96
97    pub fn get_hash_function_output_size(&self) -> usize {
98        Self::HASH_FUNCTION_OUTPUT_SIZE
99    }
100
101    pub fn get_tree_height(&self) -> u8 {
102        self.tree_height
103    }
104
105    pub fn number_of_lm_ots_keys(&self) -> usize {
106        2usize.pow(self.tree_height as u32)
107    }
108
109    pub fn get_hasher(&self) -> H {
110        H::default()
111    }
112}
113
114impl<H: HashChain> Default for LmsParameter<H> {
115    fn default() -> Self {
116        LmsAlgorithm::LmsH5.construct_parameter().unwrap()
117    }
118}