* Update changelogs and readmes
* Fix missing/wrong features in readmes
* ed: Remove std entirely
* ed: Fix deprecated warnings in bench
* Document removing std from ed
This represents the first breaking change in a new release series,
bumping all crates to the 2024 edition of Rust.
As such, the version numbers of all crates have been incremented to
represent a new prerelease series:
- `curve25519-dalek`: v5.0.0-pre
- `ed25519-dalek`: v3.0.0-pre
- `x25519-dalek`: v3.0.0-pre
Note that this commit isn't intended to cut associated crate releases of
these on crates.io, but is merely bumping the version numbers to denote
there are pending breaking changes.
This commit also includes rustfmt changes which were made as part of the
2024 edition.
Also includes clippy fixes.
The types involved are all simple 1-tuple newtypes where zeroization
only involves calling `zeroize` on the inner type, making all of the
involved impls relatively trivial.
Avoiding custom derive arguably improves auditability as you don't need
to expand a proc macro to see the resulting code. It decreases the
number of required dependencies in order for the `zeroize` feature to
work, where some of those dependencies are incredibly heavy
(particularly `syn`).
* Implementation of `hash_to_field` as defined in the standard
* Implementation of `hash_to_curve` as defined in the standard, by changing the mechanism over which we chose the sign.
* For the point above, had to change the `elligator_encode` to return whether `eps` is a square or not (required for `hash_to_curve`).
* Included test vectors of the draft.
* Included `FieldElement::from_bytes_wide(bytes: &u8; 64])` to reduce integers encoded in 64 bytes.
`merlin` is currently a blocker for upgrading to `rand_core` v0.9 by way
of the `transcript.build_rng().finalize()` function (which we only pass
`ZeroRng` to).
There is an open PR to update `rand_core` in `merlin` and I have pinged
the relevant people to take a look, hopefully: zkcrypto/merlin#11
However, in the event we can't get `merlin` updated, this at least
unblocks the `rand_core` upgrade, and is being opened as a contingency
plan for that case.
The PR has been implemented in a way that it should be easy to switch
back to upstream `merlin` in the event they upgrade `rand_core`.
* curve: extract `AffinePoint` type
Based on discussions about `elliptic-curve` trait impls in #746, and
observing a similar type in `ed448-goldilocks` which inspired this one
(not to mention in all of the @RustCrypto elliptic curve crates), adds
an `AffinePoint` type with `x` and `y` coordinates.
For now, the type is kept out of the public API, and used as an
implementation detail for point compression. However, it's been written
with the intent of eventually stabilizing and exposing it. It's been
marked `pub` so unused functionality doesn't automatically trigger dead
code lints.
Further work could include refactoring point decompression to first
produce an `AffinePoint` and then convert to extended twisted Edwards
coordinates (i.e. `EdwardsPoint`), which is more or less what the
existing `step_1` and `step_2` functions do (`step_1` technically
produces projective coordinates, but `Z` is always set to `ONE`).
* Update curve25519-dalek/src/edwards.rs
* curve: rename `FieldElement*::as_bytes` => `::to_bytes`
Methods named `as_*` should perform a zero-cost borrowing conversion:
https://rust-lang.github.io/api-guidelines/naming.html#ad-hoc-conversions-follow-as_-to_-into_-conventions-c-conv
Methods named `to_*` can perform an expensive owned conversion.
Since the `FieldElement*` types are technically part of the public API
(but feature gated), this also preserves the old names with a
deprecation. We can remove them in the next breaking release.
The same change was also made to the backend `Scalar*` types, however
these types are not a part of the public API.
* Replace recompute_R with a separate RCompute
This struct can be use to implement verifiers with incremental updates
* Add raw_sign_byupdate and raw_verify_byupdate
These allow signing/verifying a non-prehashed message
but don't require the whole message to be provided at once.
* Tests for raw_sign_byupdate, raw_verify_byupdate
* Add StreamVerifier
* Make StreamVerifier use RCompute
This allows it to use the same implementation as non-stream signature
verification.
* Guard StreamVerifier behind hazmat feature
* docs: disambiguate unsafety
Co-authored-by: Tony Arcieri <bascule@gmail.com>
* chore: relax F bounds on raw_verify_byupdate
* chore: remove raw_sign_byupdate and raw_verify_byupdate
* chore: address clippy lints within new code
* docs: fixup changelog
* test: invert new chunked test
* chore: revert raw_sign
---------
Co-authored-by: Matt Johnston <matt@ucc.asn.au>
Co-authored-by: Tony Arcieri <bascule@gmail.com>
* curve: add `EdwardsPoint::compress_batch` and `::random`
We've had various requests to implement batch point compression for
`EdwardsPoint`, e.g. #705.
We can leverage `FieldElement::batch_invert` to implement it, which
results in a fairly significant speedup.
The name `EdwardsPoint::compress_batch` has been chosen to match
`RistrettoPoint::double_and_compress_batch`.
For benchmarking, randomized `EdwardsPoint`s have been used. To obtain
these, an inherent `EdwardsPoint::random` has been extracted from the
existing `Group::random` implementation, which uses rejection sampling.
`Group::random` has been updated to call the inherent
`EdwardsPoint::random`. This avoids a `group` dependency just to run the
batch compression benchmarks.
The following benchmark results have been obtained:
edwards benches/EdwardsPoint compression
time: [3.5029 µs 3.5098 µs 3.5171 µs]
edwards benches/Batch EdwardsPoint compression/1
time: [3.6698 µs 3.6758 µs 3.6817 µs]
edwards benches/Batch EdwardsPoint compression/2
time: [3.8410 µs 3.8461 µs 3.8516 µs]
edwards benches/Batch EdwardsPoint compression/4
time: [4.1534 µs 4.1961 µs 4.2558 µs]
edwards benches/Batch EdwardsPoint compression/8
time: [4.8466 µs 4.8533 µs 4.8600 µs]
edwards benches/Batch EdwardsPoint compression/16
time: [6.1216 µs 6.1315 µs 6.1410 µs]
As you can see, it affords a fairly significant speedup, batch
compressing 16 points in less time than the standard point compression
algorithm would take to compress 2 in a row.
The test assumed that the 'avx2' target_feature would never be set
and used this fact to verify that unsafe_target_feature would
correctly not even compile test functions maked with that
target_feature. As of CentOS 10 and derivatives, th avx2
target_feature is now set by the system rustc, so let's use a
target_feature less likely to appear in the real world.
Closes#755
The build is currently broken because it's been stabilized:
error: the feature `avx512_target_feature` has been stable since 1.89.0-nightly and no longer requires an attribute to enable
Removes the previous warning that points are unvalidated: they're
validated using the ZIP-215 rules, which allows unreduced y-coordinates.
Points are ensured valid by performing decompression, which finds a
solution to the curve equation, or returns an error.
Adds references to ZIP-215 and dalek-cryptography/curve25519-dalek#626
which is an issue about potentially adding support for the RFC8032/NIST
validation criteria in the future.
* Make AVX512IFMA opt-in backend
* Updated README to have backend info
* Added entry to changelog
---------
Co-authored-by: Michael Rosenberg <michael@mrosenberg.pub>
Alternative to #659/#661 and #662 which leverages `subtle::Choice` and
`subtle::ConditionallySelectable` as the optimization barriers.
Really the previous masking was there to conditionally add the scalar
field modulus on underflow, so instead of that, we can conditionally
select zero or the modulus using a `Choice` constructed from the
underflow bit.
Replaces the security mitigation added in #659 and #661 for
masking-related timing variability which used an inline `black_box`
using the recently added `subtle::BlackBox` newtype (see
dalek-cryptography/subtle#123)
Internally `BlackBox` uses a volatile read by default (i.e. same
strategy which was used before) or when the `core_hint_black_box`
feature of `subtle` is enabled, it uses `core::hint::black_box`
(whose documentation was recently updated to reflect the nuances of
potential cryptographic use, see rust-lang/rust#126703)
This PR goes ahead and uses `BlackBox` for both `mask` and
`underflow_mask` where previously it was only used on `underflow_mask`.
The general pattern of bitwise masking inside a loop seems worrisome for
the optimizer potentially inserting branches in the future.
Below are godbolt inspections of the generated assembly, which are free
of the `jns` instructions originally spotted in #659/#661:
- 32-bit (read_volatile): https://godbolt.org/z/TKo9fqza4
- 32-bit (hint::black_box): https://godbolt.org/z/caoMxYbET
- 64-bit (read_volatile): https://godbolt.org/z/PM6zKjj1f
- 64-bit (hint::black_box): https://godbolt.org/z/nseaPvdWv