pub mod ml_dsa_44;
pub mod ml_dsa_65;
pub mod ml_dsa_87;
pub use ml_dsa_44::MlDsa44Keypair;
pub use ml_dsa_65::MlDsa65Keypair;
pub use ml_dsa_87::MlDsa87Keypair;
#[cfg(test)]
mod tests {
use super::*;
use rand::rngs::OsRng;
#[test]
fn ml_dsa_44_smoke() {
let keypair = MlDsa44Keypair::generate(&mut OsRng).expect("keygen failed");
let pk = keypair.public_key();
let message = b"test message for ML-DSA-44";
let sig = keypair.sign(&mut OsRng, message).expect("sign failed");
MlDsa44Keypair::verify(&pk, message, &sig).expect("verify failed");
}
#[test]
fn ml_dsa_44_wrong_message_fails() {
let keypair = MlDsa44Keypair::generate(&mut OsRng).expect("keygen failed");
let pk = keypair.public_key();
let sig = keypair.sign(&mut OsRng, b"correct message").expect("sign failed");
assert!(MlDsa44Keypair::verify(&pk, b"wrong message", &sig).is_err());
}
#[test]
fn ml_dsa_65_smoke() {
let keypair = MlDsa65Keypair::generate(&mut OsRng).expect("keygen failed");
let pk = keypair.public_key();
let message = b"test message for ML-DSA-65";
let sig = keypair.sign(&mut OsRng, message).expect("sign failed");
MlDsa65Keypair::verify(&pk, message, &sig).expect("verify failed");
}
#[test]
fn ml_dsa_65_wrong_message_fails() {
let keypair = MlDsa65Keypair::generate(&mut OsRng).expect("keygen failed");
let pk = keypair.public_key();
let sig = keypair.sign(&mut OsRng, b"correct message").expect("sign failed");
assert!(MlDsa65Keypair::verify(&pk, b"wrong message", &sig).is_err());
}
#[test]
fn ml_dsa_87_smoke() {
let keypair = MlDsa87Keypair::generate(&mut OsRng).expect("keygen failed");
let pk = keypair.public_key();
let message = b"test message for ML-DSA-87";
let sig = keypair.sign(&mut OsRng, message).expect("sign failed");
MlDsa87Keypair::verify(&pk, message, &sig).expect("verify failed");
}
#[test]
fn ml_dsa_87_wrong_message_fails() {
let keypair = MlDsa87Keypair::generate(&mut OsRng).expect("keygen failed");
let pk = keypair.public_key();
let sig = keypair.sign(&mut OsRng, b"correct message").expect("sign failed");
assert!(MlDsa87Keypair::verify(&pk, b"wrong message", &sig).is_err());
}
#[test]
fn public_key_sizes() {
let kp44 = MlDsa44Keypair::generate(&mut OsRng).expect("keygen failed");
let kp65 = MlDsa65Keypair::generate(&mut OsRng).expect("keygen failed");
let kp87 = MlDsa87Keypair::generate(&mut OsRng).expect("keygen failed");
assert_eq!(kp44.public_key().bytes.len(), 1312, "ML-DSA-44 public key must be 1312 bytes");
assert_eq!(kp65.public_key().bytes.len(), 1952, "ML-DSA-65 public key must be 1952 bytes");
assert_eq!(kp87.public_key().bytes.len(), 2592, "ML-DSA-87 public key must be 2592 bytes");
}
#[test]
fn secret_key_sizes() {
let kp44 = MlDsa44Keypair::generate(&mut OsRng).expect("keygen failed");
let kp65 = MlDsa65Keypair::generate(&mut OsRng).expect("keygen failed");
let kp87 = MlDsa87Keypair::generate(&mut OsRng).expect("keygen failed");
assert_eq!(kp44.secret_key().bytes.len(), 32, "ML-DSA-44 secret key (seed) must be 32 bytes");
assert_eq!(kp65.secret_key().bytes.len(), 32, "ML-DSA-65 secret key (seed) must be 32 bytes");
assert_eq!(kp87.secret_key().bytes.len(), 32, "ML-DSA-87 secret key (seed) must be 32 bytes");
}
#[test]
fn ml_dsa_65_base64url_roundtrip() {
let keypair = MlDsa65Keypair::generate(&mut OsRng).expect("keygen failed");
let pk = keypair.public_key();
let encoded = pk.to_base64url();
let decoded = crate::types::SigPublicKey::from_base64url(
crate::types::SigAlgorithm::MlDsa65,
&encoded,
).expect("decode failed");
assert_eq!(pk.bytes, decoded.bytes);
}
}