The mul_fixed regions use complete addition on the last window,
and incomplete addition on all other windows. However, the complete
addition does not depend on any offsets in the incomplete addition
region, and can be separated into a disjoint region. Since incomplete
addition uses only four advice columns, while complete addition uses
nine, separating the regions would allow the layouter to optimise
their placement.
Co-authored-by: Jack Grigg <jack@electriccoin.co>
We can use the three-bit existing running sum decomposition to
constrain alpha_0 to be within 130 bits. This removes the need for
a 10-bit lookup decomposition of alpha_0.
Co-authored-by: Daira Hopwood <daira@jacaranda.org>
The differences between the final iteration and prior iterations are:
- The final iteration does not constrain (x_T, y_T) to propagate down.
- The final iteration constrains an assigned y_A output instead of a
derived y_A from the next iteration's variables.
We also swap the init_y constraint to match the book.
Co-authored-by: therealyingtong <yingtong@z.cash>
At certain points in the circuit, we need to constrain cells in
advice columns to equal a fixed constant. Instead of defining a
new fixed column for each constant, we pass around a single
shared by all chips, that is included in the permutation over all
advice columns.
This lets us load all needed constants into a single column and
directly constrain advice cells with an equality constraint.
On the LSB of the scalar, we assign a point (x,y) = (x_p, -y_p)
if LSB = 0, and (0,0) otherwise. This if/else condition must be
enforced.
Co-authored-by: Sean Bowe <ewillbefull@gmail.com>
Using these in `OrchardFixedBases::{generator, u}` instead of the
`impl From<OrchardFixedBasesFull> for OrchardFixedBase` means we avoid
computing the Lagrange coefficients for the generator (which were then
immediately dropped).
This decreases proving time in the Action circuit by 53%.
In Orchard nullifier derivation, we multiply the fixed base
K^Orchard by a value encoded as a base field element. This commit
introduces an API that allows using a base field element as the
"scalar" in fixed-base scalar multiplication.
The API currently assumes that the base field element is output by
another instruction (i.e. there is no instruction to directly
witness it).
The magnitude of the short signed scalar must be 64 bits. We decompose
the magnitude into 22 3-bit windows and check that each window is in
the 3-bit range.
However, since the first 21 windows have already accounted for 63 bits,
the last window is constrained to be a single bit.
Simplify the canonicity check for variable-base scalar multiplication,
by range-checking the low 130 bits rather than the low 127 bits.
Signed-off-by: Daira Hopwood <daira@jacaranda.org>
Co-authored-by: ying tong <yingtong@z.cash>
Fixed-base scalar mul makes use of the add_incomplete and add
instructions internally. The full-width and short signed share
some common logic, which is captured in chip::mul_fixed.rs.
The signed short variant introduces additional logic to handle
the scalar's sign. This is done in the submodule mul_fixed::short.
A scalar used in fixed-base scalar mul needs to be decomposed into
windows to use with the fixed-base window table. Both full-width
and short signed scalars share some logic (captured in the function
decompose_scalar_fixed()).
A short signed scalar introduces additional logic: its magnitude is
decomposed, and its sign is separately witnessed. This is handled
in the submodule witness_scalar_fixed::short.
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.