use crate::types::{Adrs, Auth, ForsSig, HtSig, SlhDsaSig, WotsSig, XmssSig};
pub(crate) fn to_int(x: &[u8], n: u32) -> u64 {
debug_assert_eq!(x.len(), n as usize);
debug_assert!(n <= 8);
let mut total = 0;
for item in x.iter().take(n as usize) {
total = (total << 8) + u64::from(*item);
}
total
}
pub(crate) fn to_byte(x: u32, n: u32) -> [u8; ((crate::LEN2 * crate::LGW + 7) / 8) as usize] {
let mut s = [0u8; ((crate::LEN2 * crate::LGW + 7) / 8) as usize]; debug_assert_eq!(n, ((crate::LEN2 * crate::LGW + 7) / 8)); debug_assert_eq!(n, 2);
let mut total = x;
for i in 0..n {
s[(n - 1 - i) as usize] = total.to_le_bytes()[0];
total >>= 8;
}
s
}
pub(crate) fn base_2b(x: &[u8], b: u32, out_len: u32, baseb: &mut [u32]) {
debug_assert!(x.len() >= ((out_len * b + 7) / 8) as usize);
debug_assert!(b < 16);
debug_assert_eq!(out_len as usize, baseb.len());
let mut inn = 0;
let mut bits = 0;
let mut total = 0;
for item in baseb.iter_mut() {
while bits < b {
total = (total << 8) + u32::from(x[inn]);
inn += 1;
bits += 8;
}
bits -= b;
*item = (total >> bits) & (u32::MAX >> (32 - b));
}
}
impl<
const A: usize,
const D: usize,
const HP: usize,
const K: usize,
const LEN: usize,
const N: usize,
> SlhDsaSig<A, D, HP, K, LEN, N>
{
pub(crate) fn serialize<const SIG_LEN: usize>(self) -> [u8; SIG_LEN] {
let mut out = [0u8; SIG_LEN];
debug_assert_eq!(
out.len(),
N + N * K + K * A * N + D * (HP * N + LEN * N)
);
out[0..N].copy_from_slice(&self.randomness);
let mut start = N;
for k in 0..K {
out[start..(start + N)].copy_from_slice(&self.fors_sig.private_key_value[k]);
start += N;
for a in 0..A {
out[start..(start + N)].copy_from_slice(&self.fors_sig.auth[k].tree[a]);
start += N;
}
}
for d in 0..D {
for len in 0..LEN {
out[start..(start + N)]
.copy_from_slice(&self.ht_sig.xmss_sigs[d].sig_wots.data[len]);
start += N;
}
for hp in 0..HP {
out[start..(start + N)].copy_from_slice(&self.ht_sig.xmss_sigs[d].auth[hp]);
start += N;
}
}
debug_assert_eq!(start, out.len());
out
}
pub(crate) fn deserialize(bytes: &[u8]) -> Self {
debug_assert_eq!(
bytes.len(),
N + N * K + K * A * N + D * (HP * N + LEN * N)
);
let mut output = SlhDsaSig {
randomness: [0u8; N],
fors_sig: ForsSig {
private_key_value: [[0u8; N]; K],
auth: core::array::from_fn(|_| Auth { tree: [[0u8; N]; A] }),
},
ht_sig: HtSig {
xmss_sigs: core::array::from_fn(|_| XmssSig {
sig_wots: WotsSig { data: [[0u8; N]; LEN] },
auth: [[0u8; N]; HP],
}),
},
};
output.randomness.copy_from_slice(&bytes[0..N]);
let mut start = N;
for k in 0..K {
output.fors_sig.private_key_value[k].copy_from_slice(&bytes[start..(start + N)]);
start += N;
for a in 0..A {
output.fors_sig.auth[k].tree[a].copy_from_slice(&bytes[start..(start + N)]);
start += N;
}
}
for d in 0..D {
for len in 0..LEN {
output.ht_sig.xmss_sigs[d].sig_wots.data[len]
.copy_from_slice(&bytes[start..(start + N)]);
start += N;
}
for hp in 0..HP {
output.ht_sig.xmss_sigs[d].auth[hp].copy_from_slice(&bytes[start..(start + N)]);
start += N;
}
}
debug_assert_eq!(start, bytes.len());
output
}
}
impl Adrs {
pub(crate) fn set_layer_address(&mut self, la: u32) { self.f0 = la.to_be_bytes() }
pub(crate) fn get_key_pair_address(&self) -> u32 { u32::from_be_bytes(self.f5) }
pub(crate) fn set_key_pair_address(&mut self, kp_addr: u32) { self.f5 = kp_addr.to_be_bytes(); }
pub(crate) fn set_chain_address(&mut self, i: u32) { self.f6 = i.to_be_bytes(); }
pub(crate) fn set_type_and_clear(&mut self, type_t: u32) {
self.f4 = type_t.to_be_bytes();
self.f5 = 0u32.to_be_bytes();
self.f6 = 0u32.to_be_bytes();
self.f7 = 0u32.to_be_bytes();
}
pub(crate) fn set_tree_address(&mut self, t: u64) {
let bytes = t.to_be_bytes();
self.f2.copy_from_slice(&bytes[..4]); self.f3.copy_from_slice(&bytes[4..]); }
pub(crate) fn set_hash_address(&mut self, addr: u32) { self.f7 = addr.to_be_bytes() }
pub(crate) fn set_tree_height(&mut self, z: u32) { self.f6 = z.to_be_bytes() }
pub(crate) fn get_tree_index(&mut self) -> u32 { u32::from_be_bytes(self.f7) }
pub(crate) fn set_tree_index(&mut self, i: u32) { self.f7 = i.to_be_bytes() }
#[cfg(any(
feature = "slh_dsa_shake_128f",
feature = "slh_dsa_shake_128s",
feature = "slh_dsa_shake_192f",
feature = "slh_dsa_shake_192s",
feature = "slh_dsa_shake_256f",
feature = "slh_dsa_shake_256s"
))]
pub(crate) fn to_32_bytes(&self) -> [u8; 32] {
let mut ret = [0u8; 32];
let mut start = 0;
for sl in [
self.f0, self.f1, self.f2, self.f3, self.f4, self.f5, self.f6, self.f7,
] {
ret[start..start + 4].copy_from_slice(&sl);
start += 4;
}
ret
}
#[cfg(any(
feature = "slh_dsa_sha2_128f",
feature = "slh_dsa_sha2_128s",
feature = "slh_dsa_sha2_192f",
feature = "slh_dsa_sha2_192s",
feature = "slh_dsa_sha2_256f",
feature = "slh_dsa_sha2_256s"
))]
pub(crate) fn to_22_bytes(&self) -> [u8; 22] {
let mut ret = [0u8; 22];
ret[0] = self.f0[3];
ret[1..5].copy_from_slice(&self.f2);
ret[5..9].copy_from_slice(&self.f3);
ret[9] = self.f4[3];
ret[10..14].copy_from_slice(&self.f5);
ret[14..18].copy_from_slice(&self.f6);
ret[18..22].copy_from_slice(&self.f7);
ret
}
}