Skip to content

Commit

Permalink
dhkem: fewer curve choices, add *Kem to type names (#44)
Browse files Browse the repository at this point in the history
Also adds `#[warn(missing_docs)]`.

This reduces the curve choices to the following:

- k256: secp256k1
- p256: NIST P-256
- p384: NIST P-384
- p521: NIST P-521

It also adds `*Kem` to the end of every type name, to avoid a name clash
between elliptic curves and their respective KEMs.
  • Loading branch information
tarcieri authored Aug 8, 2024
1 parent 190c1de commit fd444af
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 118 deletions.
45 changes: 0 additions & 45 deletions Cargo.lock

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

14 changes: 3 additions & 11 deletions dhkem/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,36 +18,28 @@ kem = "0.3.0-pre.0"
rand_core = "0.6.4"

# optional dependencies
x25519 = { version = "2.0.1", package = "x25519-dalek", optional = true, default-features = false }
elliptic-curve = { version = "0.13.8", optional = true, default-features = false }
bign256 = { version = "0.13.1", optional = true, default-features = false, features = ["arithmetic"] }
k256 = { version = "0.13.3", optional = true, default-features = false, features = ["arithmetic"] }
p192 = { version = "0.13.0", optional = true, default-features = false, features = ["arithmetic"] }
p224 = { version = "0.13.2", optional = true, default-features = false, features = ["arithmetic"] }
p256 = { version = "0.13.2", optional = true, default-features = false, features = ["arithmetic"] }
p384 = { version = "0.13.0", optional = true, default-features = false, features = ["arithmetic"] }
p521 = { version = "0.13.3", optional = true, default-features = false, features = ["arithmetic"] }
sm2 = { version = "0.13.3", optional = true, default-features = false, features = ["arithmetic"] }
x25519 = { version = "2.0.1", package = "x25519-dalek", optional = true, default-features = false }
zeroize = { version = "1.8.1", optional = true, default-features = false }

[features]
default = ["zeroize"]
ecdh = ["dep:elliptic-curve", "elliptic-curve/ecdh"]
x25519 = ["dep:x25519", "x25519/reusable_secrets"]
bign256 = ["dep:bign256", "ecdh"]
k256 = ["dep:k256", "ecdh"]
p192 = ["dep:p192", "ecdh"]
p224 = ["dep:p224", "ecdh"]
p256 = ["dep:p256", "ecdh"]
p384 = ["dep:p384", "ecdh"]
p521 = ["dep:p521", "ecdh"]
sm2 = ["dep:sm2", "ecdh"]
x25519 = ["dep:x25519", "x25519/reusable_secrets"]
zeroize = ["dep:zeroize"]

[dev-dependencies]
rand = "0.8.5"
hex-literal = "0.4.1"
hkdf = "0.12.4"
rand = "0.8.5"
sha2 = "0.10.8"

[package.metadata.docs.rs]
Expand Down
10 changes: 8 additions & 2 deletions dhkem/src/ecdh.rs → dhkem/src/ecdh_kem.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Generic Elliptic Curve Diffie-Hellman KEM adapter.
use crate::{DhDecapsulator, DhEncapsulator, DhKem};
use core::marker::PhantomData;
use elliptic_curve::{
Expand All @@ -7,7 +9,11 @@ use elliptic_curve::{
use kem::{Decapsulate, Encapsulate};
use rand_core::CryptoRngCore;

pub struct ArithmeticKem<C: CurveArithmetic>(PhantomData<C>);
/// Generic Elliptic Curve Diffie-Hellman KEM adapter compatible with curves implemented using
/// traits from the `elliptic-curve` crate.
///
/// Implements a KEM interface that internally uses ECDH.
pub struct EcdhKem<C: CurveArithmetic>(PhantomData<C>);

impl<C> Encapsulate<PublicKey<C>, SharedSecret<C>> for DhEncapsulator<PublicKey<C>>
where
Expand Down Expand Up @@ -41,7 +47,7 @@ where
}
}

impl<C> DhKem for ArithmeticKem<C>
impl<C> DhKem for EcdhKem<C>
where
C: CurveArithmetic,
{
Expand Down
62 changes: 36 additions & 26 deletions dhkem/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,40 @@
html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg",
html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg"
)]
#![warn(missing_docs)]

//! # Diffie-Hellman (DH) based Key Encapsulation Mechanisms (KEM)
//!
//! This crate provides a KEM interface for DH protocols as specified in
//! [RFC9180](https://datatracker.ietf.org/doc/html/rfc9180#name-dh-based-kem-dhkem)
//! without the shared secret extraction process. In particular, `Encaps(pk)` in the
//! RFC returns the encapsulated key and an extracted shared secret, while our
//! implementation leaves the extraction process up to the user. This type of KEM
//! construction is currently being used in HPKE, as per the RFC, and in the current
//! draft of the [TLS KEM
//! combiner](https://datatracker.ietf.org/doc/html/draft-ietf-tls-hybrid-design-10).
//! This crate provides a KEM interface for DH protocols as specified in [RFC9180]
//! without the shared secret extraction process.
//!
//! In particular, `Encaps(pk)` in the RFC returns the encapsulated key and an extracted shared
//! secret, while our implementation leaves the extraction process up to the user.
//!
//! This type of KEM construction is currently being used in HPKE, as per the RFC, and in the
//! current draft of the [TLS KEM combiner].
//!
//! ## Supported elliptic curves
//!
//! Support for specific elliptic curves is gated behind the following features:
//!
//! - `k256`: secp256k1
//! - `p256`: NIST P-256
//! - `p384`: NIST P-384
//! - `p521`: NIST P-521
//!
//! [RFC9180]: https://datatracker.ietf.org/doc/html/rfc9180#name-dh-based-kem-dhkem
//! [TLS KEM combiner]: https://datatracker.ietf.org/doc/html/draft-ietf-tls-hybrid-design-10
#[cfg(feature = "ecdh")]
pub mod ecdh;

mod ecdh_kem;
#[cfg(feature = "x25519")]
mod x25519_kem;

#[cfg(feature = "ecdh")]
pub use ecdh_kem::EcdhKem;
#[cfg(feature = "x25519")]
pub use x25519_kem::X25519;
pub use x25519_kem::X25519Kem;

use kem::{Decapsulate, Encapsulate};
use rand_core::CryptoRngCore;
Expand Down Expand Up @@ -139,22 +153,18 @@ pub trait DhKem {
) -> (Self::DecapsulatingKey, Self::EncapsulatingKey);
}

#[cfg(feature = "bign256")]
pub type BignP256 = ecdh::ArithmeticKem<bign256::BignP256>;
/// secp256k1 ECDH KEM.
#[cfg(feature = "k256")]
pub type Secp256k1 = ecdh::ArithmeticKem<k256::Secp256k1>;
#[cfg(feature = "p192")]
pub type NistP192 = ecdh::ArithmeticKem<p192::NistP192>;
#[cfg(feature = "p224")]
pub type NistP224 = ecdh::ArithmeticKem<p224::NistP224>;
#[cfg(feature = "p256")]
pub type NistP256 = ecdh::ArithmeticKem<p256::NistP256>;
// include an additional alias Secp256r1 = NistP256
pub type Secp256k1Kem = EcdhKem<k256::Secp256k1>;

/// NIST P-256 ECDH KEM.
#[cfg(feature = "p256")]
pub type Secp256r1 = ecdh::ArithmeticKem<p256::NistP256>;
pub type NistP256Kem = EcdhKem<p256::NistP256>;

/// NIST P-384 ECDH KEM.
#[cfg(feature = "p384")]
pub type NistP384 = ecdh::ArithmeticKem<p384::NistP384>;
pub type NistP384Kem = EcdhKem<p384::NistP384>;

/// NIST P-521 ECDH KEM.
#[cfg(feature = "p521")]
pub type NistP521 = ecdh::ArithmeticKem<p521::NistP521>;
#[cfg(feature = "sm2")]
pub type Sm2 = ecdh::ArithmeticKem<sm2::Sm2>;
pub type NistP521Kem = EcdhKem<p521::NistP521>;
7 changes: 5 additions & 2 deletions dhkem/src/x25519_kem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ use kem::{Decapsulate, Encapsulate};
use rand_core::CryptoRngCore;
use x25519::{PublicKey, ReusableSecret, SharedSecret};

pub struct X25519;
/// X22519 Diffie-Hellman KEM adapter.
///
/// Implements a KEM interface that internally uses X25519 ECDH.
pub struct X25519Kem;

impl Encapsulate<PublicKey, SharedSecret> for DhEncapsulator<PublicKey> {
type Error = ();
Expand Down Expand Up @@ -31,7 +34,7 @@ impl Decapsulate<PublicKey, SharedSecret> for DhDecapsulator<ReusableSecret> {
}
}

impl DhKem for X25519 {
impl DhKem for X25519Kem {
type DecapsulatingKey = DhDecapsulator<ReusableSecret>;
type EncapsulatingKey = DhEncapsulator<PublicKey>;
type EncapsulatedKey = PublicKey;
Expand Down
6 changes: 3 additions & 3 deletions dhkem/tests/hpke_p256_test.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![cfg(feature = "p256")]

use dhkem::{DhKem, NistP256};
use dhkem::{DhKem, NistP256Kem};
use elliptic_curve::sec1::ToEncodedPoint;
use hex_literal::hex;
use hkdf::Hkdf;
Expand Down Expand Up @@ -67,7 +67,7 @@ fn labeled_expand(prk: &[u8], label: &[u8], info: &[u8], l: u16) -> Vec<u8> {
out
}

fn extract_and_expand(dh: <NistP256 as DhKem>::SharedSecret, kem_context: &[u8]) -> Vec<u8> {
fn extract_and_expand(dh: <NistP256Kem as DhKem>::SharedSecret, kem_context: &[u8]) -> Vec<u8> {
let eae_prk = labeled_extract(b"", b"eae_prk", dh.raw_secret_bytes());
labeled_expand(&eae_prk, b"shared_secret", kem_context, 32)
}
Expand All @@ -86,7 +86,7 @@ fn test_dhkem_p256_hkdf_sha256() {
let shared_secret_hex =
hex!("c0d26aeab536609a572b07695d933b589dcf363ff9d93c93adea537aeabb8cb8");

let (skr, pkr) = NistP256::random_keypair(&mut ConstantRng(&hex!(
let (skr, pkr) = NistP256Kem::random_keypair(&mut ConstantRng(&hex!(
"f3ce7fdae57e1a310d87f1ebbde6f328be0a99cdbcadf4d6589cf29de4b8ffd2"
)));
assert_eq!(pkr.to_encoded_point(false).as_bytes(), &pkr_hex);
Expand Down
34 changes: 5 additions & 29 deletions dhkem/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,53 +41,29 @@ where
#[cfg(feature = "x25519")]
#[test]
fn test_x25519() {
test_kem::<dhkem::X25519>();
}

#[cfg(feature = "bign256")]
#[test]
fn test_bign256() {
test_kem::<dhkem::BignP256>();
test_kem::<dhkem::X25519Kem>();
}

#[cfg(feature = "k256")]
#[test]
fn test_k256() {
test_kem::<dhkem::Secp256k1>();
}

#[cfg(feature = "p192")]
#[test]
fn test_p192() {
test_kem::<dhkem::NistP192>();
}

#[cfg(feature = "p224")]
#[test]
fn test_p224() {
test_kem::<dhkem::NistP224>();
test_kem::<dhkem::Secp256k1Kem>();
}

#[cfg(feature = "p256")]
#[test]
fn test_p256() {
test_kem::<dhkem::NistP256>();
test_kem::<dhkem::NistP256Kem>();
}

#[cfg(feature = "p384")]
#[test]
fn test_p384() {
test_kem::<dhkem::NistP384>();
test_kem::<dhkem::NistP384Kem>();
}

#[cfg(feature = "p521")]
#[test]
fn test_p521() {
test_kem::<dhkem::NistP521>();
}

#[cfg(feature = "sm2")]
#[test]
fn test_sm2() {
test_kem::<dhkem::Sm2>();
test_kem::<dhkem::NistP521Kem>();
}

0 comments on commit fd444af

Please sign in to comment.