minor clippy

This commit is contained in:
eschorn1 2024-03-10 08:15:56 -05:00
parent f4bd328bf1
commit bdd49221e4
9 changed files with 114 additions and 98 deletions

View file

@ -17,7 +17,6 @@ zeroize = { version = "1.6.0", default-features = false, features = ["zeroize_de
rand_core = { version = "0.6.4", default-features = false }
sha3 = { version = "0.10.2", default-features = false } # For MSRV 1.70
sha2 = { version = "0.10.8", default-features = false }
generic-array = { version = "1.0.0", features=["const-default", "zeroize"] }
[dev-dependencies]

View file

@ -1,6 +1,6 @@
use crate::hashers::Hashers;
use crate::helpers;
use crate::types::{Adrs, ForsPk, ForsSig, FORS_PRF, FORS_ROOTS, Auth};
use crate::helpers::base_2b;
use crate::types::{Adrs, Auth, ForsPk, ForsSig, FORS_PRF, FORS_ROOTS};
/// Algorithm 13: `fors_SKgen(SK.seed, PK.seed, ADRS, idx)` on page 29.
@ -45,11 +45,11 @@ pub(crate) fn fors_node<
>(
hashers: &Hashers<K, LEN, M, N>, sk_seed: &[u8], i: u32, z: u32, pk_seed: &[u8], adrs: &Adrs,
) -> Result<[u8; N], &'static str> {
let mut adrs = adrs.clone();
let (a32, k32) = (u32::try_from(A).unwrap(), u32::try_from(K).unwrap());
let mut adrs = adrs.clone();
// 1: if z > a or i ≥ k · 2^(az) then
if (z > a32) | (i > k32 * 2u32.pow(a32 - z)) {
if (z > a32) | (i > k32 * (1 << (a32 - z))) {
//
// 2: return NULL
return Err("Alg14 fails");
@ -61,7 +61,7 @@ pub(crate) fn fors_node<
let node = if z == 0 {
//
// 5: sk ← fors_SKgen(SK.seed, PK.seed, ADRS, i)
let sk: [u8; N] = fors_sk_gen(hashers, sk_seed, pk_seed, &adrs, i);
let sk = fors_sk_gen(hashers, sk_seed, pk_seed, &adrs, i);
// 6: ADRS.setTreeHeight(0)
adrs.set_tree_height(0);
@ -114,13 +114,17 @@ pub(crate) fn fors_sign<
>(
hashers: &Hashers<K, LEN, M, N>, md: &[u8], sk_seed: &[u8], adrs: &Adrs, pk_seed: &[u8],
) -> Result<ForsSig<A, K, N>, &'static str> {
// 1: SIG_FORS = NULL ▷ Initialize SIG_FORS as a zero-length byte string
let mut sig_fors = ForsSig { private_key_value: [[0u8; N]; K], auth: core::array::from_fn(|_| Auth{ tree: [[0u8; N]; A] }) }; //ForsSig::default();
let (a32, k32) = (u32::try_from(A).unwrap(), u32::try_from(K).unwrap());
// 1: SIG_FORS = NULL ▷ Initialize SIG_FORS as a zero-length byte string
let mut sig_fors = ForsSig {
private_key_value: [[0u8; N]; K],
auth: core::array::from_fn(|_| Auth { tree: [[0u8; N]; A] }),
};
// 2: indices ← base_2^b(md, a, k)
let mut indices = [0u32; K];
helpers::base_2b(md, a32, k32, &mut indices);
base_2b(md, a32, k32, &mut indices);
// 3: for i from 0 to k 1 do ▷ Compute signature elements
for i in 0..k32 {
@ -131,7 +135,7 @@ pub(crate) fn fors_sign<
sk_seed,
pk_seed,
adrs,
i * 2u32.pow(a32) + indices[i as usize],
i * (1 << a32) + indices[i as usize],
);
// 5:
@ -145,7 +149,7 @@ pub(crate) fn fors_sign<
sig_fors.auth[i as usize].tree[j as usize] = fors_node::<A, K, LEN, M, N>(
hashers,
sk_seed,
i * 2u32.pow(a32 - j) + s,
i * (1 << (a32 - j)) + s,
j,
pk_seed,
adrs,
@ -181,13 +185,12 @@ pub(crate) fn fors_pk_from_sig<
hashers: &Hashers<K, LEN, M, N>, sig_fors: &ForsSig<A, K, N>, md: &[u8], pk_seed: &[u8],
adrs: &Adrs,
) -> ForsPk<N> {
let mut adrs = adrs.clone();
let (a32, k32) = (u32::try_from(A).unwrap(), u32::try_from(K).unwrap());
let mut adrs = adrs.clone();
// 1: indices ← base_2^b(md, a, k)
let mut indices = [0u32; K];
helpers::base_2b(md, a32, k32, &mut indices);
base_2b(md, a32, k32, &mut indices);
// 2: for i from 0 to k 1 do
let mut root = [[0u8; N]; K];
@ -200,7 +203,7 @@ pub(crate) fn fors_pk_from_sig<
adrs.set_tree_height(0);
// 5: ADRS.setTreeIndex(i · 2^a + indices[i])
adrs.set_tree_index(i * 2u32.pow(a32) + indices[i as usize]);
adrs.set_tree_index(i * (1 << a32) + indices[i as usize]);
// 6: node[0] ← F(PK.seed, ADRS, sk)
let mut node_0 = (hashers.f)(pk_seed, &adrs, &sk);

View file

@ -1,7 +1,7 @@
use crate::types::Adrs;
// Holds hasher function references; constructed by each wrapper
// Holds hasher function references; constructed by each security parameter set wrapper
#[allow(clippy::type_complexity)]
pub(crate) struct Hashers<const K: usize, const LEN: usize, const M: usize, const N: usize> {
pub(crate) h_msg: fn(&[u8], &[u8], &[u8], &[u8]) -> [u8; M],
@ -28,7 +28,6 @@ pub(crate) mod shake {
use sha3::Shake256;
#[allow(clippy::module_name_repetitions)]
fn shake256(input: &[&[u8]], out: &mut [u8]) {
let mut hasher = Shake256::default();
input.iter().for_each(|item| hasher.update(item));
@ -49,7 +48,7 @@ pub(crate) mod shake {
#[allow(clippy::similar_names)] // pk_seed and sk_seed
pub(crate) fn prf<const N: usize>(pk_seed: &[u8], sk_seed: &[u8], adrs: &Adrs) -> [u8; N] {
let mut digest = [0u8; N];
shake256(&[pk_seed, &adrs.to_32_bytes(), sk_seed], &mut digest); // Note that the spec swaps order of last to params
shake256(&[pk_seed, &adrs.to_32_bytes(), sk_seed], &mut digest); // Spec swaps order of last two params 557/997/1005
digest
}
@ -99,7 +98,6 @@ pub(crate) mod sha2_cat_1 {
fn sha2_256(input: &[&[u8]], out: &mut [u8]) {
debug_assert!(out.len() <= 32);
let mut hasher = Sha256::new();
input.iter().for_each(|item| hasher.update(item));
let result = hasher.finalize();
@ -130,27 +128,26 @@ pub(crate) mod sha2_cat_1 {
#[allow(clippy::similar_names)] // pk_seed and sk_seed
pub(crate) fn prf<const N: usize>(pk_seed: &[u8], sk_seed: &[u8], adrs: &Adrs) -> [u8; N] {
let mut digest = [0u8; N];
let to_byte = [0u8; 64];
sha2_256(&[pk_seed, &to_byte[0..(64 - N)], &adrs.to_22_bytes(), sk_seed], &mut digest); // Note that the spec swaps order of last to params
let zeros = [0u8; 48];
sha2_256(&[pk_seed, &zeros[0..(64 - N)], &adrs.to_22_bytes(), sk_seed], &mut digest); // Spec swaps order of last two params 557/997/1005
digest
}
fn hmac_sha_256(key: &[u8], a0: &[u8], b1: &[u8]) -> [u8; 32] {
let k2 = key;
let mut padded = [0x36; 64];
for (p, &k) in padded.iter_mut().zip(k2.iter()) {
let mut padding = [0x36; 64];
for (p, &k) in padding.iter_mut().zip(key.iter()) {
*p ^= k;
}
let mut inner_hasher = Sha256::new();
inner_hasher.update(&padded[..]);
inner_hasher.update(&padding[..]);
inner_hasher.update(a0);
inner_hasher.update(b1);
for p in &mut padded {
for p in &mut padding {
*p ^= 0x6a;
}
let mut outer_hasher = Sha256::new();
outer_hasher.update(&padded[..]);
outer_hasher.update(&padding[..]);
outer_hasher.update(inner_hasher.finalize());
outer_hasher.finalize().into()
}
@ -158,37 +155,36 @@ pub(crate) mod sha2_cat_1 {
pub(crate) fn prf_msg<const N: usize>(sk_prf: &[u8], opt_rand: &[u8], m: &[u8]) -> [u8; N] {
let mut digest = [0u8; N];
let xxx = hmac_sha_256(sk_prf, opt_rand, m);
digest.copy_from_slice(&xxx[0..N]);
let full_digest = hmac_sha_256(sk_prf, opt_rand, m);
digest.copy_from_slice(&full_digest[0..N]);
digest
}
pub(crate) fn f<const N: usize>(pk_seed: &[u8], adrs: &Adrs, m1: &[u8]) -> [u8; N] {
let mut digest = [0u8; N];
let to_byte = [0u8; 64];
sha2_256(&[pk_seed, &to_byte[0..(64 - N)], &adrs.to_22_bytes(), m1], &mut digest);
let zeros = [0u8; 48];
sha2_256(&[pk_seed, &zeros[0..(64 - N)], &adrs.to_22_bytes(), m1], &mut digest);
digest
}
pub(crate) fn h<const N: usize>(pk_seed: &[u8], adrs: &Adrs, m1: &[u8], m2: &[u8]) -> [u8; N] {
let mut digest = [0u8; N];
let to_byte = [0u8; 64];
sha2_256(&[pk_seed, &to_byte[0..(64 - N)], &adrs.to_22_bytes(), m1, m2], &mut digest);
let zeros = [0u8; 48];
sha2_256(&[pk_seed, &zeros[0..(64 - N)], &adrs.to_22_bytes(), m1, m2], &mut digest);
digest
}
// Perhaps there is a more elegant way to covert ml into list of bytes
pub(crate) fn t_l<const LEN: usize, const N: usize>(
pk_seed: &[u8], adrs: &Adrs, ml: &[[u8; N]; LEN],
) -> [u8; N] {
let mut result = [0u8; N];
let to_byte = [0u8; 64];
let zeros = [0u8; 48];
let mut hasher = Sha256::new();
hasher.update(pk_seed);
hasher.update(&to_byte[0..(64 - N)]);
hasher.update(&zeros[0..(64 - N)]);
hasher.update(adrs.to_22_bytes());
ml.iter().for_each(|item| hasher.update(item));
let digest = hasher.finalize();
@ -211,7 +207,6 @@ pub(crate) mod sha2_cat_3_5 {
fn sha2_256(input: &[&[u8]], out: &mut [u8]) {
debug_assert!(out.len() <= 32);
let mut hasher = Sha256::new();
input.iter().for_each(|item| hasher.update(item));
let result = hasher.finalize();
@ -220,7 +215,6 @@ pub(crate) mod sha2_cat_3_5 {
fn sha2_512(input: &[&[u8]], out: &mut [u8]) {
debug_assert!(out.len() <= 64);
let mut hasher = Sha512::new();
input.iter().for_each(|item| hasher.update(item));
let result = hasher.finalize();
@ -251,27 +245,26 @@ pub(crate) mod sha2_cat_3_5 {
#[allow(clippy::similar_names)] // pk_seed and sk_seed
pub(crate) fn prf<const N: usize>(pk_seed: &[u8], sk_seed: &[u8], adrs: &Adrs) -> [u8; N] {
let mut digest = [0u8; N];
let to_byte = [0u8; 64];
sha2_256(&[pk_seed, &to_byte[0..(64 - N)], &adrs.to_22_bytes(), sk_seed], &mut digest); // Note that the spec swaps order of last to params
let zeros = [0u8; 40];
sha2_256(&[pk_seed, &zeros[0..(64 - N)], &adrs.to_22_bytes(), sk_seed], &mut digest); // Spec swaps order of last two params 557/997/1005
digest
}
fn hmac_sha_512(key: &[u8], a0: &[u8], b1: &[u8]) -> [u8; 64] {
let k2 = key;
let mut padded = [0x36; 128];
for (p, &k) in padded.iter_mut().zip(k2.iter()) {
let mut padding = [0x36; 128];
for (p, &k) in padding.iter_mut().zip(key.iter()) {
*p ^= k;
}
let mut inner_hasher = Sha512::new();
inner_hasher.update(&padded[..]);
inner_hasher.update(&padding[..]);
inner_hasher.update(a0);
inner_hasher.update(b1);
for p in &mut padded {
for p in &mut padding {
*p ^= 0x6a;
}
let mut outer_hasher = Sha512::new();
outer_hasher.update(&padded[..]);
outer_hasher.update(&padding[..]);
outer_hasher.update(inner_hasher.finalize());
outer_hasher.finalize().into()
}
@ -279,37 +272,36 @@ pub(crate) mod sha2_cat_3_5 {
pub(crate) fn prf_msg<const N: usize>(sk_prf: &[u8], opt_rand: &[u8], m: &[u8]) -> [u8; N] {
let mut digest = [0u8; N];
let xxx = hmac_sha_512(sk_prf, opt_rand, m);
digest.copy_from_slice(&xxx[0..N]);
let full_digest = hmac_sha_512(sk_prf, opt_rand, m);
digest.copy_from_slice(&full_digest[0..N]);
digest
}
pub(crate) fn f<const N: usize>(pk_seed: &[u8], adrs: &Adrs, m1: &[u8]) -> [u8; N] {
let mut digest = [0u8; N];
let to_byte = [0u8; 64];
sha2_256(&[pk_seed, &to_byte[0..(64-N)], &adrs.to_22_bytes(), m1], &mut digest);
let zeros = [0u8; 40];
sha2_256(&[pk_seed, &zeros[0..(64 - N)], &adrs.to_22_bytes(), m1], &mut digest);
digest
}
pub(crate) fn h<const N: usize>(pk_seed: &[u8], adrs: &Adrs, m1: &[u8], m2: &[u8]) -> [u8; N] {
let mut digest = [0u8; N];
let to_byte = [0u8; 128];
sha2_512(&[pk_seed, &to_byte[0..(128 - N)], &adrs.to_22_bytes(), m1, m2], &mut digest);
let zeros = [0u8; 104];
sha2_512(&[pk_seed, &zeros[0..(128 - N)], &adrs.to_22_bytes(), m1, m2], &mut digest);
digest
}
// Perhaps there is a more elegant way to covert ml into list of bytes
pub(crate) fn t_l<const LEN: usize, const N: usize>(
pk_seed: &[u8], adrs: &Adrs, ml: &[[u8; N]; LEN],
) -> [u8; N] {
let mut result = [0u8; N];
let to_byte = [0u8; 128];
let zeros = [0u8; 104];
let mut hasher = Sha512::new();
hasher.update(pk_seed);
hasher.update(&to_byte[0..(128 - N)]);
hasher.update(&zeros[0..(128 - N)]);
hasher.update(adrs.to_22_bytes());
ml.iter().for_each(|item| hasher.update(item));
let digest = hasher.finalize();

View file

@ -66,7 +66,7 @@ pub(crate) fn to_byte(x: u32, n: u32) -> [u8; ((crate::LEN2 * crate::LGW + 7) /
/// Output: Array of `out_len` integers in the range `[0, . . . , 2^b 1]`.
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); // Consider optimizing `baseb` output to be u16
debug_assert!(b < 16);
debug_assert_eq!(out_len as usize, baseb.len());
// 1: in ← 0
@ -138,7 +138,6 @@ impl<
}
}
for d in 0..D {
//println!("and we move to xmss {} starting at {}", d, start);
for len in 0..LEN {
out[start..(start + N)]
.copy_from_slice(&self.ht_sig.xmss_sigs[d].sig_wots.data[len]);
@ -160,11 +159,18 @@ impl<
N * K + K * A * N + // ForsSig
D * (HP * N + LEN * N)
);
//let mut output = Self::default();
let mut output = SlhDsaSig{
randomness: [0u8; N], //r.clone(),
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] }) },
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;

View file

@ -37,7 +37,12 @@ pub(crate) fn ht_sign<
xmss::xmss_sign::<H, HP, K, LEN, M, N>(hashers, m, sk_seed, idx_leaf, pk_seed, &adrs)?;
// 5: SIG_HT ← SIG_tmp
let mut sig_ht = HtSig { xmss_sigs: core::array::from_fn(|_| XmssSig { sig_wots: WotsSig { data: [[0u8; N]; LEN] }, auth: [[0u8; N]; HP] }) }; //HtSig::default();
let mut sig_ht = HtSig {
xmss_sigs: core::array::from_fn(|_| XmssSig {
sig_wots: WotsSig { data: [[0u8; N]; LEN] },
auth: [[0u8; N]; HP],
}),
};
sig_ht.xmss_sigs[0] = sig_tmp.clone();
// 6: root ← xmss_PKFromSig(idx_leaf, SIG_tmp, M, PK.seed, ADRS)
@ -48,8 +53,8 @@ pub(crate) fn ht_sign<
for j in 1..d32 {
//
// 8: idx_leaf ← idx_tree mod 2^{h} ▷ h least significant bits of idx_tree
let idx_leaf = u32::try_from(idx_tree % 2u64.pow(hp32))
.map_err(|_| "Alg11: oversized idx leaf")?;
let idx_leaf =
u32::try_from(idx_tree & ((1 << hp32) - 1)).map_err(|_| "Alg11: oversized idx leaf")?;
// 9: idx_tree ← idx_tree ≫ h ▷ Remove least significant h bits from idx_tree
idx_tree >>= hp32;
@ -124,7 +129,8 @@ pub(crate) fn ht_verify<
for j in 1..d32 {
//
// 7: idx_leaf ← idx_tree mod 2^{h} ▷ h least significant bits of idx_tree
let idx_leaf = u32::try_from(idx_tree % 2u64.pow(hp32)); // TODO: clean
let idx_leaf = u32::try_from(idx_tree & ((1 << hp32) - 1));
if idx_leaf.is_err() {
return false;
};
@ -153,5 +159,5 @@ pub(crate) fn ht_verify<
// 16: else
// 17: return false
// 18: end if
node == *pk_root // TODO: CT equal
node == *pk_root // TODO: CT equal (is this in signing path??)
}

View file

@ -181,7 +181,7 @@ macro_rules! functionality {
fn try_from_bytes(bytes: &Self::ByteArray) -> Result<Self, &'static str> {
// Result: opportunity for validation
//let mut pk = SlhPublicKey::default();
let mut pk = SlhPublicKey{pk_seed: [0u8; N], pk_root: [0u8; N]};
let mut pk = SlhPublicKey { pk_seed: [0u8; N], pk_root: [0u8; N] };
pk.pk_seed.copy_from_slice(&bytes[..(PK_LEN / 2)]);
pk.pk_root.copy_from_slice(&bytes[(PK_LEN / 2)..]);
Ok(PublicKey(pk))
@ -204,7 +204,12 @@ macro_rules! functionality {
fn try_from_bytes(bytes: &Self::ByteArray) -> Result<Self, &'static str> {
// Result: opportunity for validation
//let mut sk = SlhPrivateKey::default();
let mut sk = SlhPrivateKey{sk_seed: [0u8; N], sk_prf: [0u8; N], pk_seed: [0u8; N], pk_root: [0u8; N]};
let mut sk = SlhPrivateKey {
sk_seed: [0u8; N],
sk_prf: [0u8; N],
pk_seed: [0u8; N],
pk_root: [0u8; N],
};
sk.sk_seed.copy_from_slice(&bytes[0..(SK_LEN / 4)]);
sk.sk_prf
.copy_from_slice(&bytes[(SK_LEN / 4)..(SK_LEN / 2)]);

View file

@ -1,6 +1,6 @@
use crate::hashers::Hashers;
use crate::types::{Auth, FORS_TREE, ForsSig, HtSig, WotsSig, XmssSig};
use crate::types::{Adrs, SlhDsaSig, SlhPrivateKey, SlhPublicKey};
use crate::types::{Auth, ForsSig, HtSig, WotsSig, XmssSig, FORS_TREE};
use crate::{fors, helpers, hypertree, xmss};
use rand_core::CryptoRngCore;
@ -26,17 +26,17 @@ pub(crate) fn slh_keygen_with_rng<
//
// 1: SK.seed ←$ B^n ▷ Set SK.seed, SK.prf, and PK.seed to random n-byte
let mut sk_seed = [0u8; N]; // = GenericArray::default();
let mut sk_seed = [0u8; N];
rng.try_fill_bytes(&mut sk_seed)
.map_err(|_| "Alg17: rng failed1")?;
// 2: SK.prf ←$ B^n ▷ strings using an approved random bit generator
let mut sk_prf = [0u8; N]; //GenericArray::default();
let mut sk_prf = [0u8; N];
rng.try_fill_bytes(&mut sk_prf)
.map_err(|_| "Alg17: rng failed2")?;
// 3: PK.seed ←$ B^n
let mut pk_seed = [0u8; N]; //GenericArray::default();
let mut pk_seed = [0u8; N];
rng.try_fill_bytes(&mut pk_seed)
.map_err(|_| "Alg17: rng failed3")?;
@ -101,14 +101,19 @@ pub(crate) fn slh_sign_with_rng<
let r = (hashers.prf_msg)(&sk.sk_prf, &opt_rand, m);
// 8: SIG ← R
//let mut sig = SlhDsaSig::default();
let mut sig = SlhDsaSig{
randomness: r,
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] }) },
let mut sig = SlhDsaSig {
randomness: r, // here!
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],
}),
},
};
//sig.randomness.0 = r.clone();
// 9:
// 10: digest ← H_msg(R, PK.seed, PK.root, M) ▷ Compute message digest

View file

@ -1,5 +1,6 @@
use crate::hashers::Hashers;
use crate::helpers;
use crate::helpers::{base_2b, to_byte};
use crate::types::{Adrs, WotsPk, WotsSig, WOTS_PK, WOTS_PRF};
@ -62,9 +63,9 @@ pub(crate) fn chain<const K: usize, const LEN: usize, const M: usize, const N: u
pub(crate) fn wots_pkgen<const K: usize, const LEN: usize, const M: usize, const N: usize>(
hashers: &Hashers<K, LEN, M, N>, sk_seed: &[u8], pk_seed: &[u8], adrs: &Adrs,
) -> Result<WotsPk<N>, &'static str> {
let len32 = u32::try_from(LEN).unwrap();
let mut adrs = adrs.clone();
let mut tmp = [[0u8; N]; LEN];
let len32 = u32::try_from(LEN).unwrap();
// 1: skADRS ← ADRS ▷ Copy address to create key generation key address
let mut sk_adrs = adrs.clone();
@ -122,15 +123,14 @@ pub(crate) fn wots_sign<const K: usize, const LEN: usize, const M: usize, const
) -> WotsSig<LEN, N> {
let n32 = u32::try_from(N).unwrap();
let mut adrs = adrs.clone();
//let mut sig: WotsSig<LEN, N> = WotsSig::default();
let mut sig: WotsSig<LEN, N> = WotsSig{ data: [[0u8; N]; LEN] };
let mut sig: WotsSig<LEN, N> = WotsSig { data: [[0u8; N]; LEN] };
// 1: csum ← 0
let mut csum = 0_u32;
// 2:
// 3: msg ← base_2b(M, lgw, len1) ▷ Convert message to base w
let mut msg = [0u32; LEN]; //GenericArray::<u32, LEN>::default(); // note: 3 entries left over, used step 10
let mut msg = [0u32; LEN]; // note: 3 entries left over, used step 10
helpers::base_2b(m, crate::LGW, 2 * n32, &mut msg[0..(2 * N)]);
// 4:
@ -198,15 +198,15 @@ pub(crate) fn wots_pk_from_sig<const K: usize, const LEN: usize, const M: usize,
) -> WotsPk<N> {
let n32 = u32::try_from(N).unwrap();
let mut adrs = adrs.clone();
let mut tmp = [[0u8; N]; LEN]; //GenericArray::default();
let mut tmp = [[0u8; N]; LEN];
// 1: csum ← 0
let mut csum = 0_u32;
// 2:
// 3: msg ← base_2b (M, lgw , len1 ) ▷ Convert message to base w
let mut msg = [0u32; LEN]; //GenericArray::default();
helpers::base_2b(m, crate::LGW, 2 * n32, &mut msg[0..(2 * N)]);
let mut msg = [0u32; LEN];
base_2b(m, crate::LGW, 2 * n32, &mut msg[0..(2 * N)]);
// 4:
// 5: for i from 0 to len1 1 do ▷ Compute checksum
@ -223,8 +223,8 @@ pub(crate) fn wots_pk_from_sig<const K: usize, const LEN: usize, const M: usize,
csum <<= (8 - ((crate::LEN2 * crate::LGW) & 0x07)) & 0x07;
// 10: msg ← msg ∥ base_2^b(toByte(csum, ceil(len2·lgw/8)), lgw, len2) ▷ Convert csum to base w
helpers::base_2b(
&helpers::to_byte(csum, (crate::LEN2 * crate::LGW + 7) / 8),
base_2b(
&to_byte(csum, (crate::LEN2 * crate::LGW + 7) / 8),
crate::LGW,
crate::LEN2,
&mut msg[(2 * N)..],

View file

@ -1,5 +1,5 @@
use crate::hashers::Hashers;
use crate::types::{Adrs, XmssSig, TREE, WOTS_HASH, WotsSig};
use crate::types::{Adrs, WotsSig, XmssSig, TREE, WOTS_HASH};
use crate::wots;
@ -24,7 +24,7 @@ pub(crate) fn xmss_node<
let mut adrs = adrs.clone();
// 1: if z > h or i ≥ 2^{h z} then
if (z > hp32) | (u64::from(i) >= 2u64.pow(hp32 - z)) {
if (z > hp32) | (u64::from(i) >= (1 << (hp32 - z))) {
//
// 2: return NULL
return Err("Alg8: fail");
@ -42,8 +42,7 @@ pub(crate) fn xmss_node<
adrs.set_key_pair_address(i);
// 7: node ← wots_PKgen(SK.seed, PK.seed, ADRS)
wots::wots_pkgen::<K, LEN, M, N>(hashers, sk_seed, pk_seed, &adrs)?
.0
wots::wots_pkgen::<K, LEN, M, N>(hashers, sk_seed, pk_seed, &adrs)?.0
// 8: else
} else {
@ -95,8 +94,10 @@ pub(crate) fn xmss_sign<
) -> Result<XmssSig<HP, LEN, N>, &'static str> {
let hp32 = u32::try_from(HP).unwrap();
let mut adrs = adrs.clone();
//let mut sig_xmss = XmssSig::default();
let mut sig_xmss = XmssSig{ sig_wots: WotsSig { data: [[0u8; N]; LEN] }, auth: [[0u8; N]; HP] };
let mut sig_xmss = XmssSig {
sig_wots: WotsSig { data: [[0u8; N]; LEN] },
auth: [[0u8; N]; HP],
};
// 1: for j from 0 to h-1 do ▷ Build authentication path
for j in 0..hp32 {
@ -119,7 +120,7 @@ pub(crate) fn xmss_sign<
adrs.set_key_pair_address(idx);
// 8: sig ← wots_sign(M, SK.seed, PK.seed, ADRS)
sig_xmss.sig_wots = wots::wots_sign::<K, LEN, M, N>(hashers, m, sk_seed, pk_seed, &adrs); // TODO: polish out BB!
sig_xmss.sig_wots = wots::wots_sign::<K, LEN, M, N>(hashers, m, sk_seed, pk_seed, &adrs);
// 9: SIG_XMSS ← sig ∥ AUTH
// struct built above
@ -161,8 +162,7 @@ pub(crate) fn xmss_pk_from_sig<
let auth = sig_xmss.get_xmss_auth();
// 5: node[0] ← wots_PKFromSig(sig, M, PK.seed, ADRS)
let mut node_0 = wots::wots_pk_from_sig::<K, LEN, M, N>(hashers, sig, m, pk_seed, &adrs)
.0;
let mut node_0 = wots::wots_pk_from_sig::<K, LEN, M, N>(hashers, sig, m, pk_seed, &adrs).0;
// 6:
// 7: ADRS.setTypeAndClear(TREE) ▷ Compute root from WOTS+ pk and AUTH