More small circuit optimisations

- Placing the Poseidon `state` columns after the `partial_sbox` column
  instead of before it causes them to line up with vast stretch of free
  space, enabling the pad-and-add region to be layed out there.

- Using the `Region::assign_advice_from_constant` API to initialise the
  Poseidon state removes fixed-column contention between that region and
  fixed-base scalar multiplication, enabling it to also be layed out
  within the free space.
  - If https://github.com/zcash/halo2/issues/334 were implemented then
    this region would disappear.

- The overflow check in variable-base scalar mul is also moved into the
  columns with free space.
This commit is contained in:
Jack Grigg 2021-07-23 23:13:10 +01:00 committed by therealyingtong
parent 7af1ae5b52
commit 092cc389bb
3 changed files with 13 additions and 14 deletions

View File

@ -241,8 +241,10 @@ impl plonk::Circuit<pallas::Base> for Circuit {
let poseidon_config = PoseidonChip::configure( let poseidon_config = PoseidonChip::configure(
meta, meta,
poseidon::OrchardNullifier, poseidon::OrchardNullifier,
advices[5..8].try_into().unwrap(), // We place the state columns after the partial_sbox column so that the
advices[8], // pad-and-add region can be layed out more efficiently.
advices[6..9].try_into().unwrap(),
advices[5],
rc_a, rc_a,
rc_b, rc_b,
); );

View File

@ -29,10 +29,12 @@ impl From<&EccConfig> for Config {
Self { Self {
q_mul_overflow: ecc_config.q_mul_overflow, q_mul_overflow: ecc_config.q_mul_overflow,
lookup_config: ecc_config.lookup_config.clone(), lookup_config: ecc_config.lookup_config.clone(),
// Use advice columns that don't conflict with the either the incomplete
// additions in fixed-base scalar mul, or the lookup range checks.
advices: [ advices: [
ecc_config.advices[0], ecc_config.advices[6],
ecc_config.advices[1], ecc_config.advices[7],
ecc_config.advices[2], ecc_config.advices[8],
], ],
} }
} }

View File

@ -280,19 +280,12 @@ impl<F: FieldExt, S: Spec<F, WIDTH, 2>> PoseidonDuplexInstructions<F, S, WIDTH,
|| format!("initial state for domain {:?}", domain), || format!("initial state for domain {:?}", domain),
|mut region| { |mut region| {
let mut load_state_word = |i: usize, value: F| { let mut load_state_word = |i: usize, value: F| {
let var = region.assign_advice( let var = region.assign_advice_from_constant(
|| format!("state_{}", i), || format!("state_{}", i),
config.state[i], config.state[i],
0, 0,
|| Ok(value), value,
)?; )?;
let fixed = region.assign_fixed(
|| format!("state_{}", i),
config.rc_b[i],
0,
|| Ok(value),
)?;
region.constrain_equal(var, fixed)?;
Ok(StateWord { Ok(StateWord {
var, var,
value: Some(value), value: Some(value),
@ -754,6 +747,8 @@ mod tests {
meta.fixed_column(), meta.fixed_column(),
]; ];
meta.enable_constant(rc_b[0]);
Pow5T3Chip::configure(meta, OrchardNullifier, state, partial_sbox, rc_a, rc_b) Pow5T3Chip::configure(meta, OrchardNullifier, state, partial_sbox, rc_a, rc_b)
} }