use crate::error::CryptError;
use crate::kem::backend::rand_core_010;
use crate::sign::algorithm::SignAlgorithm;
use slh_dsa::{
signature::{Signer, Verifier},
Shake128f, Shake128s, Shake192f, Shake192s, Shake256f, Shake256s, SigningKey,
};
use zeroize::ZeroizeOnDrop;
#[derive(ZeroizeOnDrop)]
pub struct SlhDsaSigningKey(Vec<u8>);
impl SlhDsaSigningKey {
fn from_bytes(bytes: Vec<u8>) -> Self {
Self(bytes)
}
pub fn as_bytes(&self) -> &[u8] {
&self.0
}
}
#[derive(Clone, Debug)]
pub struct SlhDsaVerifyingKey(Vec<u8>);
impl SlhDsaVerifyingKey {
fn from_bytes(bytes: Vec<u8>) -> Self {
Self(bytes)
}
pub fn as_bytes(&self) -> &[u8] {
&self.0
}
}
#[derive(Clone, Debug)]
pub struct SlhDsaSignature(Vec<u8>);
impl AsRef<[u8]> for SlhDsaSignature {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
macro_rules! impl_slh_dsa {
($impl_ty:ty, $param:ty) => {
impl SignAlgorithm for $impl_ty {
type SigningKey = SlhDsaSigningKey;
type VerifyingKey = SlhDsaVerifyingKey;
type Sig = SlhDsaSignature;
fn keypair(
rng: &mut impl rand_core_010::CryptoRng,
) -> Result<(Self::SigningKey, Self::VerifyingKey), CryptError> {
let sk = SigningKey::<$param>::new(rng);
let sk_bytes = sk.to_bytes().to_vec();
let vk_bytes = sk_bytes[sk_bytes.len() / 2..].to_vec();
Ok((
SlhDsaSigningKey::from_bytes(sk_bytes),
SlhDsaVerifyingKey::from_bytes(vk_bytes),
))
}
fn sign(sk: &Self::SigningKey, message: &[u8]) -> Result<Self::Sig, CryptError> {
let signing_key = SigningKey::<$param>::try_from(sk.as_bytes())
.map_err(|_| CryptError::SigningFailed)?;
let sig = signing_key.sign(message);
Ok(SlhDsaSignature(sig.to_vec()))
}
fn verify(
vk: &Self::VerifyingKey,
message: &[u8],
sig: &Self::Sig,
) -> Result<(), CryptError> {
use slh_dsa::VerifyingKey;
let verifying_key = VerifyingKey::<$param>::try_from(vk.as_bytes())
.map_err(|_| CryptError::SignatureVerificationFailed)?;
let signature = <slh_dsa::Signature<$param>>::try_from(sig.as_ref())
.map_err(|_| CryptError::SignatureVerificationFailed)?;
verifying_key
.verify(message, &signature)
.map_err(|_| CryptError::SignatureVerificationFailed)
}
}
};
}
#[derive(Clone, Copy, Debug, Default)]
pub struct SlhDsaShake128fImpl;
#[derive(Clone, Copy, Debug, Default)]
pub struct SlhDsaShake128sImpl;
#[derive(Clone, Copy, Debug, Default)]
pub struct SlhDsaShake192fImpl;
#[derive(Clone, Copy, Debug, Default)]
pub struct SlhDsaShake192sImpl;
#[derive(Clone, Copy, Debug, Default)]
pub struct SlhDsaShake256fImpl;
#[derive(Clone, Copy, Debug, Default)]
pub struct SlhDsaShake256sImpl;
impl_slh_dsa!(SlhDsaShake128fImpl, Shake128f);
impl_slh_dsa!(SlhDsaShake128sImpl, Shake128s);
impl_slh_dsa!(SlhDsaShake192fImpl, Shake192f);
impl_slh_dsa!(SlhDsaShake192sImpl, Shake192s);
impl_slh_dsa!(SlhDsaShake256fImpl, Shake256f);
impl_slh_dsa!(SlhDsaShake256sImpl, Shake256s);