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.
Each backend can now be selected by an individual feature:
- `u32_backend` for `backend::u32`;
- `u64_backend` for `backend::u64`;
- `avx2_backend` for `backend::avx2`;
The `u64_backend` is selected by default, since most people use X64 and we have
no way to select based on target (see discussion in #126). However, these
changes mean that it is possible to select the backend explicitly, and if we
had the ability to select target-default features, we could do so easily.
When building on stable, the README.md is not included in the documentation,
leaving a bare entry. This adds a warning stub, pointing people to use nightly
rust.
Change Scalar::non_adjacent_form() to take a width parameter.
This rewrite also makes it faster, although it's probably a ways off
from optimal. I don't know how much it matters.
TODO: write up description of why this computes the same thing.
Thanks to @oleganza for pointing out an error reading bits across words
in an earlier version of this code.
This change required some work, because the to-be-stabilized SIMD functions
don't allow non-constant `imm8`s. Previously, the `stdsimd` functions had a
constifying macro that ensured that the immediates were known. The dalek code
used this to build helper functions which would be inlined into different
places where the immediates were known. Unfortunately, since constexprs aren't
fully supported in Rust yet, this is done by a hidden compiler attribute, and
there's no way to propagate "constness".
To deal with this, some of the functions are specialized (e.g.,
`square_and_negate_D` instead of taking a mask), and others use an enum.
The serial (`u32`/`u64`) implementations use a multiple curve models, passing
between extended and projective coordinates when performing addition and
doubling (respectively). But the AVX2 backend doesn't, so in order to write a
single scalar mult implementation, we have to either abstract over the curve
models or have two implementations.
A generic solution is possible but extremely unreadable: the scalar mul
implementation would be parameterized over the point types used by the serial
implementations, with many where clauses describing how the types relate. The
AVX2 types could then be substituted in the appropriate places.
Instead we just duplicate the code into the `avx2` backend.
This should contain generic implementations of scalar multiplication algorithms
that can be used with multiple backends. The goal is to move the existing
scalar multiplication code into this submodule, then call it from the
user-facing API. This can also contain code for things we can't do now, like
multiscalar multiplication with precomputation.
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.