1111//! definitions and a trait interface but no implementation, allowing downstream
1212//! code to be written against the interface without requiring the dependency.
1313
14- #[ cfg( feature = "pq-signatures" ) ]
15- use ml_dsa:: { KeyGen , MlDsa65 } ;
16-
17- #[ cfg( feature = "pq-signatures" ) ]
18- use rand_core:: { CryptoRng , RngCore } ;
19-
2014use crate :: error:: CryptoError ;
2115use alloc:: vec:: Vec ;
2216
@@ -68,9 +62,10 @@ impl MlDsa65VerifyingKey {
6862 /// Returns [`CryptoError::InvalidSignature`] if the signature is invalid.
6963 #[ cfg( feature = "pq-signatures" ) ]
7064 pub fn verify ( & self , message : & [ u8 ] , signature : & MlDsa65Signature ) -> Result < ( ) , CryptoError > {
71- use ml_dsa:: Verifier ;
72- let vk = ml_dsa:: VerifyingKey :: < ml_dsa:: MlDsa65 > :: try_from ( self . bytes . as_slice ( ) )
65+ use ml_dsa:: signature :: Verifier ;
66+ let enc = ml_dsa:: EncodedVerifyingKey :: < ml_dsa:: MlDsa65 > :: try_from ( self . bytes . as_slice ( ) )
7367 . map_err ( |_| CryptoError :: InvalidPublicKey ) ?;
68+ let vk = ml_dsa:: VerifyingKey :: < ml_dsa:: MlDsa65 > :: decode ( & enc) ;
7469 let sig = ml_dsa:: Signature :: < ml_dsa:: MlDsa65 > :: try_from ( signature. as_bytes ( ) )
7570 . map_err ( |_| CryptoError :: InvalidSignature ) ?;
7671 vk. verify ( message, & sig)
@@ -95,8 +90,8 @@ impl MlDsa65VerifyingKey {
9590/// ML-DSA-65 signing key.
9691#[ allow( dead_code) ]
9792pub struct MlDsa65SigningKey {
98- /// Raw signing key bytes .
99- bytes : Vec < u8 > ,
93+ /// 32-byte seed for deterministic key regeneration .
94+ seed : Vec < u8 > ,
10095 /// Corresponding verifying (public) key.
10196 verifying_key : MlDsa65VerifyingKey ,
10297}
@@ -108,13 +103,18 @@ impl MlDsa65SigningKey {
108103 ///
109104 /// Returns [`CryptoError::InvalidState`] when the `pq-signatures` feature is not enabled.
110105 #[ cfg( feature = "pq-signatures" ) ]
111- pub fn generate < R : RngCore + CryptoRng > ( rng : & mut R ) -> Self {
112- use signature:: Keypair ;
113- let kp = MlDsa65 :: key_gen ( rng) ;
114- let sk_bytes: Vec < u8 > = kp. signing_key ( ) . to_bytes ( ) . to_vec ( ) ;
115- let vk_bytes: Vec < u8 > = kp. verifying_key ( ) . to_bytes ( ) . to_vec ( ) ;
106+ pub fn generate < R : rand_core:: RngCore + rand_core:: CryptoRng > ( rng : & mut R ) -> Self {
107+ // Generate a 32-byte seed using the caller's RNG (rand_core 0.6).
108+ // Then use from_seed which avoids the rand_core version mismatch.
109+ let mut seed = [ 0u8 ; 32 ] ;
110+ rng. fill_bytes ( & mut seed) ;
111+
112+ let seed_array = ml_dsa:: Seed :: try_from ( seed. as_slice ( ) ) . expect ( "seed is exactly 32 bytes" ) ;
113+ let sk = ml_dsa:: SigningKey :: < ml_dsa:: MlDsa65 > :: from_seed ( & seed_array) ;
114+ let vk = sk. verifying_key ( ) ;
115+ let vk_bytes: Vec < u8 > = vk. encode ( ) . to_vec ( ) ;
116116 Self {
117- bytes : sk_bytes ,
117+ seed : seed . to_vec ( ) ,
118118 verifying_key : MlDsa65VerifyingKey :: from_bytes ( vk_bytes) ,
119119 }
120120 }
@@ -136,10 +136,12 @@ impl MlDsa65SigningKey {
136136 /// Returns [`CryptoError::InvalidState`] when the `pq-signatures` feature is not enabled.
137137 #[ cfg( feature = "pq-signatures" ) ]
138138 pub fn sign ( & self , message : & [ u8 ] ) -> Result < MlDsa65Signature , CryptoError > {
139- use ml_dsa:: Signer ;
140- let sk = ml_dsa:: SigningKey :: < ml_dsa :: MlDsa65 > :: try_from ( self . bytes . as_slice ( ) )
139+ use ml_dsa:: signature :: Signer ;
140+ let seed = ml_dsa:: Seed :: try_from ( self . seed . as_slice ( ) )
141141 . map_err ( |_| CryptoError :: InvalidKeyMaterial ) ?;
142- let sig = sk. sign ( message) ;
142+ let sk = ml_dsa:: SigningKey :: < ml_dsa:: MlDsa65 > :: from_seed ( & seed) ;
143+ let sig: ml_dsa:: Signature < ml_dsa:: MlDsa65 > = sk. sign ( message) ;
144+ use ml_dsa:: signature:: SignatureEncoding ;
143145 Ok ( MlDsa65Signature :: from_bytes ( sig. to_bytes ( ) . to_vec ( ) ) )
144146 }
145147
0 commit comments