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
7 changes: 3 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,5 @@ debug = true
[patch.crates-io]
ml-kem = { path = "./ml-kem" }
module-lattice = { path = "./module-lattice" }

kem = { git = "https://github.com/RustCrypto/traits" }
27 changes: 21 additions & 6 deletions dhkem/src/ecdh_kem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use elliptic_curve::{
sec1::{FromSec1Point, ModulusSize, ToSec1Point, UncompressedPoint, UncompressedPointSize},
};
use kem::{
Ciphertext, Encapsulate, Generate, InvalidKey, Kem, KeyExport, KeySizeUser, SharedKey,
TryDecapsulate, TryKeyInit,
Ciphertext, Decapsulator, Encapsulate, Generate, InvalidKey, Kem, KeyExport, KeySizeUser,
SharedKey, TryDecapsulate, TryKeyInit,
};
use rand_core::{CryptoRng, TryCryptoRng};

Expand All @@ -27,8 +27,8 @@ impl<C> Kem for EcdhKem<C>
where
C: CurveArithmetic,
FieldBytesSize<C>: ModulusSize,
EcdhDecapsulationKey<C>: TryDecapsulate<Self> + Generate,
EcdhEncapsulationKey<C>: Encapsulate<Self> + Clone,
EcdhDecapsulationKey<C>: TryDecapsulate<Kem = Self> + Generate,
EcdhEncapsulationKey<C>: Encapsulate<Kem = Self> + Clone,
{
type DecapsulationKey = EcdhDecapsulationKey<C>;
type EncapsulationKey = EcdhEncapsulationKey<C>;
Expand All @@ -41,6 +41,19 @@ where
/// Generic around an elliptic curve `C`.
pub type EcdhDecapsulationKey<C> = DecapsulationKey<SecretKey<C>, PublicKey<C>>;

impl<C> Decapsulator for EcdhDecapsulationKey<C>
where
C: CurveArithmetic,
FieldBytesSize<C>: ModulusSize,
AffinePoint<C>: FromSec1Point<C> + ToSec1Point<C>,
{
type Kem = EcdhKem<C>;

fn encapsulation_key(&self) -> &EcdhEncapsulationKey<C> {
&self.ek
}
}

impl<C> KeySizeUser for EcdhDecapsulationKey<C>
where
C: CurveArithmetic,
Expand Down Expand Up @@ -103,7 +116,7 @@ where
/// To produce something suitable for e.g. symmetric key(s), use the [`Expander`] type to derive
/// output keys.
/// </div>
impl<C> TryDecapsulate<EcdhKem<C>> for EcdhDecapsulationKey<C>
impl<C> TryDecapsulate for EcdhDecapsulationKey<C>
where
C: CurveArithmetic,
FieldBytesSize<C>: ModulusSize,
Expand Down Expand Up @@ -189,12 +202,14 @@ where
/// To produce something suitable for e.g. symmetric key(s), use the [`Expander`] type to derive
/// output keys.
/// </div>
impl<C> Encapsulate<EcdhKem<C>> for EcdhEncapsulationKey<C>
impl<C> Encapsulate for EcdhEncapsulationKey<C>
where
C: CurveArithmetic,
FieldBytesSize<C>: ModulusSize,
AffinePoint<C>: FromSec1Point<C> + ToSec1Point<C>,
{
type Kem = EcdhKem<C>;

fn encapsulate_with_rng<R>(
&self,
rng: &mut R,
Expand Down
16 changes: 8 additions & 8 deletions dhkem/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
mod expander;

pub use expander::{Expander, InvalidLength};
pub use kem::{self, Encapsulate, Generate, Kem, TryDecapsulate};
pub use kem::{self, Decapsulator, Encapsulate, Generate, Kem, TryDecapsulate};

#[cfg(feature = "ecdh")]
mod ecdh_kem;
Expand Down Expand Up @@ -62,6 +62,13 @@ pub struct DecapsulationKey<DK, EK> {
ek: EncapsulationKey<EK>,
}

impl<DK, EK> DecapsulationKey<DK, EK> {
/// Consumes `self` and returns the wrapped value
pub fn into_inner(self) -> DK {
self.dk
}
}

impl<DK, EK> AsRef<EncapsulationKey<EK>> for DecapsulationKey<DK, EK> {
fn as_ref(&self) -> &EncapsulationKey<EK> {
&self.ek
Expand All @@ -78,13 +85,6 @@ where
}
}

impl<DK, EK> DecapsulationKey<DK, EK> {
/// Consumes `self` and returns the wrapped value
pub fn into_inner(self) -> DK {
self.dk
}
}

/// Newtype for a piece of data that may be encapsulated
#[derive(Clone, Copy, Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Default)]
pub struct EncapsulationKey<EK>(EK);
Expand Down
18 changes: 14 additions & 4 deletions dhkem/src/x25519_kem.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{DecapsulationKey, EncapsulationKey};
use kem::{
Decapsulate, Encapsulate, Generate, InvalidKey, Kem, Key, KeyExport, KeyInit, KeySizeUser,
TryKeyInit,
Decapsulate, Decapsulator, Encapsulate, Generate, InvalidKey, Kem, Key, KeyExport, KeyInit,
KeySizeUser, TryKeyInit,
common::array::{Array, sizes::U32},
};
use rand_core::{CryptoRng, TryCryptoRng};
Expand Down Expand Up @@ -34,6 +34,14 @@ impl Kem for X25519Kem {
/// Generic around an elliptic curve `C`.
pub type X25519DecapsulationKey = DecapsulationKey<StaticSecret, PublicKey>;

impl Decapsulator for X25519DecapsulationKey {
type Kem = X25519Kem;

fn encapsulation_key(&self) -> &X25519EncapsulationKey {
&self.ek
}
}

impl KeySizeUser for X25519DecapsulationKey {
type KeySize = U32;
}
Expand Down Expand Up @@ -79,7 +87,7 @@ impl Generate for X25519DecapsulationKey {
/// To produce something suitable for e.g. symmetric key(s), use the [`Expander`] type to derive
/// output keys.
/// </div>
impl Decapsulate<X25519Kem> for X25519DecapsulationKey {
impl Decapsulate for X25519DecapsulationKey {
fn decapsulate(&self, encapsulated_key: &Ciphertext) -> SharedKey {
let public_key = PublicKey::from(encapsulated_key.0);
self.dk.diffie_hellman(&public_key).to_bytes().into()
Expand Down Expand Up @@ -137,7 +145,9 @@ impl KeyExport for X25519EncapsulationKey {
/// To produce something suitable for e.g. symmetric key(s), use the [`Expander`] type to derive
/// output keys.
/// </div>
impl Encapsulate<X25519Kem> for X25519EncapsulationKey {
impl Encapsulate for X25519EncapsulationKey {
type Kem = X25519Kem;

fn encapsulate_with_rng<R>(&self, rng: &mut R) -> (Ciphertext, SharedKey)
where
R: CryptoRng + ?Sized,
Expand Down
20 changes: 11 additions & 9 deletions dhkem/tests/tests.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
//! DHKEM tests.

#![cfg(any(
feature = "k256",
feature = "p256",
feature = "p384",
feature = "p521",
feature = "x25519"
#![cfg(all(
feature = "getrandom",
any(
feature = "k256",
feature = "p256",
feature = "p384",
feature = "p521",
feature = "x25519"
)
))]
#![allow(clippy::unwrap_used, reason = "tests")]

use kem::{Encapsulate, Generate, Kem, TryDecapsulate};
use kem::{Encapsulate, Kem, TryDecapsulate};

fn test_kem<K: Kem>() {
let dk = K::DecapsulationKey::generate();
let ek = dk.as_ref().clone();
let (dk, ek) = K::generate_keypair();
let (ek, ss1) = ek.encapsulate();
let ss2 = dk.try_decapsulate(&ek).unwrap();
assert_eq!(ss1.as_slice(), ss2.as_slice());
Expand Down
18 changes: 11 additions & 7 deletions ml-kem/src/decapsulation_key.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
use crate::{
B32, EncapsulationKey, Seed, SharedKey,
crypto::{G, J},
kem::{Generate, InvalidKey, Kem, KeyExport, KeyInit, KeySizeUser},
param::{DecapsulationKeySize, ExpandedDecapsulationKey, KemParams},
pke::{DecryptionKey, EncryptionKey},
};
use array::{
Array, ArraySize,
sizes::{U32, U64},
};
use kem::{Ciphertext, Decapsulate};
use kem::{
Ciphertext, Decapsulate, Decapsulator, Generate, InvalidKey, Kem, KeyExport, KeyInit,
KeySizeUser,
};
use rand_core::{TryCryptoRng, TryRng};
use subtle::{ConditionallySelectable, ConstantTimeEq};

Expand Down Expand Up @@ -145,7 +147,7 @@ where
}
}

impl<P> Decapsulate<P> for DecapsulationKey<P>
impl<P> Decapsulate for DecapsulationKey<P>
where
P: Kem<EncapsulationKey = EncapsulationKey<P>, SharedKeySize = U32> + KemParams,
{
Expand All @@ -158,11 +160,13 @@ where
}
}

impl<P> AsRef<EncapsulationKey<P>> for DecapsulationKey<P>
impl<P> Decapsulator for DecapsulationKey<P>
where
P: KemParams,
P: Kem<EncapsulationKey = EncapsulationKey<P>, SharedKeySize = U32> + KemParams,
{
fn as_ref(&self) -> &EncapsulationKey<P> {
type Kem = P;

fn encapsulation_key(&self) -> &EncapsulationKey<P> {
&self.ek
}
}
Expand Down Expand Up @@ -271,7 +275,7 @@ where
{
fn from_seed(seed: &Seed) -> (K::DecapsulationKey, K::EncapsulationKey) {
let dk = K::DecapsulationKey::new(seed);
let ek = dk.as_ref().clone();
let ek = dk.encapsulation_key().clone();
(dk, ek)
}
}
4 changes: 3 additions & 1 deletion ml-kem/src/encapsulation_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,12 @@ where
}
}

impl<P> Encapsulate<P> for EncapsulationKey<P>
impl<P> Encapsulate for EncapsulationKey<P>
where
P: Kem + KemParams,
{
type Kem = P;

fn encapsulate_with_rng<R>(&self, rng: &mut R) -> (Ciphertext<P>, SharedKey)
where
R: CryptoRng + ?Sized,
Expand Down
3 changes: 1 addition & 2 deletions ml-kem/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,7 @@ mod test {
where
K: Kem,
{
let dk = K::DecapsulationKey::generate();
let ek = dk.as_ref().clone();
let (dk, ek) = K::generate_keypair();
let (ct, k_send) = ek.encapsulate();
let k_recv = dk.try_decapsulate(&ct).unwrap();
assert_eq!(k_send, k_recv);
Expand Down
7 changes: 3 additions & 4 deletions ml-kem/tests/encap-decap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
#![allow(unreachable_pub, reason = "tests")]
#![allow(clippy::unwrap_used, reason = "tests")]

use ::kem::Decapsulate;
use array::{Array, ArrayN};
use kem::{Ciphertext, Decapsulate, Decapsulator};
use ml_kem::*;
use std::{fs::read_to_string, path::PathBuf};

Expand Down Expand Up @@ -92,11 +92,10 @@ fn verify_decap_group(tg: &acvp::DecapTestGroup) {
fn verify_decap<K>(tc: &acvp::DecapTestCase, dk_slice: &[u8])
where
K: Kem,
K::DecapsulationKey: Decapsulate<K> + ExpandedKeyEncoding,
K::DecapsulationKey: Decapsulate + Decapsulator<Kem = K> + ExpandedKeyEncoding,
{
let dk = K::DecapsulationKey::from_expanded_bytes(dk_slice.try_into().unwrap()).unwrap();

let c = ::kem::Ciphertext::<K>::try_from(tc.c.as_slice()).unwrap();
let c = Ciphertext::<K>::try_from(tc.c.as_slice()).unwrap();
let k = dk.decapsulate(&c);
assert_eq!(k.as_slice(), tc.k.as_slice());
}
Expand Down
24 changes: 14 additions & 10 deletions x-wing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
//! ```

pub use kem::{
self, Decapsulate, Encapsulate, Generate, InvalidKey, Kem, Key, KeyExport, KeyInit,
KeySizeUser, TryKeyInit,
self, Decapsulate, Decapsulator, Encapsulate, Generate, InvalidKey, Kem, Key, KeyExport,
KeyInit, KeySizeUser, TryKeyInit,
};

use core::fmt::{self, Debug};
Expand Down Expand Up @@ -132,7 +132,9 @@ impl EncapsulationKey {
}
}

impl Encapsulate<XWingKem> for EncapsulationKey {
impl Encapsulate for EncapsulationKey {
type Kem = XWingKem;

fn encapsulate_with_rng<R>(&self, rng: &mut R) -> (Ciphertext, SharedKey)
where
R: CryptoRng + ?Sized,
Expand Down Expand Up @@ -196,12 +198,6 @@ impl DecapsulationKey {
}
}

impl AsRef<EncapsulationKey> for DecapsulationKey {
fn as_ref(&self) -> &EncapsulationKey {
&self.ek
}
}

impl Debug for DecapsulationKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("DecapsulationKey")
Expand All @@ -210,7 +206,7 @@ impl Debug for DecapsulationKey {
}
}

impl Decapsulate<XWingKem> for DecapsulationKey {
impl Decapsulate for DecapsulationKey {
#[allow(clippy::similar_names)] // So we can use the names as in the RFC
fn decapsulate(&self, ct: &Ciphertext) -> SharedKey {
let ct = CiphertextMessage::from(ct);
Expand All @@ -225,6 +221,14 @@ impl Decapsulate<XWingKem> for DecapsulationKey {
}
}

impl Decapsulator for DecapsulationKey {
type Kem = XWingKem;

fn encapsulation_key(&self) -> &EncapsulationKey {
&self.ek
}
}

impl Drop for DecapsulationKey {
fn drop(&mut self) {
#[cfg(feature = "zeroize")]
Expand Down