1use crate::pqc::{
4 types::{MlDsaPublicKey, MlDsaSecretKey, MlDsaSignature, PqcResult},
5 MlDsaOperations,
6};
7use fips204::ml_dsa_65;
8use fips204::traits::{SerDes, Signer, Verifier};
9use rand_core::OsRng;
10
11pub struct MlDsa65;
13
14impl Default for MlDsa65 {
15 fn default() -> Self {
16 Self::new()
17 }
18}
19
20impl MlDsa65 {
21 #[must_use]
23 pub const fn new() -> Self {
24 Self
25 }
26}
27
28impl Clone for MlDsa65 {
29 fn clone(&self) -> Self {
30 Self::new()
31 }
32}
33
34impl MlDsaOperations for MlDsa65 {
35 fn generate_keypair(&self) -> PqcResult<(MlDsaPublicKey, MlDsaSecretKey)> {
36 let (pk, sk) = ml_dsa_65::try_keygen_with_rng(&mut OsRng)
37 .map_err(|e| crate::pqc::types::PqcError::KeyGenerationFailed(e.to_string()))?;
38
39 Ok((
40 MlDsaPublicKey::from_bytes(&pk.into_bytes())?,
41 MlDsaSecretKey::from_bytes(&sk.into_bytes())?,
42 ))
43 }
44
45 fn sign(&self, secret_key: &MlDsaSecretKey, message: &[u8]) -> PqcResult<MlDsaSignature> {
46 let sk_bytes: [u8; 4032] = secret_key.as_bytes().try_into().map_err(|_| {
47 crate::pqc::types::PqcError::InvalidKeySize {
48 expected: 4032,
49 actual: secret_key.as_bytes().len(),
50 }
51 })?;
52
53 let sk = ml_dsa_65::PrivateKey::try_from_bytes(sk_bytes)
54 .map_err(|e| crate::pqc::types::PqcError::CryptoError(e.to_string()))?;
55
56 let sig = sk
57 .try_sign_with_rng(&mut OsRng, message, b"")
58 .map_err(|e| crate::pqc::types::PqcError::SigningFailed(e.to_string()))?;
59
60 MlDsaSignature::from_bytes(&sig)
61 }
62
63 fn verify(
64 &self,
65 public_key: &MlDsaPublicKey,
66 message: &[u8],
67 signature: &MlDsaSignature,
68 ) -> PqcResult<bool> {
69 let pk_bytes: [u8; 1952] = public_key.as_bytes().try_into().map_err(|_| {
70 crate::pqc::types::PqcError::InvalidKeySize {
71 expected: 1952,
72 actual: public_key.as_bytes().len(),
73 }
74 })?;
75
76 let pk = ml_dsa_65::PublicKey::try_from_bytes(pk_bytes)
77 .map_err(|e| crate::pqc::types::PqcError::CryptoError(e.to_string()))?;
78
79 let sig_bytes: [u8; 3309] = signature.as_bytes().try_into().map_err(|_| {
80 crate::pqc::types::PqcError::InvalidSignatureSize {
81 expected: 3309,
82 actual: signature.as_bytes().len(),
83 }
84 })?;
85
86 Ok(pk.verify(message, &sig_bytes, b""))
87 }
88}