2018-07-13 23:57:27 +00:00
|
|
|
# ed25519-dalek [](https://crates.io/crates/ed25519-dalek) [](https://docs.rs/ed25519-dalek) [](https://travis-ci.org/dalek-cryptography/ed25519-dalek?branch=master)
|
2016-12-01 00:40:48 +00:00
|
|
|
|
2016-12-08 11:34:56 +00:00
|
|
|
Fast and efficient Rust implementation of ed25519 key generation, signing, and
|
2016-12-08 22:28:34 +00:00
|
|
|
verification in Rust.
|
2016-12-01 00:40:48 +00:00
|
|
|
|
2023-01-27 06:06:24 +00:00
|
|
|
# Use
|
2017-03-15 21:05:07 +00:00
|
|
|
|
2023-01-27 06:06:24 +00:00
|
|
|
To use, add the following to your project's `Cargo.toml`:
|
2019-11-27 22:26:54 +00:00
|
|
|
|
2022-10-16 23:38:36 +00:00
|
|
|
```toml
|
|
|
|
|
[dependencies.ed25519-dalek]
|
|
|
|
|
version = "1"
|
|
|
|
|
```
|
|
|
|
|
|
2023-01-27 06:06:24 +00:00
|
|
|
# Feature Flags
|
2022-10-16 22:51:26 +00:00
|
|
|
|
2023-01-27 06:06:24 +00:00
|
|
|
This crate is `#[no_std]` compatible with `default-features = false`
|
2022-10-16 22:51:26 +00:00
|
|
|
|
2023-01-27 06:06:24 +00:00
|
|
|
| Feature | Default? | Description |
|
|
|
|
|
| :--- | :--- | :--- |
|
|
|
|
|
| `alloc` | ✓ | Enables features that require dynamic heap allocation |
|
|
|
|
|
| `std` | ✓ | std::error::Error types |
|
|
|
|
|
| `zeroize` | ✓ | Enables `Zeroize` for `SigningKey` |
|
|
|
|
|
| `asm` | | Assembly implementation of SHA-2 compression functions |
|
|
|
|
|
| `batch` | | Batch verification. Requires `alloc` |
|
|
|
|
|
| `digest` | | TODO |
|
|
|
|
|
| `legacy_compatibility` | | See: A Note on Signature Malleability |
|
|
|
|
|
| `pkcs8` | | PKCS#8 Support |
|
|
|
|
|
| `pem` | | PEM Support |
|
|
|
|
|
| `rand_core` | | TODO |
|
2022-10-16 22:51:26 +00:00
|
|
|
|
2023-01-27 06:06:24 +00:00
|
|
|
# Major Changes
|
2022-10-16 22:51:26 +00:00
|
|
|
|
|
|
|
|
See [CHANGELOG.md](CHANGELOG.md) for a list of changes made in past version of this crate.
|
2019-11-27 22:26:54 +00:00
|
|
|
|
2023-01-27 06:06:24 +00:00
|
|
|
## 2.0.0 Breaking Changes
|
|
|
|
|
|
|
|
|
|
* Update the MSRV from 1.41 to 1.60
|
|
|
|
|
* `batch` is now `batch_deterministic`
|
|
|
|
|
* Removed `ExpandedSecretKey` API
|
|
|
|
|
* [curve25519-backend selection] is more automatic
|
|
|
|
|
|
|
|
|
|
[curve25519-backend selection]: https://github.com/dalek-cryptography/curve25519-dalek/#backends
|
|
|
|
|
|
|
|
|
|
# Documentation
|
|
|
|
|
|
|
|
|
|
Documentation is available [here](https://docs.rs/ed25519-dalek).
|
|
|
|
|
|
|
|
|
|
# Policies
|
|
|
|
|
|
|
|
|
|
All on-by-default features of this library are covered by semantic versioning (SemVer)
|
2016-12-08 11:46:08 +00:00
|
|
|
|
2023-01-27 06:06:24 +00:00
|
|
|
SemVer exemptions are outlined below for MSRV and public API.
|
2016-12-08 11:46:08 +00:00
|
|
|
|
2023-01-27 06:06:24 +00:00
|
|
|
## Minimum Supported Rust Version
|
2016-12-08 11:46:08 +00:00
|
|
|
|
2023-01-27 06:06:24 +00:00
|
|
|
| Releases | MSRV |
|
|
|
|
|
| :--- | :--- |
|
|
|
|
|
| 2.x | 1.60 |
|
|
|
|
|
| 1.x | 1.41 |
|
2016-12-08 11:46:08 +00:00
|
|
|
|
2023-01-27 06:06:24 +00:00
|
|
|
MSRV changes will be accompanied by a minor version bump.
|
2018-07-15 23:22:22 +00:00
|
|
|
|
2023-01-27 06:06:24 +00:00
|
|
|
## Public API SemVer Exemptions
|
2016-12-08 11:46:08 +00:00
|
|
|
|
2023-01-27 06:06:24 +00:00
|
|
|
Breaking changes to SemVer exempted components affecting the public API will be accompanied by some version bump.
|
2016-12-08 11:46:08 +00:00
|
|
|
|
2023-01-27 06:06:24 +00:00
|
|
|
Below are the specific policies:
|
2018-07-15 23:22:22 +00:00
|
|
|
|
2023-01-27 06:06:24 +00:00
|
|
|
| Releases | Public API Component(s) | Policy |
|
|
|
|
|
| :--- | :--- | :--- |
|
|
|
|
|
| 2.x | Dependencies `digest`, `pkcs8` and `rand_core` | Minor SemVer bump |
|
2017-03-15 21:05:07 +00:00
|
|
|
|
2023-01-27 06:06:24 +00:00
|
|
|
## Safety
|
|
|
|
|
|
|
|
|
|
This crate does not require any unsafe and forbids all unsafe in-crate outside tests.
|
|
|
|
|
|
|
|
|
|
# Performance
|
|
|
|
|
|
|
|
|
|
Performance is a secondary goal behind correctness, safety, and clarity, but we
|
|
|
|
|
aim to be competitive with other implementations.
|
|
|
|
|
|
|
|
|
|
## Benchmarks
|
|
|
|
|
|
|
|
|
|
Benchmarks are run using [criterion.rs](https://github.com/japaric/criterion.rs):
|
|
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
cargo bench --features "batch"
|
|
|
|
|
# Uses avx2 or ifma only if compiled for an appropriate target.
|
|
|
|
|
export RUSTFLAGS='--cfg curve25519_dalek_backend="simd" -C target_cpu=native'
|
|
|
|
|
cargo +nightly bench --features "batch"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
On an Intel 10700K running at stock comparing between the `curve25519-dalek` backends.
|
|
|
|
|
|
|
|
|
|
| Benchmark | u64 | simd +avx2 | fiat |
|
|
|
|
|
| :--- | :---- | :--- | :--- |
|
|
|
|
|
| signing | 15.017 µs | 13.906 µs -7.3967% | 15.877 µs +14.188% |
|
|
|
|
|
| signature verification | 40.144 µs | 25.963 µs -35.603% | 42.118 µs +62.758% |
|
|
|
|
|
| strict signature verification | 41.334 µs | 27.874 µs -32.660% | 43.985 µs +57.763% |
|
|
|
|
|
| batch signature verification/4 | 109.44 µs | 81.778 µs -25.079% | 117.80 µs +43.629% |
|
|
|
|
|
| batch signature verification/8 | 182.75 µs | 138.40 µs -23.871% | 195.86 µs +40.665% |
|
|
|
|
|
| batch signature verification/16 | 328.67 µs | 251.39 µs -23.744% | 351.55 µs +39.901% |
|
|
|
|
|
| batch signature verification/32 | 619.49 µs | 477.36 µs -23.053% | 669.41 µs +39.966% |
|
|
|
|
|
| batch signature verification/64 | 1.2136 ms | 936.85 µs -22.543% | 1.3028 ms +38.808% |
|
|
|
|
|
| batch signature verification/96 | 1.8677 ms | 1.2357 ms -33.936% | 2.0552 ms +66.439% |
|
|
|
|
|
| batch signature verification/128| 2.3281 ms | 1.5795 ms -31.996% | 2.5596 ms +61.678% |
|
|
|
|
|
| batch signature verification/256| 4.1868 ms | 2.8864 ms -31.061% | 4.6494 ms +61.081% |
|
|
|
|
|
| keypair generation | 13.973 µs | 13.108 µs -6.5062% | 15.099 µs +15.407% |
|
2018-05-30 20:59:44 +00:00
|
|
|
|
2018-07-13 19:39:45 +00:00
|
|
|
Additionally, if you're using a CSPRNG from the `rand` crate, the `nightly`
|
|
|
|
|
feature will enable `u128`/`i128` features there, resulting in potentially
|
|
|
|
|
faster performance.
|
2017-03-15 21:05:07 +00:00
|
|
|
|
2023-01-27 06:06:24 +00:00
|
|
|
## Batch Performance
|
|
|
|
|
|
2018-07-27 21:34:02 +00:00
|
|
|
If your protocol or application is able to batch signatures for verification,
|
2023-01-27 06:06:24 +00:00
|
|
|
the `verify_batch()` function has greatly improved performance.
|
2018-07-27 21:34:02 +00:00
|
|
|
|
|
|
|
|
As you can see, there's an optimal batch size for each machine, so you'll likely
|
2023-01-27 06:06:24 +00:00
|
|
|
want to test the benchmarks on your target CPU to discover the best size.
|
|
|
|
|
|
|
|
|
|
## (Micro)Architecture Specific Backends
|
|
|
|
|
|
|
|
|
|
`ed25519-dalek` uses the backends from the `curve25519-dalek` crate.
|
2018-07-27 21:34:02 +00:00
|
|
|
|
2023-01-27 06:06:24 +00:00
|
|
|
By default the serial backend is used and depending on the target
|
|
|
|
|
platform either the 32 bit or the 64 bit serial formula is automatically used.
|
2018-07-27 21:34:02 +00:00
|
|
|
|
2023-01-27 06:06:24 +00:00
|
|
|
To address variety of usage scenarios various backends are available that
|
|
|
|
|
include hardware optimisations as well as a formally verified fiat crypto
|
|
|
|
|
backend that does not use any hardware optimisations.
|
|
|
|
|
|
|
|
|
|
These backends can be overriden with various configuration predicates (cfg)
|
|
|
|
|
|
|
|
|
|
Please see the [curve25519_dalek backend documentation](https://docs.rs/curve25519-dalek/latest/curve25519_dalek).
|
|
|
|
|
|
|
|
|
|
# Contributing
|
|
|
|
|
|
|
|
|
|
See [CONTRIBUTING.md](CONTRIBUTING.md)
|
2017-03-15 21:05:07 +00:00
|
|
|
|
2019-11-27 22:26:54 +00:00
|
|
|
# A Note on Signature Malleability
|
2017-03-15 21:13:09 +00:00
|
|
|
|
|
|
|
|
The signatures produced by this library are malleable, as discussed in
|
2017-03-15 21:05:07 +00:00
|
|
|
[the original paper](https://ed25519.cr.yp.to/ed25519-20110926.pdf):
|
2016-12-08 22:25:31 +00:00
|
|
|
|
2023-01-27 06:06:24 +00:00
|
|
|

|
2016-12-08 22:25:31 +00:00
|
|
|
|
2019-11-27 22:26:54 +00:00
|
|
|
While the scalar component of our `Signature` struct is strictly *not*
|
|
|
|
|
malleable, because reduction checks are put in place upon `Signature`
|
|
|
|
|
deserialisation from bytes, for all types of signatures in this crate,
|
|
|
|
|
there is still the question of potential malleability due to the group
|
|
|
|
|
element components.
|
|
|
|
|
|
|
|
|
|
We could eliminate the latter malleability property by multiplying by the curve
|
2017-03-15 21:05:07 +00:00
|
|
|
cofactor, however, this would cause our implementation to *not* match the
|
2017-03-15 21:25:44 +00:00
|
|
|
behaviour of every other implementation in existence. As of this writing,
|
|
|
|
|
[RFC 8032](https://tools.ietf.org/html/rfc8032), "Edwards-Curve Digital
|
|
|
|
|
Signature Algorithm (EdDSA)," advises that the stronger check should be done.
|
|
|
|
|
While we agree that the stronger check should be done, it is our opinion that
|
|
|
|
|
one shouldn't get to change the definition of "ed25519 verification" a decade
|
|
|
|
|
after the fact, breaking compatibility with every other implementation.
|
2017-03-15 21:05:07 +00:00
|
|
|
|
2019-11-27 22:26:54 +00:00
|
|
|
However, if you require this, please see the documentation for the
|
|
|
|
|
`verify_strict()` function, which does the full checks for the group elements.
|
|
|
|
|
This functionality is available by default.
|
2019-10-07 19:03:15 +00:00
|
|
|
|
2021-05-29 15:38:14 +00:00
|
|
|
If for some reason—although we strongly advise you not to—you need to conform
|
2019-11-27 22:26:54 +00:00
|
|
|
to the original specification of ed25519 signatures as in the excerpt from the
|
|
|
|
|
paper above, you can disable scalar malleability checking via
|
|
|
|
|
`--features='legacy_compatibility'`. **WE STRONGLY ADVISE AGAINST THIS.**
|
|
|
|
|
|
|
|
|
|
## The `legacy_compatibility` Feature
|
2019-10-07 19:03:15 +00:00
|
|
|
|
|
|
|
|
By default, this library performs a stricter check for malleability in the
|
|
|
|
|
scalar component of a signature, upon signature deserialisation. This stricter
|
|
|
|
|
check, that `s < \ell` where `\ell` is the order of the basepoint, is
|
|
|
|
|
[mandated by RFC8032](https://tools.ietf.org/html/rfc8032#section-5.1.7).
|
|
|
|
|
However, that RFC was standardised a decade after the original paper, which, as
|
|
|
|
|
described above, (usually, falsely) stated that malleability was inconsequential.
|
|
|
|
|
|
|
|
|
|
Because of this, most ed25519 implementations only perform a limited, hackier
|
|
|
|
|
check that the most significant three bits of the scalar are unset. If you need
|
|
|
|
|
compatibility with legacy implementations, including:
|
|
|
|
|
|
|
|
|
|
* ed25519-donna
|
|
|
|
|
* Golang's /x/crypto ed25519
|
|
|
|
|
* libsodium (only when built with `-DED25519_COMPAT`)
|
|
|
|
|
* NaCl's "ref" implementation
|
|
|
|
|
* probably a bunch of others
|
|
|
|
|
|
|
|
|
|
then enable `ed25519-dalek`'s `legacy_compatibility` feature. Please note and
|
|
|
|
|
be forewarned that doing so allows for signature malleability, meaning that
|
|
|
|
|
there may be two different and "valid" signatures with the same key for the same
|
|
|
|
|
message, which is obviously incredibly dangerous in a number of contexts,
|
|
|
|
|
including—but not limited to—identification protocols and cryptocurrency
|
|
|
|
|
transactions.
|
|
|
|
|
|
2019-11-27 22:26:54 +00:00
|
|
|
## The `verify_strict()` Function
|
2019-10-07 19:03:15 +00:00
|
|
|
|
|
|
|
|
The scalar component of a signature is not the only source of signature
|
|
|
|
|
malleability, however. Both the public key used for signature verification and
|
|
|
|
|
the group element component of the signature are malleable, as they may contain
|
2023-01-15 02:26:39 +00:00
|
|
|
a small torsion component as a consequence of the curve25519 group not being of
|
2019-10-07 19:03:15 +00:00
|
|
|
prime order, but having a small cofactor of 8.
|
|
|
|
|
|
|
|
|
|
If you wish to also eliminate this source of signature malleability, please
|
|
|
|
|
review the
|
2023-01-27 06:06:24 +00:00
|
|
|
[documentation for the `verify_strict()` function](https://docs.rs/ed25519-dalek/latest/ed25519_dalek/struct.PublicKey.html#method.verify_strict).
|
2019-11-27 22:26:54 +00:00
|
|
|
|
|
|
|
|
## Batch Signature Verification
|
|
|
|
|
|
|
|
|
|
The standard variants of batch signature verification (i.e. many signatures made
|
|
|
|
|
with potentially many different public keys over potentially many different
|
2023-01-02 05:59:19 +00:00
|
|
|
messages) is available via the `batch` feature. It uses synthetic randomness, as
|
|
|
|
|
noted above. Batch verification requires allocation, so this won't function in
|
|
|
|
|
heapless settings.
|