As suggested in #453 it is sometimes feasible to
select the backend bits via an override.
This change provides `cfg(curve25519_dalek_bits)`
to override the bits used in serial or fiat target backend.
As proposed in #414, this commit changes the backend selection approach,
introspecting `target_pointer_width` to select `u32_backend` vs
`u64_backend` (or `fiat_u32_backend`/`fiat_u64_backend` if the
`fiat_backend` feature is enabled).
This helps eliminate the use of non-additive features, and also the
rather confusing errors that happen if multiple backends are selected
(i.e. thousands of lines of rustc errors).
The selection logic checks if `target_pointer_width = "64"` and uses the
64-bit backend, or falls back to the 32-bit backend otherwise. This
means the crate will always have a valid backend regardless of the
pointer width, although there may be odd edge cases for exotic platforms
which would optimally use the 64-bit backend but have a non-"64" target
pointer width for whatever reason. We can handle those cases as they
come up.
Renames fiat backend directory to fiat_u64 and does the additional plumbing required to make fiat_{u32, u64}_backend equal alternatives.
Adds a few comments.
This was more useful at the time when we were determining, e.g., optimal lookup
table sizes and could regenerate them more easily, but it came at a massive
complexity cost. It also meant that we were unable to implement backend
autoselection. This commit removes the `build.rs` entirely. In the future, a
different `build.rs` could be added that auto-selects a backend, but it seems
like the current default-u64 setup has been working fine.
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.
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.
The `MontgomeryPoint` struct is now a point on the Kummer line of the Montgomery curve.
The `ProjectivePoint` struct is made private, since its only purpose is
internal to the Montgomery ladder.
The Montgomery ladder takes affine input, making it faster, and produces affine output.
The Edwards-Montgomery correspondence is simplified.
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.
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.
Having _BASEPOINT_TABLE and _BASEPOINT_POINT means that it's not possible to
use the slow, generic scalar mult in place of the fast, precomputed scalar
mults.
Split the field arithmetic implementations into `FieldElement`,
`FieldElement32`, and `FieldElement64`. `FieldElement` is a type alias for one
of `FieldElement32` or `FieldElement64`, depending on feature selection.
`field.rs` contains tests and code which is generic with respect to the
implementation (e.g., inversions), while `field_32bit.rs` and `field_64bit.rs`
contain the implementation-specific code.
The implementation is not completely hidden, since `FieldElement32` and
`FieldElement64` are tuple structs whose elements are public; `pub(crate)`
doesn't seem to work for tuple structs.
Similarly, the constants file is split over multiple files, depending on the
implementation.