crev_ed25519_dalek/
lib.rs

1// -*- mode: rust; -*-
2//
3// This file is part of ed25519-dalek.
4// Copyright (c) 2017-2019 isis lovecruft
5// See LICENSE for licensing information.
6//
7// Authors:
8// - isis agora lovecruft <isis@patternsinthevoid.net>
9
10//! A Rust implementation of ed25519 key generation, signing, and verification.
11//!
12//! # Example
13//!
14//! Creating an ed25519 signature on a message is simple.
15//!
16//! First, we need to generate a `Keypair`, which includes both public and
17//! secret halves of an asymmetric key.  To do so, we need a cryptographically
18//! secure pseudorandom number generator (CSPRNG). For this example, we'll use
19//! the operating system's builtin PRNG:
20//!
21//! ```
22//! extern crate rand;
23//! extern crate ed25519_dalek;
24//!
25//! # #[cfg(feature = "std")]
26//! # fn main() {
27//! use rand::Rng;
28//! use rand::rngs::OsRng;
29//! use ed25519_dalek::Keypair;
30//! use ed25519_dalek::Signature;
31//!
32//! let mut csprng: OsRng = OsRng::new().unwrap();
33//! let keypair: Keypair = Keypair::generate(&mut csprng);
34//! # }
35//! #
36//! # #[cfg(not(feature = "std"))]
37//! # fn main() { }
38//! ```
39//!
40//! We can now use this `keypair` to sign a message:
41//!
42//! ```
43//! # extern crate rand;
44//! # extern crate ed25519_dalek;
45//! # fn main() {
46//! # use rand::Rng;
47//! # use rand::thread_rng;
48//! # use ed25519_dalek::Keypair;
49//! # use ed25519_dalek::Signature;
50//! # let mut csprng = thread_rng();
51//! # let keypair: Keypair = Keypair::generate(&mut csprng);
52//! let message: &[u8] = b"This is a test of the tsunami alert system.";
53//! let signature: Signature = keypair.sign(message);
54//! # }
55//! ```
56//!
57//! As well as to verify that this is, indeed, a valid signature on
58//! that `message`:
59//!
60//! ```
61//! # extern crate rand;
62//! # extern crate ed25519_dalek;
63//! # fn main() {
64//! # use rand::Rng;
65//! # use rand::thread_rng;
66//! # use ed25519_dalek::Keypair;
67//! # use ed25519_dalek::Signature;
68//! # let mut csprng = thread_rng();
69//! # let keypair: Keypair = Keypair::generate(&mut csprng);
70//! # let message: &[u8] = b"This is a test of the tsunami alert system.";
71//! # let signature: Signature = keypair.sign(message);
72//! assert!(keypair.verify(message, &signature).is_ok());
73//! # }
74//! ```
75//!
76//! Anyone else, given the `public` half of the `keypair` can also easily
77//! verify this signature:
78//!
79//! ```
80//! # extern crate rand;
81//! # extern crate ed25519_dalek;
82//! # fn main() {
83//! # use rand::Rng;
84//! # use rand::thread_rng;
85//! # use ed25519_dalek::Keypair;
86//! # use ed25519_dalek::Signature;
87//! use ed25519_dalek::PublicKey;
88//! # let mut csprng = thread_rng();
89//! # let keypair: Keypair = Keypair::generate(&mut csprng);
90//! # let message: &[u8] = b"This is a test of the tsunami alert system.";
91//! # let signature: Signature = keypair.sign(message);
92//!
93//! let public_key: PublicKey = keypair.public;
94//! assert!(public_key.verify(message, &signature).is_ok());
95//! # }
96//! ```
97//!
98//! ## Serialisation
99//!
100//! `PublicKey`s, `SecretKey`s, `Keypair`s, and `Signature`s can be serialised
101//! into byte-arrays by calling `.to_bytes()`.  It's perfectly acceptible and
102//! safe to transfer and/or store those bytes.  (Of course, never transfer your
103//! secret key to anyone else, since they will only need the public key to
104//! verify your signatures!)
105//!
106//! ```
107//! # extern crate rand;
108//! # extern crate ed25519_dalek;
109//! # fn main() {
110//! # use rand::Rng;
111//! # use rand::thread_rng;
112//! # use ed25519_dalek::{Keypair, Signature, PublicKey};
113//! use ed25519_dalek::{PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, KEYPAIR_LENGTH, SIGNATURE_LENGTH};
114//! # let mut csprng = thread_rng();
115//! # let keypair: Keypair = Keypair::generate(&mut csprng);
116//! # let message: &[u8] = b"This is a test of the tsunami alert system.";
117//! # let signature: Signature = keypair.sign(message);
118//! # let public_key: PublicKey = keypair.public;
119//!
120//! let public_key_bytes: [u8; PUBLIC_KEY_LENGTH] = public_key.to_bytes();
121//! let secret_key_bytes: [u8; SECRET_KEY_LENGTH] = keypair.secret.to_bytes();
122//! let keypair_bytes:    [u8; KEYPAIR_LENGTH]    = keypair.to_bytes();
123//! let signature_bytes:  [u8; SIGNATURE_LENGTH]  = signature.to_bytes();
124//! # }
125//! ```
126//!
127//! And similarly, decoded from bytes with `::from_bytes()`:
128//!
129//! ```
130//! # extern crate rand;
131//! # extern crate ed25519_dalek;
132//! # use rand::Rng;
133//! # use rand::thread_rng;
134//! # use ed25519_dalek::{Keypair, Signature, PublicKey, SecretKey, SignatureError};
135//! # use ed25519_dalek::{PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, KEYPAIR_LENGTH, SIGNATURE_LENGTH};
136//! # fn do_test() -> Result<(SecretKey, PublicKey, Keypair, Signature), SignatureError> {
137//! # let mut csprng = thread_rng();
138//! # let keypair_orig: Keypair = Keypair::generate(&mut csprng);
139//! # let message: &[u8] = b"This is a test of the tsunami alert system.";
140//! # let signature_orig: Signature = keypair_orig.sign(message);
141//! # let public_key_bytes: [u8; PUBLIC_KEY_LENGTH] = keypair_orig.public.to_bytes();
142//! # let secret_key_bytes: [u8; SECRET_KEY_LENGTH] = keypair_orig.secret.to_bytes();
143//! # let keypair_bytes:    [u8; KEYPAIR_LENGTH]    = keypair_orig.to_bytes();
144//! # let signature_bytes:  [u8; SIGNATURE_LENGTH]  = signature_orig.to_bytes();
145//! #
146//! let public_key: PublicKey = PublicKey::from_bytes(&public_key_bytes)?;
147//! let secret_key: SecretKey = SecretKey::from_bytes(&secret_key_bytes)?;
148//! let keypair:    Keypair   = Keypair::from_bytes(&keypair_bytes)?;
149//! let signature:  Signature = Signature::from_bytes(&signature_bytes)?;
150//! #
151//! # Ok((secret_key, public_key, keypair, signature))
152//! # }
153//! # fn main() {
154//! #     do_test();
155//! # }
156//! ```
157//!
158//! ### Using Serde
159//!
160//! If you prefer the bytes to be wrapped in another serialisation format, all
161//! types additionally come with built-in [serde](https://serde.rs) support by
162//! building `ed25519-dalek` via:
163//!
164//! ```bash
165//! $ cargo build --features="serde"
166//! ```
167//!
168//! They can be then serialised into any of the wire formats which serde supports.
169//! For example, using [bincode](https://github.com/TyOverby/bincode):
170//!
171//! ```
172//! # extern crate rand;
173//! # extern crate ed25519_dalek;
174//! # #[cfg(feature = "serde")]
175//! extern crate serde;
176//! # #[cfg(feature = "serde")]
177//! extern crate bincode;
178//!
179//! # #[cfg(feature = "serde")]
180//! # fn main() {
181//! # use rand::Rng;
182//! # use rand::thread_rng;
183//! # use ed25519_dalek::{Keypair, Signature, PublicKey};
184//! use bincode::{serialize, Infinite};
185//! # let mut csprng = thread_rng();
186//! # let keypair: Keypair = Keypair::generate(&mut csprng);
187//! # let message: &[u8] = b"This is a test of the tsunami alert system.";
188//! # let signature: Signature = keypair.sign(message);
189//! # let public_key: PublicKey = keypair.public;
190//! # let verified: bool = public_key.verify(message, &signature).is_ok();
191//!
192//! let encoded_public_key: Vec<u8> = serialize(&public_key, Infinite).unwrap();
193//! let encoded_signature: Vec<u8> = serialize(&signature, Infinite).unwrap();
194//! # }
195//! # #[cfg(not(feature = "serde"))]
196//! # fn main() {}
197//! ```
198//!
199//! After sending the `encoded_public_key` and `encoded_signature`, the
200//! recipient may deserialise them and verify:
201//!
202//! ```
203//! # extern crate rand;
204//! # extern crate ed25519_dalek;
205//! # #[cfg(feature = "serde")]
206//! # extern crate serde;
207//! # #[cfg(feature = "serde")]
208//! # extern crate bincode;
209//! #
210//! # #[cfg(feature = "serde")]
211//! # fn main() {
212//! # use rand::Rng;
213//! # use rand::thread_rng;
214//! # use ed25519_dalek::{Keypair, Signature, PublicKey};
215//! # use bincode::{serialize, Infinite};
216//! use bincode::{deserialize};
217//!
218//! # let mut csprng = thread_rng();
219//! # let keypair: Keypair = Keypair::generate(&mut csprng);
220//! let message: &[u8] = b"This is a test of the tsunami alert system.";
221//! # let signature: Signature = keypair.sign(message);
222//! # let public_key: PublicKey = keypair.public;
223//! # let verified: bool = public_key.verify(message, &signature).is_ok();
224//! # let encoded_public_key: Vec<u8> = serialize(&public_key, Infinite).unwrap();
225//! # let encoded_signature: Vec<u8> = serialize(&signature, Infinite).unwrap();
226//! let decoded_public_key: PublicKey = deserialize(&encoded_public_key).unwrap();
227//! let decoded_signature: Signature = deserialize(&encoded_signature).unwrap();
228//!
229//! # assert_eq!(public_key, decoded_public_key);
230//! # assert_eq!(signature, decoded_signature);
231//! #
232//! let verified: bool = decoded_public_key.verify(&message, &decoded_signature).is_ok();
233//!
234//! assert!(verified);
235//! # }
236//! # #[cfg(not(feature = "serde"))]
237//! # fn main() {}
238//! ```
239
240#![no_std]
241#![warn(future_incompatible)]
242#![warn(rust_2018_compatibility)]
243#![warn(rust_2018_idioms)]
244#![deny(missing_docs)] // refuse to compile if documentation is missing
245
246#[cfg(any(feature = "std", test))]
247#[macro_use]
248extern crate std;
249
250extern crate clear_on_drop;
251extern crate curve25519_dalek;
252extern crate failure;
253extern crate rand;
254#[cfg(feature = "serde")]
255extern crate serde;
256extern crate sha2;
257
258mod constants;
259mod ed25519;
260mod errors;
261mod public;
262mod secret;
263mod signature;
264
265// Export everything public in ed25519.
266pub use crate::ed25519::*;