diff --git a/README.md b/README.md
index 63744eb..70c1cc5 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,20 @@
-
# x25519-dalek [](https://crates.io/crates/x25519-dalek) [](https://docs.rs/x25519-dalek) [](https://travis-ci.org/dalek-cryptography/x25519-dalek)
A pure-Rust implementation of x25519 elliptic curve Diffie-Hellman key exchange,
-as specified by Mike Hamburg and Adam Langley in
-[RFC7748](https://tools.ietf.org/html/rfc7748), using
+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 ephemeral Diffie-Hellman.
+
## Examples
-[](https://shop.bubblesort.io)
-
-"Secret Messages" cover image and [zine](https://shop.bubblesort.io/products/secret-messages-zine)
-copyright © Amy Wibowo ([@sailorhg](https://twitter.com/sailorhg))
+
+
+
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
@@ -25,8 +28,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::EphemeralSecret::new()` and then
-`x25519_dalek::EphemeralPublic::from()` to produce her secret and public keys:
+First, Alice uses `EphemeralSecret::new()` and then
+`EphemeralPublic::from()` to produce her secret and public keys:
```rust
extern crate x25519_dalek;
@@ -70,23 +73,6 @@ 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.
-# Warnings
-
-[Our elliptic curve library](https://github.com/dalek-cryptography/curve25519-dalek)
-(which this code uses) has received *one* formal cryptographic and security
-review. It has not yet received what we would consider *sufficient* peer
-review by other qualified cryptographers to be considered in any way, shape,
-or form, safe.
-
-This code matches the test vectors, as specified in
-[RFC7748](https://tools.ietf.org/html/rfc7748), however:
-
-**USE AT YOUR OWN RISK.**
-
-# Documentation
-
-Documentation is available [here](https://docs.rs/x25519-dalek).
-
# Installation
To install, add the following to your project's `Cargo.toml`:
@@ -96,8 +82,18 @@ To install, add the following to your project's `Cargo.toml`:
version = "^0.3"
```
-Then, in your library or executable source, add:
+# Documentation
-```rust
-extern crate x25519_dalek;
-```
+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
diff --git a/src/lib.rs b/src/lib.rs
index 1e32b77..b9a1f46 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -7,122 +7,20 @@
// Authors:
// - Isis Agora Lovecruft
-//! x25519 Diffie-Hellman key exchange
-//!
-//! A pure-Rust implementation of x25519 elliptic curve Diffie-Hellman key
-//! exchange as specified by Mike Hamburg and Adam Langley in
-//! [RFC7748](https://tools.ietf.org/html/rfc7748).
-//!
-//! # Examples
-//!
-//! [](https://shop.bubblesort.io)
-//!
-//! "Secret Messages" cover image and [zine](https://shop.bubblesort.io/products/secret-messages-zine)
-//! copyright © Amy Wibowo ([@sailorhg](https://twitter.com/sailorhg))
-//!
-//! 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 `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::EphemeralPublic;
-//! use x25519_dalek::EphemeralSecret;
-//! use rand::thread_rng;
-//!
-//! let mut alice_csprng = thread_rng();
-//! let alice_secret = EphemeralSecret::new(&mut alice_csprng);
-//! let alice_public = EphemeralPublic::from(&alice_secret);
-//! # }
-//! ```
-//!
-//! Bob does the same:
-//!
-//! ```
-//! # extern crate x25519_dalek;
-//! # extern crate rand;
-//! #
-//! # fn main() {
-//! # use x25519_dalek::EphemeralPublic;
-//! # use x25519_dalek::EphemeralSecret;
-//! # use rand::thread_rng;
-//! #
-//! let mut bob_csprng = thread_rng();
-//! let bob_secret = EphemeralSecret::new(&mut bob_csprng);
-//! let bob_public = EphemeralPublic::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:
-//!
-//! ```
-//! # extern crate x25519_dalek;
-//! # extern crate rand;
-//! #
-//! # fn main() {
-//! # use x25519_dalek::EphemeralPublic;
-//! # use x25519_dalek::EphemeralSecret;
-//! # use rand::thread_rng;
-//! #
-//! # let mut alice_csprng = thread_rng();
-//! # let alice_secret = EphemeralSecret::new(&mut alice_csprng);
-//! # let alice_public = EphemeralPublic::from(&alice_secret);
-//! #
-//! # let mut bob_csprng = thread_rng();
-//! # let bob_secret = EphemeralSecret::new(&mut bob_csprng);
-//! # let bob_public = EphemeralPublic::from(&bob_secret);
-//! #
-//! #
-//! let shared_secret = EphemeralSecret::diffie_hellman(alice_secret, &bob_public);
-//! # }
-//! ```
-//!
-//! Similarly, Bob computes the same shared secret by doing:
-//!
-//! ```
-//! # extern crate x25519_dalek;
-//! # extern crate rand;
-//! #
-//! # fn main() {
-//! # use x25519_dalek::EphemeralPublic;
-//! # use x25519_dalek::EphemeralSecret;
-//! # use rand::thread_rng;
-//! #
-//! # let mut alice_csprng = thread_rng();
-//! # let alice_secret = EphemeralSecret::new(&mut alice_csprng);
-//! # let alice_public = EphemeralPublic::from(&alice_secret);
-//! #
-//! # let mut bob_csprng = thread_rng();
-//! # let bob_secret = EphemeralSecret::new(&mut bob_csprng);
-//! # let bob_public = EphemeralPublic::from(&bob_secret);
-//! #
-//! let shared_secret = EphemeralSecret::diffie_hellman(bob_secret, &alice_public);
-//! # }
-//! ```
-//!
-//! 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.
+// 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))]
-#![deny(missing_docs)]
+#![cfg_attr(feature = "nightly", feature(external_doc))]
+#![cfg_attr(feature = "nightly", deny(missing_docs))]
+#![cfg_attr(feature = "nightly", doc(include = "../README.md"))]
+#![doc(html_logo_url = "https://doc.dalek.rs/assets/dalek-logo-clear.png")]
+
+//! Note that docs will only build on nightly Rust until
+//! `feature(external_doc)` is stabilized.
extern crate clear_on_drop;