use ml_dsa::{
Generate, KeyExport, KeyInit, MlDsa44, MlDsa65, MlDsa87, Signature, SignatureEncoding, Signer,
SigningKey, Verifier, VerifyingKey,
};
use ml_dsa::Keypair as MlDsaKeypairTrait;
use crate::error::CryptError;
use crate::kem::backend::rand_core_010;
use crate::sign::algorithm::SignAlgorithm;
use zeroize::ZeroizeOnDrop;
#[derive(ZeroizeOnDrop)]
pub struct MlDsaSigningKey(Vec<u8>);
impl MlDsaSigningKey {
fn from_bytes(bytes: Vec<u8>) -> Self {
Self(bytes)
}
pub fn as_bytes(&self) -> &[u8] {
&self.0
}
}
#[derive(Clone, Debug)]
pub struct MlDsaVerifyingKey(Vec<u8>);
impl MlDsaVerifyingKey {
fn from_bytes(bytes: Vec<u8>) -> Self {
Self(bytes)
}
pub fn as_bytes(&self) -> &[u8] {
&self.0
}
}
#[derive(Clone, Debug)]
pub struct MlDsaSignature(Vec<u8>);
impl AsRef<[u8]> for MlDsaSignature {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
macro_rules! impl_ml_dsa {
($impl_ty:ty, $param:ty) => {
impl SignAlgorithm for $impl_ty {
type SigningKey = MlDsaSigningKey;
type VerifyingKey = MlDsaVerifyingKey;
type Sig = MlDsaSignature;
fn keypair(
rng: &mut impl rand_core_010::CryptoRng,
) -> Result<(Self::SigningKey, Self::VerifyingKey), CryptError> {
let sk: SigningKey<$param> = Generate::generate_from_rng(rng);
let vk: VerifyingKey<$param> = MlDsaKeypairTrait::verifying_key(&sk);
let sk_bytes = KeyExport::to_bytes(&sk).as_slice().to_vec();
let vk_bytes = KeyExport::to_bytes(&vk).as_slice().to_vec();
Ok((
MlDsaSigningKey::from_bytes(sk_bytes),
MlDsaVerifyingKey::from_bytes(vk_bytes),
))
}
fn sign(sk: &Self::SigningKey, message: &[u8]) -> Result<Self::Sig, CryptError> {
let signing_key = SigningKey::<$param>::new_from_slice(sk.as_bytes())
.map_err(|_| CryptError::SigningFailed)?;
let sig: Signature<$param> = Signer::sign(&signing_key, message);
Ok(MlDsaSignature(sig.to_vec()))
}
fn verify(
vk: &Self::VerifyingKey,
message: &[u8],
sig: &Self::Sig,
) -> Result<(), CryptError> {
let verifying_key = VerifyingKey::<$param>::new_from_slice(vk.as_bytes())
.map_err(|_| CryptError::SignatureVerificationFailed)?;
let signature = Signature::<$param>::try_from(sig.as_ref())
.map_err(|_| CryptError::SignatureVerificationFailed)?;
Verifier::verify(&verifying_key, message, &signature)
.map_err(|_| CryptError::SignatureVerificationFailed)
}
}
};
}
#[derive(Clone, Copy, Debug, Default)]
pub struct MlDsa44Impl;
#[derive(Clone, Copy, Debug, Default)]
pub struct MlDsa65Impl;
#[derive(Clone, Copy, Debug, Default)]
pub struct MlDsa87Impl;
impl_ml_dsa!(MlDsa44Impl, MlDsa44);
impl_ml_dsa!(MlDsa65Impl, MlDsa65);
impl_ml_dsa!(MlDsa87Impl, MlDsa87);