@@ -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 < ( ) > {
@@ -767,10 +799,19 @@ mod tests {
767799 use encoding:: Encode ;
768800 use hex_literal:: hex;
769801
770- #[ cfg( any( feature = "ed25519" , all( feature = "rsa" , feature = "sha1" ) ) ) ]
771- use signature:: Verifier ;
772802 #[ cfg( feature = "ed25519" ) ]
773- use { super :: Ed25519Keypair , signature:: Signer } ;
803+ use super :: Ed25519Keypair ;
804+ #[ cfg( any( feature = "ed25519" , feature = "mldsa" ) ) ]
805+ use signature:: Signer ;
806+ #[ cfg( any(
807+ feature = "ed25519" ,
808+ feature = "mldsa" ,
809+ all( feature = "rsa" , feature = "sha1" )
810+ ) ) ]
811+ use signature:: Verifier ;
812+
813+ #[ cfg( feature = "mldsa" ) ]
814+ use { super :: MlDsaKeypair , crate :: MlDsaParams } ;
774815
775816 #[ cfg( feature = "p256" ) ]
776817 use super :: { Mpint , zero_pad_field_bytes} ;
@@ -922,7 +963,6 @@ mod tests {
922963 fn try_sign_and_verify_dsa ( ) {
923964 use super :: { DSA_COMPONENT_SIZE , DsaKeypair } ;
924965 use encoding:: Decode as _;
925- use signature:: { Signer as _, Verifier as _} ;
926966
927967 fn check_signature_component_lengths (
928968 keypair : & DsaKeypair ,
@@ -1001,6 +1041,59 @@ mod tests {
10011041 assert ! ( keypair. public. verify( EXAMPLE_MSG , & signature) . is_ok( ) ) ;
10021042 }
10031043
1044+ #[ cfg( feature = "mldsa" ) ]
1045+ #[ test]
1046+ fn sign_and_verify_mldsa ( ) {
1047+ let msg = b"Hello, world!" ;
1048+
1049+ for params in [
1050+ MlDsaParams :: MlDsa44 ,
1051+ MlDsaParams :: MlDsa65 ,
1052+ MlDsaParams :: MlDsa87 ,
1053+ ] {
1054+ let keypair = MlDsaKeypair :: from_seed ( params, & [ 42 ; 32 ] ) . unwrap ( ) ;
1055+ let signature = keypair. sign ( msg) ;
1056+
1057+ assert_eq ! ( signature. algorithm( ) , Algorithm :: MlDsa { params } ) ;
1058+ assert_eq ! ( signature. as_bytes( ) . len( ) , params. signature_size( ) ) ;
1059+ assert ! ( keypair. public. verify( msg, & signature) . is_ok( ) ) ;
1060+
1061+ // Signing is deterministic (empty context, deterministic variant).
1062+ assert_eq ! ( keypair. sign( msg) , signature) ;
1063+
1064+ // A tampered message must fail verification.
1065+ assert ! ( keypair. public. verify( b"tampered" , & signature) . is_err( ) ) ;
1066+
1067+ // Signature encode/decode round-trips.
1068+ let encoded = signature. encode_vec ( ) . unwrap ( ) ;
1069+ let decoded = Signature :: try_from ( & encoded[ ..] ) . unwrap ( ) ;
1070+ assert_eq ! ( decoded, signature) ;
1071+ }
1072+ }
1073+
1074+ #[ cfg( feature = "mldsa" ) ]
1075+ #[ test]
1076+ fn mldsa_key_roundtrip ( ) {
1077+ use crate :: { private:: KeypairData , public:: KeyData } ;
1078+ use encoding:: Decode ;
1079+
1080+ let params = MlDsaParams :: MlDsa65 ;
1081+ let keypair = MlDsaKeypair :: from_seed ( params, & [ 7 ; 32 ] ) . unwrap ( ) ;
1082+
1083+ // Public key wire-format round-trips and reports the correct algorithm.
1084+ let public: KeyData = keypair. public . clone ( ) . into ( ) ;
1085+ let encoded = public. encode_vec ( ) . unwrap ( ) ;
1086+ let decoded = KeyData :: decode ( & mut & encoded[ ..] ) . unwrap ( ) ;
1087+ assert_eq ! ( decoded, public) ;
1088+ assert_eq ! ( decoded. algorithm( ) , Algorithm :: MlDsa { params } ) ;
1089+
1090+ // Keypair wire-format round-trips.
1091+ let keypair_data = KeypairData :: from ( keypair) ;
1092+ let encoded = keypair_data. encode_vec ( ) . unwrap ( ) ;
1093+ let decoded = KeypairData :: decode ( & mut & encoded[ ..] ) . unwrap ( ) ;
1094+ assert_eq ! ( decoded, keypair_data) ;
1095+ }
1096+
10041097 #[ test]
10051098 fn placeholder ( ) {
10061099 assert ! (
0 commit comments