diff --git a/Cargo.lock b/Cargo.lock index 8743656..2b7b342 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,6 +55,12 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b59d472eab27ade8d770dcb11da7201c11234bef9f82ce7aa517be028d462b" +[[package]] +name = "base64ct" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" + [[package]] name = "bincode" version = "1.3.3" @@ -243,9 +249,9 @@ checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" [[package]] name = "const-oid" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cb3c4a0d3776f7535c32793be81d6d5fec0d48ac70955d9834e643aa249a52f" +checksum = "0dabb6555f92fb9ee4140454eb5dcd14c7960e1225c6d1a6cc361f032947713e" [[package]] name = "cpufeatures" @@ -401,9 +407,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7050e8041c28720851f7db83183195b6acf375bb7bb28e3b86f0fe6cbd69459d" dependencies = [ "const-oid", + "der_derive", + "pem-rfc7468", "zeroize", ] +[[package]] +name = "der_derive" +version = "0.8.0-rc.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14bfffadecb79dfde429f5dcd7553780c2cea5f7d0e72ad7c37a74f1ef79230a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "dhkem" version = "0.0.1-alpha" @@ -854,13 +873,16 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" name = "ml-kem" version = "0.3.0-pre" dependencies = [ + "const-oid", "criterion", "crypto-common", + "der", "hex", "hex-literal", "hybrid-array", "kem", "num-rational", + "pkcs8", "rand", "rand_core", "serde", @@ -973,6 +995,15 @@ dependencies = [ "primeorder", ] +[[package]] +name = "pem-rfc7468" +version = "1.0.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8e58fab693c712c0d4e88f8eb3087b6521d060bcaf76aeb20cb192d809115ba" +dependencies = [ + "base64ct", +] + [[package]] name = "pin-project-lite" version = "0.2.16" @@ -985,6 +1016,16 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs8" +version = "0.11.0-rc.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c53e5d0804fa4070b1b2a5b320102f2c1c094920a7533d5d87c2630609bcbd34" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.32" @@ -1440,6 +1481,16 @@ dependencies = [ "lock_api", ] +[[package]] +name = "spki" +version = "0.8.0-rc.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8baeff88f34ed0691978ec34440140e1572b68c7dd4a495fd14a3dc1944daa80" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" diff --git a/ml-kem/Cargo.toml b/ml-kem/Cargo.toml index 08a0e3b..9b8dc9e 100644 --- a/ml-kem/Cargo.toml +++ b/ml-kem/Cargo.toml @@ -17,7 +17,10 @@ exclude = ["tests/key-gen.rs", "tests/key-gen.json", "tests/encap-decap.rs", "te [features] deterministic = [] # Expose deterministic generation and encapsulation functions +alloc = ["pkcs8?/alloc"] zeroize = ["dep:zeroize"] +pkcs8 = ["dep:const-oid", "dep:pkcs8"] +pem = ["pkcs8?/pem"] [dependencies] kem = "0.3.0-pre.0" @@ -25,6 +28,9 @@ hybrid-array = { version = "0.4", features = ["extra-sizes"] } rand_core = "0.9" sha3 = { version = "0.11.0-rc.0", default-features = false } zeroize = { version = "1.8.1", optional = true, default-features = false } +pkcs8 = { version = "0.11.0-rc.4", optional = true, default-features = false } +const-oid = { version = "0.10.1", optional = true, features = ["db"], default-features = false } +der = { version = "0.8.0-rc.0", features = ["derive"] } [dev-dependencies] criterion = "0.5.1" diff --git a/ml-kem/src/kem.rs b/ml-kem/src/kem.rs index 8c8edf7..3551f1f 100644 --- a/ml-kem/src/kem.rs +++ b/ml-kem/src/kem.rs @@ -18,6 +18,17 @@ pub use ::kem::{Decapsulate, Encapsulate}; /// A shared key resulting from an ML-KEM transaction pub(crate) type SharedKey = B32; +#[cfg(all(feature = "pkcs8", feature = "alloc"))] +use pkcs8::der::{Encode, asn1::BitStringRef}; +#[cfg(feature = "pkcs8")] +use { + hybrid_array::Array, + pkcs8::{ + der::{AnyRef, asn1::OctetStringRef}, + spki::AssociatedAlgorithmIdentifier, + }, +}; + /// A `DecapsulationKey` provides the ability to generate a new key pair, and decapsulate an /// encapsulated shared key. #[derive(Clone, Debug, PartialEq)] @@ -253,6 +264,189 @@ where } } +/// The serialization of the private key is a choice between three different formats +/// [according to PKCS#8](https://lamps-wg.github.io/kyber-certificates/draft-ietf-lamps-kyber-certificates.html#name-private-key-format). +/// +/// “For ML-KEM private keys, the privateKey field in `OneAsymmetricKey` +/// contains one of the following DER-encoded `CHOICE` structures. +/// The seed format is a fixed 64-byte `OCTET STRING` (66 bytes total +/// with the 0x8040 tag and length) for all security levels, +/// while the expandedKey and both formats vary in size by security level” +#[cfg(feature = "pkcs8")] +#[derive(Clone, Debug, pkcs8::der::Choice)] +pub(crate) enum PrivateKeyChoice<'o> { + /// FIPS 203 format for an ML-KEM private key: a 64-octet seed + #[asn1(tag_mode = "IMPLICIT", context_specific = "0")] + Seed(OctetStringRef<'o>), + /// FIPS 203 format for an ML-KEM private key: the decapsulation key resulting from PKE's `KeyGen` operation + Expanded(OctetStringRef<'o>), + /// In this setting both key formats are provided in a `PrivateKeyBothChoice` `struct` + Both(PrivateKeyBothChoice<'o>), +} + +/// The private key's `Both` variant contains the seed as well as the expanded key. +#[cfg(feature = "pkcs8")] +#[derive(Clone, Debug, pkcs8::der::Sequence)] +pub(crate) struct PrivateKeyBothChoice<'o> { + /// FIPS 203 format for an ML-KEM private key: a 64-octet seed + pub seed: OctetStringRef<'o>, + /// FIPS 203 format for an ML-KEM private key: the decapsulation key resulting from PKE's `KeyGen` operation + pub expanded: OctetStringRef<'o>, +} + +#[cfg(feature = "pkcs8")] +impl

AssociatedAlgorithmIdentifier for EncapsulationKey

+where + P: KemParams + AssociatedAlgorithmIdentifier>, +{ + type Params = P::Params; + + const ALGORITHM_IDENTIFIER: pkcs8::spki::AlgorithmIdentifier = + P::ALGORITHM_IDENTIFIER; +} + +#[cfg(all(feature = "pkcs8", feature = "alloc"))] +impl

pkcs8::EncodePublicKey for EncapsulationKey

+where + P: KemParams + AssociatedAlgorithmIdentifier>, +{ + /// Serialize the given `EncapsulationKey` into DER format. + /// Returns a `Document` which wraps the DER document in case of success. + fn to_public_key_der(&self) -> pkcs8::spki::Result { + let public_key = self.as_bytes(); + let subject_public_key = BitStringRef::new(0, &public_key)?; + + pkcs8::SubjectPublicKeyInfo { + algorithm: P::ALGORITHM_IDENTIFIER, + subject_public_key, + } + .try_into() + } +} + +#[cfg(feature = "pkcs8")] +impl

TryFrom> for EncapsulationKey

+where + P: KemParams + AssociatedAlgorithmIdentifier>, +{ + type Error = pkcs8::spki::Error; + + /// Deserialize the encapsulation key from DER format found in `spki.subject_public_key`. + /// Returns an `EncapsulationKey` containing `ek_{pke}` and `h` in case of success. + fn try_from(spki: pkcs8::SubjectPublicKeyInfoRef<'_>) -> Result { + if spki.algorithm.oid != P::ALGORITHM_IDENTIFIER.oid { + return Err(pkcs8::spki::Error::OidUnknown { + oid: P::ALGORITHM_IDENTIFIER.oid, + }); + } + + let bitstring_of_encapsulation_key = spki.subject_public_key; + let enc_key = match bitstring_of_encapsulation_key.as_bytes() { + Some(bytes) => { + let arr: Array> = match bytes.try_into() { + Ok(array) => array, + Err(_) => return Err(pkcs8::spki::Error::KeyMalformed), + }; + EncryptionKey::from_bytes(&arr) + } + None => return Err(pkcs8::spki::Error::KeyMalformed), + }; + + Ok(Self::new(enc_key)) + } +} + +#[cfg(feature = "pkcs8")] +impl

AssociatedAlgorithmIdentifier for DecapsulationKey

+where + P: KemParams + AssociatedAlgorithmIdentifier>, +{ + type Params = P::Params; + + const ALGORITHM_IDENTIFIER: pkcs8::spki::AlgorithmIdentifier = + P::ALGORITHM_IDENTIFIER; +} + +#[cfg(all(feature = "pkcs8", feature = "alloc"))] +impl

pkcs8::EncodePrivateKey for DecapsulationKey

+where + P: KemParams + AssociatedAlgorithmIdentifier>, +{ + /// Serialize the given `DecapsulationKey` into DER format. + /// Returns a `SecretDocument` which wraps the DER document in case of success. + fn to_pkcs8_der(&self) -> pkcs8::Result { + let decaps_key_bytes: Array::DecapsulationKeySize> = self.as_bytes(); + + // NOTE: “The seed format is RECOMMENDED as it efficiently stores both the private and public key”, + // but this is impossible with the definition of the type `DecapsulationKey`; see issue 53. + let pk_key_der = + PrivateKeyChoice::Expanded(OctetStringRef::new(decaps_key_bytes.as_slice())?) + .to_der()?; + let pk_key_octetstr: OctetStringRef<'_> = OctetStringRef::new(&pk_key_der)?; + + let private_key_info = + pkcs8::PrivateKeyInfoRef::new(P::ALGORITHM_IDENTIFIER, pk_key_octetstr); + pkcs8::SecretDocument::encode_msg(&private_key_info).map_err(pkcs8::Error::Asn1) + } +} + +#[cfg(feature = "pkcs8")] +impl

TryFrom> for DecapsulationKey

+where + P: KemParams + AssociatedAlgorithmIdentifier>, +{ + type Error = pkcs8::Error; + + /// Deserialize the decapsulation key from DER format found in `spki.private_key`. + /// Returns a `DecapsulationKey` containing `dk_{pke}`, `ek`, and `z` in case of success. + fn try_from(private_key_info_ref: pkcs8::PrivateKeyInfoRef<'_>) -> Result { + if private_key_info_ref.algorithm.oid != P::ALGORITHM_IDENTIFIER.oid { + return Err(pkcs8::Error::PublicKey(pkcs8::spki::Error::OidUnknown { + oid: P::ALGORITHM_IDENTIFIER.oid, + })); + } + + let seed_to_key = |seed: OctetStringRef<'_>| -> Result, Self::Error> { + let (head, tail) = seed.as_bytes().split_at(32); + let d: &B32 = head.try_into().map_err(|_| pkcs8::Error::KeyMalformed)?; + let z: &B32 = tail.try_into().map_err(|_| pkcs8::Error::KeyMalformed)?; + Ok(Self::generate_deterministic(d, z)) + }; + + let expanded_to_key = + |expanded: OctetStringRef<'_>| -> Result, Self::Error> { + let bytes = expanded.as_bytes(); + let array = + Encoded::::try_from(bytes).map_err(|_| pkcs8::Error::KeyMalformed)?; + Ok(Self::from_bytes(&array)) + }; + + let decaps_key = match private_key_info_ref + .private_key + .decode_into::() + { + Ok(PrivateKeyChoice::Seed(seed)) => seed_to_key(seed)?, + Ok(PrivateKeyChoice::Expanded(expanded)) => expanded_to_key(expanded)?, + Ok(PrivateKeyChoice::Both(PrivateKeyBothChoice { seed, expanded })) => { + let computed_decaps_key = seed_to_key(seed)?; + let given_decaps_key = expanded_to_key(expanded)?; + + // “When receiving a private key that contains both the seed and the expandedKey, + // the recipient SHOULD perform a seed consistency check to ensure + // that the sender properly generated the private key” + if computed_decaps_key != given_decaps_key { + return Err(pkcs8::Error::KeyMalformed); + } + + computed_decaps_key + } + Err(_) => return Err(pkcs8::Error::KeyMalformed), + }; + + Ok(decaps_key) + } +} + #[cfg(test)] mod test { use super::*; diff --git a/ml-kem/src/lib.rs b/ml-kem/src/lib.rs index a08ae00..484010a 100644 --- a/ml-kem/src/lib.rs +++ b/ml-kem/src/lib.rs @@ -80,6 +80,9 @@ pub use util::B32; pub use param::{ArraySize, ParameterSet}; +#[cfg(feature = "pkcs8")] +pub use pkcs8::{self, AssociatedOid}; + /// An object that knows what size it is pub trait EncodedSizeUser { /// The size of an encoded object @@ -165,6 +168,22 @@ impl ParameterSet for MlKem512Params { type Dv = U4; } +#[cfg(feature = "pkcs8")] +impl AssociatedOid for MlKem512Params { + const OID: pkcs8::ObjectIdentifier = const_oid::db::fips203::ID_ALG_ML_KEM_512; +} + +#[cfg(feature = "pkcs8")] +impl pkcs8::spki::AssociatedAlgorithmIdentifier for MlKem512Params { + type Params = pkcs8::der::AnyRef<'static>; + + const ALGORITHM_IDENTIFIER: pkcs8::spki::AlgorithmIdentifier = + pkcs8::spki::AlgorithmIdentifier { + oid: Self::OID, + parameters: None, + }; +} + /// `MlKem768` is the parameter set for security category 3, corresponding to key search on a block /// cipher with a 192-bit key. #[derive(Default, Clone, Debug, PartialEq)] @@ -178,6 +197,22 @@ impl ParameterSet for MlKem768Params { type Dv = U4; } +#[cfg(feature = "pkcs8")] +impl AssociatedOid for MlKem768Params { + const OID: pkcs8::ObjectIdentifier = const_oid::db::fips203::ID_ALG_ML_KEM_768; +} + +#[cfg(feature = "pkcs8")] +impl pkcs8::spki::AssociatedAlgorithmIdentifier for MlKem768Params { + type Params = pkcs8::der::AnyRef<'static>; + + const ALGORITHM_IDENTIFIER: pkcs8::spki::AlgorithmIdentifier = + pkcs8::spki::AlgorithmIdentifier { + oid: Self::OID, + parameters: None, + }; +} + /// `MlKem1024` is the parameter set for security category 5, corresponding to key search on a block /// cipher with a 256-bit key. #[derive(Default, Clone, Debug, PartialEq)] @@ -191,6 +226,22 @@ impl ParameterSet for MlKem1024Params { type Dv = U5; } +#[cfg(feature = "pkcs8")] +impl AssociatedOid for MlKem1024Params { + const OID: pkcs8::ObjectIdentifier = const_oid::db::fips203::ID_ALG_ML_KEM_1024; +} + +#[cfg(feature = "pkcs8")] +impl pkcs8::spki::AssociatedAlgorithmIdentifier for MlKem1024Params { + type Params = pkcs8::der::AnyRef<'static>; + + const ALGORITHM_IDENTIFIER: pkcs8::spki::AlgorithmIdentifier = + pkcs8::spki::AlgorithmIdentifier { + oid: Self::OID, + parameters: None, + }; +} + /// A shared key produced by the KEM `K` pub type SharedKey = Array::SharedKeySize>; @@ -212,6 +263,19 @@ pub type MlKem1024 = kem::Kem; #[cfg(test)] mod test { use super::*; + #[cfg(all(feature = "pkcs8", feature = "alloc", feature = "pem"))] + use crate::kem::PrivateKeyBothChoice; + #[cfg(all(feature = "pkcs8", feature = "alloc"))] + use { + crate::kem::PrivateKeyChoice, + pkcs8::{ + der::{self, Decode}, + { + DecodePrivateKey, DecodePublicKey, EncodePrivateKey, EncodePublicKey, + PrivateKeyInfoRef, SubjectPublicKeyInfoRef, + }, + }, + }; fn round_trip_test() where @@ -232,4 +296,254 @@ mod test { round_trip_test::(); round_trip_test::(); } + + #[cfg(all(feature = "pkcs8", feature = "alloc"))] + fn der_serialization_and_deserialization(expected_encaps_len: u32, expected_decaps_len: u32) + where + K: KemCore, + K::EncapsulationKey: EncodePublicKey + DecodePublicKey, + K::DecapsulationKey: EncodePrivateKey + DecodePrivateKey, + { + let mut rng = rand::rng(); + let (decaps_key, encaps_key) = K::generate(&mut rng); + + // TEST: (de)serialize encapsulation key into DER document + { + let der_document = encaps_key.to_public_key_der().unwrap(); + let serialized_document = der_document.as_bytes(); + + // deserialize encapsulation key from DER document + let parsed = der::Document::from_der(serialized_document).unwrap(); + assert_eq!(parsed.len(), der::Length::new(expected_encaps_len)); + + // verify that original encapsulation key corresponds to deserialized encapsulation key + let pub_key = parsed.decode_msg::().unwrap(); + assert_eq!( + encaps_key.as_bytes().as_slice(), + pub_key.subject_public_key.as_bytes().unwrap() + ); + } + + // TEST: (de)serialize encapsulation key into DER document with the blanket implementation for DecodePublicKey + { + let der_document = encaps_key.to_public_key_der().unwrap(); + let serialized_document = der_document.as_bytes(); + + // deserialize encapsulation key from DER document + let parsed = K::EncapsulationKey::from_public_key_der(serialized_document).unwrap(); + + // verify that original encapsulation key corresponds to deserialized encapsulation key + assert_eq!(parsed, encaps_key); + } + + // TEST: (de)serialize decapsulation key into DER document + { + let der_document = decaps_key.to_pkcs8_der().unwrap(); + let serialized_document = der_document.as_bytes(); + + // deserialize decapsulation key from DER document + let secret_document = der::SecretDocument::from_pkcs8_der(serialized_document).unwrap(); + assert_eq!(secret_document.len(), der::Length::new(expected_decaps_len)); + assert_eq!(secret_document.as_bytes(), der_document.as_bytes()); + + // verify that original decapsulation key corresponds to deserialized decapsulation key + let priv_key = secret_document.decode_msg::().unwrap(); + + if let Ok(PrivateKeyChoice::Expanded(expanded)) = priv_key.private_key.decode_into() { + assert_eq!(decaps_key.as_bytes().as_slice(), expanded.as_bytes()); + } else { + panic!("unexpected PrivateKey serialization"); + } + } + + // TEST: (de)serialize decapsulation key into DER document with the blanket implementation for DecodePrivateKey + { + let der_document = decaps_key.to_pkcs8_der().unwrap(); + let serialized_document = der_document.as_bytes(); + + // deserialize decapsulation key from DER document + let parsed = K::DecapsulationKey::from_pkcs8_der(serialized_document).unwrap(); + + // verify that original decapsulation key corresponds to deserialized decapsulation key + assert_eq!(parsed, decaps_key); + } + } + + #[cfg(all(feature = "pkcs8", feature = "alloc"))] + #[test] + fn pkcs8_serialize_and_deserialize_round_trip() { + // NOTE: standardized encapsulation key sizes for MlKem{512,768,1024} are {800,1184,1568} bytes respectively. + // DER serialization adds 22 bytes. Thus we expect a length of {822,1206,1590} respectively. + // NOTE: standardized decapsulation key sizes for MlKem{512,768,1024} are {1632,2400,3168} bytes respectively. + // DER serialization adds 28 bytes. Thus we expect a length of {1660,2428,3196} respectively. + der_serialization_and_deserialization::(822, 1660); + der_serialization_and_deserialization::(1206, 2428); + der_serialization_and_deserialization::(1590, 3196); + } + + #[cfg(all(feature = "pkcs8", feature = "alloc", feature = "pem"))] + fn compare_with_reference_keys(variant: usize, ref_pub_key_pem: &str, ref_priv_key_pem: &str) + where + K: KemCore, + K::EncapsulationKey: EncodePublicKey, + K::DecapsulationKey: EncodePrivateKey, + { + // auxiliary RNG implementation for a static seed + struct SeedBasedRng { + index: usize, + seed: [u8; SEED_LEN], + } + + impl rand_core::RngCore for SeedBasedRng { + fn next_u32(&mut self) -> u32 { + let mut buf = [0u8; 4]; + self.fill_bytes(&mut buf); + u32::from_be_bytes(buf) + } + + fn next_u64(&mut self) -> u64 { + let mut buf = [0u8; 8]; + self.fill_bytes(&mut buf); + u64::from_be_bytes(buf) + } + + fn fill_bytes(&mut self, dst: &mut [u8]) { + for item in dst { + *item = self.seed[self.index]; + self.index = self.index.wrapping_add(1) & ((1 << SEED_LEN.ilog2()) - 1); + } + } + } + + impl CryptoRng for SeedBasedRng {} + + const SEED_LEN: usize = 64; + assert_eq!(SEED_LEN & (SEED_LEN - 1), 0); + + let seed: [u8; SEED_LEN] = core::array::from_fn(|i| u8::try_from(i).unwrap()); + let mut rng = SeedBasedRng { seed, index: 0 }; + let (decaps_key, encaps_key) = K::generate(&mut rng); + + let gen_pub_key_pem = encaps_key + .to_public_key_pem(pkcs8::LineEnding::LF) + .expect("serialization works"); + let gen_priv_key_pem = decaps_key + .to_pkcs8_pem(pkcs8::LineEnding::LF) + .expect("serialization works"); + + { + // TEST: DER document of public key must match + let gen_pub_key_der = encaps_key.to_public_key_der().expect("serialization works"); + let ref_pub_key_der = der::Document::from_pem(ref_pub_key_pem) + .expect("can read pubkey PEM document") + .1; + assert_eq!(gen_pub_key_der, ref_pub_key_der); + } + + // TEST: PEM document of public key must match + assert_eq!( + gen_pub_key_pem, ref_pub_key_pem, + "key generated from static seed and reference public key for ML-KEM-{variant} do not match" + ); + // TEST: PEM document of private key must match + assert_eq!( + gen_priv_key_pem.as_str(), + ref_priv_key_pem, + "key generated from static seed and reference private key for ML-KEM-{variant} do not match" + ); + } + + #[cfg(all(feature = "pkcs8", feature = "alloc", feature = "pem"))] + #[test] + fn pkcs8_generate_same_keys_like_golang_for_static_seed() { + // NOTE: test vector files come from https://github.com/lamps-wg/kyber-certificates/tree/624bcaa4bd9ea9e72de5b51d81ce2d90cbd7e54a + const PEM_512_PUB: &str = include_str!("../tests/examples/ML-KEM-512.pub"); + const PEM_768_PUB: &str = include_str!("../tests/examples/ML-KEM-768.pub"); + const PEM_1024_PUB: &str = include_str!("../tests/examples/ML-KEM-1024.pub"); + const PEM_512_PRIV: &str = include_str!("../tests/examples/ML-KEM-512-expanded.priv"); + const PEM_768_PRIV: &str = include_str!("../tests/examples/ML-KEM-768-expanded.priv"); + const PEM_1024_PRIV: &str = include_str!("../tests/examples/ML-KEM-1024-expanded.priv"); + + compare_with_reference_keys::(512, PEM_512_PUB, PEM_512_PRIV); + compare_with_reference_keys::(768, PEM_768_PUB, PEM_768_PRIV); + compare_with_reference_keys::(1024, PEM_1024_PUB, PEM_1024_PRIV); + } + + #[cfg(all(feature = "pkcs8", feature = "alloc", feature = "pem"))] + #[test] + fn pkcs8_can_read_reference_private_keys() { + // NOTE: test vector files come from https://github.com/lamps-wg/kyber-certificates/tree/624bcaa4bd9ea9e72de5b51d81ce2d90cbd7e54a + const PEM_512_SEED: &str = include_str!("../tests/examples/ML-KEM-512-seed.priv"); + const PEM_512_EXPANDED: &str = include_str!("../tests/examples/ML-KEM-512-expanded.priv"); + const PEM_512_BOTH: &str = include_str!("../tests/examples/ML-KEM-512-both.priv"); + const PEM_768_SEED: &str = include_str!("../tests/examples/ML-KEM-768-seed.priv"); + const PEM_768_EXPANDED: &str = include_str!("../tests/examples/ML-KEM-768-expanded.priv"); + const PEM_768_BOTH: &str = include_str!("../tests/examples/ML-KEM-768-both.priv"); + const PEM_1024_SEED: &str = include_str!("../tests/examples/ML-KEM-1024-seed.priv"); + const PEM_1024_EXPANDED: &str = include_str!("../tests/examples/ML-KEM-1024-expanded.priv"); + const PEM_1024_BOTH: &str = include_str!("../tests/examples/ML-KEM-1024-both.priv"); + + fn expect_seed_bytes(ref_pem: &str, expected_seed_prefix: &[u8]) { + let length = expected_seed_prefix.len(); + let secret_document = der::SecretDocument::from_pkcs8_pem(ref_pem) + .expect("can read reference PEM private key file"); + let priv_key = secret_document.decode_msg::().unwrap(); + + let given_prefix = match priv_key + .private_key + .decode_into() + .expect("could not read internal structure of PEM private key") + { + PrivateKeyChoice::Seed(seed) + | PrivateKeyChoice::Both(PrivateKeyBothChoice { seed, .. }) => { + &seed.as_bytes()[0..length] + } + PrivateKeyChoice::Expanded(_) => return, + }; + + assert_eq!(given_prefix, expected_seed_prefix); + } + + fn expect_expanded_bytes(ref_pem: &str, expected_expanded_prefix: &[u8]) { + let length = expected_expanded_prefix.len(); + let secret_document = der::SecretDocument::from_pkcs8_pem(ref_pem) + .expect("can read reference PEM private key file"); + let priv_key = secret_document.decode_msg::().unwrap(); + + let given_prefix = match priv_key + .private_key + .decode_into() + .expect("could not read internal expanded structure of PEM private key") + { + PrivateKeyChoice::Seed(_) => return, + PrivateKeyChoice::Expanded(expanded) + | PrivateKeyChoice::Both(PrivateKeyBothChoice { expanded, .. }) => { + &expanded.as_bytes()[0..length] + } + }; + + assert_eq!(given_prefix, expected_expanded_prefix); + } + + const STATIC_SEED_PREFIX: &[u8] = + &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]; + const EXPANDED_512_KEY_PREFIX: &[u8] = &[0x70, 0x55, 0x4f, 0xd4, 0x36, 0x34, 0x4f, 0x27]; + const EXPANDED_768_KEY_PREFIX: &[u8] = &[0x27, 0xd2, 0xa7, 0x7f, 0x33, 0x75, 0x6f, 0x61]; + const EXPANDED_1024_KEY_PREFIX: &[u8] = &[0xf7, 0x7b, 0x7f, 0x6b, 0x15, 0xc7, 0x3f, 0xe2]; + + expect_seed_bytes(PEM_512_SEED, STATIC_SEED_PREFIX); + expect_expanded_bytes(PEM_512_EXPANDED, EXPANDED_512_KEY_PREFIX); + expect_seed_bytes(PEM_512_BOTH, STATIC_SEED_PREFIX); + expect_expanded_bytes(PEM_512_BOTH, EXPANDED_512_KEY_PREFIX); + + expect_seed_bytes(PEM_768_SEED, STATIC_SEED_PREFIX); + expect_expanded_bytes(PEM_768_EXPANDED, EXPANDED_768_KEY_PREFIX); + expect_seed_bytes(PEM_768_BOTH, STATIC_SEED_PREFIX); + expect_expanded_bytes(PEM_768_BOTH, EXPANDED_768_KEY_PREFIX); + + expect_seed_bytes(PEM_1024_SEED, STATIC_SEED_PREFIX); + expect_expanded_bytes(PEM_1024_EXPANDED, EXPANDED_1024_KEY_PREFIX); + expect_seed_bytes(PEM_1024_BOTH, STATIC_SEED_PREFIX); + expect_expanded_bytes(PEM_1024_BOTH, EXPANDED_1024_KEY_PREFIX); + } } diff --git a/ml-kem/tests/examples/ML-KEM-1024-both.priv b/ml-kem/tests/examples/ML-KEM-1024-both.priv new file mode 100644 index 0000000..ff3dcbe --- /dev/null +++ b/ml-kem/tests/examples/ML-KEM-1024-both.priv @@ -0,0 +1,71 @@ +-----BEGIN PRIVATE KEY----- +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 +Pj8= +-----END PRIVATE KEY----- diff --git a/ml-kem/tests/examples/ML-KEM-1024-expanded.priv b/ml-kem/tests/examples/ML-KEM-1024-expanded.priv new file mode 100644 index 0000000..88ab933 --- /dev/null +++ b/ml-kem/tests/examples/ML-KEM-1024-expanded.priv @@ -0,0 +1,69 @@ +-----BEGIN PRIVATE KEY----- +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 +JCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+Pw== +-----END PRIVATE KEY----- diff --git a/ml-kem/tests/examples/ML-KEM-1024-seed.priv b/ml-kem/tests/examples/ML-KEM-1024-seed.priv new file mode 100644 index 0000000..e9d8768 --- /dev/null +++ b/ml-kem/tests/examples/ML-KEM-1024-seed.priv @@ -0,0 +1,4 @@ +-----BEGIN PRIVATE KEY----- +MFQCAQAwCwYJYIZIAWUDBAQDBEKAQAABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZ +GhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj8= +-----END PRIVATE KEY----- diff --git a/ml-kem/tests/examples/ML-KEM-1024.pub b/ml-kem/tests/examples/ML-KEM-1024.pub new file mode 100644 index 0000000..d44e8f0 --- /dev/null +++ b/ml-kem/tests/examples/ML-KEM-1024.pub @@ -0,0 +1,36 @@ +-----BEGIN PUBLIC KEY----- +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 +uYOILhF1 +-----END PUBLIC KEY----- diff --git a/ml-kem/tests/examples/ML-KEM-512-both.priv b/ml-kem/tests/examples/ML-KEM-512-both.priv new file mode 100644 index 0000000..51d4be4 --- /dev/null +++ b/ml-kem/tests/examples/ML-KEM-512-both.priv @@ -0,0 +1,39 @@ +-----BEGIN PRIVATE KEY----- +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 +Pj8= +-----END PRIVATE KEY----- diff --git a/ml-kem/tests/examples/ML-KEM-512-expanded.priv b/ml-kem/tests/examples/ML-KEM-512-expanded.priv new file mode 100644 index 0000000..418dfa0 --- /dev/null +++ b/ml-kem/tests/examples/ML-KEM-512-expanded.priv @@ -0,0 +1,37 @@ +-----BEGIN PRIVATE KEY----- +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 +JCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+Pw== +-----END PRIVATE KEY----- diff --git a/ml-kem/tests/examples/ML-KEM-512-seed.priv b/ml-kem/tests/examples/ML-KEM-512-seed.priv new file mode 100644 index 0000000..8222519 --- /dev/null +++ b/ml-kem/tests/examples/ML-KEM-512-seed.priv @@ -0,0 +1,4 @@ +-----BEGIN PRIVATE KEY----- +MFQCAQAwCwYJYIZIAWUDBAQBBEKAQAABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZ +GhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj8= +-----END PRIVATE KEY----- diff --git a/ml-kem/tests/examples/ML-KEM-512.pub b/ml-kem/tests/examples/ML-KEM-512.pub new file mode 100644 index 0000000..da30af4 --- /dev/null +++ b/ml-kem/tests/examples/ML-KEM-512.pub @@ -0,0 +1,20 @@ +-----BEGIN PUBLIC KEY----- +MIIDMjALBglghkgBZQMEBAEDggMhADmVgV5ZfRBDVc8pqlMzyTJRhp1bzb5IcST2 +Ari2pmwWxHYWSK12XPXYAGtRXpBafwrAdrDGLvoygVPnylcBaZ8TBfHmvG+QsOSb +aTUSts6ZKouAFt38GmYsfj+WGcvYad13GvMIlszVkYrGy3dGbF53mZbWf/mqvJdQ +Pyx7fi0ADYZFD7GAfKTKvaRlgloxx4mht6SRqzhydl0yDQtxkg+iE8lAk0Frg7gS +Tmn2XmLLUADcw3qpoP/3OXDEdy81fSQYnKb1MFVowOI3ajdipoxgXlY8XSCVcuD8 +dTLKKUcpU1VntfxBPF6HktJGRTbMgI+YrddGZPFBVm+QFqkKVBgpqYoEZM5BqLtE +wtT6PCwglGByjvFKGnxMm5jRIgO0zDUpFgqasteDj3/2tTrgWqMafWRrevpsRZMl +JqPDdVYZvplMIRwqMcBbNEeDbLIVC+GCna5rBMVTXP9Ubjkrp5dBFyD5JPSQpaxU +lfITVtVQt4KmTBaItrZVvMeEIZekNML2Vjtbfwmni8xIgjJ4NWHRb0y6tnVUAAUH +gVcMZmBLgXrRJSKUc26LAYYaS1p0UZuLb+UUiaUHI5Llh2JscTd2V10zgGocjicy +r5fCaA9RZmMxxOuLvAQxxPloMtrxs8RVKPuhU/bHixwZhwKUfM0zdyekb7U7oR3l +y0GRNGhZUWy2rXJADzzyCbI2rvNaWArIfrPjD6/WaXPKin3SZ1r0H3oXthQzzRr4 +D3cIhp9mVIhJeYCxrBCgzctjagDthoGzXkKRJMqANQcluF+DperDpKPMFgCQPmUp +NWC5szblrw1SnawaBIEZMCy3qbzBELlIUb8CEX8ZncSFqFK3Rz8JuDGmgx1bVMC3 +kNIlz2u5LZRiomzbM92lEjx6rw4moLg2Ve6ii/OoB0clAY/WuuS2Ac9huqtxp6PT +UZejQ+dLSicsEl1UCJZCbYW3lY07OKa6mH7DciXHtEzbEt3kU5tKsII2NoPwS/eg +nMXEHf6DChsWLgsyQzQ2LwhKFEZ3IzRLrdAA+NjFN8SPmY8FMHzr0e3guBw7xZoG +WhttY7Js +-----END PUBLIC KEY----- diff --git a/ml-kem/tests/examples/ML-KEM-768-both.priv b/ml-kem/tests/examples/ML-KEM-768-both.priv new file mode 100644 index 0000000..0c603db --- /dev/null +++ b/ml-kem/tests/examples/ML-KEM-768-both.priv @@ -0,0 +1,55 @@ +-----BEGIN PRIVATE KEY----- +MIIJvgIBADALBglghkgBZQMEBAIEggmqMIIJpgRAAAECAwQFBgcICQoLDA0ODxAR +EhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+PwSC +CWAn0qd/M3VvYSCO8ROr6CWVhz1KvHMOW11nlSm/akzrY4NCcjGoYS9BVQUVrLpS +5I6ti5QoM7vmhl0T0Up50sXD4H8KBW2N56rfyroFjEk8gLN8q4xWJ1O7O6a27IKX ++IXqp1QNUwAVqEQG5VsTZrV34jbOWKJtih61pE1UIyPCFn2b9KR/mFaZygW65DuN +7GF/AjgKOJCv1LjH7H7eJlU6Al885bxdemITAwQjXLGtSDa1ZrW4Y72b20WihEpw +R7bI04PkSFJeBAtNyKK0jGw3yW1i1D8/2I4ogcQKIFyeJI9lK1kngad5+GiA8qFH +tnhj85HMGlqQjACV4HISKR4u+KNuuanAxgcyJbNHA6SvBJOCxHVz2mj96SRa1ETj +Gx+9tSHx9h83vAzvKSBn5nDSih/9kE9vEZCplpGKEwN6bKvzw3O/gpbNN6szundG +gJzD+K3hs2Ob1Xv8xpZQqq8d4Zj8TARjKZ5SxGF4DMQo/F0EpcUYUMumwqUnQ0Bn +V5PdoJvkTCnmOVxl+F0qCnxt9BHmkRsfLLbDUc0uh19Rtji+d2CX6T4vKy+D2gvu +9KqFup52OrZFAqDKUiLp6rWztwiO1SBg6Mgmm5Q6casK4cWxtofS4BnPgDa8+b9u +e6w6qjbkFmD6pFQPJkjNk6GJ7Fwt6nC6yqpP/JBvkIEOobZ78k8seM9rqIGq6mHA +ZSv/lbG65EJtF3O5zCyoLCHjjGNuOxxSMkSYawvoqD9d1c8tVHYvs8Xr9ZuOiFMC +sc5HAz7fdg9OApvkC21WaxnddYrNXHQSh4ExJE+QFyxT8mZjwh2QUwHUi6+RyRfM +d3np2IAswQ2Jo3BQmaKtOjqIlnQ8EURpgJO+JX2stm3HhSKLkSyNll0Uqig0LDrE +qT/vpTKyCUXdwQIBOcFNY4uQjE3d6aBkW5Wy5EFNQLt58EQTgw8VqHPCi7cFnCdB +ACAV8gQI8FjnFbC/mVtTgLfdMloFarl+ZZor4M32wzcxxoOmNLdx6MkqE5ruS7Dk +nHB3Mh1C/BmffB8pjKYl0iOlwmOgPMSBWbeBJmW3hjfk4YcgssKaa5n0J2aky8Tc +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 +Pj8= +-----END PRIVATE KEY----- diff --git a/ml-kem/tests/examples/ML-KEM-768-expanded.priv b/ml-kem/tests/examples/ML-KEM-768-expanded.priv new file mode 100644 index 0000000..9b2f13c --- /dev/null +++ b/ml-kem/tests/examples/ML-KEM-768-expanded.priv @@ -0,0 +1,53 @@ +-----BEGIN PRIVATE KEY----- +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 +JCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+Pw== +-----END PRIVATE KEY----- diff --git a/ml-kem/tests/examples/ML-KEM-768-seed.priv b/ml-kem/tests/examples/ML-KEM-768-seed.priv new file mode 100644 index 0000000..4e7d5a0 --- /dev/null +++ b/ml-kem/tests/examples/ML-KEM-768-seed.priv @@ -0,0 +1,4 @@ +-----BEGIN PRIVATE KEY----- +MFQCAQAwCwYJYIZIAWUDBAQCBEKAQAABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZ +GhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj8= +-----END PRIVATE KEY----- diff --git a/ml-kem/tests/examples/ML-KEM-768.pub b/ml-kem/tests/examples/ML-KEM-768.pub new file mode 100644 index 0000000..36dddd6 --- /dev/null +++ b/ml-kem/tests/examples/ML-KEM-768.pub @@ -0,0 +1,28 @@ +-----BEGIN PUBLIC KEY----- +MIIEsjALBglghkgBZQMEBAIDggShACmKoQ1CPI3aBp0CvFnmzfA6CWuLPaTKubgM +pKFJB2cszvHsT68jSgvFt+nUc/KzEzs7JqHRdctnp4BZGWmcAvdlMbmcX4kYBwS7 +TKRTXFuJcmecZgoHxeUUuHAJyGLrj1FXaV77P8QKne9rgcHMAqJJrk8JStDZvTSF +wcHGgIBSCnyMYyAyzuc4FU5cUXbAfaVgJHdqQw/nbqz2ZaP3uDIQIhW8gvEJOcg1 +VwQzao+sHYHkuwSFql18dNa1m75cXpcqDYusQRtVtdVVfNaAoaj3G064a8SMmgUJ +cxpUvZ1ykLJ5Y+Q3Lcmxmc/crAsBrNKKYjlREuTENkjWIsSMgjTQFEDozDdskn8j +pa/JrAR0xmInTkJFJchVLs47P+JlFt6QG8fVFb3olVjmJslcgLkzQvgBAATznmxs +lIccXjRMqzlmyDX5qWpZr9McQChrOLHBp4RwurlHUYk0RTzoZzapGfH1ptUQqG9U +VPw5gMtcdlvSvV97NrFBDWY1yM60fE3aDXaijqyTnHHDAkgEhmxxYmZYRCFjwsIh +F+UKzvzmN4qYVlIwKk7wws4Mxxa3eW4ray43d9+hrD2iWaMbWptTD4y2OKgaYqww +GEmrr5WnMBvaMAaJCb/bfmfbzLs4pVUaJbGjoPaFdIrVdT2IgPABbGJ0hhZjhMVX +H+I2WQA2TQODEeLYdds2ZoaTK17GAkMKNp6Hpu9cM4eGZXglvUwFes65I+sJNeaQ +XmO0ztf4CFenc91ksVDSZhLqmsEgUtsgF78YQ8y0sygbaQ3HKK36hcACgbjjwJKH +M1+Fa0/CiS9povV5Ia2gGRTECYhmLVd2lmKnhjUbm2ZJPat5WU2YbeIQDWW6D/Tq +WLgVONJKRDWiWPrCVASqf0H2WLE4UGXhWNy2ARVzJyD0BFmqrBXkBpU6kKxSmX0c +zQcAYO/GXbnmUzVEZ/rVbscTyG51QMQjrPJmn1L6b0rGiI2HHvPoR8ApqKr7uS4X +skqgebH0GbphdbRCr7EZCdSla3CgM1soc5IYqnyTSOLDwvPrPRWkHmQXwN2Uv+sh +QZsxGnuxOhgLvoMyGKmmsXRHzIXyJYWVh6cwdwSay8/UTQ8CVDjhXRU4Jw1Ybhv4 +MZKpRZz2PA6XL4UpdnmDHs8SFQmFHLg0D28Qew+hoO/Rs2qBibwIXE9ct4TlU/Qb +kY+AOXzhlW94W+43fKmqi+aZitowwmt8PYxrVSVMyWIDsgxCruCsTh67QI5JqeP4 +edCrB4XrcCVCXRMFoimcAV4SDRY7DhlJTOVyU9AkbRgnRcuBl6t0OLPBu3lyvsWj +BuujVnhVwBRpn+9lrlTHcKDYXBhADPZCrtxmB3e6SxOFAr1aeBL2IfhKSClrmN1D +IrbxWCi4qPDgCoukSlPDqLFDVxsHQKvVZ9rxzenHnCBLbV4lnRdmoxu7y05qBc9F +AhdrMBwcL0Ekd1AVe87IXoCbMKTWDXdHzdD1uZqoyCaYdRd5OqqAgKCxJKhVjfcr +vje3X07btr6CFtbGM/srIoDiURPYaV5DSBw+6zl+sZJQUim2eiAeqJPD4ssy2ovD +QvpN6gV4 +-----END PUBLIC KEY-----