mirror of https://github.com/zcash/halo2.git
merkle: Replace l_plus_1 fixed column with q_decompose selector.
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.
This commit is contained in:
parent
f532ecec10
commit
29f185014f
|
@ -62,5 +62,5 @@ name = "small"
|
|||
harness = false
|
||||
|
||||
[patch.crates-io]
|
||||
halo2 = { git = "https://github.com/zcash/halo2.git", rev = "62f088e2f249dfce2c3bcab7321cba0d99697af9" }
|
||||
halo2 = { git = "https://github.com/zcash/halo2.git", rev = "92645b6ee9a2a91649bf22caebe5b1017ff67198" }
|
||||
zcash_note_encryption = { git = "https://github.com/zcash/librustzcash.git", rev = "cc533a9da4f6a7209a7be05f82b12a03969152c9" }
|
||||
|
|
|
@ -500,7 +500,7 @@ pub mod tests {
|
|||
},
|
||||
VerifyFailure::Permutation {
|
||||
column: (Any::Fixed, 9).into(),
|
||||
row: 2
|
||||
row: 0
|
||||
},
|
||||
VerifyFailure::Permutation {
|
||||
column: (Any::Advice, 4).into(),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use halo2::{
|
||||
circuit::{Chip, Layouter},
|
||||
plonk::{Advice, Column, ConstraintSystem, Error, Expression, Fixed},
|
||||
plonk::{Advice, Column, ConstraintSystem, Error, Expression, Selector},
|
||||
poly::Rotation,
|
||||
};
|
||||
use pasta_curves::{arithmetic::FieldExt, pallas};
|
||||
|
@ -25,7 +25,7 @@ use std::array;
|
|||
#[derive(Clone, Debug)]
|
||||
pub struct MerkleConfig {
|
||||
advices: [Column<Advice>; 5],
|
||||
l_plus_1: Column<Fixed>,
|
||||
q_decompose: Selector,
|
||||
pub(super) cond_swap_config: CondSwapConfig,
|
||||
pub(super) sinsemilla_config: SinsemillaConfig,
|
||||
}
|
||||
|
@ -57,13 +57,8 @@ impl MerkleChip {
|
|||
let advices = sinsemilla_config.advices();
|
||||
let cond_swap_config = CondSwapChip::configure(meta, advices);
|
||||
|
||||
// This fixed column serves two purposes:
|
||||
// - Fixing the value of l* for rows in which a Merkle path layer
|
||||
// is decomposed.
|
||||
// - Disabling the entire decomposition gate when set to zero
|
||||
// (i.e. replacing a Selector).
|
||||
|
||||
let l_plus_1 = meta.fixed_column();
|
||||
// This selector enables the decomposition gate.
|
||||
let q_decompose = meta.selector();
|
||||
|
||||
// Check that pieces have been decomposed correctly for Sinsemilla hash.
|
||||
// <https://zips.z.cash/protocol/protocol.pdf#orchardmerklecrh>
|
||||
|
@ -78,13 +73,14 @@ impl MerkleChip {
|
|||
//
|
||||
/*
|
||||
The pieces and subpieces are arranged in the following configuration:
|
||||
| A_0 | A_1 | A_2 | A_3 | A_4 | l_plus_1 |
|
||||
----------------------------------------------------
|
||||
| a | b | c | left | right | l + 1 |
|
||||
| z1_a | z1_b | b_1 | b_2 | | |
|
||||
| A_0 | A_1 | A_2 | A_3 | A_4 | q_decompose |
|
||||
-------------------------------------------------------
|
||||
| a | b | c | left | right | 1 |
|
||||
| z1_a | z1_b | b_1 | b_2 | l + 1 | |
|
||||
*/
|
||||
meta.create_gate("Decomposition check", |meta| {
|
||||
let l_plus_1_whole = meta.query_fixed(l_plus_1, Rotation::cur());
|
||||
let q_decompose = meta.query_selector(q_decompose);
|
||||
let l_plus_1_whole = meta.query_advice(advices[4], Rotation::next());
|
||||
|
||||
let two_pow_5 = pallas::Base::from_u64(1 << 5);
|
||||
let two_pow_10 = two_pow_5.square();
|
||||
|
@ -146,12 +142,12 @@ impl MerkleChip {
|
|||
("right_check", right_check),
|
||||
("b1_b2_check", b1_b2_check),
|
||||
])
|
||||
.map(move |(name, poly)| (name, l_plus_1_whole.clone() * poly))
|
||||
.map(move |(name, poly)| (name, q_decompose.clone() * poly))
|
||||
});
|
||||
|
||||
MerkleConfig {
|
||||
advices,
|
||||
l_plus_1,
|
||||
q_decompose,
|
||||
cond_swap_config,
|
||||
sinsemilla_config,
|
||||
}
|
||||
|
@ -270,10 +266,10 @@ impl MerkleInstructions<pallas::Affine, MERKLE_DEPTH_ORCHARD, { sinsemilla::K },
|
|||
// Check that the pieces have been decomposed properly.
|
||||
/*
|
||||
The pieces and subpieces are arranged in the following configuration:
|
||||
| A_0 | A_1 | A_2 | A_3 | A_4 | l_plus_1 |
|
||||
----------------------------------------------------
|
||||
| a | b | c | left | right | l + 1 |
|
||||
| z1_a | z1_b | b_1 | b_2 | | |
|
||||
| A_0 | A_1 | A_2 | A_3 | A_4 | q_decompose |
|
||||
-------------------------------------------------------
|
||||
| a | b | c | left | right | 1 |
|
||||
| z1_a | z1_b | b_1 | b_2 | l + 1 | |
|
||||
*/
|
||||
{
|
||||
layouter.assign_region(
|
||||
|
@ -283,11 +279,12 @@ impl MerkleInstructions<pallas::Affine, MERKLE_DEPTH_ORCHARD, { sinsemilla::K },
|
|||
// Recall that l = MERKLE_DEPTH_ORCHARD - layer - 1.
|
||||
// The layer with 2^n nodes is called "layer n".
|
||||
let l_plus_1 = (l as u64) + 1;
|
||||
region.assign_fixed(
|
||||
config.q_decompose.enable(&mut region, 0)?;
|
||||
region.assign_advice_from_constant(
|
||||
|| format!("l_plus_1 {}", l_plus_1),
|
||||
config.l_plus_1,
|
||||
0,
|
||||
|| Ok(pallas::Base::from_u64(l_plus_1)),
|
||||
config.advices[4],
|
||||
1,
|
||||
pallas::Base::from_u64(l_plus_1),
|
||||
)?;
|
||||
|
||||
// Offset 0
|
||||
|
|
Loading…
Reference in New Issue