Timing variability of any kind is problematic when working with
potentially secret values such as elliptic curve scalars, and such
issues can potentially leak private keys and other secrets. Such a
problem was recently discovered in `curve25519-dalek`.
The `Scalar52::sub` function contained usage of a mask value inside of a
loop where LLVM saw an opportunity to insert a branch instruction
(`jns` on x86) to conditionally bypass this code section when the mask
value is set to zero, as can be seen in godbolt:
https://godbolt.org/z/PczYj7Pda
A similar problem was recently discovered in the Kyber reference
implementation:
https://groups.google.com/a/list.nist.gov/g/pqc-forum/c/hqbtIGFKIpU/m/cnE3pbueBgAJ
As discussed on that thread, one portable solution, which is also used
in this PR, is to introduce a volatile read as an optimization barrier,
which prevents the compiler from optimizing it away.
The fix can be validated in godbolt here:
https://godbolt.org/z/x8d46Yfah
The problem was discovered and the solution independently verified by
Alexander Wagner <alexander.wagner@aisec.fraunhofer.de> and
Lea Themint <lea.thiemt@tum.de> using their DATA tool:
https://github.com/Fraunhofer-AISEC/DATA
Co-authored-by: Tony Arcieri <bascule@gmail.com>
* Fix nightly build
* Add nightly feature constraint so AVX-512 requires either x86 or x86_64
Co-authored-by: Tony Arcieri <bascule@gmail.com>
* fmt
---------
Co-authored-by: Michael Rosenberg <micro@fastmail.com>
Co-authored-by: Tony Arcieri <bascule@gmail.com>
Co-authored-by: Michael Rosenberg <michael@mrosenberg.pub>
* Mark constants::BASEPOINT_ORDER_PRIVATE deprecated from pub API
* Move all BASEPOINT_ORDER use private internally
Co-authored-by: Tony Arcieri <bascule@gmail.com>
* Fix CHANGELOG for 4.1.1
---------
Co-authored-by: Tony Arcieri <bascule@gmail.com>
We have a lot of backend types leaking via the public API, including
e.g. `FieldElement51`:
https://docs.rs/curve25519-dalek/latest/curve25519_dalek/backend/serial/u64/field/struct.FieldElement51.html
At the very least, these types shouldn't be visible in the rustdoc.
This PR hides them from the docs, but ideally we would hide them
completely from the public API (which might technically be considered a
breaking change, but IMO leaking them at all is a bug).
Adds a lints section to the top of lib.rs with the following:
#![warn(
clippy::unwrap_used,
missing_docs,
rust_2018_idioms,
unused_lifetimes,
unused_qualifications
)]
`warn` is used instead of `deny` to prevent the lints from firing during
local development, however we already configure `-D warnings` in CI so
if any lint fails on checked-in code, it will cause a CI failure.
This commit also fixes or explicitly allows any current violations of
these lints. The main ones were:
- `clippy::unwrap_used`: replaces usages of `unwrap` with `expect`
- `rust_2018_idioms`: no implicit lifetimes, which were present on
usages of `core::fmt::Formatter`
There is occasionally [a need](https://github.com/dalek-cryptography/curve25519-dalek/pull/519#issuecomment-1637770888) to multiply a non-prime-order Montgomery point by an integer. There's currently no way to do this, since our only methods are multiplication by `Scalar` (doesn't make sense in the non-prime-order case), and `MontgomeryPoint::mul_base_clamped` clamps the integer before multiplying.
This defines `MontgomeryPoint::mul_bits_be`, which takes a big-endian representation of an integer and multiplies the point by that integer. Its usage is not recommended by default, but it is also not so unsafe as to be gated behind a `hazmat` feature.