Previously, l_plus_1 was a non-binary fixed column, used to
1. provide the value of l + 1; and
2. toggle the decomposition gate.
Now, the value is copied in from the global constants column, and
the toggle is handled by a binary q_decompose selector.
Previously, fixed_y_q was a non-binary selector that both loaded
the y_Q value and toggled the y_Q gate.
Now, the gate is toggled by a q_s4 simple selector, while the value
is loaded into a separate fixed column.
The Sinsemilla chip witnesses message pieces in individual regions, and
then copies them into the `hash_piece` region to initialize the running
sum. Previously these occured in the same column, but we can reduce the
utilized rows of the Action circuit by moving these into a less-used
column.
If https://github.com/zcash/halo2/issues/334 is implemented, this change
would be unnecessary, as the witnessed message piece regions would never
be assigned into the circuit.
We were configuring multiple instances of this across all of the advice
columns, in order to spread their assignments. However, we are actually
more constrained by columns than rows, and we have comparatively few
rows of range check logic required for the Action circuit.
We now use a single LookupRangeCheckConfig for the entire circuit. The
reduction in lookup arguments and fixed columns cuts the proof size in
half (now at 6048 bytes when using `floor_planner::V1`).
Co-authored-by: therealyingtong <yingtong@z.cash>
- Move Poseidon into the right-hand advice columns. The Action circuit
has 33 Sinsemilla invocations with 510-bit inputs (the 32 Merkle path
hashes, and Commit^ivk). Poseidon fits within the row count of one of
these invocations, so we can run it in parallel with these.
- Share fixed columns between ECC and Poseidon chips. Poseidon requires
four advice columns, while ECC incomplete addition requires six, so we
could choose to configure them in parallel. However, we only use a
single Poseidon invocation, and we have the rows to accomodate it
serially with fixed-base scalar mul. Sharing the ECC chip's 8 Lagrange
coefficient fixed columns instead reduces the proof size.
- We position Poseidon in the right-most 6 fixed columns, anticipating
a further optimisation to Sinsemilla that will occupy the left-most
2 fixed columns.
The Action Circuit configuration uses 10 advice columns. It contains:
- a single EccConfig (10 advice columns);
- two SinsemillaConfigs (5 advice columns each);
- two MerkleConfigs (5 advice columns each);
- a PoseidonConfig, (4 advice columns);
- a PLONKConfig for standard PLONK operations (3 advice columns);
and some infrastructure to handle public inputs (subject to change
at the time of commit).
The 5-column configs are placed side-by-side in the circuit to
optimize space usage.
Gate creation is delegated to the configure() function of each
respective Chip.
- `halo2::plonk::{create_proof, verify_proof}` now take instance columns
as slices of values.
- `halo2::plonk::Permutation` has been replaced by a global permutation,
to which columns can be added with `ConstraintSystem::enable_equality`.
- The introduction of blinding rows means that various tests now require
larger circuit parameters.
This has three const generic parameters: PATH_LENGTH, K, MAX_WORDS.
PATH_LENGTH is the length of the Merkle path being hashed. K and
MAX_WORDS parameterize the internal Sinsemilla instance used in
hashing the path.
These instructions were not making any assignments; instead, they
were calling through to witness_message_piece_field().
This PR also renames the witness_message_piece_field() instruction
to witness_message_piece().
hash_piece() is an internal API, which means its caller hash_message()
is working in the same region. We rely on the caller to have already
assigned each piece's initial x_a at the correct offset before making
the call to hash_piece().
Co-authored-by: Jack Grigg <jack@electriccoin.co>
This toggles the assignment of q_s2 on the last row of each piece.
We assign q_s2 = 2 on the last row of the final piece, and q_s2 = 0
on the last row of other pieces.
This allows us to process the final_piece in the main loop together
with the other pieces.
Co-authored-by: Jack Grigg <jack@electriccoin.co>
Also, GeneratorTable::configure() was not being called in the main
SinsemillaChip::configure(), which meant the lookup argument had
not been activated. This has now been fixed.
Co-authored-by: Jack Grigg <jack@electriccoin.co>
witness_message() witnesses a full message given a bitstring.
The other two APIs, witness_message_piece_bitstring() and
witness_message_piece_field(), both witness a message piece, i.e.
part of a message that fits within a single base field element.
witness_message_piece_bitstring() takes in a bitstring, while
witness_message_piece_field() takes in a field element. In the
latter case, the number of words encoded must be specified.