#![doc = include_str!("../README.md")]
#![cfg_attr(not(feature = "std"), no_std)]
#![warn(missing_docs)]
#![warn(clippy::use_self)]
#[cfg(not(feature = "std"))]
extern crate alloc;
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, vec::Vec};
use generic_array::{GenericArray, typenum::Unsigned};
use pastey::paste;
use rand_core::CryptoRngCore;
#[cfg(any(feature = "randomized-signer", feature = "capi"))]
use rand_core::RngCore;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg(feature = "randomized-signer")]
pub use signature::RandomizedSigner;
use signature::SignatureEncoding;
pub use signature::{self, Error, Keypair, Signer, Verifier};
#[cfg(feature = "zeroize")]
use zeroize::{Zeroize, ZeroizeOnDrop};
mod aes;
mod bavc;
#[cfg(feature = "capi")]
pub mod capi;
mod faest;
mod fields;
mod internal_keys;
mod parameter;
mod prg;
mod prover;
mod random_oracles;
mod rijndael_32;
mod universal_hashing;
mod utils;
mod verifier;
mod vole;
mod witness;
mod zk_constraints;
use crate::{
faest::{faest_keygen, faest_sign, faest_unpacked_sign, faest_verify},
internal_keys::{PublicKey, SecretKey, UnpackedSecretKey},
parameter::{
FAEST128fParameters, FAEST128sParameters, FAEST192fParameters, FAEST192sParameters,
FAEST256fParameters, FAEST256sParameters, FAESTEM128fParameters, FAESTEM128sParameters,
FAESTEM192fParameters, FAESTEM192sParameters, FAESTEM256fParameters, FAESTEM256sParameters,
FAESTParameters, OWFParameters,
},
};
#[cfg(all(
feature = "opt-simd",
any(target_arch = "x86", target_arch = "x86_64"),
not(all(target_feature = "avx2", target_feature = "pclmulqdq"))
))]
use parameter::x86_simd;
#[cfg(all(
feature = "opt-simd",
any(target_arch = "x86", target_arch = "x86_64"),
not(all(target_feature = "avx2", target_feature = "pclmulqdq"))
))]
cpufeatures::new!(x86_intrinsics, "avx2", "pclmulqdq");
pub trait KeypairGenerator: Keypair {
fn generate<R>(rng: R) -> Self
where
R: CryptoRngCore;
}
#[derive(Debug)]
pub struct SignatureRef<'a>(&'a [u8]);
impl<'a, 'b> From<&'b [u8]> for SignatureRef<'a>
where
'b: 'a,
{
fn from(value: &'b [u8]) -> Self {
Self(value)
}
}
pub trait ByteEncoding: Clone + Sized + for<'a> TryFrom<&'a [u8]> + TryInto<Self::Repr> {
type Repr: 'static + AsRef<[u8]> + Clone + Send + Sync;
fn to_bytes(&self) -> Self::Repr;
fn to_vec(&self) -> Vec<u8>;
fn encoded_len(&self) -> usize;
}
macro_rules! define_impl {
($param:ident) => {
paste! {
struct $param;
impl $param {
#[cfg(feature="capi")]
const SIGNATURE_SIZE: usize = <[<$param Parameters>] as FAESTParameters>::SignatureSize::USIZE;
#[cfg(feature="capi")]
const SK_SIZE: usize = <<[<$param Parameters>] as FAESTParameters>::OWF as OWFParameters>::SK::USIZE;
#[cfg(feature="capi")]
const PK_SIZE: usize = <<[<$param Parameters>] as FAESTParameters>::OWF as OWFParameters>::PK::USIZE;
#[cfg(any(feature="randomized-signer", feature="capi"))]
fn sample_rho<R: RngCore>(mut rng: R) -> GenericArray<
u8,
<<[<$param Parameters>] as FAESTParameters>::OWF as OWFParameters>::LambdaBytes> {
let mut rho = GenericArray::default();
rng.fill_bytes(&mut rho);
rho
}
#[inline]
fn sign(
msg: &[u8],
sk: &SecretKey<<[<$param Parameters>] as FAESTParameters>::OWF>,
rho: &[u8],
signature: &mut GenericArray<u8, <[<$param Parameters>] as FAESTParameters>::SignatureSize>,
) -> Result<(), Error> {
#[cfg(all(
feature = "opt-simd",
any(target_arch = "x86", target_arch = "x86_64"),
not(all(target_feature = "avx2", target_feature = "pclmulqdq"))
))]
if x86_intrinsics::get() {
let sk: &SecretKey<<x86_simd::[<$param Parameters>] as FAESTParameters>::OWF> = unsafe { core::mem::transmute(sk) };
return faest_sign::<x86_simd::[<$param Parameters>]>(msg, sk, rho, signature);
}
faest_sign::<[<$param Parameters>]>(msg, sk, rho, signature)
}
#[inline]
fn unpacked_sign(
msg: &[u8],
sk: &UnpackedSecretKey<<[<$param Parameters>] as FAESTParameters>::OWF>,
rho: &[u8],
signature: &mut GenericArray<u8, <[<$param Parameters>] as FAESTParameters>::SignatureSize>,
) -> Result<(), Error> {
#[cfg(all(
feature = "opt-simd",
any(target_arch = "x86", target_arch = "x86_64"),
not(all(target_feature = "avx2", target_feature = "pclmulqdq"))
))]
if x86_intrinsics::get() {
let sk: &UnpackedSecretKey<<x86_simd::[<$param Parameters>] as FAESTParameters>::OWF> = unsafe { core::mem::transmute(sk) };
return faest_unpacked_sign::<x86_simd::[<$param Parameters>]>(msg, sk, rho, signature);
}
faest_unpacked_sign::<[<$param Parameters>]>(msg, sk, rho, signature)
}
#[inline]
fn verify(
msg: &[u8],
pk: &PublicKey<<[<$param Parameters>] as FAESTParameters>::OWF>,
sigma: &GenericArray<u8, <[<$param Parameters>] as FAESTParameters>::SignatureSize>,
) -> Result<(), Error>
{
#[cfg(all(
feature = "opt-simd",
any(target_arch = "x86", target_arch = "x86_64"),
not(all(target_feature = "avx2", target_feature = "pclmulqdq"))
))]
if x86_intrinsics::get() {
let pk: &PublicKey<<x86_simd::[<$param Parameters>] as FAESTParameters>::OWF> = unsafe { core::mem::transmute(pk) };
return faest_verify::<x86_simd::[<$param Parameters>]>(msg, pk, sigma);
}
faest_verify::<[<$param Parameters>]>(msg, pk, sigma)
}
}
#[doc = "Signing key for " $param]
#[doc = "use faest::{" $param "SigningKey as SK, " $param "Signature as Sig};"]
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "zeroize", derive(Zeroize, ZeroizeOnDrop))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct [<$param SigningKey>](SecretKey<<[<$param Parameters>] as FAESTParameters>::OWF>);
impl TryFrom<&[u8]> for [<$param SigningKey>] {
type Error = Error;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
SecretKey::try_from(value).map(|sk| Self(sk))
}
}
impl From<&[<$param SigningKey>]> for [u8; <<[<$param Parameters>] as FAESTParameters>::OWF as OWFParameters>::SK::USIZE] {
fn from(value: &[<$param SigningKey>]) -> Self {
value.to_bytes()
}
}
impl From<[<$param SigningKey>]> for [u8; <<[<$param Parameters>] as FAESTParameters>::OWF as OWFParameters>::SK::USIZE] {
fn from(value: [<$param SigningKey>]) -> Self {
value.to_bytes()
}
}
impl ByteEncoding for [<$param SigningKey>] {
type Repr = [u8; <<[<$param Parameters>] as FAESTParameters>::OWF as OWFParameters>::SK::USIZE];
fn to_bytes(&self) -> Self::Repr {
self.0.to_bytes().into_array()
}
fn to_vec(&self) -> Vec<u8> {
self.0.to_vec()
}
fn encoded_len(&self) -> usize {
self.0.encoded_len()
}
}
#[doc = "Unpacked signing key for " $param]
#[doc = "use faest::{" $param "UnpackedSigningKey as UnpackedSK, " $param "Signature as Sig};"]
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct [<$param UnpackedSigningKey>](UnpackedSecretKey<<[<$param Parameters>] as FAESTParameters>::OWF>);
impl From<&[<$param SigningKey>]> for [<$param UnpackedSigningKey>] {
fn from(value: &[<$param SigningKey>]) -> Self {
Self(UnpackedSecretKey::from(value.0.clone()))
}
}
impl TryFrom<&[u8]> for [<$param UnpackedSigningKey>] {
type Error = Error;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
UnpackedSecretKey::try_from(value).map(|sk| Self(sk))
}
}
impl From<&[<$param UnpackedSigningKey>]> for [u8; <<[<$param Parameters>] as FAESTParameters>::OWF as OWFParameters>::SK::USIZE] {
fn from(value: &[<$param UnpackedSigningKey>]) -> Self {
value.to_bytes()
}
}
impl From<[<$param UnpackedSigningKey>]> for [u8; <<[<$param Parameters>] as FAESTParameters>::OWF as OWFParameters>::SK::USIZE] {
fn from(value: [<$param UnpackedSigningKey>]) -> Self {
value.to_bytes()
}
}
impl ByteEncoding for [<$param UnpackedSigningKey>] {
type Repr = [u8; <<[<$param Parameters>] as FAESTParameters>::OWF as OWFParameters>::SK::USIZE];
fn to_bytes(&self) -> Self::Repr {
self.0.to_bytes().into_array()
}
fn to_vec(&self) -> Vec<u8> {
self.0.to_vec()
}
fn encoded_len(&self) -> usize {
self.0.encoded_len()
}
}
#[doc = "Verification key for " $param]
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct [<$param VerificationKey>](PublicKey<<[<$param Parameters>] as FAESTParameters>::OWF>);
impl TryFrom<&[u8]> for [<$param VerificationKey>] {
type Error = Error;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
PublicKey::try_from(value).map(|pk| Self(pk))
}
}
impl From<&[<$param VerificationKey>]> for [u8; <<[<$param Parameters>] as FAESTParameters>::OWF as OWFParameters>::PK::USIZE] {
fn from(value: &[<$param VerificationKey>]) -> Self {
value.to_bytes()
}
}
impl From<[<$param VerificationKey>]> for [u8; <<[<$param Parameters>] as FAESTParameters>::OWF as OWFParameters>::PK::USIZE] {
fn from(value: [<$param VerificationKey>]) -> Self {
value.to_bytes()
}
}
impl ByteEncoding for [<$param VerificationKey>] {
type Repr = [u8; <<[<$param Parameters>] as FAESTParameters>::OWF as OWFParameters>::PK::USIZE];
fn to_bytes(&self) -> Self::Repr {
self.0.to_bytes().into_array()
}
fn to_vec(&self) -> Vec<u8> {
self.0.to_vec()
}
fn encoded_len(&self) -> usize {
self.0.encoded_len()
}
}
impl Keypair for [<$param SigningKey>] {
type VerifyingKey = [<$param VerificationKey>];
fn verifying_key(&self) -> Self::VerifyingKey {
[<$param VerificationKey>](self.0.as_public_key())
}
}
impl KeypairGenerator for [<$param SigningKey>] {
fn generate<R>(rng: R) -> Self
where
R: CryptoRngCore,
{
Self(faest_keygen::<<[<$param Parameters>] as FAESTParameters>::OWF, R>(rng))
}
}
impl Keypair for [<$param UnpackedSigningKey>] {
type VerifyingKey = [<$param VerificationKey>];
fn verifying_key(&self) -> Self::VerifyingKey {
[<$param VerificationKey>](self.0.as_public_key())
}
}
impl KeypairGenerator for [<$param UnpackedSigningKey>] {
fn generate<R>(rng: R) -> Self
where
R: CryptoRngCore,
{
Self(faest_keygen::<<[<$param Parameters>] as FAESTParameters>::OWF, R>(rng).into())
}
}
#[doc = "Signature for " $param]
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct [<$param Signature>](GenericArray<u8, <[<$param Parameters>] as FAESTParameters>::SignatureSize>);
impl Signer<[<$param Signature>]> for [<$param SigningKey>] {
fn try_sign(&self, msg: &[u8]) -> Result<[<$param Signature>], Error> {
let mut signature = GenericArray::default();
$param::sign(msg, &self.0, &[], &mut signature).map(|_| [<$param Signature>](signature))
}
}
impl Signer<Box<[<$param Signature>]>> for [<$param SigningKey>] {
fn try_sign(&self, msg: &[u8]) -> Result<Box<[<$param Signature>]>, Error> {
let mut signature = Box::new([<$param Signature>](GenericArray::default()));
$param::sign(msg, &self.0, &[], &mut signature.0).map(|_| signature)
}
}
impl Signer<[<$param Signature>]> for [<$param UnpackedSigningKey>] {
fn try_sign(&self, msg: &[u8]) -> Result<[<$param Signature>], Error> {
let mut signature = GenericArray::default();
$param::unpacked_sign(msg, &self.0, &[], &mut signature).map(|_| [<$param Signature>](signature))
}
}
impl Verifier<[<$param Signature>]> for [<$param VerificationKey>] {
fn verify(&self, msg: &[u8], signature: &[<$param Signature>]) -> Result<(), Error> {
$param::verify(msg, &self.0, &signature.0)
}
}
impl Verifier<Box<[<$param Signature>]>> for [<$param VerificationKey>] {
fn verify(&self, msg: &[u8], signature: &Box<[<$param Signature>]>) -> Result<(), Error> {
$param::verify(msg, &self.0, &signature.0)
}
}
impl Verifier<SignatureRef<'_>> for [<$param VerificationKey>] {
fn verify(&self, msg: &[u8], signature: &SignatureRef<'_>) -> Result<(), Error> {
GenericArray::try_from_slice(signature.0)
.map_err(|_| Error::new())
.and_then(|sig| $param::verify(msg, &self.0, sig))
}
}
impl Verifier<[<$param Signature>]> for [<$param SigningKey>] {
fn verify(&self, msg: &[u8], signature: &[<$param Signature>]) -> Result<(), Error> {
$param::verify(msg, &self.0.pk, &signature.0)
}
}
impl Verifier<Box<[<$param Signature>]>> for [<$param SigningKey>] {
fn verify(&self, msg: &[u8], signature: &Box<[<$param Signature>]>) -> Result<(), Error> {
$param::verify(msg, &self.0.pk, &signature.0)
}
}
impl Verifier<SignatureRef<'_>> for [<$param SigningKey>] {
fn verify(&self, msg: &[u8], signature: &SignatureRef<'_>) -> Result<(), Error> {
GenericArray::try_from_slice(signature.0)
.map_err(|_| Error::new())
.and_then(|sig| $param::verify(msg, &self.0.pk, sig))
}
}
impl Verifier<[<$param Signature>]> for [<$param UnpackedSigningKey>] {
fn verify(&self, msg: &[u8], signature: &[<$param Signature>]) -> Result<(), Error> {
$param::verify(msg, &self.verifying_key().0, &signature.0)
}
}
impl Verifier<Box<[<$param Signature>]>> for [<$param UnpackedSigningKey>] {
fn verify(&self, msg: &[u8], signature: &Box<[<$param Signature>]>) -> Result<(), Error> {
$param::verify(msg, &self.verifying_key().0, &signature.0)
}
}
impl Verifier<SignatureRef<'_>> for [<$param UnpackedSigningKey>] {
fn verify(&self, msg: &[u8], signature: &SignatureRef<'_>) -> Result<(), Error> {
GenericArray::try_from_slice(signature.0)
.map_err(|_| Error::new())
.and_then(|sig| $param::verify(msg, &self.verifying_key().0, sig))
}
}
#[cfg(feature = "randomized-signer")]
impl RandomizedSigner<[<$param Signature>]> for [<$param SigningKey>] {
fn try_sign_with_rng(
&self,
rng: &mut impl CryptoRngCore,
msg: &[u8],
) -> Result<[<$param Signature>], Error> {
let rho = $param::sample_rho(rng);
let mut signature = GenericArray::default();
$param::sign(msg, &self.0, &rho, &mut signature).map(|_| [<$param Signature>](signature))
}
}
#[cfg(feature = "randomized-signer")]
impl RandomizedSigner<Box<[<$param Signature>]>> for [<$param SigningKey>] {
fn try_sign_with_rng(
&self,
rng: &mut impl CryptoRngCore,
msg: &[u8],
) -> Result<Box<[<$param Signature>]>, Error> {
let rho = $param::sample_rho(rng);
let mut signature = Box::new([<$param Signature>](GenericArray::default()));
$param::sign(msg, &self.0, &rho, &mut signature.0).map(|_| signature)
}
}
#[cfg(feature = "randomized-signer")]
impl RandomizedSigner<[<$param Signature>]> for [<$param UnpackedSigningKey>] {
fn try_sign_with_rng(
&self,
rng: &mut impl CryptoRngCore,
msg: &[u8],
) -> Result<[<$param Signature>], Error> {
let rho = $param::sample_rho(rng);
let mut signature = GenericArray::default();
$param::unpacked_sign(msg, &self.0, &rho, &mut signature).map(|_| [<$param Signature>](signature))
}
}
impl AsRef<[u8]> for [<$param Signature>] {
fn as_ref(&self) -> &[u8] {
self.0.as_slice()
}
}
impl TryFrom<&[u8]> for [<$param Signature>] {
type Error = Error;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
GenericArray::try_from_slice(value)
.map_err(|_| Error::new())
.map(|arr| Self(arr.clone()))
}
}
impl From<[<$param Signature>]> for [u8; <[<$param Parameters>] as FAESTParameters>::SignatureSize::USIZE] {
fn from(value: [<$param Signature>]) -> Self {
value.to_bytes()
}
}
impl SignatureEncoding for [<$param Signature>] {
type Repr = [u8; <[<$param Parameters>] as FAESTParameters>::SignatureSize::USIZE];
fn to_bytes(&self) -> Self::Repr {
let mut ret = [0; <[<$param Parameters>] as FAESTParameters>::SignatureSize::USIZE];
ret.copy_from_slice(self.0.as_slice());
ret
}
fn to_vec(&self) -> Vec<u8> {
self.0.to_vec()
}
fn encoded_len(&self) -> usize {
<[<$param Parameters>] as FAESTParameters>::SignatureSize::USIZE
}
}
}
};
}
define_impl!(FAEST128f);
define_impl!(FAEST128s);
define_impl!(FAEST192f);
define_impl!(FAEST192s);
define_impl!(FAEST256f);
define_impl!(FAEST256s);
define_impl!(FAESTEM128f);
define_impl!(FAESTEM128s);
define_impl!(FAESTEM192f);
define_impl!(FAESTEM192s);
define_impl!(FAESTEM256f);
define_impl!(FAESTEM256s);
#[cfg(test)]
#[generic_tests::define]
mod tests {
use super::*;
use core::fmt::Debug;
use nist_pqc_seeded_rng::NistPqcAes256CtrRng;
use rand_core::SeedableRng;
#[cfg(feature = "serde")]
use serde::{Serialize, de::DeserializeOwned};
const TEST_MESSAGE: &[u8] = "test message".as_bytes();
#[test]
fn sign_and_verify<KP, S>()
where
KP: KeypairGenerator + Signer<S> + Verifier<S>,
KP::VerifyingKey: Verifier<S> + for<'a> Verifier<SignatureRef<'a>>,
S: AsRef<[u8]>,
{
let kp = KP::generate(NistPqcAes256CtrRng::seed_from_u64(1234));
let vk = kp.verifying_key();
let signature = kp.sign(TEST_MESSAGE);
vk.verify(TEST_MESSAGE, &signature)
.expect("signatures verifies");
vk.verify(TEST_MESSAGE, &SignatureRef::from(signature.as_ref()))
.expect("signature verifies as &[u8]");
kp.verify(TEST_MESSAGE, &signature)
.expect("signature verifies with sk");
}
#[test]
fn empty_sign_and_verify<KP, S>()
where
KP: KeypairGenerator + Signer<S> + Verifier<S>,
KP::VerifyingKey: Verifier<S> + for<'a> Verifier<SignatureRef<'a>>,
S: AsRef<[u8]>,
{
let kp = KP::generate(NistPqcAes256CtrRng::seed_from_u64(1234));
let vk = kp.verifying_key();
let signature = kp.sign(&[]);
vk.verify(&[], &signature).expect("signatures verifies");
vk.verify(&[], &SignatureRef::from(signature.as_ref()))
.expect("signature verifies as &[u8]");
kp.verify(&[], &signature)
.expect("signature verifies with sk");
}
#[cfg(feature = "randomized-signer")]
#[test]
fn randomized_sign_and_verify<KP, S>()
where
KP: KeypairGenerator + RandomizedSigner<S> + Verifier<S>,
KP::VerifyingKey: Verifier<S> + for<'a> Verifier<SignatureRef<'a>>,
S: AsRef<[u8]>,
{
let mut rng = NistPqcAes256CtrRng::seed_from_u64(1234);
let kp = KP::generate(&mut rng);
let vk = kp.verifying_key();
let signature = kp.sign_with_rng(&mut rng, TEST_MESSAGE);
vk.verify(TEST_MESSAGE, &signature)
.expect("signatures verifies");
vk.verify(TEST_MESSAGE, &SignatureRef::from(signature.as_ref()))
.expect("signature verifies as &[u8]");
kp.verify(TEST_MESSAGE, &signature)
.expect("signature verifies with sk");
}
#[test]
fn serialize_signature<KP, S>()
where
KP: KeypairGenerator + Signer<S> + Verifier<S>,
KP::VerifyingKey: Verifier<S> + for<'a> Verifier<SignatureRef<'a>>,
S: AsRef<[u8]> + for<'a> TryFrom<&'a [u8], Error = Error>,
{
let kp = KP::generate(NistPqcAes256CtrRng::seed_from_u64(1234));
let vk = kp.verifying_key();
let signature = kp.sign(TEST_MESSAGE);
let signature2 = S::try_from(signature.as_ref()).expect("signature deserializes");
vk.verify(TEST_MESSAGE, &signature2)
.expect("signature verifies");
}
#[test]
fn serialize_keys<KP, S>()
where
KP: KeypairGenerator + Signer<S> + Verifier<S> + ByteEncoding + Eq + Debug,
KP::VerifyingKey: Verifier<S> + ByteEncoding + Eq + Debug,
for<'a> <KP as TryFrom<&'a [u8]>>::Error: Debug,
for<'a> <KP::VerifyingKey as TryFrom<&'a [u8]>>::Error: Debug,
{
let kp = KP::generate(NistPqcAes256CtrRng::seed_from_u64(1234));
let vk = kp.verifying_key();
let signature = kp.sign(TEST_MESSAGE);
let kp2 = KP::try_from(kp.to_bytes().as_ref()).unwrap();
let vk2 = KP::VerifyingKey::try_from(vk.to_bytes().as_ref()).unwrap();
assert_eq!(kp, kp2);
assert_eq!(vk, vk2);
vk2.verify(TEST_MESSAGE, &signature)
.expect("signature verifies");
let signature = kp2.sign(TEST_MESSAGE);
vk.verify(TEST_MESSAGE, &signature)
.expect("signature verifies");
}
#[cfg(feature = "serde")]
#[test]
fn serde_serialization<KP, S>()
where
KP: KeypairGenerator + Signer<S> + Serialize + DeserializeOwned + Eq + Debug,
{
let mut out = vec![];
let mut ser = serde_json::Serializer::new(&mut out);
let kp = KP::generate(NistPqcAes256CtrRng::seed_from_u64(1234));
kp.serialize(&mut ser).expect("serialize key pair");
let serialized = String::from_utf8(out).expect("serialize to string");
let mut de = serde_json::Deserializer::from_str(&serialized);
let kp2 = KP::deserialize(&mut de).expect("deserialize key pair");
assert_eq!(kp, kp2);
}
#[instantiate_tests(<FAEST128fSigningKey, FAEST128fSignature>)]
mod faest_128f {}
#[instantiate_tests(<FAEST128sSigningKey, FAEST128sSignature>)]
mod faest_128s {}
#[instantiate_tests(<FAEST192fSigningKey, FAEST192fSignature>)]
mod faest_192f {}
#[instantiate_tests(<FAEST192sSigningKey, FAEST192sSignature>)]
mod faest_192s {}
#[instantiate_tests(<FAEST256fSigningKey, FAEST256fSignature>)]
mod faest_256f {}
#[instantiate_tests(<FAEST256sSigningKey, FAEST256sSignature>)]
mod faest_256s {}
#[instantiate_tests(<FAESTEM128fSigningKey, FAESTEM128fSignature>)]
mod faest_em_128f {}
#[instantiate_tests(<FAESTEM128sSigningKey, FAESTEM128sSignature>)]
mod faest_em_128s {}
#[instantiate_tests(<FAESTEM192fSigningKey, FAESTEM192fSignature>)]
mod faest_em_192f {}
#[instantiate_tests(<FAESTEM192sSigningKey, FAESTEM192sSignature>)]
mod faest_em_192s {}
#[instantiate_tests(<FAESTEM256fSigningKey, FAESTEM256fSignature>)]
mod faest_em_256f {}
#[instantiate_tests(<FAESTEM256sSigningKey, FAESTEM256sSignature>)]
mod faest_em_256s {}
#[instantiate_tests(<FAEST128fUnpackedSigningKey, FAEST128fSignature>)]
mod faest_128f_unpacked {}
#[instantiate_tests(<FAEST128sUnpackedSigningKey, FAEST128sSignature>)]
mod faest_128s_unpacked {}
#[instantiate_tests(<FAEST192fUnpackedSigningKey, FAEST192fSignature>)]
mod faest_192f_unpacked {}
#[instantiate_tests(<FAEST192sUnpackedSigningKey, FAEST192sSignature>)]
mod faest_192s_unpacked {}
#[instantiate_tests(<FAEST256fUnpackedSigningKey, FAEST256fSignature>)]
mod faest_256f_unpacked {}
#[instantiate_tests(<FAEST256sUnpackedSigningKey, FAEST256sSignature>)]
mod faest_256s_unpacked {}
#[instantiate_tests(<FAESTEM128fUnpackedSigningKey, FAESTEM128fSignature>)]
mod faest_em_128f_unpacked {}
#[instantiate_tests(<FAESTEM128sUnpackedSigningKey, FAESTEM128sSignature>)]
mod faest_em_128s_unpacked {}
#[instantiate_tests(<FAESTEM192fUnpackedSigningKey, FAESTEM192fSignature>)]
mod faest_em_192f_unpacked {}
#[instantiate_tests(<FAESTEM192sUnpackedSigningKey, FAESTEM192sSignature>)]
mod faest_em_192s_unpacked {}
#[instantiate_tests(<FAESTEM256fUnpackedSigningKey, FAESTEM256fSignature>)]
mod faest_em_256f_unpacked {}
#[instantiate_tests(<FAESTEM256sUnpackedSigningKey, FAESTEM256sSignature>)]
mod faest_em_256s_unpacked {}
}