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
5 changes: 2 additions & 3 deletions ml-kem/src/kem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,8 @@ where
(dk, ek)
}

#[cfg(feature = "deterministic")]
fn generate_deterministic(d: B32, z: B32) -> (Self::DecapsulationKey, Self::EncapsulationKey) {
let dk = Self::DecapsulationKey::generate_deterministic(d, z);
fn from_seed(seed: Seed) -> (Self::DecapsulationKey, Self::EncapsulationKey) {
let dk = Self::DecapsulationKey::from_seed(seed);
let ek = dk.encapsulation_key().clone();
(dk, ek)
}
Expand Down
24 changes: 8 additions & 16 deletions ml-kem/src/traits.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use crate::{ArraySize, Ciphertext, SharedKey};
//! Trait definitions

use crate::{ArraySize, Ciphertext, Seed, SharedKey};
use core::fmt::Debug;
use hybrid_array::Array;
use kem::{Decapsulate, Encapsulate};
use rand_core::CryptoRng;

#[cfg(feature = "deterministic")]
use crate::util::B32;
use crate::B32;

/// An object that knows what size it is
pub trait EncodedSizeUser {
Expand Down Expand Up @@ -52,28 +54,18 @@ pub trait KemCore: Clone {
+ PartialEq;

/// An encapsulation key for this KEM
#[cfg(not(feature = "deterministic"))]
type EncapsulationKey: Encapsulate<Ciphertext<Self>, SharedKey<Self>>
+ EncodedSizeUser
+ Clone
+ Debug
+ PartialEq;

/// An encapsulation key for this KEM
#[cfg(feature = "deterministic")]
type EncapsulationKey: Encapsulate<Ciphertext<Self>, SharedKey<Self>>
+ EncapsulateDeterministic<Ciphertext<Self>, SharedKey<Self>>
+ EncodedSizeUser
+ Clone
+ Debug
+ PartialEq;

/// Generate a new (decapsulation, encapsulation) key pair
/// Generate a new (decapsulation, encapsulation) key pair.
fn generate<R: CryptoRng + ?Sized>(
rng: &mut R,
) -> (Self::DecapsulationKey, Self::EncapsulationKey);

/// Generate a new (decapsulation, encapsulation) key pair deterministically
#[cfg(feature = "deterministic")]
fn generate_deterministic(d: B32, z: B32) -> (Self::DecapsulationKey, Self::EncapsulationKey);
/// Generate a new (decapsulation, encapsulation) key pair deterministically from the given
/// uniformly random seed value.
fn from_seed(seed: Seed) -> (Self::DecapsulationKey, Self::EncapsulationKey);
}
6 changes: 5 additions & 1 deletion ml-kem/tests/encap-decap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ fn verify_encap_group(tg: &acvp::EncapTestGroup) {
}
}

fn verify_encap<K: KemCore>(tc: &acvp::EncapTestCase) {
fn verify_encap<K>(tc: &acvp::EncapTestCase)
where
K: KemCore,
K::EncapsulationKey: EncapsulateDeterministic<Ciphertext<K>, SharedKey<K>>,
{
let m = Array::try_from(tc.m.as_slice()).unwrap();
let ek_bytes = Encoded::<K::EncapsulationKey>::try_from(tc.ek.as_slice()).unwrap();
let ek = K::EncapsulationKey::from_bytes(&ek_bytes);
Expand Down
6 changes: 3 additions & 3 deletions ml-kem/tests/key-gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ fn acvp_key_gen() {

fn verify<K: KemCore>(tc: &acvp::TestCase) {
// Import test data into the relevant array structures
let d = Array::try_from(tc.d.as_slice()).unwrap();
let z = Array::try_from(tc.z.as_slice()).unwrap();
let d: B32 = Array::try_from(tc.d.as_slice()).unwrap();
let z: B32 = Array::try_from(tc.z.as_slice()).unwrap();
let dk_bytes = Encoded::<K::DecapsulationKey>::try_from(tc.dk.as_slice()).unwrap();
let ek_bytes = Encoded::<K::EncapsulationKey>::try_from(tc.ek.as_slice()).unwrap();

let (dk, ek) = K::generate_deterministic(d, z);
let (dk, ek) = K::from_seed(d.concat(z));

// Verify correctness via serialization
assert_eq!(dk.as_bytes().as_slice(), tc.dk.as_slice());
Expand Down
5 changes: 2 additions & 3 deletions x-wing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,8 @@ impl DecapsulationKey {
shaker.update(&self.sk);
let mut expanded: Shake256Reader = shaker.finalize_xof();

let d = read_from(&mut expanded).into();
let z = read_from(&mut expanded).into();
let (sk_m, pk_m) = MlKem768::generate_deterministic(d, z);
let seed = read_from(&mut expanded).into();
let (sk_m, pk_m) = MlKem768::from_seed(seed);

let sk_x = read_from(&mut expanded);
let sk_x = StaticSecret::from(sk_x);
Expand Down