mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-04 20:24:10 +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
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
)
|
||||
});
|
||||
}
|
||||
|
|
|
|||
44
src/lib.rs
44
src/lib.rs
|
|
@ -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);
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue