wrap MontgomeryPoint in EphemeralPublic, impl From; remove byte fns for EphemeralSecret

This commit is contained in:
DebugSteven 2018-12-02 14:23:09 -05:00
parent a599644406
commit 734abac70b
4 changed files with 71 additions and 61 deletions

View file

@ -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
the rest of the afternoon nomming some yummy pie!
First, Alice uses `x25519_dalek::Ephemeral::generate_secret()` and then
`x25519_dalek::Ephemeral::generate_public()` to produce her secret and public keys:
First, Alice uses `x25519_dalek::EphemeralSecret::new()` and then
`x25519_dalek::EphemeralPublic::generate_public()` to produce her secret and public keys:
```rust
extern crate x25519_dalek;
@ -36,16 +36,16 @@ use x25519_dalek::Ephemeral;
use rand::OsRng;
let mut alice_csprng = OsRng::new().unwrap();
let alice_secret = Ephemeral::generate_secret(&mut alice_csprng);
let alice_public = Ephemeral::generate_public(&alice_secret);
let alice_secret = EphemeralSecret::new(&mut alice_csprng);
let alice_public = EphemeralPublic::generate_public(&alice_secret);
```
Bob does the same:
```rust
let mut bob_csprng = OsRng::new().unwrap();
let bob_secret = Ephemeral::generate_secret(&mut bob_csprng);
let bob_public = Ephemeral::generate_public(&bob_secret);
let bob_secret = EphemeralSecret::new(&mut bob_csprng);
let bob_public = EphemeralPublic::generate_public(&bob_secret);
```
Alice meows across the room, telling `alice_public` to Bob, and Bob

View file

@ -21,17 +21,18 @@ use curve25519_dalek::montgomery::MontgomeryPoint;
use rand::OsRng;
use x25519_dalek::Ephemeral;
use x25519_dalek::EphemeralPublic;
use x25519_dalek::EphemeralSecret;
fn bench_diffie_hellman(c: &mut Criterion) {
let mut csprng: OsRng = OsRng::new().unwrap();
let alice_secret: Ephemeral = Ephemeral::generate_secret(&mut csprng);
let bob_secret: Ephemeral = Ephemeral::generate_secret(&mut csprng);
let bob_public: MontgomeryPoint = Ephemeral::generate_public(&bob_secret);
let alice_secret: EphemeralSecret = EphemeralSecret::new(&mut csprng);
let bob_secret: EphemeralSecret = EphemeralSecret::new(&mut csprng);
let bob_public: EphemeralPublic = EphemeralPublic::from(&bob_secret);
c.bench_function("diffie_hellman", move |b| {
b.iter(||
Ephemeral::diffie_hellman(&alice_secret, &bob_public)
EphemeralSecret::diffie_hellman(&alice_secret, &bob_public)
)
});
}

View file

@ -32,20 +32,21 @@
//! 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!
//!
//! First, Alice uses `x25519_dalek::Ephemeral::generate_secret()` and
//! `x25519_dalek::Ephemeral::generate_public()` to produce her secret and public keys:
//! First, Alice uses `x25519_dalek::EphemeralSecret::new()` and
//! `x25519_dalek::EphemeralPublic::from()` to produce her secret and public keys:
//!
//! ```
//! extern crate x25519_dalek;
//! extern crate rand;
//!
//! # fn main() {
//! use x25519_dalek::Ephemeral;
//! use x25519_dalek::EphemeralPublic;
//! use x25519_dalek::EphemeralSecret;
//! use rand::thread_rng;
//!
//! let mut alice_csprng = thread_rng();
//! let alice_secret = Ephemeral::generate_secret(&mut alice_csprng);
//! let alice_public = Ephemeral::generate_public(&alice_secret);
//! let alice_secret = EphemeralSecret::new(&mut alice_csprng);
//! let alice_public = EphemeralPublic::from(&alice_secret);
//! # }
//! ```
//!
@ -56,12 +57,13 @@
//! # extern crate rand;
//! #
//! # fn main() {
//! # use x25519_dalek::Ephemeral;
//! # use x25519_dalek::EphemeralPublic;
//! # use x25519_dalek::EphemeralSecret;
//! # use rand::thread_rng;
//! #
//! let mut bob_csprng = thread_rng();
//! let bob_secret = Ephemeral::generate_secret(&mut bob_csprng);
//! let bob_public = Ephemeral::generate_public(&bob_secret);
//! let bob_secret = EphemeralSecret::new(&mut bob_csprng);
//! let bob_public = EphemeralPublic::from(&bob_secret);
//! # }
//! ```
//!
@ -74,19 +76,20 @@
//! # extern crate rand;
//! #
//! # fn main() {
//! # use x25519_dalek::Ephemeral;
//! # use x25519_dalek::EphemeralPublic;
//! # use x25519_dalek::EphemeralSecret;
//! # use rand::thread_rng;
//! #
//! # let mut alice_csprng = thread_rng();
//! # let alice_secret = Ephemeral::generate_secret(&mut alice_csprng);
//! # let alice_public = Ephemeral::generate_public(&alice_secret);
//! # let alice_secret = EphemeralSecret::new(&mut alice_csprng);
//! # let alice_public = EphemeralPublic::from(&alice_secret);
//! #
//! # let mut bob_csprng = thread_rng();
//! # let bob_secret = Ephemeral::generate_secret(&mut bob_csprng);
//! # let bob_public = Ephemeral::generate_public(&bob_secret);
//! # let bob_secret = EphemeralSecret::new(&mut bob_csprng);
//! # 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;
//! #
//! # fn main() {
//! # use x25519_dalek::Ephemeral;
//! # use x25519_dalek::EphemeralPublic;
//! # use x25519_dalek::EphemeralSecret;
//! # use rand::thread_rng;
//! #
//! # let mut alice_csprng = thread_rng();
//! # let alice_secret = Ephemeral::generate_secret(&mut alice_csprng);
//! # let alice_public = Ephemeral::generate_public(&alice_secret);
//! # let alice_secret = EphemeralSecret::new(&mut alice_csprng);
//! # let alice_public = EphemeralPublic::from(&alice_secret);
//! #
//! # let mut bob_csprng = thread_rng();
//! # let bob_secret = Ephemeral::generate_secret(&mut bob_csprng);
//! # let bob_public = Ephemeral::generate_public(&bob_secret);
//! # let bob_secret = EphemeralSecret::new(&mut bob_csprng);
//! # 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);
//! # }
//! ```
//!

View file

@ -23,61 +23,57 @@ use curve25519_dalek::scalar::Scalar;
use rand_core::RngCore;
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)]
#[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.
impl Drop for Ephemeral {
/// Overwrite ephemeral secret key material with null bytes when it goes out of scope.
impl Drop for EphemeralSecret {
fn drop(&mut self) {
self.0.clear();
}
}
/// Multiply this `Ephemeral` key by a `MontgomeryPoint`.
impl<'a, 'b> Mul<&'b MontgomeryPoint> for &'a Ephemeral {
type Output = Ephemeral;
/// Multiply this `EphemeralPublic` key by a `EphemeralSecret` key.
impl<'a, 'b> Mul<&'b EphemeralSecret> for &'a EphemeralPublic {
type Output = EphemeralPublic;
fn mul(self, point: &'b MontgomeryPoint) -> Ephemeral {
Ephemeral(Scalar::from_bits((point * self.to_bytes()).to_bytes()))
fn mul(self, secret: &'b EphemeralSecret) -> EphemeralPublic {
EphemeralPublic(self.0 * secret.0)
}
}
impl Ephemeral {
/// 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
}
impl EphemeralSecret {
/// Utility function to make it easier to call `x25519()` with
/// an ephemeral secret key and montegomery point as input and
/// a shared secret as the output.
pub fn diffie_hellman(&self, their_public: &MontgomeryPoint) -> SharedSecret {
SharedSecret(x25519(self.as_bytes(), &MontgomeryPoint(*their_public.as_bytes())))
pub fn diffie_hellman(&self, their_public: &EphemeralPublic) -> SharedSecret {
SharedSecret(x25519(&self.0, &MontgomeryPoint(*their_public.0.as_bytes())))
}
/// Generate an x25519 `Ephemeral` secret key.
pub fn generate_secret<T>(csprng: &mut T) -> Self
/// Generate an x25519 `EphemeralSecret` key.
pub fn new<T>(csprng: &mut T) -> Self
where T: RngCore + CryptoRng
{
let mut bytes = [0u8; 32];
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.
///
/// By "decode" here, what is really meant is applying key clamping by twiddling