`PrimeField::from_repr` explicitly leaves the endianness opaque. We
therefore can't use it in places we were using `FieldExt::from_bytes`
(which was specifically little-endian) generically, but the previous
commit replaced it everywhere. We now handle generic contexts on a
case-by-case basis:
- Where we needed to convert bitstrings into field elements, we now use
double-and-add on the field elements directly instead of on bytes.
This is less efficient, but visible correct (and a future change to
the `ff` crate APIs could enable the more efficient version).
- `INV_TWO_POW_K`, which is pre-computed for `pallas::Base`, was being
incorrectly used in a field-generic circuit. We now compute it live.
- `test_zs_and_us` was only used in tests, and hard-coded a field
element encoding length of 32 bytes. It now uses Pallas concretely.
In the Orchard protocol, only the NullifierK fixed base in used in
scalar multiplication with a base field element.
The mul_fixed_base_field_elem() API does not have to accept fixed
bases other than NullifierK; conversely, NullifierK does not have
to work with the full-width mul_fixed() API.
This uses the complete addition instruction internally. The module
is split up into mul::incomplete.rs and mul::complete.rs, where
mul::incomplete handles the incomplete additions used in the
starting rounds of the variable-base scalar mul algorithm, and
mul::complete handles the complete additions in the final rounds.
Incomplete additions are broken into "hi" and "lo" halves and
processed on the same rows across different columns. This is an
optimization to make full use of the advice columns in this
instruction.
- document that find_zs_and_us is not meant to be used anywhere
- use F::zero() instead of F::default() in constants/util.rs
- use personalisations from constants in spec.rs
Also test that L_ORCHARD_BASE, L_ORCHARD_SCALAR, L_ORCHARD_MERKLE
are consistent with the Pallas curve.
Co-authored-by: Jack Grigg <jack@electriccoin.co>
Previously, the window table M for fixed-base scalar multiplication
computed M[w][k] = [(k+1)*(2^3)^w]B for each window w, where k is a
3-bit chunk in the scalar decomposition in the range [0..8).
However, in the case k_0 = 7, k_1= 0, the window table entries would
evaluate to:
* M[0][k_0] = [(7+1)*(2^3)^0]B = [8]B,
* M[1][k_1] = [(0+1)*(2^3)^1]B = [8]B,
which means the first addition would require complete addition.
To avoid this, we alter the formula to M[w][k] = [(k+2)*(2^3)^w]B.
We make a corresponding change to the formula for the last window
W. Previously, we had:
M[W][k] = [k * (2^3)^W - \sum((2^3)^j)]B, for j in [0..W-1).
Now, we have:
M[W][k] = [k * (2^3)^W - \sum(2^(3j+1))]B, for j in [0..W-1).