Update README w.r.t. new features, malleability, synthethic randomness.

This commit is contained in:
Isis Lovecruft 2019-11-27 22:26:54 +00:00
parent b5ffcdf3ac
commit 52a7fc88b6
No known key found for this signature in database
GPG key ID: AB41313533E8E812

119
README.md
View file

@ -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):
![](https://github.com/dalek-cryptography/ed25519-dalek/blob/master/res/ed25519-malleability.png)
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.