@@ -9,6 +9,9 @@ use signature::{SignatureEncoding, Signer, Verifier};
99#[ cfg( feature = "ed25519" ) ]
1010use crate :: { private:: Ed25519Keypair , public:: Ed25519PublicKey } ;
1111
12+ #[ cfg( feature = "mldsa" ) ]
13+ use crate :: { private:: MlDsaKeypair , public:: MlDsaPublicKey } ;
14+
1215#[ cfg( feature = "dsa" ) ]
1316use {
1417 crate :: { private:: DsaKeypair , public:: DsaPublicKey } ,
@@ -112,6 +115,7 @@ impl Signature {
112115 Algorithm :: SkEd25519 if data. len ( ) == SK_ED25519_SIGNATURE_SIZE => ( ) ,
113116 Algorithm :: SkEcdsaSha2NistP256 => ecdsa_sig_size ( & data, EcdsaCurve :: NistP256 , true ) ?,
114117 Algorithm :: Rsa { .. } => ( ) ,
118+ Algorithm :: MlDsa { params } if data. len ( ) == params. signature_size ( ) => ( ) ,
115119 Algorithm :: Other ( _) if !data. is_empty ( ) => ( ) ,
116120 _ => return Err ( encoding:: Error :: Length . into ( ) ) ,
117121 }
@@ -293,6 +297,8 @@ impl Signer<Signature> for private::KeypairData {
293297 Self :: Ed25519 ( keypair) => keypair. try_sign ( message) ,
294298 #[ cfg( feature = "rsa" ) ]
295299 Self :: Rsa ( keypair) => keypair. try_sign ( message) ,
300+ #[ cfg( feature = "mldsa" ) ]
301+ Self :: MlDsa ( keypair) => keypair. try_sign ( message) ,
296302 _ => Err ( self . algorithm ( ) ?. unsupported_error ( ) . into ( ) ) ,
297303 }
298304 }
@@ -320,6 +326,8 @@ impl Verifier<Signature> for public::KeyData {
320326 Self :: SkEcdsaSha2NistP256 ( pk) => pk. verify ( message, signature) ,
321327 #[ cfg( feature = "rsa" ) ]
322328 Self :: Rsa ( pk) => pk. verify ( message, signature) ,
329+ #[ cfg( feature = "mldsa" ) ]
330+ Self :: MlDsa ( pk) => pk. verify ( message, signature) ,
323331 #[ allow( unreachable_patterns) ]
324332 _ => Err ( self . algorithm ( ) . unsupported_error ( ) . into ( ) ) ,
325333 }
@@ -452,6 +460,30 @@ impl Verifier<Signature> for Ed25519PublicKey {
452460 }
453461}
454462
463+ #[ cfg( feature = "mldsa" ) ]
464+ impl Signer < Signature > for MlDsaKeypair {
465+ fn try_sign ( & self , message : & [ u8 ] ) -> signature:: Result < Signature > {
466+ let data = self . sign_msg ( message) ?;
467+
468+ Ok ( Signature {
469+ algorithm : self . algorithm ( ) ,
470+ data,
471+ } )
472+ }
473+ }
474+
475+ #[ cfg( feature = "mldsa" ) ]
476+ impl Verifier < Signature > for MlDsaPublicKey {
477+ fn verify ( & self , message : & [ u8 ] , signature : & Signature ) -> signature:: Result < ( ) > {
478+ // The signature's algorithm (including parameter set) must match this key.
479+ if signature. algorithm ( ) != self . algorithm ( ) {
480+ return Err ( Error :: Signature . into ( ) ) ;
481+ }
482+
483+ Ok ( self . verify_msg ( message, signature. as_bytes ( ) ) ?)
484+ }
485+ }
486+
455487#[ cfg( feature = "ed25519" ) ]
456488impl Verifier < Signature > for public:: SkEd25519 {
457489 fn verify ( & self , message : & [ u8 ] , signature : & Signature ) -> signature:: Result < ( ) > {
@@ -772,6 +804,9 @@ mod tests {
772804 #[ cfg( feature = "ed25519" ) ]
773805 use { super :: Ed25519Keypair , signature:: Signer } ;
774806
807+ #[ cfg( feature = "mldsa" ) ]
808+ use { super :: MlDsaKeypair , crate :: MlDsaParams } ;
809+
775810 #[ cfg( feature = "p256" ) ]
776811 use super :: { Mpint , zero_pad_field_bytes} ;
777812
@@ -922,7 +957,6 @@ mod tests {
922957 fn try_sign_and_verify_dsa ( ) {
923958 use super :: { DSA_COMPONENT_SIZE , DsaKeypair } ;
924959 use encoding:: Decode as _;
925- use signature:: { Signer as _, Verifier as _} ;
926960
927961 fn check_signature_component_lengths (
928962 keypair : & DsaKeypair ,
@@ -1001,6 +1035,59 @@ mod tests {
10011035 assert ! ( keypair. public. verify( EXAMPLE_MSG , & signature) . is_ok( ) ) ;
10021036 }
10031037
1038+ #[ cfg( feature = "mldsa" ) ]
1039+ #[ test]
1040+ fn sign_and_verify_mldsa ( ) {
1041+ let msg = b"Hello, world!" ;
1042+
1043+ for params in [
1044+ MlDsaParams :: MlDsa44 ,
1045+ MlDsaParams :: MlDsa65 ,
1046+ MlDsaParams :: MlDsa87 ,
1047+ ] {
1048+ let keypair = MlDsaKeypair :: from_seed ( params, & [ 42 ; 32 ] ) . unwrap ( ) ;
1049+ let signature = keypair. sign ( msg) ;
1050+
1051+ assert_eq ! ( signature. algorithm( ) , Algorithm :: MlDsa { params } ) ;
1052+ assert_eq ! ( signature. as_bytes( ) . len( ) , params. signature_size( ) ) ;
1053+ assert ! ( keypair. public. verify( msg, & signature) . is_ok( ) ) ;
1054+
1055+ // Signing is deterministic (empty context, deterministic variant).
1056+ assert_eq ! ( keypair. sign( msg) , signature) ;
1057+
1058+ // A tampered message must fail verification.
1059+ assert ! ( keypair. public. verify( b"tampered" , & signature) . is_err( ) ) ;
1060+
1061+ // Signature encode/decode round-trips.
1062+ let encoded = signature. encode_vec ( ) . unwrap ( ) ;
1063+ let decoded = Signature :: try_from ( & encoded[ ..] ) . unwrap ( ) ;
1064+ assert_eq ! ( decoded, signature) ;
1065+ }
1066+ }
1067+
1068+ #[ cfg( feature = "mldsa" ) ]
1069+ #[ test]
1070+ fn mldsa_key_roundtrip ( ) {
1071+ use crate :: { private:: KeypairData , public:: KeyData } ;
1072+ use encoding:: Decode ;
1073+
1074+ let params = MlDsaParams :: MlDsa65 ;
1075+ let keypair = MlDsaKeypair :: from_seed ( params, & [ 7 ; 32 ] ) . unwrap ( ) ;
1076+
1077+ // Public key wire-format round-trips and reports the correct algorithm.
1078+ let public: KeyData = keypair. public . clone ( ) . into ( ) ;
1079+ let encoded = public. encode_vec ( ) . unwrap ( ) ;
1080+ let decoded = KeyData :: decode ( & mut & encoded[ ..] ) . unwrap ( ) ;
1081+ assert_eq ! ( decoded, public) ;
1082+ assert_eq ! ( decoded. algorithm( ) , Algorithm :: MlDsa { params } ) ;
1083+
1084+ // Keypair wire-format round-trips.
1085+ let keypair_data = KeypairData :: from ( keypair) ;
1086+ let encoded = keypair_data. encode_vec ( ) . unwrap ( ) ;
1087+ let decoded = KeypairData :: decode ( & mut & encoded[ ..] ) . unwrap ( ) ;
1088+ assert_eq ! ( decoded, keypair_data) ;
1089+ }
1090+
10041091 #[ test]
10051092 fn placeholder ( ) {
10061093 assert ! (
0 commit comments