diff --git a/Cargo.lock b/Cargo.lock index 6a5e3d4..b6acba5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,16 +35,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" -[[package]] -name = "bign256" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a060e09443574e5518c7eced1ef6ff33496be5aee6dc101f99102039d3922eff" -dependencies = [ - "elliptic-curve", - "primeorder", -] - [[package]] name = "block-buffer" version = "0.10.4" @@ -269,21 +259,17 @@ dependencies = [ name = "dhkem" version = "0.1.0" dependencies = [ - "bign256", "elliptic-curve", "hex-literal", "hkdf", "k256", "kem", - "p192", - "p224", "p256", "p384", "p521", "rand", "rand_core", "sha2", - "sm2", "x25519-dalek", "zeroize", ] @@ -577,27 +563,6 @@ version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" -[[package]] -name = "p192" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b0533bc6c238f2669aab8db75ae52879dc74e88d6bd3685bd4022a00fa85cd2" -dependencies = [ - "elliptic-curve", - "primeorder", - "sec1", -] - -[[package]] -name = "p224" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30c06436d66652bc2f01ade021592c80a2aad401570a18aa18b82e440d2b9aa1" -dependencies = [ - "elliptic-curve", - "primeorder", -] - [[package]] name = "p256" version = "0.13.2" @@ -870,16 +835,6 @@ dependencies = [ "keccak", ] -[[package]] -name = "sm2" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98b22092ef242a118f03ee41dc46b2720c0ca076f544116dbc915cacf532cfaa" -dependencies = [ - "elliptic-curve", - "primeorder", -] - [[package]] name = "subtle" version = "2.5.0" diff --git a/dhkem/Cargo.toml b/dhkem/Cargo.toml index 7eeaa43..7eda465 100644 --- a/dhkem/Cargo.toml +++ b/dhkem/Cargo.toml @@ -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] diff --git a/dhkem/src/ecdh.rs b/dhkem/src/ecdh_kem.rs similarity index 82% rename from dhkem/src/ecdh.rs rename to dhkem/src/ecdh_kem.rs index ef1fb56..8dda9e0 100644 --- a/dhkem/src/ecdh.rs +++ b/dhkem/src/ecdh_kem.rs @@ -1,3 +1,5 @@ +//! Generic Elliptic Curve Diffie-Hellman KEM adapter. + use crate::{DhDecapsulator, DhEncapsulator, DhKem}; use core::marker::PhantomData; use elliptic_curve::{ @@ -7,7 +9,11 @@ use elliptic_curve::{ use kem::{Decapsulate, Encapsulate}; use rand_core::CryptoRngCore; -pub struct ArithmeticKem(PhantomData); +/// 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(PhantomData); impl Encapsulate, SharedSecret> for DhEncapsulator> where @@ -41,7 +47,7 @@ where } } -impl DhKem for ArithmeticKem +impl DhKem for EcdhKem where C: CurveArithmetic, { diff --git a/dhkem/src/lib.rs b/dhkem/src/lib.rs index af4a999..6dc79c6 100644 --- a/dhkem/src/lib.rs +++ b/dhkem/src/lib.rs @@ -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; @@ -139,22 +153,18 @@ pub trait DhKem { ) -> (Self::DecapsulatingKey, Self::EncapsulatingKey); } -#[cfg(feature = "bign256")] -pub type BignP256 = ecdh::ArithmeticKem; +/// secp256k1 ECDH KEM. #[cfg(feature = "k256")] -pub type Secp256k1 = ecdh::ArithmeticKem; -#[cfg(feature = "p192")] -pub type NistP192 = ecdh::ArithmeticKem; -#[cfg(feature = "p224")] -pub type NistP224 = ecdh::ArithmeticKem; -#[cfg(feature = "p256")] -pub type NistP256 = ecdh::ArithmeticKem; -// include an additional alias Secp256r1 = NistP256 +pub type Secp256k1Kem = EcdhKem; + +/// NIST P-256 ECDH KEM. #[cfg(feature = "p256")] -pub type Secp256r1 = ecdh::ArithmeticKem; +pub type NistP256Kem = EcdhKem; + +/// NIST P-384 ECDH KEM. #[cfg(feature = "p384")] -pub type NistP384 = ecdh::ArithmeticKem; +pub type NistP384Kem = EcdhKem; + +/// NIST P-521 ECDH KEM. #[cfg(feature = "p521")] -pub type NistP521 = ecdh::ArithmeticKem; -#[cfg(feature = "sm2")] -pub type Sm2 = ecdh::ArithmeticKem; +pub type NistP521Kem = EcdhKem; diff --git a/dhkem/src/x25519_kem.rs b/dhkem/src/x25519_kem.rs index daaf7c6..2deb80c 100644 --- a/dhkem/src/x25519_kem.rs +++ b/dhkem/src/x25519_kem.rs @@ -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 for DhEncapsulator { type Error = (); @@ -31,7 +34,7 @@ impl Decapsulate for DhDecapsulator { } } -impl DhKem for X25519 { +impl DhKem for X25519Kem { type DecapsulatingKey = DhDecapsulator; type EncapsulatingKey = DhEncapsulator; type EncapsulatedKey = PublicKey; diff --git a/dhkem/tests/hpke_p256_test.rs b/dhkem/tests/hpke_p256_test.rs index 5c3da95..e308c6d 100644 --- a/dhkem/tests/hpke_p256_test.rs +++ b/dhkem/tests/hpke_p256_test.rs @@ -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; @@ -67,7 +67,7 @@ fn labeled_expand(prk: &[u8], label: &[u8], info: &[u8], l: u16) -> Vec { out } -fn extract_and_expand(dh: ::SharedSecret, kem_context: &[u8]) -> Vec { +fn extract_and_expand(dh: ::SharedSecret, kem_context: &[u8]) -> Vec { let eae_prk = labeled_extract(b"", b"eae_prk", dh.raw_secret_bytes()); labeled_expand(&eae_prk, b"shared_secret", kem_context, 32) } @@ -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); diff --git a/dhkem/tests/tests.rs b/dhkem/tests/tests.rs index e320211..b88423f 100644 --- a/dhkem/tests/tests.rs +++ b/dhkem/tests/tests.rs @@ -41,53 +41,29 @@ where #[cfg(feature = "x25519")] #[test] fn test_x25519() { - test_kem::(); -} - -#[cfg(feature = "bign256")] -#[test] -fn test_bign256() { - test_kem::(); + test_kem::(); } #[cfg(feature = "k256")] #[test] fn test_k256() { - test_kem::(); -} - -#[cfg(feature = "p192")] -#[test] -fn test_p192() { - test_kem::(); -} - -#[cfg(feature = "p224")] -#[test] -fn test_p224() { - test_kem::(); + test_kem::(); } #[cfg(feature = "p256")] #[test] fn test_p256() { - test_kem::(); + test_kem::(); } #[cfg(feature = "p384")] #[test] fn test_p384() { - test_kem::(); + test_kem::(); } #[cfg(feature = "p521")] #[test] fn test_p521() { - test_kem::(); -} - -#[cfg(feature = "sm2")] -#[test] -fn test_sm2() { - test_kem::(); + test_kem::(); }