|
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}; |
@@ -182,6 +182,9 @@ pub struct KeyPair<P: MlDsaParams> { |
182 | 182 |
|
183 | 183 | /// The verifying key of the key pair |
184 | 184 | verifying_key: VerifyingKey<P>, |
| 185 | + |
| 186 | + /// The seed this signing key was derived from |
| 187 | + seed: B32, |
185 | 188 | } |
186 | 189 |
|
187 | 190 | impl<P: MlDsaParams> KeyPair<P> { |
@@ -241,6 +244,21 @@ where |
241 | 244 | Signature::<P>::ALGORITHM_IDENTIFIER; |
242 | 245 | } |
243 | 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 | + |
244 | 262 | /// An ML-DSA signing key |
245 | 263 | #[derive(Clone, PartialEq)] |
246 | 264 | pub struct SigningKey<P: MlDsaParams> { |
@@ -800,6 +818,7 @@ where |
800 | 818 | KeyPair { |
801 | 819 | signing_key, |
802 | 820 | verifying_key, |
| 821 | + seed: xi.clone(), |
803 | 822 | } |
804 | 823 | } |
805 | 824 | } |
|
0 commit comments