mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-06 20:41:14 +00:00
wrap MontgomeryPoint in EphemeralPublic, impl From; remove byte fns for EphemeralSecret
This commit is contained in:
parent
a599644406
commit
734abac70b
4 changed files with 71 additions and 61 deletions
12
README.md
12
README.md
|
|
@ -25,8 +25,8 @@ up on modern public key cryptography and have learned a nifty trick called
|
||||||
kittens will be able to secretly organise to find their mittens, and then spend
|
kittens will be able to secretly organise to find their mittens, and then spend
|
||||||
the rest of the afternoon nomming some yummy pie!
|
the rest of the afternoon nomming some yummy pie!
|
||||||
|
|
||||||
First, Alice uses `x25519_dalek::Ephemeral::generate_secret()` and then
|
First, Alice uses `x25519_dalek::EphemeralSecret::new()` and then
|
||||||
`x25519_dalek::Ephemeral::generate_public()` to produce her secret and public keys:
|
`x25519_dalek::EphemeralPublic::generate_public()` to produce her secret and public keys:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
extern crate x25519_dalek;
|
extern crate x25519_dalek;
|
||||||
|
|
@ -36,16 +36,16 @@ use x25519_dalek::Ephemeral;
|
||||||
use rand::OsRng;
|
use rand::OsRng;
|
||||||
|
|
||||||
let mut alice_csprng = OsRng::new().unwrap();
|
let mut alice_csprng = OsRng::new().unwrap();
|
||||||
let alice_secret = Ephemeral::generate_secret(&mut alice_csprng);
|
let alice_secret = EphemeralSecret::new(&mut alice_csprng);
|
||||||
let alice_public = Ephemeral::generate_public(&alice_secret);
|
let alice_public = EphemeralPublic::generate_public(&alice_secret);
|
||||||
```
|
```
|
||||||
|
|
||||||
Bob does the same:
|
Bob does the same:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
let mut bob_csprng = OsRng::new().unwrap();
|
let mut bob_csprng = OsRng::new().unwrap();
|
||||||
let bob_secret = Ephemeral::generate_secret(&mut bob_csprng);
|
let bob_secret = EphemeralSecret::new(&mut bob_csprng);
|
||||||
let bob_public = Ephemeral::generate_public(&bob_secret);
|
let bob_public = EphemeralPublic::generate_public(&bob_secret);
|
||||||
```
|
```
|
||||||
|
|
||||||
Alice meows across the room, telling `alice_public` to Bob, and Bob
|
Alice meows across the room, telling `alice_public` to Bob, and Bob
|
||||||
|
|
|
||||||
|
|
@ -21,17 +21,18 @@ use curve25519_dalek::montgomery::MontgomeryPoint;
|
||||||
|
|
||||||
use rand::OsRng;
|
use rand::OsRng;
|
||||||
|
|
||||||
use x25519_dalek::Ephemeral;
|
use x25519_dalek::EphemeralPublic;
|
||||||
|
use x25519_dalek::EphemeralSecret;
|
||||||
|
|
||||||
fn bench_diffie_hellman(c: &mut Criterion) {
|
fn bench_diffie_hellman(c: &mut Criterion) {
|
||||||
let mut csprng: OsRng = OsRng::new().unwrap();
|
let mut csprng: OsRng = OsRng::new().unwrap();
|
||||||
let alice_secret: Ephemeral = Ephemeral::generate_secret(&mut csprng);
|
let alice_secret: EphemeralSecret = EphemeralSecret::new(&mut csprng);
|
||||||
let bob_secret: Ephemeral = Ephemeral::generate_secret(&mut csprng);
|
let bob_secret: EphemeralSecret = EphemeralSecret::new(&mut csprng);
|
||||||
let bob_public: MontgomeryPoint = Ephemeral::generate_public(&bob_secret);
|
let bob_public: EphemeralPublic = EphemeralPublic::from(&bob_secret);
|
||||||
|
|
||||||
c.bench_function("diffie_hellman", move |b| {
|
c.bench_function("diffie_hellman", move |b| {
|
||||||
b.iter(||
|
b.iter(||
|
||||||
Ephemeral::diffie_hellman(&alice_secret, &bob_public)
|
EphemeralSecret::diffie_hellman(&alice_secret, &bob_public)
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
44
src/lib.rs
44
src/lib.rs
|
|
@ -32,20 +32,21 @@
|
||||||
//! incantations, the kittens will be able to secretly organise to find their
|
//! incantations, the kittens will be able to secretly organise to find their
|
||||||
//! mittens, and then spend the rest of the afternoon nomming some yummy pie!
|
//! mittens, and then spend the rest of the afternoon nomming some yummy pie!
|
||||||
//!
|
//!
|
||||||
//! First, Alice uses `x25519_dalek::Ephemeral::generate_secret()` and
|
//! First, Alice uses `x25519_dalek::EphemeralSecret::new()` and
|
||||||
//! `x25519_dalek::Ephemeral::generate_public()` to produce her secret and public keys:
|
//! `x25519_dalek::EphemeralPublic::from()` to produce her secret and public keys:
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! extern crate x25519_dalek;
|
//! extern crate x25519_dalek;
|
||||||
//! extern crate rand;
|
//! extern crate rand;
|
||||||
//!
|
//!
|
||||||
//! # fn main() {
|
//! # fn main() {
|
||||||
//! use x25519_dalek::Ephemeral;
|
//! use x25519_dalek::EphemeralPublic;
|
||||||
|
//! use x25519_dalek::EphemeralSecret;
|
||||||
//! use rand::thread_rng;
|
//! use rand::thread_rng;
|
||||||
//!
|
//!
|
||||||
//! let mut alice_csprng = thread_rng();
|
//! let mut alice_csprng = thread_rng();
|
||||||
//! let alice_secret = Ephemeral::generate_secret(&mut alice_csprng);
|
//! let alice_secret = EphemeralSecret::new(&mut alice_csprng);
|
||||||
//! let alice_public = Ephemeral::generate_public(&alice_secret);
|
//! let alice_public = EphemeralPublic::from(&alice_secret);
|
||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
|
|
@ -56,12 +57,13 @@
|
||||||
//! # extern crate rand;
|
//! # extern crate rand;
|
||||||
//! #
|
//! #
|
||||||
//! # fn main() {
|
//! # fn main() {
|
||||||
//! # use x25519_dalek::Ephemeral;
|
//! # use x25519_dalek::EphemeralPublic;
|
||||||
|
//! # use x25519_dalek::EphemeralSecret;
|
||||||
//! # use rand::thread_rng;
|
//! # use rand::thread_rng;
|
||||||
//! #
|
//! #
|
||||||
//! let mut bob_csprng = thread_rng();
|
//! let mut bob_csprng = thread_rng();
|
||||||
//! let bob_secret = Ephemeral::generate_secret(&mut bob_csprng);
|
//! let bob_secret = EphemeralSecret::new(&mut bob_csprng);
|
||||||
//! let bob_public = Ephemeral::generate_public(&bob_secret);
|
//! let bob_public = EphemeralPublic::from(&bob_secret);
|
||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
|
|
@ -74,19 +76,20 @@
|
||||||
//! # extern crate rand;
|
//! # extern crate rand;
|
||||||
//! #
|
//! #
|
||||||
//! # fn main() {
|
//! # fn main() {
|
||||||
//! # use x25519_dalek::Ephemeral;
|
//! # use x25519_dalek::EphemeralPublic;
|
||||||
|
//! # use x25519_dalek::EphemeralSecret;
|
||||||
//! # use rand::thread_rng;
|
//! # use rand::thread_rng;
|
||||||
//! #
|
//! #
|
||||||
//! # let mut alice_csprng = thread_rng();
|
//! # let mut alice_csprng = thread_rng();
|
||||||
//! # let alice_secret = Ephemeral::generate_secret(&mut alice_csprng);
|
//! # let alice_secret = EphemeralSecret::new(&mut alice_csprng);
|
||||||
//! # let alice_public = Ephemeral::generate_public(&alice_secret);
|
//! # let alice_public = EphemeralPublic::from(&alice_secret);
|
||||||
//! #
|
//! #
|
||||||
//! # let mut bob_csprng = thread_rng();
|
//! # let mut bob_csprng = thread_rng();
|
||||||
//! # let bob_secret = Ephemeral::generate_secret(&mut bob_csprng);
|
//! # let bob_secret = EphemeralSecret::new(&mut bob_csprng);
|
||||||
//! # let bob_public = Ephemeral::generate_public(&bob_secret);
|
//! # let bob_public = EphemeralPublic::from(&bob_secret);
|
||||||
//! #
|
//! #
|
||||||
//!
|
//!
|
||||||
//! let shared_secret = Ephemeral::diffie_hellman(&alice_secret, &bob_public);
|
//! let shared_secret = EphemeralSecret::diffie_hellman(&alice_secret, &bob_public);
|
||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
|
|
@ -97,18 +100,19 @@
|
||||||
//! # extern crate rand;
|
//! # extern crate rand;
|
||||||
//! #
|
//! #
|
||||||
//! # fn main() {
|
//! # fn main() {
|
||||||
//! # use x25519_dalek::Ephemeral;
|
//! # use x25519_dalek::EphemeralPublic;
|
||||||
|
//! # use x25519_dalek::EphemeralSecret;
|
||||||
//! # use rand::thread_rng;
|
//! # use rand::thread_rng;
|
||||||
//! #
|
//! #
|
||||||
//! # let mut alice_csprng = thread_rng();
|
//! # let mut alice_csprng = thread_rng();
|
||||||
//! # let alice_secret = Ephemeral::generate_secret(&mut alice_csprng);
|
//! # let alice_secret = EphemeralSecret::new(&mut alice_csprng);
|
||||||
//! # let alice_public = Ephemeral::generate_public(&alice_secret);
|
//! # let alice_public = EphemeralPublic::from(&alice_secret);
|
||||||
//! #
|
//! #
|
||||||
//! # let mut bob_csprng = thread_rng();
|
//! # let mut bob_csprng = thread_rng();
|
||||||
//! # let bob_secret = Ephemeral::generate_secret(&mut bob_csprng);
|
//! # let bob_secret = EphemeralSecret::new(&mut bob_csprng);
|
||||||
//! # let bob_public = Ephemeral::generate_public(&bob_secret);
|
//! # let bob_public = EphemeralPublic::from(&bob_secret);
|
||||||
//! #
|
//! #
|
||||||
//! let shared_secret = Ephemeral::diffie_hellman(&bob_secret, &alice_public);
|
//! let shared_secret = EphemeralSecret::diffie_hellman(&bob_secret, &alice_public);
|
||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
|
|
|
||||||
|
|
@ -23,61 +23,57 @@ use curve25519_dalek::scalar::Scalar;
|
||||||
use rand_core::RngCore;
|
use rand_core::RngCore;
|
||||||
use rand_core::CryptoRng;
|
use rand_core::CryptoRng;
|
||||||
|
|
||||||
/// A DH ephemeral key.
|
/// A DH ephemeral public key.
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct EphemeralPublic(pub (crate) MontgomeryPoint);
|
||||||
|
|
||||||
|
/// A DH ephemeral secret key.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Default)] // we derive Default in order to use the clear() method in Drop
|
#[derive(Default)] // we derive Default in order to use the clear() method in Drop
|
||||||
pub struct Ephemeral(pub (crate) Scalar);
|
pub struct EphemeralSecret(pub (crate) Scalar);
|
||||||
|
|
||||||
/// Overwrite ephemeral key material with null bytes when it goes out of scope.
|
/// Overwrite ephemeral secret key material with null bytes when it goes out of scope.
|
||||||
impl Drop for Ephemeral {
|
impl Drop for EphemeralSecret {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.0.clear();
|
self.0.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Multiply this `Ephemeral` key by a `MontgomeryPoint`.
|
/// Multiply this `EphemeralPublic` key by a `EphemeralSecret` key.
|
||||||
impl<'a, 'b> Mul<&'b MontgomeryPoint> for &'a Ephemeral {
|
impl<'a, 'b> Mul<&'b EphemeralSecret> for &'a EphemeralPublic {
|
||||||
type Output = Ephemeral;
|
type Output = EphemeralPublic;
|
||||||
|
|
||||||
fn mul(self, point: &'b MontgomeryPoint) -> Ephemeral {
|
fn mul(self, secret: &'b EphemeralSecret) -> EphemeralPublic {
|
||||||
Ephemeral(Scalar::from_bits((point * self.to_bytes()).to_bytes()))
|
EphemeralPublic(self.0 * secret.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ephemeral {
|
impl EphemeralSecret {
|
||||||
/// Convert this `Ephemeral` key to a `Scalar`.
|
|
||||||
#[inline]
|
|
||||||
pub fn to_bytes(&self) -> Scalar {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// View this `Ephemeral` key as a `Scalar`.
|
|
||||||
#[inline]
|
|
||||||
pub fn as_bytes<'a>(&'a self) -> &'a Scalar {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Utility function to make it easier to call `x25519()` with
|
/// Utility function to make it easier to call `x25519()` with
|
||||||
/// an ephemeral secret key and montegomery point as input and
|
/// an ephemeral secret key and montegomery point as input and
|
||||||
/// a shared secret as the output.
|
/// a shared secret as the output.
|
||||||
pub fn diffie_hellman(&self, their_public: &MontgomeryPoint) -> SharedSecret {
|
pub fn diffie_hellman(&self, their_public: &EphemeralPublic) -> SharedSecret {
|
||||||
SharedSecret(x25519(self.as_bytes(), &MontgomeryPoint(*their_public.as_bytes())))
|
SharedSecret(x25519(&self.0, &MontgomeryPoint(*their_public.0.as_bytes())))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate an x25519 `Ephemeral` secret key.
|
/// Generate an x25519 `EphemeralSecret` key.
|
||||||
pub fn generate_secret<T>(csprng: &mut T) -> Self
|
pub fn new<T>(csprng: &mut T) -> Self
|
||||||
where T: RngCore + CryptoRng
|
where T: RngCore + CryptoRng
|
||||||
{
|
{
|
||||||
let mut bytes = [0u8; 32];
|
let mut bytes = [0u8; 32];
|
||||||
|
|
||||||
csprng.fill_bytes(&mut bytes);
|
csprng.fill_bytes(&mut bytes);
|
||||||
|
|
||||||
Ephemeral(decode_scalar(&bytes))
|
EphemeralSecret(decode_scalar(&bytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given an x25519 `Ephemeral` secret key, compute its corresponding public key.
|
}
|
||||||
pub fn generate_public(&self) -> MontgomeryPoint {
|
|
||||||
(self.as_bytes() * &ED25519_BASEPOINT_TABLE).to_montgomery()
|
impl From<&EphemeralSecret> for EphemeralPublic {
|
||||||
|
/// Given an x25519 `EphemeralSecret` key, compute its corresponding
|
||||||
|
/// `EphemeralPublic` key.
|
||||||
|
fn from(secret: &EphemeralSecret) -> EphemeralPublic {
|
||||||
|
EphemeralPublic((&ED25519_BASEPOINT_TABLE * &secret.0).to_montgomery())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -94,6 +90,15 @@ impl Drop for SharedSecret {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SharedSecret {
|
||||||
|
|
||||||
|
/// View this shared secret key as a byte array.
|
||||||
|
#[inline]
|
||||||
|
pub fn as_bytes<'a>(&'a self) -> &'a [u8; 32] {
|
||||||
|
&self.0.as_bytes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// "Decode" a scalar from a 32-byte array.
|
/// "Decode" a scalar from a 32-byte array.
|
||||||
///
|
///
|
||||||
/// By "decode" here, what is really meant is applying key clamping by twiddling
|
/// By "decode" here, what is really meant is applying key clamping by twiddling
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue