We due this in lieu of implementing `TryFrom` to allow for API
consumers to use the `?` operator to convert potential `None`s into
their own `Result<T, CustomError>` types for better error handling
with less boilerplate.
Note that this is a breaking API change.
This is a breaking change to the serialization format. It fixes it so that the
Serde encoding can match the conventional encoding of each type of object, and
so that Serde can be used with no overhead -- when using serde-bincode, the
Serde encoding now matches the manual encoding.
This ensures that the serde Serialize and Deserialize implementations use
fixed-length Serde tuples, rather than variable-length byte arrays. This flaw
in data modeling was pointed out by Trevor Perrin.
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.
The function `FieldElement::sqrt_ratio_i` always returns a positive root
by definition. Therefore the test for negativity in the edwards point
decompression function always returns false and we only need to flip its
sign if `compressed_sign_bit` is set.
When using Scalar::from_bits to manually create unreduced Scalars (e.g.,
X/Ed25519 keys with specified bit patterns), it's possible to construct Scalar
values that range up to 2^255-1. These shouldn't ever end up in a vartime
multiscalar mul call anyways, because it doesn't handle secret data, but it is
technically allowed by the type system and should be handled. When w=8, these
can generate terminal carries that can't be folded into the last digit, but
this can be handled by folding them into an extra digit instead.
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.
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.
This partially re-adds functionality removed in commit
d2ce1ce5dc
We would like to require ExactSizeIterator, but unfortunately we can't
do that, since ExactSizeIterators aren't chainable, for (in my opinion)
silly reasons (chaining two 4-billion-element ExactSizeIterators could
overflow on 32-bit systems). Instead we inspect the size hints manually
and assert that the lower and upper bounds are all equal.
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.