diff --git a/ml-kem/src/kem.rs b/ml-kem/src/kem.rs index 2e18806..27d6088 100644 --- a/ml-kem/src/kem.rs +++ b/ml-kem/src/kem.rs @@ -5,7 +5,10 @@ use rand_core::{CryptoRng, TryCryptoRng}; use subtle::{ConditionallySelectable, ConstantTimeEq}; use crate::crypto::{G, H, J, rand}; -use crate::param::{DecapsulationKeySize, EncapsulationKeySize, EncodedCiphertext, KemParams}; +use crate::param::{ + DecapsulationKeySize, EncapsulationKeySize, EncodedCiphertext, ExpandedDecapsulationKey, + KemParams, +}; use crate::pke::{DecryptionKey, EncryptionKey}; use crate::util::B32; use crate::{Encoded, EncodedSizeUser, Seed}; @@ -72,23 +75,9 @@ where { type EncodedSize = DecapsulationKeySize

; - #[allow(clippy::similar_names)] // allow dk_pke, ek_pke, following the spec - fn from_bytes(enc: &Encoded) -> Self { - let (dk_pke, ek_pke, h, z) = P::split_dk(enc); - let ek_pke = EncryptionKey::from_bytes(ek_pke); - - // XXX(RLB): The encoding here is redundant, since `h` can be computed from `ek_pke`. - // Should we verify that the provided `h` value is valid? - - Self { - dk_pke: DecryptionKey::from_bytes(dk_pke), - ek: EncapsulationKey { - ek_pke, - h: h.clone(), - }, - d: None, - z: z.clone(), - } + fn from_bytes(expanded: &Encoded) -> Self { + #[allow(deprecated)] + Self::from_expanded(expanded) } fn as_bytes(&self) -> Encoded { @@ -154,6 +143,30 @@ where Self::generate_deterministic(d, z) } + /// Initialize a [`DecapsulationKey`] from the serialized expanded key form. + /// + /// Note that this form is deprecated in practice; prefer to use + /// [`DecapsulationKey::from_seed`]. + #[deprecated(since = "0.3.0", note = "use `DecapsulationKey::from_seed` instead")] + #[must_use] + pub fn from_expanded(enc: &ExpandedDecapsulationKey

) -> Self { + let (dk_pke, ek_pke, h, z) = P::split_dk(enc); + let ek_pke = EncryptionKey::from_bytes(ek_pke); + + // XXX(RLB): The encoding here is redundant, since `h` can be computed from `ek_pke`. + // Should we verify that the provided `h` value is valid? + + Self { + dk_pke: DecryptionKey::from_bytes(dk_pke), + ek: EncapsulationKey { + ek_pke, + h: h.clone(), + }, + d: None, + z: z.clone(), + } + } + /// Serialize the [`Seed`] value: 64-bytes which can be used to reconstruct the /// [`DecapsulationKey`]. /// diff --git a/ml-kem/src/lib.rs b/ml-kem/src/lib.rs index 5c66283..ac4226d 100644 --- a/ml-kem/src/lib.rs +++ b/ml-kem/src/lib.rs @@ -88,7 +88,7 @@ pub use util::B32; pub use ml_kem_512::MlKem512Params; pub use ml_kem_768::MlKem768Params; pub use ml_kem_1024::MlKem1024Params; -pub use param::{ArraySize, ParameterSet}; +pub use param::{ArraySize, ExpandedDecapsulationKey, ParameterSet}; pub use traits::*; /// ML-KEM seeds are decapsulation (private) keys, which are consistently 64-bytes across all diff --git a/ml-kem/src/param.rs b/ml-kem/src/param.rs index e75021c..b1f4ed6 100644 --- a/ml-kem/src/param.rs +++ b/ml-kem/src/param.rs @@ -26,6 +26,9 @@ use crate::algebra::{FieldElement, NttVector}; use crate::encode::Encode; use crate::util::{B32, Flatten, Unflatten}; +#[cfg(doc)] +use crate::Seed; + /// An array length with other useful properties pub trait ArraySize: hybrid_array::ArraySize + PartialEq + Debug {} @@ -241,10 +244,10 @@ pub trait KemParams: PkeParams { ek: EncodedEncryptionKey, h: B32, z: B32, - ) -> EncodedDecapsulationKey; + ) -> ExpandedDecapsulationKey; fn split_dk( - enc: &EncodedDecapsulationKey, + enc: &ExpandedDecapsulationKey, ) -> ( &EncodedDecryptionKey, &EncodedEncryptionKey, @@ -256,7 +259,8 @@ pub trait KemParams: PkeParams { pub type DecapsulationKeySize

=

::DecapsulationKeySize; pub type EncapsulationKeySize

=

::EncryptionKeySize; -pub type EncodedDecapsulationKey

= Array::DecapsulationKeySize>; +/// Serialized decapsulation key after having been expanded from a [`Seed`]. +pub type ExpandedDecapsulationKey

= Array::DecapsulationKeySize>; impl

KemParams for P where @@ -276,13 +280,13 @@ where ek: EncodedEncryptionKey, h: B32, z: B32, - ) -> EncodedDecapsulationKey { + ) -> ExpandedDecapsulationKey { dk.concat(ek).concat(h).concat(z) } #[allow(clippy::similar_names)] // allow dk_pke, ek_pke, following the spec fn split_dk( - enc: &EncodedDecapsulationKey, + enc: &ExpandedDecapsulationKey, ) -> ( &EncodedDecryptionKey, &EncodedEncryptionKey,