pub mod fors;
pub mod hash;
pub mod hypertree;
pub mod merkle;
mod params;
mod utils;
pub mod winternitz_ots;
pub mod xmss;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum AdrsType {
WotsHash = 0,
WotsPk = 1,
Tree = 2,
ForsTree = 3,
ForsRoots = 4,
WotsPrf = 5,
ForsPrf = 6,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct Adrs([u8; 32]);
impl Adrs {
pub fn new() -> Self {
Self([0u8; 32])
}
fn get_word(&self, word: usize) -> u32 {
let off = word * 4;
u32::from_be_bytes(self.0[off..off + 4].try_into().unwrap())
}
fn set_word(&mut self, word: usize, val: u32) {
let off = word * 4;
self.0[off..off + 4].copy_from_slice(&val.to_be_bytes());
}
pub fn with_xmss_height(mut self, height: impl Into<u32>) -> Self {
self.set_word(0, height.into());
self
}
pub fn get_xmss_height(&self) -> u32 {
self.get_word(0)
}
pub fn with_xmss_index(mut self, idx: u64) -> Self {
self.0[4..8].fill(0);
self.0[8..16].copy_from_slice(&idx.to_be_bytes());
self
}
pub fn with_type(mut self, adrs_type: AdrsType) -> Self {
self.set_word(4, adrs_type as u32);
self.0[20..32].fill(0);
self
}
pub fn get_type(&self) -> AdrsType {
let x = self.get_word(4);
match x {
0 => AdrsType::WotsHash,
1 => AdrsType::WotsPk,
2 => AdrsType::Tree,
3 => AdrsType::ForsTree,
4 => AdrsType::ForsRoots,
5 => AdrsType::WotsPrf,
6 => AdrsType::ForsPrf,
_ => unreachable!("Invalid AdrsType"),
}
}
pub fn with_key_pair_address(mut self, kp: impl Into<u32>) -> Self {
self.set_word(5, kp.into());
self
}
pub fn get_key_pair_address(&self) -> u32 {
self.get_word(5)
}
pub fn with_chain_address(mut self, chain: impl Into<u32>) -> Self {
self.set_word(6, chain.into());
self
}
pub fn get_chain_address(&self) -> u32 {
self.get_word(6)
}
pub fn with_hash_address(mut self, hash: impl Into<u32>) -> Self {
self.set_word(7, hash.into());
self
}
pub fn get_hash_address(&self) -> u32 {
self.get_word(7)
}
pub fn with_tree_height(mut self, height: impl Into<u32>) -> Self {
self.set_word(6, height.into());
self
}
pub fn get_tree_height(&self) -> u32 {
self.get_word(6)
}
pub fn with_tree_index(mut self, index: impl Into<u32>) -> Self {
self.set_word(7, index.into());
self
}
pub fn get_tree_index(&self) -> u32 {
self.get_word(7)
}
pub fn compress(&self) -> [u8; 22] {
let mut out = [0u8; 22];
out[0] = self.0[3]; out[1..9].copy_from_slice(&self.0[8..16]); out[9] = self.0[19]; out[10..22].copy_from_slice(&self.0[20..32]); out
}
pub fn as_bytes(&self) -> &[u8; 32] {
&self.0
}
}