Skip to content

Commit 0830445

Browse files
committed
ml-dsa: impl pkcs8::EncodePrivateKey
1 parent 6d32f22 commit 0830445

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

ml-dsa/src/lib.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,9 @@ use {
7171

7272
#[cfg(all(feature = "alloc", feature = "pkcs8"))]
7373
use pkcs8::{
74-
der::asn1::{BitString, BitStringRef},
74+
der::asn1::{BitString, BitStringRef, OctetStringRef},
7575
spki::{SignatureBitStringEncoding, SubjectPublicKeyInfo},
76-
EncodePublicKey,
76+
EncodePrivateKey, EncodePublicKey,
7777
};
7878

7979
use crate::algebra::{AlgebraExt, Elem, NttMatrix, NttVector, Truncate, Vector};
@@ -182,6 +182,9 @@ pub struct KeyPair<P: MlDsaParams> {
182182

183183
/// The verifying key of the key pair
184184
verifying_key: VerifyingKey<P>,
185+
186+
/// The seed this signing key was derived from
187+
seed: B32,
185188
}
186189

187190
impl<P: MlDsaParams> KeyPair<P> {
@@ -241,6 +244,21 @@ where
241244
Signature::<P>::ALGORITHM_IDENTIFIER;
242245
}
243246

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+
244262
/// An ML-DSA signing key
245263
#[derive(Clone, PartialEq)]
246264
pub struct SigningKey<P: MlDsaParams> {
@@ -800,6 +818,7 @@ where
800818
KeyPair {
801819
signing_key,
802820
verifying_key,
821+
seed: xi.clone(),
803822
}
804823
}
805824
}

ml-dsa/tests/pkcs8.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use ml_dsa::{KeyPair, MlDsa44, MlDsa65, MlDsa87, MlDsaParams, SigningKey, Verify
55
use pkcs8::{
66
der::{pem::LineEnding, AnyRef},
77
spki::AssociatedAlgorithmIdentifier,
8-
DecodePrivateKey, DecodePublicKey, EncodePublicKey,
8+
DecodePrivateKey, DecodePublicKey, EncodePrivateKey, EncodePublicKey,
99
};
1010
use signature::Keypair;
1111

@@ -19,6 +19,12 @@ fn private_key_serialization() {
1919
let sk = SigningKey::<P>::from_pkcs8_pem(private_bytes).expect("parse private key");
2020
let kp = KeyPair::<P>::from_pkcs8_pem(private_bytes).expect("parse private key");
2121
assert!(sk == *kp.signing_key());
22+
assert_eq!(
23+
kp.to_pkcs8_pem(LineEnding::LF)
24+
.expect("serialize private seed")
25+
.deref(),
26+
private_bytes
27+
);
2228

2329
let pk = VerifyingKey::<P>::from_public_key_pem(public_bytes).expect("parse public key");
2430
assert_eq!(

0 commit comments

Comments
 (0)