mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-04 20:24:10 +00:00
* Docs unlink from dalek.rs * Link katex assets to jsdelivr Co-authored-by: Michael Rosenberg <michael@mrosenberg.pub>
248 lines
11 KiB
Markdown
248 lines
11 KiB
Markdown
|
|
# curve25519-dalek [](https://crates.io/crates/curve25519-dalek) [](https://docs.rs/curve25519-dalek) [](https://travis-ci.org/dalek-cryptography/curve25519-dalek)
|
|
|
|
<p style="float: right">
|
|
<img
|
|
width="300px"
|
|
alt="dalek-cryptography logo: a dalek with edwards curves as sparkles coming out of its radar-schnozzley blaster thingies"
|
|
src="https://cdn.jsdelivr.net/gh/dalek-cryptography/curve25519-dalek/docs/assets/dalek-logo-clear.png"/>
|
|
</p>
|
|
|
|
**A pure-Rust implementation of group operations on Ristretto and Curve25519.**
|
|
|
|
`curve25519-dalek` is a library providing group operations on the Edwards and
|
|
Montgomery forms of Curve25519, and on the prime-order Ristretto group.
|
|
|
|
`curve25519-dalek` is not intended to provide implementations of any particular
|
|
crypto protocol. Rather, implementations of those protocols (such as
|
|
[`x25519-dalek`][x25519-dalek] and [`ed25519-dalek`][ed25519-dalek]) should use
|
|
`curve25519-dalek` as a library.
|
|
|
|
`curve25519-dalek` is intended to provide a clean and safe _mid-level_ API for use
|
|
implementing a wide range of ECC-based crypto protocols, such as key agreement,
|
|
signatures, anonymous credentials, rangeproofs, and zero-knowledge proof
|
|
systems.
|
|
|
|
In particular, `curve25519-dalek` implements Ristretto, which constructs a
|
|
prime-order group from a non-prime-order Edwards curve. This provides the
|
|
speed and safety benefits of Edwards curve arithmetic, without the pitfalls of
|
|
cofactor-related abstraction mismatches.
|
|
|
|
# Documentation
|
|
|
|
The `curve25519-dalek` public API and the backends are documented [here][docs-external].
|
|
|
|
In addition, the unstable internal implementation can be generated locally as below.
|
|
|
|
```sh
|
|
make doc-internal
|
|
```
|
|
|
|
# Use
|
|
|
|
To import `curve25519-dalek`, add the following to the dependencies section of
|
|
your project's `Cargo.toml`:
|
|
```toml
|
|
curve25519-dalek = "4.0.0-pre.2"
|
|
```
|
|
|
|
## Major Version API Changes
|
|
|
|
See `CHANGELOG.md` for more details.
|
|
|
|
### 2.x
|
|
|
|
The `2.x` series has API almost entirely unchanged from the `1.x` series,
|
|
except that:
|
|
|
|
* an error in the data modeling for the (optional) `serde` feature was
|
|
corrected, so that when the `2.x`-series `serde` implementation is used
|
|
with `serde-bincode`, the derived serialization matches the usual X/Ed25519
|
|
formats;
|
|
* the `rand` version was updated.
|
|
|
|
### 3.x (current stable)
|
|
|
|
The sole breaking change in the `3.x` series was an update to the `digest`
|
|
version, and in terms of non-breaking changes it includes:
|
|
|
|
* support for using `alloc` instead of `std` on stable Rust,
|
|
* the Elligator2 encoding for Edwards points,
|
|
* a fix to use `packed_simd2`,
|
|
* various documentation fixes and improvements,
|
|
* support for configurably-sized, precomputed lookup tables for basepoint scalar
|
|
multiplication,
|
|
* two new formally-verified field arithmetic backends which use the Fiat Crypto
|
|
Rust code, which is generated from proofs of functional correctness checked by
|
|
the Coq theorem proving system, and
|
|
* support for explicitly calling the `zeroize` traits for all point types.
|
|
|
|
### 4.x (current alpha)
|
|
|
|
The `4.x` series has an API largely unchanged from `3.x`, with a breaking change
|
|
to update the `rand` dependency crates.
|
|
|
|
It also requires including a new trait,
|
|
`use curve25519_dalek::traits::BasepointTable`, whenever using
|
|
`EdwardsBasepointTable` or `RistrettoBasepointTable`.
|
|
|
|
Backend selection has also been updated to be more automatic. See below.
|
|
|
|
# Backends and Features
|
|
|
|
The `nightly` feature enables features available only when using a Rust nightly
|
|
compiler. In particular, it is required for rendering documentation and for
|
|
the SIMD backends.
|
|
|
|
Curve arithmetic is implemented using one of the following backends:
|
|
|
|
* a `u32` backend using serial formulas and `u64` products;
|
|
* a `u64` backend using serial formulas and `u128` products;
|
|
* an `avx2` backend using [parallel formulas][parallel_doc] and `avx2` instructions (sets speed records);
|
|
* an `ifma` backend using [parallel formulas][parallel_doc] and `ifma` instructions (sets speed records);
|
|
* a `fiat` backend using formally verified field arithmetic from [fiat-crypto];
|
|
|
|
The `std` feature is enabled by default, but it can be disabled for no-`std`
|
|
builds using `--no-default-features`. Note that this requires explicitly
|
|
selecting an arithmetic backend using one of the `_backend` features.
|
|
If no backend is selected, compilation will fail.
|
|
|
|
## Backend selection
|
|
|
|
Backend selection is done automatically. E.g., if you're compiling on a
|
|
64-bit machine, then the `u64` backend is automatically chosen. And
|
|
if the `fiat_backend` feature is set, then the fiat `u64` backend is
|
|
chosen.
|
|
|
|
If you need a `u32` backend on a `u64` machine, then simple
|
|
cross-compiling will work on an x86-64 Linux machine:
|
|
|
|
* `sudo apt install gcc-multilib` (or whatever package manager you use)
|
|
* `rustup target add i686-unknown-linux-gnu`
|
|
* `cargo build --target i686-unknown-linux-gnu`
|
|
|
|
# Minimum Supported Rust Version
|
|
|
|
This crate requires Rust 1.56.1 at a minimum. 3.x releases of this crate supported an MSRV of 1.41.
|
|
|
|
In the future, MSRV changes will be accompanied by a minor version bump.
|
|
|
|
# Safety
|
|
|
|
The `curve25519-dalek` types are designed to make illegal states
|
|
unrepresentable. For example, any instance of an `EdwardsPoint` is
|
|
guaranteed to hold a point on the Edwards curve, and any instance of a
|
|
`RistrettoPoint` is guaranteed to hold a valid point in the Ristretto
|
|
group.
|
|
|
|
All operations are implemented using constant-time logic (no
|
|
secret-dependent branches, no secret-dependent memory accesses),
|
|
unless specifically marked as being variable-time code.
|
|
We believe that our constant-time logic is lowered to constant-time
|
|
assembly, at least on `x86_64` targets.
|
|
|
|
As an additional guard against possible future compiler optimizations,
|
|
the `subtle` crate places an optimization barrier before every
|
|
conditional move or assignment. More details can be found in [the
|
|
documentation for the `subtle` crate][subtle_doc].
|
|
|
|
Some functionality (e.g., multiscalar multiplication or batch
|
|
inversion) requires heap allocation for temporary buffers. All
|
|
heap-allocated buffers of potentially secret data are explicitly
|
|
zeroed before release.
|
|
|
|
However, we do not attempt to zero stack data, for two reasons.
|
|
First, it's not possible to do so correctly: we don't have control
|
|
over stack allocations, so there's no way to know how much data to
|
|
wipe. Second, because `curve25519-dalek` provides a mid-level API,
|
|
the correct place to start zeroing stack data is likely not at the
|
|
entrypoints of `curve25519-dalek` functions, but at the entrypoints of
|
|
functions in other crates.
|
|
|
|
The implementation is memory-safe, and contains no significant
|
|
`unsafe` code. The SIMD backend uses `unsafe` internally to call SIMD
|
|
intrinsics. These are marked `unsafe` only because invoking them on an
|
|
inappropriate CPU would cause `SIGILL`, but the entire backend is only
|
|
compiled with appropriate `target_feature`s, so this cannot occur.
|
|
|
|
# Performance
|
|
|
|
Benchmarks are run using [`criterion.rs`][criterion]:
|
|
|
|
```sh
|
|
cargo bench --no-default-features
|
|
# Uses avx2 or ifma only if compiled for an appropriate target.
|
|
export RUSTFLAGS="-C target_cpu=native"
|
|
cargo +nightly bench --no-default-features --features simd_backend
|
|
```
|
|
|
|
Performance is a secondary goal behind correctness, safety, and
|
|
clarity, but we aim to be competitive with other implementations.
|
|
|
|
# FFI
|
|
|
|
Unfortunately, we have no plans to add FFI to `curve25519-dalek` directly. The
|
|
reason is that we use Rust features to provide an API that maintains safety
|
|
invariants, which are not possible to maintain across an FFI boundary. For
|
|
instance, as described in the _Safety_ section above, invalid points are
|
|
impossible to construct, and this would not be the case if we exposed point
|
|
operations over FFI.
|
|
|
|
However, `curve25519-dalek` is designed as a *mid-level* API, aimed at
|
|
implementing other, higher-level primitives. Instead of providing FFI at the
|
|
mid-level, our suggestion is to implement the higher-level primitive (a
|
|
signature, PAKE, ZKP, etc) in Rust, using `curve25519-dalek` as a dependency,
|
|
and have that crate provide a minimal, byte-buffer-oriented FFI specific to
|
|
that primitive.
|
|
|
|
# Contributing
|
|
|
|
Please see [CONTRIBUTING.md][contributing].
|
|
|
|
Patches and pull requests should be make against the `develop`
|
|
branch, **not** `main`.
|
|
|
|
# About
|
|
|
|
**SPOILER ALERT:** *The Twelfth Doctor's first encounter with the Daleks is in
|
|
his second full episode, "Into the Dalek". A beleaguered ship of the "Combined
|
|
Galactic Resistance" has discovered a broken Dalek that has turned "good",
|
|
desiring to kill all other Daleks. The Doctor, Clara and a team of soldiers
|
|
are miniaturized and enter the Dalek, which the Doctor names Rusty. They
|
|
repair the damage, but accidentally restore it to its original nature, causing
|
|
it to go on the rampage and alert the Dalek fleet to the whereabouts of the
|
|
rebel ship. However, the Doctor manages to return Rusty to its previous state
|
|
by linking his mind with the Dalek's: Rusty shares the Doctor's view of the
|
|
universe's beauty, but also his deep hatred of the Daleks. Rusty destroys the
|
|
other Daleks and departs the ship, determined to track down and bring an end
|
|
to the Dalek race.*
|
|
|
|
`curve25519-dalek` is authored by Isis Agora Lovecruft and Henry de Valence.
|
|
|
|
Portions of this library were originally a port of [Adam Langley's
|
|
Golang ed25519 library](https://github.com/agl/ed25519), which was in
|
|
turn a port of the reference `ref10` implementation. Most of this code,
|
|
including the 32-bit field arithmetic, has since been rewritten.
|
|
|
|
The fast `u32` and `u64` scalar arithmetic was implemented by Andrew Moon, and
|
|
the addition chain for scalar inversion was provided by Brian Smith. The
|
|
optimised batch inversion was contributed by Sean Bowe and Daira Hopwood.
|
|
|
|
The `no_std` and `zeroize` support was contributed by Tony Arcieri.
|
|
|
|
The formally verified `fiat_backend` integrates Rust code generated by the
|
|
[Fiat Crypto project](https://github.com/mit-plv/fiat-crypto) and was
|
|
contributed by François Garillot.
|
|
|
|
Thanks also to Ashley Hauck, Lucas Salibian, Manish Goregaokar, Jack Grigg,
|
|
Pratyush Mishra, Michael Rosenberg, and countless others for their
|
|
contributions.
|
|
|
|
[ed25519-dalek]: https://github.com/dalek-cryptography/ed25519-dalek
|
|
[x25519-dalek]: https://github.com/dalek-cryptography/x25519-dalek
|
|
[contributing]: https://github.com/dalek-cryptography/curve25519-dalek/blob/master/CONTRIBUTING.md
|
|
[docs-external]: https://docs.rs/curve25519-dalek
|
|
[criterion]: https://github.com/japaric/criterion.rs
|
|
[parallel_doc]: https://docs.rs/curve25519-dalek/latest/curve25519_dalek/backend/vector/index.html
|
|
[subtle_doc]: https://docs.rs/subtle
|
|
[fiat-crypto]: https://github.com/mit-plv/fiat-crypto
|