diff --git a/Cargo.toml b/Cargo.toml index 7e9d325..9a68726 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "x25519-dalek" -version = "0.5.0" +version = "0.5.1" authors = [ "Isis Lovecruft ", "DebugSteven ", diff --git a/README.md b/README.md index f435094..e1c37df 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # x25519-dalek [![](https://img.shields.io/crates/v/x25519-dalek.svg)](https://crates.io/crates/x25519-dalek) [![](https://docs.rs/x25519-dalek/badge.svg)](https://docs.rs/x25519-dalek) [![](https://travis-ci.org/dalek-cryptography/x25519-dalek.svg?branch=master)](https://travis-ci.org/dalek-cryptography/x25519-dalek) A pure-Rust implementation of x25519 elliptic curve Diffie-Hellman key exchange, -with curve operations provided by +with curve operations provided by [curve25519-dalek](https://github.com/dalek-cryptography/curve25519-dalek). This crate provides two levels of API: a bare byte-oriented `x25519` @@ -11,7 +11,7 @@ well as a higher-level Rust API for static and ephemeral Diffie-Hellman. ## Examples - @@ -31,99 +31,46 @@ the rest of the afternoon nomming some yummy pie! First, Alice uses `EphemeralSecret::new()` and then `PublicKey::from()` to produce her secret and public keys: -```rust +```rust,ignore extern crate rand_os; +extern crate x25519_dalek; + use rand_os::OsRng; -extern crate x25519_dalek; use x25519_dalek::EphemeralSecret; use x25519_dalek::PublicKey; -# fn main() { let mut alice_csprng = OsRng::new().unwrap(); let alice_secret = EphemeralSecret::new(&mut alice_csprng); let alice_public = PublicKey::from(&alice_secret); -# } ``` Bob does the same: -```rust -# extern crate rand_os; -# use rand_os::OsRng; -# -# extern crate x25519_dalek; -# use x25519_dalek::EphemeralSecret; -# use x25519_dalek::PublicKey; -# fn main() { +```rust,ignore let mut bob_csprng = OsRng::new().unwrap(); let bob_secret = EphemeralSecret::new(&mut bob_csprng); let bob_public = PublicKey::from(&bob_secret); -# } ``` Alice meows across the room, telling `alice_public` to Bob, and Bob loudly meows `bob_public` back to Alice. Alice now computes her shared secret with Bob by doing: -```rust -# extern crate rand_os; -# use rand_os::OsRng; -# -# extern crate x25519_dalek; -# use x25519_dalek::EphemeralSecret; -# use x25519_dalek::PublicKey; -# -# fn main() { -# let mut csprng = OsRng::new().unwrap(); -# let alice_secret = EphemeralSecret::new(&mut csprng); -# let alice_public = PublicKey::from(&alice_secret); -# let bob_secret = EphemeralSecret::new(&mut csprng); -# let bob_public = PublicKey::from(&bob_secret); +```rust,ignore let alice_shared_secret = alice_secret.diffie_hellman(&bob_public); -# } ``` Similarly, Bob computes a shared secret by doing: -```rust -# extern crate rand_os; -# use rand_os::OsRng; -# -# extern crate x25519_dalek; -# use x25519_dalek::EphemeralSecret; -# use x25519_dalek::PublicKey; -# -# fn main() { -# let mut csprng = OsRng::new().unwrap(); -# let alice_secret = EphemeralSecret::new(&mut csprng); -# let alice_public = PublicKey::from(&alice_secret); -# let bob_secret = EphemeralSecret::new(&mut csprng); -# let bob_public = PublicKey::from(&bob_secret); +```rust,ignore let bob_shared_secret = bob_secret.diffie_hellman(&alice_public); -# } ``` These secrets are the same: -```rust -# extern crate rand_os; -# use rand_os::OsRng; -# -# extern crate x25519_dalek; -# use x25519_dalek::EphemeralSecret; -# use x25519_dalek::PublicKey; -# -# fn main() { -# let mut csprng = OsRng::new().unwrap(); -# let alice_secret = EphemeralSecret::new(&mut csprng); -# let alice_public = PublicKey::from(&alice_secret); -# let bob_secret = EphemeralSecret::new(&mut csprng); -# let bob_public = PublicKey::from(&bob_secret); -# let alice_shared_secret = alice_secret.diffie_hellman(&bob_public); -# let bob_shared_secret = bob_secret.diffie_hellman(&alice_public); +```rust,ignore assert_eq!(alice_shared_secret.as_bytes(), bob_shared_secret.as_bytes()); -# } ``` Voilá! Alice and Bob can now use their shared secret to encrypt their @@ -140,7 +87,7 @@ To install, add the following to your project's `Cargo.toml`: ```toml [dependencies.x25519-dalek] -version = "^0.4" +version = "^0.5" ``` # Documentation diff --git a/src/lib.rs b/src/lib.rs index 11e4471..8c1916f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,6 +30,9 @@ extern crate curve25519_dalek; extern crate rand_core; +#[cfg(test)] +extern crate rand_os; + mod x25519; pub use x25519::*; diff --git a/src/x25519.rs b/src/x25519.rs index 511a9b5..11786b1 100644 --- a/src/x25519.rs +++ b/src/x25519.rs @@ -25,6 +25,7 @@ use rand_core::CryptoRng; /// A `PublicKey` is the corresponding public key converted from /// an `EphemeralSecret` or a `StaticSecret` key. +#[derive(Copy, Clone, Debug)] pub struct PublicKey(pub (crate) MontgomeryPoint); impl From<[u8; 32]> for PublicKey { @@ -191,6 +192,24 @@ pub const X25519_BASEPOINT_BYTES: [u8; 32] = [ mod test { use super::*; + use rand_os::OsRng; + + // This was previously a doctest but it got moved to the README to + // avoid duplication where it then wasn't being run, so now it + // lives here. + #[test] + fn alice_and_bob() { + let mut csprng = OsRng::new().unwrap(); + let alice_secret = EphemeralSecret::new(&mut csprng); + let alice_public = PublicKey::from(&alice_secret); + let bob_secret = EphemeralSecret::new(&mut csprng); + let bob_public = PublicKey::from(&bob_secret); + let alice_shared_secret = alice_secret.diffie_hellman(&bob_public); + let bob_shared_secret = bob_secret.diffie_hellman(&alice_public); + + assert_eq!(alice_shared_secret.as_bytes(), bob_shared_secret.as_bytes()); + } + #[test] fn byte_basepoint_matches_edwards_scalar_mul() { let mut scalar_bytes = [0x37; 32];