|
18 | 18 | //! |
19 | 19 | //! ``` |
20 | 20 | //! use ml_dsa::{MlDsa65, KeyGen}; |
21 | | -//! use signature::{Signer, Verifier}; |
| 21 | +//! use signature::{Keypair, Signer, Verifier}; |
22 | 22 | //! |
23 | 23 | //! let mut rng = rand::thread_rng(); |
24 | 24 | //! let kp = MlDsa65::key_gen(&mut rng); |
25 | 25 | //! |
26 | 26 | //! let msg = b"Hello world"; |
27 | | -//! let sig = kp.signing_key.sign(msg); |
| 27 | +//! let sig = kp.signing_key().sign(msg); |
28 | 28 | //! |
29 | | -//! assert!(kp.verifying_key.verify(msg, &sig).is_ok()); |
| 29 | +//! assert!(kp.verifying_key().verify(msg, &sig).is_ok()); |
30 | 30 | //! ``` |
31 | 31 |
|
32 | 32 | mod algebra; |
|
71 | 71 |
|
72 | 72 | #[cfg(all(feature = "alloc", feature = "pkcs8"))] |
73 | 73 | use pkcs8::{ |
74 | | - der::asn1::{BitString, BitStringRef}, |
| 74 | + der::asn1::{BitString, BitStringRef, OctetStringRef}, |
75 | 75 | spki::{SignatureBitStringEncoding, SubjectPublicKeyInfo}, |
76 | | - EncodePublicKey, |
| 76 | + EncodePrivateKey, EncodePublicKey, |
77 | 77 | }; |
78 | 78 |
|
79 | 79 | use crate::algebra::{AlgebraExt, Elem, NttMatrix, NttVector, Truncate, Vector}; |
@@ -178,10 +178,20 @@ fn message_representative(tr: &[u8], Mp: &[&[u8]]) -> B64 { |
178 | 178 | /// An ML-DSA key pair |
179 | 179 | pub struct KeyPair<P: MlDsaParams> { |
180 | 180 | /// The signing key of the key pair |
181 | | - pub signing_key: SigningKey<P>, |
| 181 | + signing_key: SigningKey<P>, |
182 | 182 |
|
183 | 183 | /// The verifying key of the key pair |
184 | | - pub verifying_key: VerifyingKey<P>, |
| 184 | + verifying_key: VerifyingKey<P>, |
| 185 | + |
| 186 | + /// The seed this signing key was derived from |
| 187 | + seed: B32, |
| 188 | +} |
| 189 | + |
| 190 | +impl<P: MlDsaParams> KeyPair<P> { |
| 191 | + /// The signing key of the key pair |
| 192 | + pub fn signing_key(&self) -> &SigningKey<P> { |
| 193 | + &self.signing_key |
| 194 | + } |
185 | 195 | } |
186 | 196 |
|
187 | 197 | impl<P: MlDsaParams> AsRef<VerifyingKey<P>> for KeyPair<P> { |
@@ -234,6 +244,21 @@ where |
234 | 244 | Signature::<P>::ALGORITHM_IDENTIFIER; |
235 | 245 | } |
236 | 246 |
|
| 247 | +#[cfg(all(feature = "alloc", feature = "pkcs8"))] |
| 248 | +impl<P> EncodePrivateKey for KeyPair<P> |
| 249 | +where |
| 250 | + P: MlDsaParams, |
| 251 | + P: AssociatedAlgorithmIdentifier<Params = AnyRef<'static>>, |
| 252 | +{ |
| 253 | + fn to_pkcs8_der(&self) -> pkcs8::Result<der::SecretDocument> { |
| 254 | + let pkcs8_key = pkcs8::PrivateKeyInfoRef::new( |
| 255 | + P::ALGORITHM_IDENTIFIER, |
| 256 | + OctetStringRef::new(&self.seed)?, |
| 257 | + ); |
| 258 | + Ok(der::SecretDocument::encode_msg(&pkcs8_key)?) |
| 259 | + } |
| 260 | +} |
| 261 | + |
237 | 262 | /// An ML-DSA signing key |
238 | 263 | #[derive(Clone, PartialEq)] |
239 | 264 | pub struct SigningKey<P: MlDsaParams> { |
@@ -793,6 +818,7 @@ where |
793 | 818 | KeyPair { |
794 | 819 | signing_key, |
795 | 820 | verifying_key, |
| 821 | + seed: xi.clone(), |
796 | 822 | } |
797 | 823 | } |
798 | 824 | } |
|
0 commit comments