This commit is contained in:
eschorn1 2024-02-07 15:31:17 -06:00
parent 7bb838973b
commit a6ff2130de
4 changed files with 45 additions and 42 deletions

View file

@ -10,7 +10,7 @@ use rand_core::CryptoRngCore;
/// Algorithm 1: `toInt(X, n)` on page 14. /// Algorithm 1: `toInt(X, n)` on page 14.
/// Convert a byte string to an integer. /// Convert a byte string to an integer.
/// ///
/// Input: n-byte string `X`. <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: usize) -> u64 {
debug_assert_eq!(x.len(), n); debug_assert_eq!(x.len(), n);
@ -66,12 +66,12 @@ pub(crate) fn to_byte(x: u64, n: usize) -> [u8; ((crate::LEN2 * crate::LGW + 7)
/// Algorithm 3: `base_2^b(X, b, out_len)` on page 15. /// Algorithm 3: `base_2^b(X, b, out_len)` on page 15.
/// Compute the base 2^b representation of X. /// Compute the base 2^b representation of X.
/// ///
/// 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: usize, baseb: &mut [u64]) { pub(crate) fn base_2b(x: &[u8], b: u32, out_len: usize, baseb: &mut [u64]) {
assert!(x.len() >= out_len * b as usize / 8); debug_assert!(x.len() >= out_len * b as usize / 8);
assert!(b < 64); debug_assert!(b < 16);
assert_eq!(out_len, baseb.len()); debug_assert_eq!(out_len, baseb.len());
// 1: in ← 0 // 1: in ← 0
let mut inn = 0; let mut inn = 0;
@ -105,7 +105,7 @@ pub(crate) fn base_2b(x: &[u8], b: u32, out_len: usize, baseb: &mut [u64]) {
bits -= b; bits -= b;
// 12: baseb[out] ← (total ≫ bits) mod 2^b // 12: baseb[out] ← (total ≫ bits) mod 2^b
*item = (total >> bits) % 2u64.pow(b); *item = (total >> bits) & (u64::MAX >> (16 - b));
// 13: end for // 13: end for
} }
@ -116,7 +116,7 @@ pub(crate) fn base_2b(x: &[u8], b: u32, out_len: usize, baseb: &mut [u64]) {
/// Algorithm 4: `chain(X, i, s, PK.seed, ADRS)` on page 17. /// Algorithm 4: `chain(X, i, s, PK.seed, ADRS)` on page 17.
/// Chaining function used in WOTS+. The chain function takes as input an n-byte string `X` and integers `s` and `i` /// Chaining function used in WOTS+. The chain function takes as input an n-byte string `X` and integers `s` and `i`
/// and returns the result of iterating a hash function `F` on the input `s` times, starting from an index of `i`. /// and returns the result of iterating the hash function `F` on the input `s` times, starting from an index of `i`.
/// The chain function also requires as input PK.seed, which is part of the SLH-DSA public key, and an address `ADRS`. /// The chain function also requires as input PK.seed, which is part of the SLH-DSA public key, and an address `ADRS`.
/// The type in `ADRS` must be set to `WOTS_HASH`, and the layer address, tree address, key pair address, and chain /// The type in `ADRS` must be set to `WOTS_HASH`, and the layer address, tree address, key pair address, and chain
/// address must be set to the address of the chain being computed. The chain function updates the hash address in /// address must be set to the address of the chain being computed. The chain function updates the hash address in
@ -128,6 +128,7 @@ pub(crate) fn chain<K: ArrayLength, LEN: ArrayLength, M: ArrayLength, N: ArrayLe
hashers: &Hashers<K, LEN, M, N>, cap_x: GenericArray<u8, N>, i: usize, s: usize, hashers: &Hashers<K, LEN, M, N>, cap_x: GenericArray<u8, N>, i: usize, s: usize,
pk_seed: &[u8], adrs: &Adrs, pk_seed: &[u8], adrs: &Adrs,
) -> Option<GenericArray<u8, N>> { ) -> Option<GenericArray<u8, N>> {
debug_assert!(i + s < u32::MAX as usize);
let mut adrs = adrs.clone(); let mut adrs = adrs.clone();
// 1: if (i + s) ≥ w then // 1: if (i + s) ≥ w then
@ -148,7 +149,7 @@ pub(crate) fn chain<K: ArrayLength, LEN: ArrayLength, M: ArrayLength, N: ArrayLe
for j in i..(i + s) { for j in i..(i + s) {
// //
// 8: ADRS.setHashAddress(j) // 8: ADRS.setHashAddress(j)
adrs.set_hash_address(j.try_into().expect("usize->u32 fails")); // TODO: something better than expect? adrs.set_hash_address(j as u32);
// 9: tmp ← F(PK.seed, ADRS, tmp) // 9: tmp ← F(PK.seed, ADRS, tmp)
tmp = (hashers.f)(pk_seed, &adrs, &tmp); tmp = (hashers.f)(pk_seed, &adrs, &tmp);
@ -172,7 +173,7 @@ pub(crate) fn chain<K: ArrayLength, LEN: ArrayLength, M: ArrayLength, N: ArrayLe
#[allow(clippy::similar_names)] #[allow(clippy::similar_names)]
pub(crate) fn wots_pkgen<K: ArrayLength, LEN: ArrayLength, M: ArrayLength, N: ArrayLength>( pub(crate) fn wots_pkgen<K: ArrayLength, LEN: ArrayLength, M: ArrayLength, N: ArrayLength>(
hashers: &Hashers<K, LEN, M, N>, sk_seed: &[u8], pk_seed: &[u8], adrs: &Adrs, hashers: &Hashers<K, LEN, M, N>, sk_seed: &[u8], pk_seed: &[u8], adrs: &Adrs,
) -> WotsPk<N> { ) -> Result<WotsPk<N>, &'static str> {
let mut adrs = adrs.clone(); let mut adrs = adrs.clone();
let mut tmp: GenericArray<GenericArray<u8, N>, LEN> = GenericArray::default(); let mut tmp: GenericArray<GenericArray<u8, N>, LEN> = GenericArray::default();
@ -186,8 +187,7 @@ pub(crate) fn wots_pkgen<K: ArrayLength, LEN: ArrayLength, M: ArrayLength, N: Ar
sk_adrs.set_key_pair_address(adrs.get_key_pair_address()); sk_adrs.set_key_pair_address(adrs.get_key_pair_address());
// 4: for i from 0 to len 1 do // 4: for i from 0 to len 1 do
let len = 2 * N::to_u32() + 3; for i in 0..LEN::to_u32() {
for i in 0..len {
// //
// 5: skADRS.setChainAddress(i) // 5: skADRS.setChainAddress(i)
sk_adrs.set_chain_address(i); sk_adrs.set_chain_address(i);
@ -200,7 +200,7 @@ pub(crate) fn wots_pkgen<K: ArrayLength, LEN: ArrayLength, M: ArrayLength, N: Ar
// 8: tmp[i] ← chain(sk, 0, w 1, PK.seed, ADRS) ▷ Compute public value for chain i // 8: tmp[i] ← chain(sk, 0, w 1, PK.seed, ADRS) ▷ Compute public value for chain i
tmp[i as usize] = tmp[i as usize] =
chain(hashers, sk, 0, crate::W as usize - 1, pk_seed, &adrs).expect("chain broke!"); chain(hashers, sk, 0, crate::W as usize - 1, pk_seed, &adrs).ok_or("chain broke")?;
// 9: end for // 9: end for
} }
@ -218,7 +218,7 @@ pub(crate) fn wots_pkgen<K: ArrayLength, LEN: ArrayLength, M: ArrayLength, N: Ar
let pk = (hashers.t_l)(pk_seed, &wotspk_adrs, &tmp); let pk = (hashers.t_l)(pk_seed, &wotspk_adrs, &tmp);
// 14: return pk // 14: return pk
WotsPk(pk) Ok(WotsPk(pk))
} }
@ -235,7 +235,7 @@ pub(crate) fn wots_sign<K: ArrayLength, LEN: ArrayLength, M: ArrayLength, N: Arr
let mut sig: WotsSig<LEN, N> = WotsSig::default(); let mut sig: WotsSig<LEN, N> = WotsSig::default();
// 1: csum ← 0 // 1: csum ← 0
let mut csum = 0u64; 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
@ -255,11 +255,11 @@ 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_usize; // let len2 = 3_usize; //
csum <<= (8 - ((len2 as u64 * u64::from(crate::LGW)) % 8)) % 8; csum <<= (8 - ((len2 as u64 * u64::from(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, (len2 * crate::LGW as usize).div_ceil(8)), &to_byte(csum as u64, (len2 * crate::LGW as usize).div_ceil(8)),
crate::LGW, crate::LGW,
len2, len2,
&mut msg[(2 * N::to_usize())..], &mut msg[(2 * N::to_usize())..],
@ -277,20 +277,20 @@ pub(crate) fn wots_sign<K: ArrayLength, LEN: ArrayLength, M: ArrayLength, N: Arr
// 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; let len = 2 * N::to_usize() + 3;
#[allow(clippy::cast_possible_truncation)] // step 18/19 #[allow(clippy::cast_possible_truncation)] // step 19
for (i, item) in msg.iter().enumerate().take(len) { for (item, i) in msg.iter().zip(0u32..).take(len) {
// //
// 16: skADRS.setChainAddress(i) // 16: skADRS.setChainAddress(i)
sk_addrs.set_chain_address(i as u32); sk_addrs.set_chain_address(i);
// 17: sk ← PRF(PK.seed, SK.seed, skADRS) ▷ Compute secret value for chain i // 17: sk ← PRF(PK.seed, SK.seed, skADRS) ▷ Compute secret value for chain i
let sk = (hashers.prf)(pk_seed, sk_seed, &sk_addrs); let sk = (hashers.prf)(pk_seed, sk_seed, &sk_addrs);
// 18: ADRS.setChainAddress(i) // 18: ADRS.setChainAddress(i)
adrs.set_chain_address(i as u32); adrs.set_chain_address(i);
// 19: sig[i] ← chain(sk, 0, msg[i], PK.seed, ADRS) ▷ Compute signature value for chain i // 19: sig[i] ← chain(sk, 0, msg[i], PK.seed, ADRS) ▷ Compute signature value for chain i
sig.data[i] = chain(hashers, sk, 0, *item as usize, pk_seed, &adrs).unwrap(); sig.data[i as usize] = chain(hashers, sk, 0, *item as usize, pk_seed, &adrs).unwrap();
// 20: end for // 20: end for
} }
@ -316,13 +316,12 @@ pub(crate) fn wots_pk_from_sig<K: ArrayLength, LEN: ArrayLength, M: ArrayLength,
// 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
let len1 = 2 * N::to_usize();
let mut msg: GenericArray<u64, LEN> = GenericArray::default(); let mut msg: GenericArray<u64, LEN> = GenericArray::default();
base_2b(m, crate::LGW, 2 * N::to_usize(), &mut msg[0..(2 * N::to_usize())]); base_2b(m, crate::LGW, 2 * N::to_usize(), &mut msg[0..(2 * N::to_usize())]);
// 4: // 4:
// 5: for i from 0 to len1 1 do ▷ Compute checksum // 5: for i from 0 to len1 1 do ▷ Compute checksum
for item in msg.iter().take(len1) { for item in msg.iter().take(2 * N::to_usize()) {
// //
// 6: csum ← csum + w 1 msg[i] // 6: csum ← csum + w 1 msg[i]
csum += u64::from(crate::W) - 1 - item; csum += u64::from(crate::W) - 1 - item;
@ -333,11 +332,11 @@ 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; let len2 = 3;
csum <<= (8 - ((len2 * crate::LGW as usize) % 8)) % 8; csum <<= (8 - ((len2 * crate::LGW as usize) & 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, (len2 * crate::LGW as usize).div_ceil(8)), &to_byte(csum as u64, (len2 * crate::LGW as usize).div_ceil(8)),
crate::LGW, crate::LGW,
len2, len2,
&mut msg[(2 * N::to_usize())..], &mut msg[(2 * N::to_usize())..],
@ -419,7 +418,7 @@ pub(crate) fn xmss_node<
adrs.set_key_pair_address(i); adrs.set_key_pair_address(i);
// 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() // TODO remove clone?

View file

@ -1,14 +1,13 @@
//#![no_std] #![no_std]
#![deny(clippy::pedantic)] #![deny(clippy::pedantic)]
#![deny(warnings)] #![deny(warnings)]
//#![deny(missing_docs)] //#![deny(missing_docs)]
/// TKTK crate doc /// TKTK crate doc
/// crate doc?
// TODO // TODO
// 1. General clean-up // 1. General clean-up
// 2. NOTE: SHA2 HASHERS DUMMIED UP TO PASS TEST; IMPLEMENT! // 2. SerDes on keys
// 3. Implement SHA2 KATs // 3. Proper traits and non-rng functions
// 4. Separate into proper files // 4. Separate into proper files
// 5. Doc, of course! // 5. Doc, of course!
mod algs; mod algs;
@ -17,16 +16,16 @@ mod test;
mod traits; mod traits;
mod types; mod types;
// Per eqns 5.1-4 on page 16, LGW=4, W=16 and LEN2=3 are constant across all parameter sets. // Per eqns 5.1-4 on page 16, LGW=4, W=16 and LEN2=3 are constant across all security parameter sets.
const LGW: u32 = 4; const LGW: u32 = 4;
const W: u32 = 16; const W: u32 = 16;
const LEN2: u32 = 3; const LEN2: u32 = 3;
/// blah /// blah
macro_rules! functionality { macro_rules! functionality {
() => { () => {
use crate::types::{SlhDsaSig, SlhPrivateKey, SlhPublicKey}; use crate::types::{SlhDsaSig, SlhPrivateKey, SlhPublicKey};
//use generic_array::typenum::{Prod, Sum, U2, U3};
use rand_core::CryptoRngCore; use rand_core::CryptoRngCore;
/// blah /// blah
@ -61,13 +60,13 @@ macro_rules! functionality {
use rand_chacha::rand_core::SeedableRng; use rand_chacha::rand_core::SeedableRng;
#[test] #[test]
fn simple_loop() { fn simple_round_trips() {
let mut message = [0u8, 1, 2, 3]; let mut message = [0u8, 1, 2, 3];
let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(123); let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(123);
for i in 0..5 { for i in 0..5 {
message[3] = i as u8; message[3] = i as u8;
let (sk, pk) = slh_keygen_with_rng(&mut rng).unwrap(); let (sk, pk) = slh_keygen_with_rng(&mut rng).unwrap();
let sig = slh_sign_with_rng(&mut rng, &message, &sk, false).unwrap(); let sig = slh_sign_with_rng(&mut rng, &message, &sk, true).unwrap();
let result = slh_verify(&message, &sig, &pk); let result = slh_verify(&message, &sig, &pk);
assert_eq!(result, true, "Signature failed to verify"); assert_eq!(result, true, "Signature failed to verify");
message[3] = (i + 1) as u8; message[3] = (i + 1) as u8;
@ -79,11 +78,11 @@ macro_rules! functionality {
}; };
} }
/// TKTK /// TKTK
#[cfg(feature = "slh_dsa_sha2_128s")] #[cfg(feature = "slh_dsa_sha2_128s")]
pub mod slh_dsa_sha2_128s { pub mod slh_dsa_sha2_128s {
use crate::hashers::sha2_cat_1::{f, h, h_msg, prf, prf_msg, t_l, t_len}; use crate::hashers::sha2_cat_1::{f, h, h_msg, prf, prf_msg, t_l, t_len};
use crate::hashers::Hashers; use crate::hashers::Hashers;
use generic_array::typenum::{Prod, Sum, U12, U14, U16, U2, U3, U30, U63, U7, U9}; use generic_array::typenum::{Prod, Sum, U12, U14, U16, U2, U3, U30, U63, U7, U9};
@ -104,6 +103,7 @@ pub mod slh_dsa_sha2_128s {
functionality!(); functionality!();
} }
/// TKTK /// TKTK
#[cfg(feature = "slh_dsa_shake_128s")] #[cfg(feature = "slh_dsa_shake_128s")]
pub mod slh_dsa_shake_128s { pub mod slh_dsa_shake_128s {
@ -128,11 +128,11 @@ pub mod slh_dsa_shake_128s {
functionality!(); functionality!();
} }
/// TKTK /// TKTK
#[cfg(feature = "slh_dsa_sha2_128f")] #[cfg(feature = "slh_dsa_sha2_128f")]
pub mod slh_dsa_sha2_128f { pub mod slh_dsa_sha2_128f {
use crate::hashers::sha2_cat_1::{f, h, h_msg, prf, prf_msg, t_l, t_len}; use crate::hashers::sha2_cat_1::{f, h, h_msg, prf, prf_msg, t_l, t_len};
use crate::hashers::Hashers; use crate::hashers::Hashers;
use generic_array::typenum::{Prod, Sum, U16, U2, U22, U3, U33, U34, U6, U66}; use generic_array::typenum::{Prod, Sum, U16, U2, U22, U3, U33, U34, U6, U66};
@ -153,6 +153,7 @@ pub mod slh_dsa_sha2_128f {
functionality!(); functionality!();
} }
/// TKTK /// TKTK
#[cfg(feature = "slh_dsa_shake_128f")] #[cfg(feature = "slh_dsa_shake_128f")]
pub mod slh_dsa_shake_128f { pub mod slh_dsa_shake_128f {
@ -177,11 +178,11 @@ pub mod slh_dsa_shake_128f {
functionality!(); functionality!();
} }
/// TKTK /// TKTK
#[cfg(feature = "slh_dsa_sha2_192s")] #[cfg(feature = "slh_dsa_sha2_192s")]
pub mod slh_dsa_sha2_192s { pub mod slh_dsa_sha2_192s {
use crate::hashers::sha2_cat_3_5::{f, h, h_msg, prf, prf_msg, t_l, t_len}; use crate::hashers::sha2_cat_3_5::{f, h, h_msg, prf, prf_msg, t_l, t_len};
use crate::hashers::Hashers; use crate::hashers::Hashers;
use generic_array::typenum::{Prod, Sum, U14, U17, U2, U24, U3, U39, U63, U7, U9}; use generic_array::typenum::{Prod, Sum, U14, U17, U2, U24, U3, U39, U63, U7, U9};
@ -202,11 +203,11 @@ pub mod slh_dsa_sha2_192s {
functionality!(); functionality!();
} }
/// TKTK /// TKTK
#[cfg(feature = "slh_dsa_shake_192s")] #[cfg(feature = "slh_dsa_shake_192s")]
pub mod slh_dsa_shake_192s { pub mod slh_dsa_shake_192s {
use crate::hashers::shake::{f, h, h_msg, prf, prf_msg, t_l, t_len}; use crate::hashers::shake::{f, h, h_msg, prf, prf_msg, t_l, t_len};
use crate::hashers::Hashers; use crate::hashers::Hashers;
use generic_array::typenum::{Prod, Sum, U14, U17, U2, U24, U3, U39, U63, U7, U9}; use generic_array::typenum::{Prod, Sum, U14, U17, U2, U24, U3, U39, U63, U7, U9};
@ -227,6 +228,7 @@ pub mod slh_dsa_shake_192s {
functionality!(); functionality!();
} }
/// TKTK /// TKTK
#[cfg(feature = "slh_dsa_sha2_192f")] #[cfg(feature = "slh_dsa_sha2_192f")]
pub mod slh_dsa_sha2_192f { pub mod slh_dsa_sha2_192f {
@ -251,6 +253,7 @@ pub mod slh_dsa_sha2_192f {
functionality!(); functionality!();
} }
/// TKTK /// TKTK
#[cfg(feature = "slh_dsa_shake_192f")] #[cfg(feature = "slh_dsa_shake_192f")]
pub mod slh_dsa_shake_192f { pub mod slh_dsa_shake_192f {
@ -275,11 +278,11 @@ pub mod slh_dsa_shake_192f {
functionality!(); functionality!();
} }
/// TKTK /// TKTK
#[cfg(feature = "slh_dsa_sha2_256s")] #[cfg(feature = "slh_dsa_sha2_256s")]
pub mod slh_dsa_sha2_256s { pub mod slh_dsa_sha2_256s {
use crate::hashers::sha2_cat_3_5::{f, h, h_msg, prf, prf_msg, t_l, t_len}; use crate::hashers::sha2_cat_3_5::{f, h, h_msg, prf, prf_msg, t_l, t_len};
use crate::hashers::Hashers; use crate::hashers::Hashers;
use generic_array::typenum::{Prod, Sum, U14, U2, U22, U3, U32, U47, U64, U8}; use generic_array::typenum::{Prod, Sum, U14, U2, U22, U3, U32, U47, U64, U8};
@ -300,6 +303,7 @@ pub mod slh_dsa_sha2_256s {
functionality!(); functionality!();
} }
/// TKTK /// TKTK
#[cfg(feature = "slh_dsa_shake_256s")] #[cfg(feature = "slh_dsa_shake_256s")]
pub mod slh_dsa_shake_256s { pub mod slh_dsa_shake_256s {
@ -324,11 +328,11 @@ pub mod slh_dsa_shake_256s {
functionality!(); functionality!();
} }
/// TKTK /// TKTK
#[cfg(feature = "slh_dsa_sha2_256f")] #[cfg(feature = "slh_dsa_sha2_256f")]
pub mod slh_dsa_sha2_256f { pub mod slh_dsa_sha2_256f {
use crate::hashers::sha2_cat_3_5::{f, h, h_msg, prf, prf_msg, t_l, t_len}; use crate::hashers::sha2_cat_3_5::{f, h, h_msg, prf, prf_msg, t_l, t_len};
use crate::hashers::Hashers; use crate::hashers::Hashers;
use generic_array::typenum::{Prod, Sum, U17, U2, U3, U32, U35, U4, U49, U68, U9}; use generic_array::typenum::{Prod, Sum, U17, U2, U3, U32, U35, U4, U49, U68, U9};
@ -349,6 +353,7 @@ pub mod slh_dsa_sha2_256f {
functionality!(); functionality!();
} }
/// TKTK /// TKTK
#[cfg(feature = "slh_dsa_shake_256f")] #[cfg(feature = "slh_dsa_shake_256f")]
pub mod slh_dsa_shake_256f { pub mod slh_dsa_shake_256f {

File diff suppressed because one or more lines are too long