mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-04 20:24:10 +00:00
Update README w.r.t. new features, malleability, synthethic randomness.
This commit is contained in:
parent
b5ffcdf3ac
commit
52a7fc88b6
1 changed files with 89 additions and 30 deletions
119
README.md
119
README.md
|
|
@ -7,6 +7,15 @@ verification in Rust.
|
|||
|
||||
Documentation is available [here](https://docs.rs/ed25519-dalek).
|
||||
|
||||
# Installation
|
||||
|
||||
To install, add the following to your project's `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[dependencies.ed25519-dalek]
|
||||
version = "1"
|
||||
```
|
||||
|
||||
# Benchmarks
|
||||
|
||||
On an Intel Skylake i9-7900X running at 3.30 GHz, without TurboBoost, this code achieves
|
||||
|
|
@ -89,14 +98,20 @@ can read qhasm, making it more readily and more easily auditable. We're of
|
|||
the opinion that, ultimately, these features—combined with speed—are more
|
||||
valuable than simply cycle counts alone.
|
||||
|
||||
### A Note on Signature Malleability
|
||||
# A Note on Signature Malleability
|
||||
|
||||
The signatures produced by this library are malleable, as discussed in
|
||||
[the original paper](https://ed25519.cr.yp.to/ed25519-20110926.pdf):
|
||||
|
||||

|
||||
|
||||
We could eliminate the malleability property by multiplying by the curve
|
||||
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
|
||||
cofactor, however, this would cause our implementation to *not* match the
|
||||
behaviour of every other implementation in existence. As of this writing,
|
||||
[RFC 8032](https://tools.ietf.org/html/rfc8032), "Edwards-Curve Digital
|
||||
|
|
@ -105,12 +120,16 @@ 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.
|
||||
|
||||
In short, if malleable signatures are bad for your protocol, don't use them.
|
||||
Consider using a curve25519-based Verifiable Random Function (VRF), such as
|
||||
[Trevor Perrin's VXEdDSA](https://www.whispersystems.org/docs/specifications/xeddsa/),
|
||||
instead.
|
||||
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.
|
||||
|
||||
#### The `legacy_compatibility` Feature
|
||||
If for some reason—although we strongely advise you not to—you need to conform
|
||||
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
|
||||
|
||||
By default, this library performs a stricter check for malleability in the
|
||||
scalar component of a signature, upon signature deserialisation. This stricter
|
||||
|
|
@ -136,7 +155,7 @@ message, which is obviously incredibly dangerous in a number of contexts,
|
|||
including—but not limited to—identification protocols and cryptocurrency
|
||||
transactions.
|
||||
|
||||
#### The `verify_strict()` Function
|
||||
## The `verify_strict()` Function
|
||||
|
||||
The scalar component of a signature is not the only source of signature
|
||||
malleability, however. Both the public key used for signature verification and
|
||||
|
|
@ -148,23 +167,51 @@ If you wish to also eliminate this source of signature malleability, please
|
|||
review the
|
||||
[documentation for the `verify_strict()` function](https://doc.dalek.rs/ed25519_dalek/struct.PublicKey.html#method.verify_strict).
|
||||
|
||||
# Installation
|
||||
# A Note on Randomness Generation
|
||||
|
||||
To install, add the following to your project's `Cargo.toml`:
|
||||
The original paper's specification and the standarisation of RFC8032 do not
|
||||
specify precisely how randomness is to be generated, other than using a CSPRNG
|
||||
(Cryptographically Secure Random Number Generator). Particularly in the case of
|
||||
signature verification, where the security proof _relies_ on the uniqueness of
|
||||
the blinding factors/nonces, it is paramount that these samples of randomness be
|
||||
unguessable to an adversary. Because of this, a current growing belief among
|
||||
cryptographers is that it is safer to prefer _synthetic randomness_.
|
||||
|
||||
```toml
|
||||
[dependencies.ed25519-dalek]
|
||||
version = "1"
|
||||
```
|
||||
To explain synthetic randomness, we should first explain how `ed25519-dalek`
|
||||
handles generation of _deterministic randomness_. This mode is disabled by
|
||||
default due to a tiny-but-not-nonexistent chance that this mode will open users
|
||||
up to fault attacks, wherein an adversary who controls all of the inputs to
|
||||
batch verification (i.e. the public keys, signatures, and messages) can craft
|
||||
them in a specialised manner such as to induce a fault (e.g. causing a
|
||||
mistakenly flipped bit in RAM, overheating a processor, etc.). In the
|
||||
deterministic mode, we seed the PRNG which generates our blinding factors/nonces
|
||||
by creating
|
||||
[a PRNG based on the Fiat-Shamir transform of the public inputs](https://merlin.cool/transcript/rng.html).
|
||||
This mode is potentially useful to protocols which require strong auditability
|
||||
guarantees, as well as those which do not have access to secure system-/chip-
|
||||
provided randomness. This feature can be enabled via
|
||||
`--features='batch_deterministic'`. Note that we _do not_ support deterministic
|
||||
signing, due to the numerous pitfalls therein, including a re-used nonce
|
||||
accidentally revealing the secret key.
|
||||
|
||||
Then, in your library or executable source, add:
|
||||
|
||||
```rust
|
||||
extern crate ed25519_dalek;
|
||||
```
|
||||
In the default mode, we do as above in the fully deterministic mode, but we
|
||||
ratchet the underlying keccak-f1600 function (used for the provided
|
||||
transcript-based PRNG) forward additionally based on some system-/chip- provided
|
||||
randomness. This provides _synthetic randomness_, that is, randomness based on
|
||||
both deterministic and undeterinistic data. The reason for doing this is to
|
||||
prevent badly seeded system RNGs from ruining the security of the signature
|
||||
verification scheme.
|
||||
|
||||
# Features
|
||||
|
||||
## #![no_std]
|
||||
|
||||
This library aims to be `#![no_std]` compliant. If batch verification is
|
||||
required (`--features='batch'`), please enable either of the `std` or `alloc`
|
||||
features.
|
||||
|
||||
## Nightly Compilers
|
||||
|
||||
To cause your application to build `ed25519-dalek` with the nightly feature
|
||||
enabled by default, instead do:
|
||||
|
||||
|
|
@ -183,19 +230,31 @@ to the `Cargo.toml`:
|
|||
nightly = ["ed25519-dalek/nightly"]
|
||||
```
|
||||
|
||||
To enable [serde](https://serde.rs) support, build `ed25519-dalek` with:
|
||||
## Serde
|
||||
|
||||
```toml
|
||||
[dependencies.ed25519-dalek]
|
||||
version = "1"
|
||||
features = ["serde"]
|
||||
```
|
||||
To enable [serde](https://serde.rs) support, build `ed25519-dalek` with the
|
||||
`serde` feature.
|
||||
|
||||
## (Micro)Architecture Specific Backends
|
||||
|
||||
By default, `ed25519-dalek` builds against `curve25519-dalek`'s `u64_backend`
|
||||
feature, which uses Rust's `i128` feature to achieve roughly double the speed as
|
||||
the `u32_backend` feature. When targetting 32-bit systems, however, you'll
|
||||
likely want to compile with
|
||||
`cargo build --no-default-features --features="u32_backend"`.
|
||||
If you're building for a machine with avx2 instructions, there's also the
|
||||
experimental `avx2_backend`. To use it, compile with
|
||||
`RUSTFLAGS="-C target_cpu=native" cargo build --no-default-features --features="avx2_backend"`
|
||||
likely want to compile with `cargo build --no-default-features
|
||||
--features="u32_backend"`. If you're building for a machine with avx2
|
||||
instructions, there's also the experimental `simd_backend`s, currently
|
||||
comprising either avx2 or avx512 backends. To use them, compile with
|
||||
`RUSTFLAGS="-C target_cpu=native" cargo build --no-default-features
|
||||
--features="simd_backend"`
|
||||
|
||||
## 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
|
||||
message) is available via the `batch` feature. It uses synthetic randomness, as
|
||||
noted above.
|
||||
|
||||
### Deterministic Batch Signature Verification
|
||||
|
||||
The same notion of batch signature verification as above, but with purely
|
||||
deterministic randomness can be enabled via the `batch_deterministic` feature.
|
||||
|
|
|
|||
Loading…
Reference in a new issue