README.md
1
2# curve25519-dalek [![](https://img.shields.io/crates/v/curve25519-dalek.svg)](https://crates.io/crates/curve25519-dalek) [![](https://img.shields.io/badge/dynamic/json.svg?label=docs&uri=https%3A%2F%2Fcrates.io%2Fapi%2Fv1%2Fcrates%2Fcurve25519-dalek%2Fversions&query=%24.versions%5B0%5D.num&colorB=4F74A6)](https://doc.dalek.rs) [![](https://travis-ci.org/dalek-cryptography/curve25519-dalek.svg?branch=master)](https://travis-ci.org/dalek-cryptography/curve25519-dalek)
3
4<img
5 width="33%"
6 align="right"
7 src="https://doc.dalek.rs/assets/dalek-logo-clear.png"/>
8
9**A pure-Rust implementation of group operations on Ristretto and Curve25519.**
10
11`curve25519-dalek` is a library providing group operations on the Edwards and
12Montgomery forms of Curve25519, and on the prime-order Ristretto group.
13
14`curve25519-dalek` is not intended to provide implementations of any particular
15crypto protocol. Rather, implementations of those protocols (such as
16[`x25519-dalek`][x25519-dalek] and [`ed25519-dalek`][ed25519-dalek]) should use
17`curve25519-dalek` as a library.
18
19`curve25519-dalek` is intended to provide a clean and safe _mid-level_ API for use
20implementing a wide range of ECC-based crypto protocols, such as key agreement,
21signatures, anonymous credentials, rangeproofs, and zero-knowledge proof
22systems.
23
24In particular, `curve25519-dalek` implements Ristretto, which constructs a
25prime-order group from a non-prime-order Edwards curve. This provides the
26speed and safety benefits of Edwards curve arithmetic, without the pitfalls of
27cofactor-related abstraction mismatches.
28
29# Documentation
30
31The semver-stable, public-facing `curve25519-dalek` API is documented
32[here][docs-external]. In addition, the unstable internal implementation
33details are documented [here][docs-internal].
34
35The `curve25519-dalek` documentation requires a custom HTML header to include
36KaTeX for math support. Unfortunately `cargo doc` does not currently support
37this, but docs can be built using
38```sh
39make doc
40make doc-internal
41```
42
43# Use
44
45To import `curve25519-dalek`, add the following to the dependencies section of
46your project's `Cargo.toml`:
47```toml
48curve25519-dalek = "3"
49```
50
51The sole breaking change in the `3.x` series was an update to the `digest`
52version, and in terms of non-breaking changes it includes:
53
54* support for using `alloc` instead of `std` on stable Rust,
55* the Elligator2 encoding for Edwards points,
56* a fix to use `packed_simd2`,
57* various documentation fixes and improvements,
58* support for configurably-sized, precomputed lookup tables for basepoint scalar
59 multiplication,
60* two new formally-verified field arithmetic backends which use the Fiat Crypto
61 Rust code, which is generated from proofs of functional correctness checked by
62 the Coq theorem proving system, and
63* support for explicitly calling the `zeroize` traits for all point types.
64
65The `2.x` series has API almost entirely unchanged from the `1.x` series,
66except that:
67
68* an error in the data modeling for the (optional) `serde` feature was
69 corrected, so that when the `2.x`-series `serde` implementation is used
70 with `serde-bincode`, the derived serialization matches the usual X/Ed25519
71 formats;
72* the `rand` version was updated.
73
74See `CHANGELOG.md` for more details.
75
76# Backends and Features
77
78The `nightly` feature enables features available only when using a Rust nightly
79compiler. In particular, it is required for rendering documentation and for
80the SIMD backends.
81
82Curve arithmetic is implemented using one of the following backends:
83
84* a `u32` backend using serial formulas and `u64` products;
85* a `u64` backend using serial formulas and `u128` products;
86* an `avx2` backend using [parallel formulas][parallel_doc] and `avx2` instructions (sets speed records);
87* an `ifma` backend using [parallel formulas][parallel_doc] and `ifma` instructions (sets speed records);
88
89By default the `u64` backend is selected. To select a specific backend, use:
90```sh
91cargo build --no-default-features --features "std u32_backend"
92cargo build --no-default-features --features "std u64_backend"
93# Requires nightly, RUSTFLAGS="-C target_feature=+avx2" to use avx2
94cargo build --no-default-features --features "std simd_backend"
95# Requires nightly, RUSTFLAGS="-C target_feature=+avx512ifma" to use ifma
96cargo build --no-default-features --features "std simd_backend"
97```
98Crates using `curve25519-dalek` can either select a backend on behalf of their
99users, or expose feature flags that control the `curve25519-dalek` backend.
100
101The `std` feature is enabled by default, but it can be disabled for no-`std`
102builds using `--no-default-features`. Note that this requires explicitly
103selecting an arithmetic backend using one of the `_backend` features.
104If no backend is selected, compilation will fail.
105
106# Safety
107
108The `curve25519-dalek` types are designed to make illegal states
109unrepresentable. For example, any instance of an `EdwardsPoint` is
110guaranteed to hold a point on the Edwards curve, and any instance of a
111`RistrettoPoint` is guaranteed to hold a valid point in the Ristretto
112group.
113
114All operations are implemented using constant-time logic (no
115secret-dependent branches, no secret-dependent memory accesses),
116unless specifically marked as being variable-time code.
117We believe that our constant-time logic is lowered to constant-time
118assembly, at least on `x86_64` targets.
119
120As an additional guard against possible future compiler optimizations,
121the `subtle` crate places an optimization barrier before every
122conditional move or assignment. More details can be found in [the
123documentation for the `subtle` crate][subtle_doc].
124
125Some functionality (e.g., multiscalar multiplication or batch
126inversion) requires heap allocation for temporary buffers. All
127heap-allocated buffers of potentially secret data are explicitly
128zeroed before release.
129
130However, we do not attempt to zero stack data, for two reasons.
131First, it's not possible to do so correctly: we don't have control
132over stack allocations, so there's no way to know how much data to
133wipe. Second, because `curve25519-dalek` provides a mid-level API,
134the correct place to start zeroing stack data is likely not at the
135entrypoints of `curve25519-dalek` functions, but at the entrypoints of
136functions in other crates.
137
138The implementation is memory-safe, and contains no significant
139`unsafe` code. The SIMD backend uses `unsafe` internally to call SIMD
140intrinsics. These are marked `unsafe` only because invoking them on an
141inappropriate CPU would cause `SIGILL`, but the entire backend is only
142compiled with appropriate `target_feature`s, so this cannot occur.
143
144# Performance
145
146Benchmarks are run using [`criterion.rs`][criterion]:
147
148```sh
149cargo bench --no-default-features --features "std u32_backend"
150cargo bench --no-default-features --features "std u64_backend"
151# Uses avx2 or ifma only if compiled for an appropriate target.
152export RUSTFLAGS="-C target_cpu=native"
153cargo bench --no-default-features --features "std simd_backend"
154```
155
156Performance is a secondary goal behind correctness, safety, and
157clarity, but we aim to be competitive with other implementations.
158
159# FFI
160
161Unfortunately, we have no plans to add FFI to `curve25519-dalek` directly. The
162reason is that we use Rust features to provide an API that maintains safety
163invariants, which are not possible to maintain across an FFI boundary. For
164instance, as described in the _Safety_ section above, invalid points are
165impossible to construct, and this would not be the case if we exposed point
166operations over FFI.
167
168However, `curve25519-dalek` is designed as a *mid-level* API, aimed at
169implementing other, higher-level primitives. Instead of providing FFI at the
170mid-level, our suggestion is to implement the higher-level primitive (a
171signature, PAKE, ZKP, etc) in Rust, using `curve25519-dalek` as a dependency,
172and have that crate provide a minimal, byte-buffer-oriented FFI specific to
173that primitive.
174
175# Contributing
176
177Please see [CONTRIBUTING.md][contributing].
178
179Patches and pull requests should be make against the `develop`
180branch, **not** `master`.
181
182# About
183
184**SPOILER ALERT:** *The Twelfth Doctor's first encounter with the Daleks is in
185his second full episode, "Into the Dalek". A beleaguered ship of the "Combined
186Galactic Resistance" has discovered a broken Dalek that has turned "good",
187desiring to kill all other Daleks. The Doctor, Clara and a team of soldiers
188are miniaturized and enter the Dalek, which the Doctor names Rusty. They
189repair the damage, but accidentally restore it to its original nature, causing
190it to go on the rampage and alert the Dalek fleet to the whereabouts of the
191rebel ship. However, the Doctor manages to return Rusty to its previous state
192by linking his mind with the Dalek's: Rusty shares the Doctor's view of the
193universe's beauty, but also his deep hatred of the Daleks. Rusty destroys the
194other Daleks and departs the ship, determined to track down and bring an end
195to the Dalek race.*
196
197`curve25519-dalek` is authored by Isis Agora Lovecruft and Henry de Valence.
198
199Portions of this library were originally a port of [Adam Langley's
200Golang ed25519 library](https://github.com/agl/ed25519), which was in
201turn a port of the reference `ref10` implementation. Most of this code,
202including the 32-bit field arithmetic, has since been rewritten.
203
204The fast `u32` and `u64` scalar arithmetic was implemented by Andrew Moon, and
205the addition chain for scalar inversion was provided by Brian Smith. The
206optimised batch inversion was contributed by Sean Bowe and Daira Hopwood.
207
208The `no_std` and `zeroize` support was contributed by Tony Arcieri.
209
210The formally verified backends, `fiat_u32_backend` and `fiat_u64_backend`, which
211integrate with the Rust generated by the
212[Fiat Crypto project](https://github.com/mit-plv/fiat-crypto) were contributed
213by François Garillot.
214
215Thanks also to Ashley Hauck, Lucas Salibian, Manish Goregaokar, Jack Grigg,
216Pratyush Mishra, Michael Rosenberg, and countless others for their
217contributions.
218
219[ed25519-dalek]: https://github.com/dalek-cryptography/ed25519-dalek
220[x25519-dalek]: https://github.com/dalek-cryptography/x25519-dalek
221[contributing]: https://github.com/dalek-cryptography/curve25519-dalek/blob/master/CONTRIBUTING.md
222[docs-external]: https://doc.dalek.rs/curve25519_dalek/
223[docs-internal]: https://doc-internal.dalek.rs/curve25519_dalek/
224[criterion]: https://github.com/japaric/criterion.rs
225[parallel_doc]: https://doc-internal.dalek.rs/curve25519_dalek/backend/vector/avx2/index.html
226[subtle_doc]: https://doc.dalek.rs/subtle/
227