* Removed Scalar::{from_bits, from_bytes_clamped}; all constructible scalars are now reduced mod l
* Made Scalar::reduce() not pub; fixed test warning
* Added benches for scalar add/sub/mul
* Docs
* Added EdwardsPoint::mul_base_clamped and gated Scalar::from_bits behind legacy_compatibility
* Added unit test for Mul impl on unreduced Scalars
* Added Montgomery::mul_base_clamped
* Added BasepointTable::mul_base_clamped
* Removed invalid scalar arithmetic test; this functionality is no longer supported
* Made clamp_integer() const
* Updated readme and changelog
* Added BasepointTable::mul_base_clamped to tests
* Added proper deprecation notice to Scalar::from_bits; added legacy_compatibility to Makefile and docsrs flags
* Fixed-based Montgomery scalar multiplication
Adds `MontgomeryPoint::mul_base` as an API for fixed-base scalar
multiplication which allows for potential future optimizations.
As a baseline implementation, it uses the variable base scalar
multiplication implementation.
This follows the existing `EdwardsPoint::mul_base` and
`RistrettoPoint::mul_base` APIs.
* Added Montgomery mul_base bench
* Switched MontgomeryPoint::mul_base to use EdwardsPoint::mul_base
---------
Co-authored-by: Michael Rosenberg <michael@mrosenberg.pub>
* Make basepoint table constants static references
This ensures they have a fixed address and aren't duplicated across
compilation units.
Since they were already always borrowed, this changes the static values
to be `&'static` addresses to ensure they're always borrowed rather than
potentially copied.
* rustfmt
The functionality we were using is now contained in the `rand_core` crate, which
we already depend upon. As far as testing code goes, only benchmarks still
depend upon `rand`, as they use `thread_rng`.
This avoids potentially misleading benchmark results where the memory cost of
precomputation becomes "free" as re-running the benchmark loop lifts exactly
the required table entries into the highest-level caches.
This doesn't (yet) give any speedup over the non-precomputed multiscalar
multiplication, and it's not clear that it's a good idea to commit to
supporting it in the future. Removing it means that it's not committed-to as
part of the public API, but the source is still there in the tree if we want to
revisit it later.
Unfortunately, Rust selects `i32` as the type for an integer literal
when the literal has no other type constraints. This means that someone
cannot write `Scalar::from(1)`, as Rust will choose `i32` as the type for
`1`, and we don't `impl From<i32> for Scalar`.
We could implement `From` conversions for signed integers, but since
`Scalar` operations should be constant-time by default, this would
require us to extract the sign bit of the integer and use it to
conditionally select between the positive and negative of Scalar
constructed from the value bits. This is more expensive than the
unsigned operation, and I don't think it's what anyone really wants.
Making API consumers specify that their literals are unsigned is
slightly annoying, but better than the above alternative.
It would also be nice to change `Scalar::from_hash` to be
`impl<D: Digest<OutputSize = U64>> From<D> for Scalar`,
but this isn't currently allowed by Rust (since that `impl` "could"
conflict with the `impl From<u8>` if someone decided that `u8` should
`impl Digest`).
These traits have the same interface, but with different names, so that it's
not possible to use them interchangeably. (Constant-time and variable-time
routines should not be used interchangeably).
This commit changes the external API to use these traits, replacing
```
edwards::multiscalar_mul
edwards::vartime::multiscalar_mul
```
with
```
EdwardsPoint::multiscalar_mul (as an impl)
EdwardsPoint::vartime_multiscalar_mul (as an impl)
```
and similarly for Ristretto.
Refactoring the backend is for a later commit.
Multiscalar multiplication with precomputation is for a later commit.
The `edwards::vartime` module is retained since it's used for
`vartime_double_base_scalar_mul`.
It should be subsumed into the precomputation API in a later commit.
Since Criterion can only benchmark public API, these changes just drop
all internal benchmarks (e.g., benchmarks for field operations). But
those are usually microbenchmarks whose meaning is kind of questionable
anyways, so I don't think this is a big loss.
The `bench` feature disappears, since Criterion works on stable Rust.