mirror of
https://github.com/saymrwulf/fips205-source.git
synced 2026-09-03 19:53:49 +00:00
minor clippy
This commit is contained in:
parent
f4bd328bf1
commit
bdd49221e4
9 changed files with 114 additions and 98 deletions
|
|
@ -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]
|
||||
|
|
|
|||
31
src/fors.rs
31
src/fors.rs
|
|
@ -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^(a−z) 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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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??)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)]);
|
||||
|
|
|
|||
27
src/slh.rs
27
src/slh.rs
|
|
@ -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
|
||||
|
|
|
|||
18
src/wots.rs
18
src/wots.rs
|
|
@ -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)..],
|
||||
|
|
|
|||
18
src/xmss.rs
18
src/xmss.rs
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue