diff --git a/Cargo.lock b/Cargo.lock index 79616e19..b7caf0cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -782,6 +782,7 @@ dependencies = [ "elliptic-curve", "hex-literal", "primeorder", + "rand_core", "sha2", ] diff --git a/p521/Cargo.toml b/p521/Cargo.toml index 42f02924..50071a94 100644 --- a/p521/Cargo.toml +++ b/p521/Cargo.toml @@ -27,6 +27,7 @@ base16ct = "0.2.0" [dev-dependencies] hex-literal = "0.4" primeorder = { version = "0.13.3", features = ["dev"], path = "../primeorder" } +rand_core = { version = "0.6", features = ["getrandom"] } [features] default = ["arithmetic", "pem", "std"] @@ -34,6 +35,7 @@ alloc = ["elliptic-curve/alloc"] std = ["alloc", "elliptic-curve/std"] arithmetic = ["dep:primeorder"] +ecdh = ["arithmetic", "elliptic-curve/ecdh"] jwk = ["elliptic-curve/jwk"] pem = ["elliptic-curve/pem", "pkcs8"] pkcs8 = ["elliptic-curve/pkcs8"] diff --git a/p521/src/ecdh.rs b/p521/src/ecdh.rs new file mode 100644 index 00000000..295fcb9d --- /dev/null +++ b/p521/src/ecdh.rs @@ -0,0 +1,47 @@ +//! Elliptic Curve Diffie-Hellman (Ephemeral) Support. +//! +//! This module contains a high-level interface for performing ephemeral +//! Diffie-Hellman key exchanges using the secp521r1 elliptic curve. +//! +//! # Usage +//! +//! This usage example is from the perspective of two participants in the +//! exchange, nicknamed "Alice" and "Bob". +//! +//! ``` +//! use p521::{EncodedPoint, PublicKey, ecdh::EphemeralSecret}; +//! use rand_core::OsRng; // requires 'getrandom' feature +//! +//! // Alice +//! let alice_secret = EphemeralSecret::random(&mut OsRng); +//! let alice_pk_bytes = EncodedPoint::from(alice_secret.public_key()); +//! +//! // Bob +//! let bob_secret = EphemeralSecret::random(&mut OsRng); +//! let bob_pk_bytes = EncodedPoint::from(bob_secret.public_key()); +//! +//! // Alice decodes Bob's serialized public key and computes a shared secret from it +//! let bob_public = PublicKey::from_sec1_bytes(bob_pk_bytes.as_ref()) +//! .expect("bob's public key is invalid!"); // In real usage, don't panic, handle this! +//! +//! let alice_shared = alice_secret.diffie_hellman(&bob_public); +//! +//! // Bob decodes Alice's serialized public key and computes the same shared secret +//! let alice_public = PublicKey::from_sec1_bytes(alice_pk_bytes.as_ref()) +//! .expect("alice's public key is invalid!"); // In real usage, don't panic, handle this! +//! +//! let bob_shared = bob_secret.diffie_hellman(&alice_public); +//! +//! // Both participants arrive on the same shared secret +//! assert_eq!(alice_shared.raw_secret_bytes(), bob_shared.raw_secret_bytes()); +//! ``` + +pub use elliptic_curve::ecdh::diffie_hellman; + +use crate::NistP521; + +/// NIST P-521 Ephemeral Diffie-Hellman Secret. +pub type EphemeralSecret = elliptic_curve::ecdh::EphemeralSecret; + +/// Shared secret value computed via ECDH key agreement. +pub type SharedSecret = elliptic_curve::ecdh::SharedSecret; diff --git a/p521/src/lib.rs b/p521/src/lib.rs index bf1281ea..0a33cc8a 100644 --- a/p521/src/lib.rs +++ b/p521/src/lib.rs @@ -18,6 +18,9 @@ #[cfg(feature = "arithmetic")] pub mod arithmetic; +#[cfg(feature = "ecdh")] +pub mod ecdh; + #[cfg(any(feature = "test-vectors", test))] pub mod test_vectors; @@ -82,6 +85,10 @@ pub type FieldBytes = elliptic_curve::FieldBytes; impl FieldBytesEncoding for U576 {} +/// NIST P-521 public key. +#[cfg(feature = "arithmetic")] +pub type PublicKey = elliptic_curve::PublicKey; + /// NIST P-521 secret key. pub type SecretKey = elliptic_curve::SecretKey;