mirror of
https://github.com/saymrwulf/fips205-source.git
synced 2026-09-05 20:10:45 +00:00
polish
This commit is contained in:
parent
4f8f03546c
commit
569374a055
1 changed files with 123 additions and 130 deletions
69
src/algs.rs
69
src/algs.rs
|
|
@ -12,15 +12,16 @@ use rand_core::CryptoRngCore;
|
||||||
///
|
///
|
||||||
/// Input: n-byte string `X`, string length `n`. <br>
|
/// Input: n-byte string `X`, string length `n`. <br>
|
||||||
/// Output: Integer value of `X`.
|
/// Output: Integer value of `X`.
|
||||||
pub(crate) fn to_int(x: &[u8], n: usize) -> u64 {
|
pub(crate) fn to_int(x: &[u8], n: u32) -> u64 {
|
||||||
debug_assert_eq!(x.len(), n);
|
debug_assert_eq!(x.len(), n as usize);
|
||||||
|
debug_assert!(n <= 8);
|
||||||
|
|
||||||
// 1: total ← 0
|
// 1: total ← 0
|
||||||
let mut total = 0_u64;
|
let mut total = 0;
|
||||||
|
|
||||||
// 2:
|
// 2:
|
||||||
// 3: for i from 0 to n − 1 do
|
// 3: for i from 0 to n − 1 do
|
||||||
for item in x.iter().take(n) {
|
for item in x.iter().take(n as usize) {
|
||||||
//
|
//
|
||||||
// 4: total ← 256 · total + X[i]
|
// 4: total ← 256 · total + X[i]
|
||||||
total = (total << 8) + u64::from(*item);
|
total = (total << 8) + u64::from(*item);
|
||||||
|
|
@ -38,9 +39,10 @@ pub(crate) fn to_int(x: &[u8], n: usize) -> u64 {
|
||||||
///
|
///
|
||||||
/// Input: Integer `x`, string length `n`. <br>
|
/// Input: Integer `x`, string length `n`. <br>
|
||||||
/// Output: Byte string of length `n` containing binary representation of `x` in big-endian byte-order.
|
/// Output: Byte string of length `n` containing binary representation of `x` in big-endian byte-order.
|
||||||
pub(crate) fn to_byte(x: u16, n: usize) -> [u8; ((crate::LEN2 * crate::LGW + 7) / 8) as usize] {
|
pub(crate) fn to_byte(x: u16, n: u32) -> [u8; ((crate::LEN2 * crate::LGW + 7) / 8) as usize] {
|
||||||
let mut s = [0u8; ((crate::LEN2 * crate::LGW + 7) / 8) as usize]; // Size fixed across all profiles (2)
|
let mut s = [0u8; ((crate::LEN2 * crate::LGW + 7) / 8) as usize]; // Size fixed across all profiles (2)
|
||||||
debug_assert_eq!(n, ((crate::LEN2 * crate::LGW + 7) / 8) as usize); // just in case life changes
|
debug_assert_eq!(n, ((crate::LEN2 * crate::LGW + 7) / 8)); // just in case life changes
|
||||||
|
debug_assert_eq!(n, 2); // optimize: this resolves into a two-byte (be) write!
|
||||||
|
|
||||||
// 1: total ← x
|
// 1: total ← x
|
||||||
let mut total = x;
|
let mut total = x;
|
||||||
|
|
@ -50,7 +52,7 @@ pub(crate) fn to_byte(x: u16, n: usize) -> [u8; ((crate::LEN2 * crate::LGW + 7)
|
||||||
for i in 0..n {
|
for i in 0..n {
|
||||||
//
|
//
|
||||||
// 4: S[n − 1 − i] ← total mod 256 ▷ Least significant 8 bits of total
|
// 4: S[n − 1 − i] ← total mod 256 ▷ Least significant 8 bits of total
|
||||||
s[n - 1 - i] = total.to_le_bytes()[0];
|
s[(n - 1 - i) as usize] = total.to_le_bytes()[0];
|
||||||
|
|
||||||
// 5: total ← total ≫ 8
|
// 5: total ← total ≫ 8
|
||||||
total >>= 8;
|
total >>= 8;
|
||||||
|
|
@ -69,8 +71,8 @@ pub(crate) fn to_byte(x: u16, n: usize) -> [u8; ((crate::LEN2 * crate::LGW + 7)
|
||||||
/// Input: Byte string `X` of length at least ceil(out_len·b/8), integer `b`, output length `out_len`. <br>
|
/// Input: Byte string `X` of length at least ceil(out_len·b/8), integer `b`, output length `out_len`. <br>
|
||||||
/// Output: Array of `out_len` integers in the range `[0, . . . , 2^b − 1]`.
|
/// 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]) {
|
pub(crate) fn base_2b(x: &[u8], b: u32, out_len: u32, baseb: &mut [u32]) {
|
||||||
debug_assert!(x.len() >= (out_len * b / 8) as usize);
|
debug_assert!(x.len() >= (out_len * b).div_ceil(8) as usize);
|
||||||
debug_assert!(b < 16);
|
debug_assert!(b < 16); // Consider optimizing `baseb` output to be u16
|
||||||
debug_assert_eq!(out_len as usize, baseb.len());
|
debug_assert_eq!(out_len as usize, baseb.len());
|
||||||
|
|
||||||
// 1: in ← 0
|
// 1: in ← 0
|
||||||
|
|
@ -84,7 +86,7 @@ pub(crate) fn base_2b(x: &[u8], b: u32, out_len: u32, baseb: &mut [u32]) {
|
||||||
|
|
||||||
// 4:
|
// 4:
|
||||||
// 5: for out from 0 to out_len − 1 do
|
// 5: for out from 0 to out_len − 1 do
|
||||||
for item in baseb.iter_mut().take(out_len as usize) {
|
for item in baseb.iter_mut() {
|
||||||
//
|
//
|
||||||
// 6: while bits < b do
|
// 6: while bits < b do
|
||||||
while bits < b {
|
while bits < b {
|
||||||
|
|
@ -107,7 +109,6 @@ pub(crate) fn base_2b(x: &[u8], b: u32, out_len: u32, baseb: &mut [u32]) {
|
||||||
// 12: baseb[out] ← (total ≫ bits) mod 2^b
|
// 12: baseb[out] ← (total ≫ bits) mod 2^b
|
||||||
*item = (total >> bits) & (u32::MAX >> (32 - b));
|
*item = (total >> bits) & (u32::MAX >> (32 - b));
|
||||||
|
|
||||||
assert!(*item < u32::MAX);
|
|
||||||
// 13: end for
|
// 13: end for
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -126,8 +127,8 @@ pub(crate) fn base_2b(x: &[u8], b: u32, out_len: u32, baseb: &mut [u32]) {
|
||||||
/// Input: Input string `X`, start index `i`, number of steps `s`, public seed `PK.seed`, address `ADRS`. <br>
|
/// Input: Input string `X`, start index `i`, number of steps `s`, public seed `PK.seed`, address `ADRS`. <br>
|
||||||
/// Output: Value of `F` iterated `s` times on `X`.
|
/// Output: Value of `F` iterated `s` times on `X`.
|
||||||
pub(crate) fn chain<K: ArrayLength, LEN: ArrayLength, M: ArrayLength, N: ArrayLength>(
|
pub(crate) fn chain<K: ArrayLength, LEN: ArrayLength, M: ArrayLength, N: ArrayLength>(
|
||||||
hashers: &Hashers<K, LEN, M, N>, cap_x: GenericArray<u8, N>, i: u32, s: u32,
|
hashers: &Hashers<K, LEN, M, N>, cap_x: GenericArray<u8, N>, i: u32, s: u32, pk_seed: &[u8],
|
||||||
pk_seed: &[u8], adrs: &Adrs,
|
adrs: &Adrs,
|
||||||
) -> Option<GenericArray<u8, N>> {
|
) -> Option<GenericArray<u8, N>> {
|
||||||
debug_assert!(i + s < u32::MAX);
|
debug_assert!(i + s < u32::MAX);
|
||||||
let mut adrs = adrs.clone();
|
let mut adrs = adrs.clone();
|
||||||
|
|
@ -255,14 +256,13 @@ pub(crate) fn wots_sign<K: ArrayLength, LEN: ArrayLength, M: ArrayLength, N: Arr
|
||||||
|
|
||||||
// 8:
|
// 8:
|
||||||
// 9: csum ← csum ≪ ((8 − ((len2·lgw) mod 8)) mod 8) ▷ For lgw = 4 left shift by 4
|
// 9: csum ← csum ≪ ((8 − ((len2·lgw) mod 8)) mod 8) ▷ For lgw = 4 left shift by 4
|
||||||
let len2 = 3_u32; //
|
csum <<= (8 - ((crate::LEN2 * crate::LGW) & 0x07)) & 0x07;
|
||||||
csum <<= (8 - ((len2 * crate::LGW) & 0x07)) & 0x07;
|
|
||||||
|
|
||||||
// 10: msg ← msg ∥ base_2^b(toByte(csum, ceil(len2·lgw/8)), lgw, len2) ▷ Convert csum to base w
|
// 10: msg ← msg ∥ base_2^b(toByte(csum, ceil(len2·lgw/8)), lgw, len2) ▷ Convert csum to base w
|
||||||
base_2b(
|
base_2b(
|
||||||
&to_byte(csum as u16, ((len2 * crate::LGW) as usize).div_ceil(8)),
|
&to_byte(csum as u16, (crate::LEN2 * crate::LGW).div_ceil(8)),
|
||||||
crate::LGW,
|
crate::LGW,
|
||||||
len2,
|
crate::LEN2,
|
||||||
&mut msg[(2 * N::to_usize())..],
|
&mut msg[(2 * N::to_usize())..],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -277,9 +277,8 @@ pub(crate) fn wots_sign<K: ArrayLength, LEN: ArrayLength, M: ArrayLength, N: Arr
|
||||||
sk_addrs.set_key_pair_address(adrs.get_key_pair_address());
|
sk_addrs.set_key_pair_address(adrs.get_key_pair_address());
|
||||||
|
|
||||||
// 15: for i from 0 to len − 1 do
|
// 15: for i from 0 to len − 1 do
|
||||||
let len = 2 * N::to_usize() + 3;
|
|
||||||
//#[allow(clippy::cast_possible_truncation)] // step 19
|
//#[allow(clippy::cast_possible_truncation)] // step 19
|
||||||
for (item, i) in msg.iter().zip(0u32..).take(len) {
|
for (item, i) in msg.iter().zip(0u32..) {
|
||||||
//
|
//
|
||||||
// 16: skADRS.setChainAddress(i)
|
// 16: skADRS.setChainAddress(i)
|
||||||
sk_addrs.set_chain_address(i);
|
sk_addrs.set_chain_address(i);
|
||||||
|
|
@ -313,7 +312,7 @@ pub(crate) fn wots_pk_from_sig<K: ArrayLength, LEN: ArrayLength, M: ArrayLength,
|
||||||
let mut tmp: GenericArray<GenericArray<u8, N>, LEN> = GenericArray::default();
|
let mut tmp: GenericArray<GenericArray<u8, N>, LEN> = GenericArray::default();
|
||||||
|
|
||||||
// 1: csum ← 0
|
// 1: csum ← 0
|
||||||
let mut csum = 0_u64;
|
let mut csum = 0;
|
||||||
|
|
||||||
// 2:
|
// 2:
|
||||||
// 3: msg ← base_2b (M, lgw , len1 ) ▷ Convert message to base w
|
// 3: msg ← base_2b (M, lgw , len1 ) ▷ Convert message to base w
|
||||||
|
|
@ -332,14 +331,13 @@ pub(crate) fn wots_pk_from_sig<K: ArrayLength, LEN: ArrayLength, M: ArrayLength,
|
||||||
|
|
||||||
// 8:
|
// 8:
|
||||||
// 9: csum ← csum ≪ ((8 − ((len2·lgw) mod 8)) mod 8) ▷ For lgw = 4 left shift by 4
|
// 9: csum ← csum ≪ ((8 − ((len2·lgw) mod 8)) mod 8) ▷ For lgw = 4 left shift by 4
|
||||||
let len2 = 3_u32;
|
csum <<= (8 - ((crate::LEN2 * crate::LGW) & 0x07)) & 0x07;
|
||||||
csum <<= (8 - ((len2 * crate::LGW) & 0x07)) & 0x07;
|
|
||||||
|
|
||||||
// 10: msg ← msg ∥ base_2^b(toByte(csum, ceil(len2·lgw/8)), lgw, len2) ▷ Convert csum to base w
|
// 10: msg ← msg ∥ base_2^b(toByte(csum, ceil(len2·lgw/8)), lgw, len2) ▷ Convert csum to base w
|
||||||
base_2b(
|
base_2b(
|
||||||
&to_byte(csum as u16, (len2 * crate::LGW).div_ceil(8) as usize),
|
&to_byte(csum as u16, (crate::LEN2 * crate::LGW).div_ceil(8)),
|
||||||
crate::LGW,
|
crate::LGW,
|
||||||
len2,
|
crate::LEN2,
|
||||||
&mut msg[(2 * N::to_usize())..],
|
&mut msg[(2 * N::to_usize())..],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -421,7 +419,7 @@ pub(crate) fn xmss_node<
|
||||||
// 7: node ← wots_PKgen(SK.seed, PK.seed, ADRS)
|
// 7: node ← wots_PKgen(SK.seed, PK.seed, ADRS)
|
||||||
wots_pkgen::<K, LEN, M, N>(hashers, sk_seed, pk_seed, &adrs)?
|
wots_pkgen::<K, LEN, M, N>(hashers, sk_seed, pk_seed, &adrs)?
|
||||||
.0
|
.0
|
||||||
.clone() // TODO remove clone?
|
.clone()
|
||||||
|
|
||||||
// 8: else
|
// 8: else
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -498,7 +496,7 @@ pub(crate) fn xmss_sign<
|
||||||
sig_xmss.sig_wots = wots_sign::<K, LEN, M, N>(hashers, m, sk_seed, pk_seed, &adrs); // TODO: polish out BB!
|
sig_xmss.sig_wots = wots_sign::<K, LEN, M, N>(hashers, m, sk_seed, pk_seed, &adrs); // TODO: polish out BB!
|
||||||
|
|
||||||
// 9: SIG_XMSS ← sig ∥ AUTH
|
// 9: SIG_XMSS ← sig ∥ AUTH
|
||||||
// struct constructed above
|
// struct built above
|
||||||
|
|
||||||
// 10: return SIG_XMSS
|
// 10: return SIG_XMSS
|
||||||
Ok(sig_xmss)
|
Ok(sig_xmss)
|
||||||
|
|
@ -706,7 +704,7 @@ pub(crate) fn ht_verify<
|
||||||
for j in 1..D::to_u32() {
|
for j in 1..D::to_u32() {
|
||||||
//
|
//
|
||||||
// 7: idx_leaf ← idx_tree mod 2^{h′} ▷ h′ least significant bits of idx_tree
|
// 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(HP::to_u32()));
|
let idx_leaf = u32::try_from(idx_tree % 2u64.pow(HP::to_u32())); // TODO: clean
|
||||||
if idx_leaf.is_err() {
|
if idx_leaf.is_err() {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
@ -1099,7 +1097,6 @@ pub(crate) fn slh_sign_with_rng<
|
||||||
// 10: digest ← H_msg(R, PK.seed, PK.root, M) ▷ Compute message digest
|
// 10: digest ← H_msg(R, PK.seed, PK.root, M) ▷ Compute message digest
|
||||||
let digest = (hashers.h_msg)(&r, &sk.pk_seed, &sk.pk_root, m);
|
let digest = (hashers.h_msg)(&r, &sk.pk_seed, &sk.pk_root, m);
|
||||||
|
|
||||||
|
|
||||||
// 11: md ← digest[0 : ceil(k·a/8)] ▷ first ceil(k·a/8) bytes
|
// 11: md ← digest[0 : ceil(k·a/8)] ▷ first ceil(k·a/8) bytes
|
||||||
let index1 = (K::to_usize() * A::to_usize()).div_ceil(8);
|
let index1 = (K::to_usize() * A::to_usize()).div_ceil(8);
|
||||||
let md = &digest[0..index1];
|
let md = &digest[0..index1];
|
||||||
|
|
@ -1114,14 +1111,12 @@ pub(crate) fn slh_sign_with_rng<
|
||||||
|
|
||||||
// 14:
|
// 14:
|
||||||
// 15: idx_tree ← toInt(tmp_idx_tree, ceil((h-h/d)/8)) mod 2^{h−h/d}
|
// 15: idx_tree ← toInt(tmp_idx_tree, ceil((h-h/d)/8)) mod 2^{h−h/d}
|
||||||
let idx_tree =
|
let idx_tree = to_int(tmp_idx_tree, (H::to_u32() - H::to_u32() / D::to_u32()).div_ceil(8))
|
||||||
to_int(tmp_idx_tree, (H::to_usize() - H::to_usize() / D::to_usize()).div_ceil(8))
|
|
||||||
& (u64::MAX >> (64 - (H::to_u32() - H::to_u32() / D::to_u32())));
|
& (u64::MAX >> (64 - (H::to_u32() - H::to_u32() / D::to_u32())));
|
||||||
// % 2u64.pow(H::to_u32() - H::to_u32() / D::to_u32()); // Can be 2^64
|
|
||||||
|
|
||||||
// 16: idx_leaf ← toInt(tmp_idx_leaf, ceil(h/8d) mod 2^{h/d}
|
// 16: idx_leaf ← toInt(tmp_idx_leaf, ceil(h/8d) mod 2^{h/d}
|
||||||
let idx_leaf = to_int(tmp_idx_leaf, H::to_usize().div_ceil(8 * D::to_usize()))
|
let idx_leaf = to_int(tmp_idx_leaf, H::to_u32().div_ceil(8 * D::to_u32()))
|
||||||
% 2u64.pow(H::to_u32() / D::to_u32());
|
& (u64::MAX >> (64 - H::to_u32() / D::to_u32()));
|
||||||
|
|
||||||
// 17:
|
// 17:
|
||||||
// 18: ADRS.setTreeAddress(idx_tree)
|
// 18: ADRS.setTreeAddress(idx_tree)
|
||||||
|
|
@ -1213,14 +1208,12 @@ pub(crate) fn slh_verify<
|
||||||
|
|
||||||
// 13:
|
// 13:
|
||||||
// 14: idx_tree ← toInt(tmp_idx_tree, ceil((h - h/d)/8)) mod 2^{h−h/d}
|
// 14: idx_tree ← toInt(tmp_idx_tree, ceil((h - h/d)/8)) mod 2^{h−h/d}
|
||||||
let idx_tree =
|
let idx_tree = to_int(tmp_idx_tree, (H::to_u32() - H::to_u32() / D::to_u32()).div_ceil(8))
|
||||||
to_int(tmp_idx_tree, (H::to_usize() - H::to_usize() / D::to_usize()).div_ceil(8))
|
|
||||||
& (u64::MAX >> (64 - (H::to_u32() - H::to_u32() / D::to_u32())));
|
& (u64::MAX >> (64 - (H::to_u32() - H::to_u32() / D::to_u32())));
|
||||||
// % 2u64.pow(H::to_u32() - H::to_u32() / D::to_u32()); // Can be 2^64
|
|
||||||
|
|
||||||
// 15: idx_leaf ← toInt(tmp_idx_leaf, ceil(h/8d) mod 2^{h/d}
|
// 15: idx_leaf ← toInt(tmp_idx_leaf, ceil(h/8d) mod 2^{h/d}
|
||||||
let idx_leaf = to_int(tmp_idx_leaf, H::to_usize().div_ceil(8 * D::to_usize()))
|
let idx_leaf = to_int(tmp_idx_leaf, H::to_u32().div_ceil(8 * D::to_u32()))
|
||||||
% 2u64.pow(H::to_u32() / D::to_u32());
|
& (u64::MAX >> (64 - H::to_u32() / D::to_u32()));
|
||||||
|
|
||||||
// 16:
|
// 16:
|
||||||
// 17: ADRS.setTreeAddress(idx_tree) ▷ Compute FORS public key
|
// 17: ADRS.setTreeAddress(idx_tree) ▷ Compute FORS public key
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue