logo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
// -*- mode: rust; -*-
//
// This file is part of x25519-dalek.
// Copyright (c) 2017-2021 isis lovecruft
// Copyright (c) 2019-2021 DebugSteven
// See LICENSE for licensing information.
//
// Authors:
// - isis agora lovecruft <isis@patternsinthevoid.net>
// - DebugSteven <debugsteven@gmail.com>

// Refuse to compile if documentation is missing, but only on nightly.
//
// This means that missing docs will still fail CI, but means we can use
// README.md as the crate documentation.

#![no_std]
#![cfg_attr(feature = "bench", feature(test))]
#![cfg_attr(feature = "nightly", deny(missing_docs))]
#![doc(html_logo_url = "https://doc.dalek.rs/assets/dalek-logo-clear.png")]
#![doc(html_root_url = "https://docs.rs/x25519-dalek/1.2.0")]

//! # 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
//! [curve25519-dalek](https://github.com/dalek-cryptography/curve25519-dalek).
//!
//! This crate provides two levels of API: a bare byte-oriented `x25519`
//! function which matches the function specified in [RFC7748][rfc7748], as
//! well as a higher-level Rust API for static and ephemeral Diffie-Hellman.
//!
//! ## Examples
//!
//! <a href="https://shop.bubblesort.io">
//! <img
//!   style="float: right; width: auto; height: 300px;"
//!   src="https://raw.githubusercontent.com/dalek-cryptography/x25519-dalek/master/res/bubblesort-zines-secret-messages-cover.jpeg"/>
//! </a>
//!
//! Alice and Bob are two adorable kittens who have lost their mittens, and they
//! wish to be able to send secret messages to each other to coordinate finding
//! them, otherwise—if their caretaker cat finds out—they will surely be called
//! naughty kittens and be given no pie!
//!
//! But the two kittens are quite clever.  Even though their paws are still too big
//! and the rest of them is 90% fuzziness, these clever kittens have been studying
//! up on modern public key cryptography and have learned a nifty trick called
//! *elliptic curve Diffie-Hellman key exchange*.  With the right 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 `EphemeralSecret::new()` and then
//! `PublicKey::from()` to produce her secret and public keys:
//!
//! ```rust
//! use rand_core::OsRng;
//! use x25519_dalek::{EphemeralSecret, PublicKey};
//!
//! let alice_secret = EphemeralSecret::new(OsRng);
//! let alice_public = PublicKey::from(&alice_secret);
//! ```
//!
//! Bob does the same:
//!
//! ```rust
//! # use rand_core::OsRng;
//! # use x25519_dalek::{EphemeralSecret, PublicKey};
//! let bob_secret = EphemeralSecret::new(OsRng);
//! 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
//! # use rand_core::OsRng;
//! # use x25519_dalek::{EphemeralSecret, PublicKey};
//! # let alice_secret = EphemeralSecret::new(OsRng);
//! # let alice_public = PublicKey::from(&alice_secret);
//! # let bob_secret = EphemeralSecret::new(OsRng);
//! # let bob_public = PublicKey::from(&bob_secret);
//! let alice_shared_secret = alice_secret.diffie_hellman(&bob_public);
//! ```
//!
//! Similarly, Bob computes a shared secret by doing:
//!
//! ```rust
//! # use rand_core::OsRng;
//! # use x25519_dalek::{EphemeralSecret, PublicKey};
//! # let alice_secret = EphemeralSecret::new(OsRng);
//! # let alice_public = PublicKey::from(&alice_secret);
//! # let bob_secret = EphemeralSecret::new(OsRng);
//! # let bob_public = PublicKey::from(&bob_secret);
//! let bob_shared_secret = bob_secret.diffie_hellman(&alice_public);
//! ```
//!
//! These secrets are the same:
//!
//! ```rust
//! # use rand_core::OsRng;
//! # use x25519_dalek::{EphemeralSecret, PublicKey};
//! # let alice_secret = EphemeralSecret::new(OsRng);
//! # let alice_public = PublicKey::from(&alice_secret);
//! # let bob_secret = EphemeralSecret::new(OsRng);
//! # 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());
//! ```
//!
//! Voilà!  Alice and Bob can now use their shared secret to encrypt their
//! meows, for example, by using it to generate a key and nonce for an
//! authenticated-encryption cipher.
//!
//! This example used the ephemeral DH API, which ensures that secret keys
//! cannot be reused; Alice and Bob could instead use the static DH API
//! and load a long-term secret key.
//!
//! # Installation
//!
//! To install, add the following to your project's `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! x25519-dalek = "1"
//! ```
//!
//! # MSRV
//!
//! Current MSRV is 1.41 for production builds, and 1.48 for running tests.
//!
//! # Documentation
//!
//! Documentation is available [here](https://docs.rs/x25519-dalek).
//!
//! # Note
//!
//! This code matches the [RFC7748][rfc7748] test vectors.
//! The elliptic curve
//! operations are provided by `curve25519-dalek`, which makes a best-effort
//! attempt to prevent software side-channels.
//!
//! "Secret Messages" cover image and [zine](https://shop.bubblesort.io/products/secret-messages-zine)
//! copyright © Amy Wibowo ([@sailorhg](https://twitter.com/sailorhg))
//!
//! [rfc7748]: https://tools.ietf.org/html/rfc7748
//!
//! # See also
//!
//! - [crypto_box]: pure Rust public-key authenticated encryption compatible with
//!   the NaCl family of encryption libraries (libsodium, TweetNaCl) which uses
//!   `x25519-dalek` for key agreement
//!
//! [crypto_box]: https://github.com/RustCrypto/AEADs/tree/master/crypto_box

extern crate curve25519_dalek;

extern crate rand_core;

extern crate zeroize;

mod x25519;

pub use crate::x25519::*;