This begins to attempt to restructure the source tree so that the common parts
are common and the different parts are different.
The backend is now split into two parts:
- serial (containing the implementation using serial formulas and mixed-model arithmetic).
- vector (containing the implementation using parallel formulas and single-model arithmetic).
The serial scalar_mul tree is now under backend::serial::scalar_mul.
The avx2 scalar_mul tree is now under backend::avx2::scalar_mul.
`FieldElement32` -> `FieldElement2625`
`FieldElement64` -> `FieldElement51`
`Scalar32` -> `Scalar29`
`Scalar64` -> `Scalar52`
This naming is more accurate and would let us add an ADX backend later.
Vicariously updates to `generic-array` 0.12, however this change also
removes `generic-array` as a direct dependency, as it can be sourced
from the `digest` crate.
This change provides a common convention for using allocator-dependent
features with:
#![cfg(feature = "alloc")]
When available, `Vec` is imported consistently as `prelude::Vec`, which
means modules that need access to `Vec` can simply do:
use prelude::*;
and if an allocator is available, `Vec` will be in the crate prelude.
This allows all `alloc` vs `std` gating to be handled in `lib.rs`,
`build.rs`, and `prelude.rs` so the rest of the codebase doesn't have to
do any gating whatsoever.
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`).
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.
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.
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.
These were originally added in 32da4c7d50
to implement Scalar negation in terms of multiply-add.
But we have a full implementation of scalar arithmetic now, so it's not
necessary to keep the constants around.
The public-facing types with arithmetic operations are:
- `Scalar`s
- `ExtendedPoint`s
- `RistrettoPoint`s
For these types we define operators with all combinations of borrowed and
non-borrowed inputs, to avoid forcing API consumers to write extra ampersands.
Since all of the operations involved with these types are expensive relative to
the cost of an unnecessary copy, this isn't a big deal.
The `MontgomeryPoint` struct isn't included in the above because it's only
useful for scalar multiplication.
This commit is based on work by @UnlawfulMonad.
This commit defines a Scalar to hold an integer representing an element of
Z/lZ. Applications like X/Ed25519 that care about the bit-patterns of the
scalars they use can set a specific bit-pattern using the `from_bits`
constructor. Applications that want to treat scalars as integers mod l can use
the `from_bytes_mod_order` constructor. Either way, the constructor ensures
that the integer representing each Scalar is bounded by 2^255 so that the high
bit is set. This means that any Scalar object is always safe to use for scalar
multiplication, while maintaining compatibility with both the Ristretto
use-case and the X/Ed25519 usecase.
This reverts commit 804dab8924, reversing
changes made to 5d15ca77ff.
This is due to a (previously undocumented) contract on the behaviours of
(potentially unreduced mod \ell) "packed" scalars w.r.t. to the manner in which
their bytes are interpreted.
Upon documentation fixes and corresponding fixes being made on top of the
floodyberry/optimized_scalar branch, this revert will again be reverted and then
the additional changes merged (à la
file:///usr/share/doc/git/html/howto/revert-a-faulty-merge.html).
Signed-off-by: Isis Lovecruft <isis@patternsinthevoid.net>
Make the 2 digit, `_10`, the first argument to more closely match the
Haskell code in the source article. Align the code into columns to
further clarify the patterns.