use pqcrypto_mldsa::mldsa87;
use pqcrypto_traits::sign::{DetachedSignature as _, PublicKey as _};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PQSignature {
pub signature: Vec<u8>,
pub public_key: Vec<u8>,
pub algorithm: String,
}
pub struct PQKeyPair {
pub public_key: mldsa87::PublicKey,
pub secret_key: mldsa87::SecretKey,
}
impl PQKeyPair {
pub fn generate() -> Self {
let (pk, sk) = mldsa87::keypair();
PQKeyPair {
public_key: pk,
secret_key: sk,
}
}
pub fn sign(&self, message: &[u8]) -> PQSignature {
let sig = mldsa87::detached_sign(message, &self.secret_key);
PQSignature {
signature: sig.as_bytes().to_vec(),
public_key: self.public_key.as_bytes().to_vec(),
algorithm: "ML-DSA-87".to_string(),
}
}
}
impl PQSignature {
pub fn verify(&self, message: &[u8]) -> Result<(), String> {
let pk =
mldsa87::PublicKey::from_bytes(&self.public_key).map_err(|_| "Invalid public key")?;
let sig = mldsa87::DetachedSignature::from_bytes(&self.signature)
.map_err(|_| "Invalid signature")?;
mldsa87::verify_detached_signature(&sig, message, &pk)
.map_err(|_| "Signature verification failed".to_string())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_pq_signature() {
let keypair = PQKeyPair::generate();
let message = b"Test commit message";
let signature = keypair.sign(message);
assert!(signature.verify(message).is_ok());
let wrong_message = b"Wrong message";
assert!(signature.verify(wrong_message).is_err());
}
}