Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 31 additions & 18 deletions ml-kem/src/kem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -72,23 +75,9 @@ where
{
type EncodedSize = DecapsulationKeySize<P>;

#[allow(clippy::similar_names)] // allow dk_pke, ek_pke, following the spec
fn from_bytes(enc: &Encoded<Self>) -> 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>) -> Self {
#[allow(deprecated)]
Self::from_expanded(expanded)
}

fn as_bytes(&self) -> Encoded<Self> {
Expand Down Expand Up @@ -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<P>) -> 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`].
///
Expand Down
2 changes: 1 addition & 1 deletion ml-kem/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 9 additions & 5 deletions ml-kem/src/param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}

Expand Down Expand Up @@ -241,10 +244,10 @@ pub trait KemParams: PkeParams {
ek: EncodedEncryptionKey<Self>,
h: B32,
z: B32,
) -> EncodedDecapsulationKey<Self>;
) -> ExpandedDecapsulationKey<Self>;

fn split_dk(
enc: &EncodedDecapsulationKey<Self>,
enc: &ExpandedDecapsulationKey<Self>,
) -> (
&EncodedDecryptionKey<Self>,
&EncodedEncryptionKey<Self>,
Expand All @@ -256,7 +259,8 @@ pub trait KemParams: PkeParams {
pub type DecapsulationKeySize<P> = <P as KemParams>::DecapsulationKeySize;
pub type EncapsulationKeySize<P> = <P as PkeParams>::EncryptionKeySize;

pub type EncodedDecapsulationKey<P> = Array<u8, <P as KemParams>::DecapsulationKeySize>;
/// Serialized decapsulation key after having been expanded from a [`Seed`].
pub type ExpandedDecapsulationKey<P> = Array<u8, <P as KemParams>::DecapsulationKeySize>;

impl<P> KemParams for P
where
Expand All @@ -276,13 +280,13 @@ where
ek: EncodedEncryptionKey<Self>,
h: B32,
z: B32,
) -> EncodedDecapsulationKey<Self> {
) -> ExpandedDecapsulationKey<Self> {
dk.concat(ek).concat(h).concat(z)
}

#[allow(clippy::similar_names)] // allow dk_pke, ek_pke, following the spec
fn split_dk(
enc: &EncodedDecapsulationKey<Self>,
enc: &ExpandedDecapsulationKey<Self>,
) -> (
&EncodedDecryptionKey<Self>,
&EncodedEncryptionKey<Self>,
Expand Down