mirror of
https://github.com/saymrwulf/fips205-source.git
synced 2026-09-03 19:53:49 +00:00
clippy juice
This commit is contained in:
parent
5ee9e944b6
commit
f3f22d6c4f
3 changed files with 90 additions and 59 deletions
106
src/algs.rs
106
src/algs.rs
|
|
@ -1,4 +1,4 @@
|
|||
use crate::types::{ADRS, WotsSig};
|
||||
use crate::types::{WotsSig, Adrs};
|
||||
use crate::types::{WOTS_PK, WOTS_PRF};
|
||||
use crate::Context;
|
||||
use alloc::vec;
|
||||
|
|
@ -9,6 +9,7 @@ use sha3::{
|
|||
Shake256,
|
||||
};
|
||||
|
||||
|
||||
/// Algorithm 1: `toInt(X, n)` on page 14.
|
||||
/// Convert a byte string to an integer.
|
||||
///
|
||||
|
|
@ -16,15 +17,20 @@ use sha3::{
|
|||
/// Output: Integer value of `X`.
|
||||
pub(crate) fn to_int(x: &[u8], n: usize) -> u64 {
|
||||
assert_eq!(x.len(), n);
|
||||
|
||||
// 1: total ← 0
|
||||
let mut total = 0_u64;
|
||||
|
||||
// 2:
|
||||
// 3: for i from 0 to n − 1 do
|
||||
for i in 0..n {
|
||||
for item in x.iter().take(n) {
|
||||
//
|
||||
// 4: total ← 256 · total + X[i]
|
||||
total = (total << 8) + x[i] as u64;
|
||||
total = (total << 8) + u64::from(*item);
|
||||
|
||||
// 5: end for
|
||||
}
|
||||
|
||||
// 6: return total
|
||||
total
|
||||
}
|
||||
|
|
@ -42,12 +48,11 @@ pub(crate) fn to_byte(x: u64, n: usize) -> Vec<u8> {
|
|||
let mut total = x;
|
||||
|
||||
// 2:
|
||||
|
||||
// 3: for i from 0 to n − 1 do
|
||||
for i in 0..n {
|
||||
//
|
||||
// 4: S[n − 1 − i] ← total mod 256 ▷ Least significant 8 bits of total
|
||||
s[n - 1 - i] = total as u8;
|
||||
s[n - 1 - i] = total.to_le_bytes()[0];
|
||||
|
||||
// 5: total ← total ≫ 8
|
||||
total >>= 8;
|
||||
|
|
@ -68,35 +73,49 @@ pub(crate) fn to_byte(x: u64, n: usize) -> Vec<u8> {
|
|||
pub(crate) fn base_2b(x: &[u8], b: u32, out_len: usize) -> Vec<u64> {
|
||||
assert!(x.len() >= out_len * b as usize / 8);
|
||||
let mut baseb = vec![0u64; out_len];
|
||||
|
||||
// 1: in ← 0
|
||||
let mut inn = 0;
|
||||
|
||||
// 2: bits ← 0
|
||||
let mut bits = 0;
|
||||
|
||||
// 3: total ← 0
|
||||
let mut total = 0;
|
||||
|
||||
// 4:
|
||||
// 5: for out from 0 to out_len − 1 do
|
||||
for out in 0..out_len {
|
||||
for item in baseb.iter_mut().take(out_len) {
|
||||
//
|
||||
// 6: while bits < b do
|
||||
while bits < b {
|
||||
//
|
||||
// 7: total ← (total ≪ 8) + X[in]
|
||||
total = (total << 8) + x[inn] as u64;
|
||||
total = (total << 8) + u64::from(x[inn]);
|
||||
|
||||
// 8: in ← in + 1
|
||||
inn += 1;
|
||||
|
||||
// 9: bits ← bits + 8
|
||||
bits += 8;
|
||||
|
||||
// 10: end while
|
||||
}
|
||||
|
||||
// 11: bits ← bits − b
|
||||
bits -= b;
|
||||
|
||||
// 12: baseb[out] ← (total ≫ bits) mod 2^b
|
||||
baseb[out] = (total >> bits) & (2u64.pow(b) - 1);
|
||||
*item = (total >> bits) & (2u64.pow(b) - 1);
|
||||
|
||||
// 13: end for
|
||||
}
|
||||
|
||||
// 14: return baseb
|
||||
baseb
|
||||
}
|
||||
|
||||
|
||||
#[must_use]
|
||||
pub(crate) fn shake256<N: ArrayLength>(input: &[&[u8]]) -> GenericArray<u8, N> {
|
||||
let mut hasher = Shake256::default();
|
||||
|
|
@ -107,8 +126,11 @@ pub(crate) fn shake256<N: ArrayLength>(input: &[&[u8]]) -> GenericArray<u8, N> {
|
|||
result
|
||||
}
|
||||
|
||||
pub(crate) fn f<N: ArrayLength>(pk_seed: &[u8], adrs: &ADRS, tmp: &GenericArray<u8, N>) -> GenericArray<u8, N> {
|
||||
shake256(&[&pk_seed, &adrs.to_bytes(), tmp]).into()
|
||||
|
||||
pub(crate) fn f<N: ArrayLength>(
|
||||
pk_seed: &[u8], adrs: &Adrs, tmp: &GenericArray<u8, N>,
|
||||
) -> GenericArray<u8, N> {
|
||||
shake256(&[&pk_seed, &adrs.to_bytes(), tmp])
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -123,48 +145,56 @@ pub(crate) fn f<N: ArrayLength>(pk_seed: &[u8], adrs: &ADRS, tmp: &GenericArray<
|
|||
/// 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`.
|
||||
pub(crate) fn chain<N: ArrayLength>(
|
||||
context: &Context, cap_x: GenericArray<u8, N>, i: usize, s: usize, pk_seed: &[u8], adrs: &ADRS,
|
||||
context: &Context, cap_x: GenericArray<u8, N>, i: usize, s: usize, pk_seed: &[u8], adrs: &Adrs,
|
||||
) -> Option<GenericArray<u8, N>> {
|
||||
let mut adrs = adrs.clone();
|
||||
|
||||
// 1: if (i + s) ≥ w then
|
||||
if (i + s) >= context.w {
|
||||
//
|
||||
// 2: return NULL
|
||||
return None;
|
||||
|
||||
// 3: end if
|
||||
}
|
||||
|
||||
// 4:
|
||||
// 5: tmp ← X
|
||||
let mut tmp = cap_x;
|
||||
|
||||
// 6:
|
||||
// 7: for j from i to i + s − 1 do
|
||||
for j in i..(i + s) {
|
||||
//
|
||||
// 8: ADRS.setHashAddress(j)
|
||||
adrs.set_hash_address(j.try_into().expect("usize->u32 fails"));
|
||||
|
||||
// 9: tmp ← F(PK.seed, ADRS, tmp)
|
||||
tmp = f(&pk_seed, &adrs, &tmp)
|
||||
tmp = f(pk_seed, &adrs, &tmp);
|
||||
|
||||
// 10: end for
|
||||
}
|
||||
|
||||
// 11: return tmp
|
||||
Some(tmp)
|
||||
}
|
||||
|
||||
|
||||
pub(crate) fn prf<N: ArrayLength>(pk_seed: &[u8], sk_seed: &[u8], adrs: &ADRS) -> GenericArray<u8, N> {
|
||||
#[allow(clippy::similar_names)]
|
||||
pub(crate) fn prf<N: ArrayLength>(
|
||||
pk_seed: &[u8], sk_seed: &[u8], adrs: &Adrs,
|
||||
) -> GenericArray<u8, N> {
|
||||
shake256(&[&pk_seed, &sk_seed, &adrs.to_bytes()])
|
||||
}
|
||||
|
||||
|
||||
pub(crate) fn tlen<LEN: ArrayLength, N: ArrayLength>(
|
||||
_context: &Context, pk_seed: &[u8], adrs: &ADRS, ml: &GenericArray<GenericArray<u8, N>, LEN>,
|
||||
_context: &Context, pk_seed: &[u8], adrs: &Adrs, ml: &GenericArray<GenericArray<u8, N>, LEN>,
|
||||
) -> GenericArray<u8, N> {
|
||||
// assert!(ml
|
||||
// .iter()
|
||||
// .all(|item| item.as_ref().len() == context.len1));
|
||||
let mut hasher = Shake256::default();
|
||||
hasher.update(pk_seed);
|
||||
hasher.update(&adrs.to_bytes());
|
||||
ml.iter()
|
||||
.for_each(|item| hasher.update(&item.as_ref()));
|
||||
ml.iter().for_each(|item| hasher.update(item));
|
||||
let mut reader = hasher.finalize_xof();
|
||||
let mut result = GenericArray::default();
|
||||
reader.read(&mut result);
|
||||
|
|
@ -180,8 +210,9 @@ pub(crate) fn tlen<LEN: ArrayLength, N: ArrayLength>(
|
|||
///
|
||||
/// Input: Secret seed `SK.seed`, public seed `PK.seed`, address `ADRS`. <br>
|
||||
/// Output: WOTS+ public key `pk`.
|
||||
#[allow(clippy::similar_names)]
|
||||
pub(crate) fn wots_pkgen<LEN: ArrayLength, N: ArrayLength>(
|
||||
context: &Context, sk_seed: &[u8], pk_seed: &[u8], adrs: &mut ADRS,
|
||||
context: &Context, sk_seed: &[u8], pk_seed: &[u8], adrs: &mut Adrs,
|
||||
) -> GenericArray<u8, N> {
|
||||
let mut tmp: GenericArray<GenericArray<u8, N>, LEN> = GenericArray::default();
|
||||
|
||||
|
|
@ -196,6 +227,7 @@ pub(crate) fn wots_pkgen<LEN: ArrayLength, N: ArrayLength>(
|
|||
|
||||
// 4: for i from 0 to len − 1 do
|
||||
for i in 0..context.len1 {
|
||||
//
|
||||
// 5: skADRS.setChainAddress(i)
|
||||
sk_adrs.set_chain_address(i);
|
||||
|
||||
|
|
@ -210,6 +242,7 @@ pub(crate) fn wots_pkgen<LEN: ArrayLength, N: ArrayLength>(
|
|||
|
||||
// 9: end for
|
||||
}
|
||||
|
||||
// 10: wotspkADRS ← ADRS ▷ Copy address to create WOTS+ public key address
|
||||
let mut wotspk_adrs = adrs.clone();
|
||||
|
||||
|
|
@ -220,6 +253,7 @@ pub(crate) fn wots_pkgen<LEN: ArrayLength, N: ArrayLength>(
|
|||
wotspk_adrs.set_key_pair_address(adrs.get_key_pair_address());
|
||||
|
||||
// 13: pk ← Tlen (PK.seed, wotspkADRS,tmp) ▷ Compress public key
|
||||
#[allow(clippy::let_and_return)]
|
||||
let pk = tlen(context, pk_seed, &wotspk_adrs, &tmp);
|
||||
|
||||
// 14: return pk
|
||||
|
|
@ -232,7 +266,10 @@ pub(crate) fn wots_pkgen<LEN: ArrayLength, N: ArrayLength>(
|
|||
///
|
||||
/// Input: Message `M`, secret seed `SK.seed`, public seed `PK.seed`, address `ADRS`. <br>
|
||||
/// Output: WOTS+ signature sig.
|
||||
pub(crate) fn wots_sign<N: ArrayLength, LEN: ArrayLength>(context: &Context, m: &[u8], sk_seed: &[u8], pk_seed: &[u8], adrs: ADRS) -> WotsSig<N, LEN> {
|
||||
#[allow(clippy::similar_names)]
|
||||
pub(crate) fn wots_sign<N: ArrayLength, LEN: ArrayLength>(
|
||||
context: &Context, m: &[u8], sk_seed: &[u8], pk_seed: &[u8], adrs: Adrs,
|
||||
) -> WotsSig<N, LEN> {
|
||||
let mut adrs = adrs;
|
||||
let mut sig: WotsSig<N, LEN> = WotsSig::default();
|
||||
|
||||
|
|
@ -245,19 +282,25 @@ pub(crate) fn wots_sign<N: ArrayLength, LEN: ArrayLength>(context: &Context, m:
|
|||
|
||||
// 4:
|
||||
// 5: for i from 0 to len1 − 1 do ▷ Compute checksum
|
||||
for i in 0..context.len1 {
|
||||
|
||||
for item in msg.iter().take(context.len1) {
|
||||
//
|
||||
// 6: csum ← csum + w − 1 − msg[i]
|
||||
csum += context.w as u64 - 1 - msg[i];
|
||||
csum += context.w as u64 - 1 - item;
|
||||
|
||||
// 7: end for
|
||||
}
|
||||
|
||||
// 8:
|
||||
// 9: csum ← csum ≪ ((8 − ((len2·lgw) mod 8)) mod 8) ▷ For lgw = 4 left shift by 4
|
||||
csum = csum << ((8 - ((context.len2 * context.lgw as usize) % 8)) % 8);
|
||||
//csum = csum << ((8 - ((context.len2 * context.lgw as usize) % 8)) % 8);
|
||||
csum <<= (8 - ((context.len2 * context.lgw as usize) % 8)) % 8;
|
||||
|
||||
// 10: msg ← msg ∥ base_2^b(toByte(csum, ceil(len2·lgw/8)), lgw, len2) ▷ Convert csum to base w
|
||||
msg.extend(&base_2b(&to_byte(csum, (context.len2 * context.lgw as usize).div_ceil(8)), context.lgw, context.len2));
|
||||
msg.extend(&base_2b(
|
||||
&to_byte(csum, (context.len2 * context.lgw as usize).div_ceil(8)),
|
||||
context.lgw,
|
||||
context.len2,
|
||||
));
|
||||
|
||||
// 11:
|
||||
// 12: skADRS ← ADRS
|
||||
|
|
@ -270,8 +313,9 @@ pub(crate) fn wots_sign<N: ArrayLength, LEN: ArrayLength>(context: &Context, m:
|
|||
sk_addrs.set_key_pair_address(adrs.get_key_pair_address());
|
||||
|
||||
// 15: for i from 0 to len − 1 do
|
||||
for i in 0..context.len {
|
||||
|
||||
#[allow(clippy::cast_possible_truncation)] // step 19
|
||||
for (i, item) in msg.iter().enumerate().take(context.len) {
|
||||
//
|
||||
// 16: skADRS.setChainAddress(i)
|
||||
sk_addrs.set_chain_address(i);
|
||||
|
||||
|
|
@ -282,14 +326,16 @@ pub(crate) fn wots_sign<N: ArrayLength, LEN: ArrayLength>(context: &Context, m:
|
|||
adrs.set_chain_address(i);
|
||||
|
||||
// 19: sig[i] ← chain(sk, 0, msg[i], PK.seed, ADRS) ▷ Compute signature value for chain i
|
||||
sig.data[i] = chain(context, sk, 0, msg[i] as usize, pk_seed, &adrs).unwrap();
|
||||
sig.data[i] = chain(context, sk, 0, *item as usize, pk_seed, &adrs).unwrap();
|
||||
|
||||
// 20: end for
|
||||
}
|
||||
|
||||
// 21: return sig
|
||||
sig
|
||||
}
|
||||
|
||||
|
||||
/// Algorithm 7: `wots_PKFromSig(sig, M, PK.seed, ADRS)` on page 20.
|
||||
/// Compute a WOTS+ public key from a message and its signature.
|
||||
///
|
||||
|
|
@ -395,7 +441,7 @@ const _A10: u32 = 0;
|
|||
///
|
||||
/// Input: Message `M`, private seed `SK.seed`, public seed `PK.seed`, tree index `idx_tree`, leaf
|
||||
/// index `idx_leaf`. <br>
|
||||
/// Output: HT signature SIG_HT.
|
||||
/// Output: HT signature `SIG_HT`.
|
||||
const _A11: u32 = 0;
|
||||
// 1: ADRS ← toByte(0, 32)
|
||||
// 2:
|
||||
|
|
|
|||
17
src/lib.rs
17
src/lib.rs
|
|
@ -22,31 +22,28 @@ struct Context {
|
|||
w: usize,
|
||||
len1: usize,
|
||||
len2: usize,
|
||||
len: usize
|
||||
len: usize,
|
||||
}
|
||||
|
||||
|
||||
macro_rules! functionality {
|
||||
() => {
|
||||
use crate::traits::PK;
|
||||
use crate::types::{SlhDsaSig};
|
||||
use generic_array::typenum::{U5, U16};
|
||||
use crate::types::SlhDsaSig;
|
||||
use crate::Context;
|
||||
use generic_array::typenum::{U16, U5};
|
||||
use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||
// ----- 'EXTERNAL' DATA TYPES -----
|
||||
|
||||
const W: usize = 2_usize.pow(LGW);
|
||||
const LEN1: usize = (8*N).div_ceil(LGW as usize);
|
||||
const LEN2: usize = ((LEN1*(W-1)).ilog2()/LGW) as usize + 1;
|
||||
const LEN1: usize = (8 * N).div_ceil(LGW as usize);
|
||||
const LEN2: usize = ((LEN1 * (W - 1)).ilog2() / LGW) as usize + 1;
|
||||
const LEN: usize = LEN1 + LEN2;
|
||||
|
||||
static CONTEXT: Context = Context{lgw: LGW, w: W, len1: LEN1,
|
||||
len2: LEN2, len: LEN};
|
||||
static CONTEXT: Context = Context { lgw: LGW, w: W, len1: LEN1, len2: LEN2, len: LEN };
|
||||
|
||||
|
||||
fn sign() -> SlhDsaSig::<U5, U5, U16> {
|
||||
SlhDsaSig::<U5, U5, U16>::default()
|
||||
}
|
||||
fn sign() -> SlhDsaSig<U5, U5, U16> { SlhDsaSig::<U5, U5, U16>::default() }
|
||||
|
||||
/// Correctly sized private key specific to the target security parameter set. <br>
|
||||
#[derive(Clone, Zeroize, ZeroizeOnDrop)]
|
||||
|
|
|
|||
26
src/types.rs
26
src/types.rs
|
|
@ -23,34 +23,22 @@ pub(crate) struct ForsSig<A: ArrayLength, K: ArrayLength, N: ArrayLength> {
|
|||
/// Fig 10?
|
||||
#[derive(Clone, Default, Zeroize, ZeroizeOnDrop)]
|
||||
pub(crate) struct Auth<A: ArrayLength, N: ArrayLength> {
|
||||
tree: GenericArray<GenericArray<u8, N>, A>
|
||||
tree: GenericArray<GenericArray<u8, N>, A>,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, Default, Zeroize, ZeroizeOnDrop)]
|
||||
pub(crate) struct HtSig<N: ArrayLength> {
|
||||
x: GenericArray<u8, N>
|
||||
x: GenericArray<u8, N>,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, Default, Zeroize, ZeroizeOnDrop)]
|
||||
pub struct WotsSig<N: ArrayLength, LEN: ArrayLength> {
|
||||
pub(crate) data: GenericArray<GenericArray<u8, N>, LEN>
|
||||
pub(crate) data: GenericArray<GenericArray<u8, N>, LEN>,
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const WOTS_HASH: u32 = 0;
|
||||
pub(crate) const WOTS_PK: u32 = 1;
|
||||
const TREE: u32 = 2;
|
||||
|
|
@ -63,7 +51,7 @@ const FORS_PRF: u32 = 6;
|
|||
/// Straddling the line between struct, enum and union...
|
||||
#[derive(Clone, Default, Zeroize, ZeroizeOnDrop)]
|
||||
#[repr(align(32))]
|
||||
pub struct ADRS {
|
||||
pub struct Adrs {
|
||||
f0: [u8; 4], // layer address
|
||||
f1: [u8; 4], // tree address (LSB?)
|
||||
f2: [u8; 4], // tree address
|
||||
|
|
@ -75,11 +63,12 @@ pub struct ADRS {
|
|||
}
|
||||
|
||||
|
||||
impl ADRS {
|
||||
impl Adrs {
|
||||
pub(crate) fn get_key_pair_address(&self) -> [u8; 4] { self.f5 }
|
||||
|
||||
pub(crate) fn set_key_pair_address(&mut self, kp_addr: [u8; 4]) { self.f5 = kp_addr; }
|
||||
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
pub(crate) fn set_chain_address(&mut self, i: usize) { self.f6 = (i as u32).to_be_bytes(); }
|
||||
|
||||
pub(crate) fn set_type_and_clear(&mut self, type_t: u32) {
|
||||
|
|
@ -92,7 +81,6 @@ impl ADRS {
|
|||
pub(crate) fn set_hash_address(&mut self, addr: u32) { self.f7 = addr.to_be_bytes(); }
|
||||
|
||||
pub(crate) fn to_bytes(&self) -> Vec<u8> {
|
||||
let x = [self.f0, self.f1, self.f2, self.f3].concat();
|
||||
x
|
||||
[self.f0, self.f1, self.f2, self.f3].concat()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue