|
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