Skip to content

Commit c6f9150

Browse files
committed
ml-kem: add DecapsulationKey::from_expanded
This is intended to subsume the uses of the `EncodedSizeUser` trait, providing a way for users who insist on using the expanded key format to be able to initialize `DecapsulationKey`s. To deter its use, it's marked as deprecated. Many implementations have opted not to support it at all, and in the future we can potentially consider removing it (which would allow `to_seed` to be infallible). After this, it should be possible to deprecate `EncodedSizeUser` as well, and remove it in a future release.
1 parent eb189d7 commit c6f9150

File tree

3 files changed

+41
-24
lines changed

3 files changed

+41
-24
lines changed

ml-kem/src/kem.rs

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ use rand_core::{CryptoRng, TryCryptoRng};
55
use subtle::{ConditionallySelectable, ConstantTimeEq};
66

77
use crate::crypto::{G, H, J, rand};
8-
use crate::param::{DecapsulationKeySize, EncapsulationKeySize, EncodedCiphertext, KemParams};
8+
use crate::param::{
9+
DecapsulationKeySize, EncapsulationKeySize, EncodedCiphertext, ExpandedDecapsulationKey,
10+
KemParams,
11+
};
912
use crate::pke::{DecryptionKey, EncryptionKey};
1013
use crate::util::B32;
1114
use crate::{Encoded, EncodedSizeUser, Seed};
@@ -72,23 +75,9 @@ where
7275
{
7376
type EncodedSize = DecapsulationKeySize<P>;
7477

75-
#[allow(clippy::similar_names)] // allow dk_pke, ek_pke, following the spec
76-
fn from_bytes(enc: &Encoded<Self>) -> Self {
77-
let (dk_pke, ek_pke, h, z) = P::split_dk(enc);
78-
let ek_pke = EncryptionKey::from_bytes(ek_pke);
79-
80-
// XXX(RLB): The encoding here is redundant, since `h` can be computed from `ek_pke`.
81-
// Should we verify that the provided `h` value is valid?
82-
83-
Self {
84-
dk_pke: DecryptionKey::from_bytes(dk_pke),
85-
ek: EncapsulationKey {
86-
ek_pke,
87-
h: h.clone(),
88-
},
89-
d: None,
90-
z: z.clone(),
91-
}
78+
fn from_bytes(expanded: &Encoded<Self>) -> Self {
79+
#[allow(deprecated)]
80+
Self::from_expanded(expanded)
9281
}
9382

9483
fn as_bytes(&self) -> Encoded<Self> {
@@ -154,6 +143,30 @@ where
154143
Self::generate_deterministic(d, z)
155144
}
156145

146+
/// Initialize a [`DecapsulationKey`] from the serialized expanded key form.
147+
///
148+
/// Note that this form is deprecated in practice; prefer to use
149+
/// [`DecapsulationKey::from_seed`].
150+
#[deprecated(since = "0.3.0", note = "use `DecapsulationKey::from_seed` instead")]
151+
#[must_use]
152+
pub fn from_expanded(enc: &ExpandedDecapsulationKey<P>) -> Self {
153+
let (dk_pke, ek_pke, h, z) = P::split_dk(enc);
154+
let ek_pke = EncryptionKey::from_bytes(ek_pke);
155+
156+
// XXX(RLB): The encoding here is redundant, since `h` can be computed from `ek_pke`.
157+
// Should we verify that the provided `h` value is valid?
158+
159+
Self {
160+
dk_pke: DecryptionKey::from_bytes(dk_pke),
161+
ek: EncapsulationKey {
162+
ek_pke,
163+
h: h.clone(),
164+
},
165+
d: None,
166+
z: z.clone(),
167+
}
168+
}
169+
157170
/// Serialize the [`Seed`] value: 64-bytes which can be used to reconstruct the
158171
/// [`DecapsulationKey`].
159172
///

ml-kem/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ pub use util::B32;
8888
pub use ml_kem_512::MlKem512Params;
8989
pub use ml_kem_768::MlKem768Params;
9090
pub use ml_kem_1024::MlKem1024Params;
91-
pub use param::{ArraySize, ParameterSet};
91+
pub use param::{ArraySize, ExpandedDecapsulationKey, ParameterSet};
9292
pub use traits::*;
9393

9494
/// ML-KEM seeds are decapsulation (private) keys, which are consistently 64-bytes across all

ml-kem/src/param.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ use crate::algebra::{FieldElement, NttVector};
2626
use crate::encode::Encode;
2727
use crate::util::{B32, Flatten, Unflatten};
2828

29+
#[cfg(doc)]
30+
use crate::Seed;
31+
2932
/// An array length with other useful properties
3033
pub trait ArraySize: hybrid_array::ArraySize + PartialEq + Debug {}
3134

@@ -241,10 +244,10 @@ pub trait KemParams: PkeParams {
241244
ek: EncodedEncryptionKey<Self>,
242245
h: B32,
243246
z: B32,
244-
) -> EncodedDecapsulationKey<Self>;
247+
) -> ExpandedDecapsulationKey<Self>;
245248

246249
fn split_dk(
247-
enc: &EncodedDecapsulationKey<Self>,
250+
enc: &ExpandedDecapsulationKey<Self>,
248251
) -> (
249252
&EncodedDecryptionKey<Self>,
250253
&EncodedEncryptionKey<Self>,
@@ -256,7 +259,8 @@ pub trait KemParams: PkeParams {
256259
pub type DecapsulationKeySize<P> = <P as KemParams>::DecapsulationKeySize;
257260
pub type EncapsulationKeySize<P> = <P as PkeParams>::EncryptionKeySize;
258261

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

261265
impl<P> KemParams for P
262266
where
@@ -276,13 +280,13 @@ where
276280
ek: EncodedEncryptionKey<Self>,
277281
h: B32,
278282
z: B32,
279-
) -> EncodedDecapsulationKey<Self> {
283+
) -> ExpandedDecapsulationKey<Self> {
280284
dk.concat(ek).concat(h).concat(z)
281285
}
282286

283287
#[allow(clippy::similar_names)] // allow dk_pke, ek_pke, following the spec
284288
fn split_dk(
285-
enc: &EncodedDecapsulationKey<Self>,
289+
enc: &ExpandedDecapsulationKey<Self>,
286290
) -> (
287291
&EncodedDecryptionKey<Self>,
288292
&EncodedEncryptionKey<Self>,

0 commit comments

Comments
 (0)