Skip to content

Commit

Permalink
Remove standard PLONK helper.
Browse files Browse the repository at this point in the history
The Action circuit only used standard PLONK in one place. Since it
used non-binary selectors, it cannot be optimised by the halo2
selector optimisations. We now replace it with a custom gate which
uses a binary selector.
  • Loading branch information
therealyingtong committed Jul 23, 2021
1 parent 8cf7a68 commit cba0d86
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 379 deletions.
83 changes: 49 additions & 34 deletions src/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,7 @@ use gadget::{
},
note_commit::NoteCommitConfig,
},
utilities::{
copy,
plonk::{PLONKChip, PLONKConfig, PLONKInstructions},
CellValue, UtilitiesInstructions, Var,
},
utilities::{copy, CellValue, UtilitiesInstructions, Var},
};

use std::convert::TryInto;
Expand Down Expand Up @@ -85,10 +81,11 @@ const ENABLE_OUTPUT: usize = 8;
pub struct Config {
primary: Column<InstanceColumn>,
q_orchard: Selector,
// Selector for the field addition gate poseidon_hash(nk, rho_old) + psi_old.
q_add: Selector,
advices: [Column<Advice>; 10],
ecc_config: EccConfig,
poseidon_config: PoseidonConfig<pallas::Base>,
plonk_config: PLONKConfig,
merkle_config_1: MerkleConfig,
merkle_config_2: MerkleConfig,
sinsemilla_config_1: SinsemillaConfig,
Expand Down Expand Up @@ -186,6 +183,17 @@ impl plonk::Circuit<pallas::Base> for Circuit {
.map(move |(name, poly)| (name, q_orchard.clone() * poly))
});

// Addition of two field elements poseidon_hash(nk, rho_old) + psi_old.
let q_add = meta.selector();
meta.create_gate("poseidon_hash(nk, rho_old) + psi_old", |meta| {
let q_add = meta.query_selector(q_add);
let sum = meta.query_advice(advices[0], Rotation::cur());
let nk_rho_old = meta.query_advice(advices[1], Rotation::cur());
let psi_old = meta.query_advice(advices[2], Rotation::cur());

vec![q_add * (nk_rho_old + psi_old - sum)]
});

// Fixed columns for the Sinsemilla generator lookup table
let table_idx = meta.fixed_column();
let lookup = (table_idx, meta.fixed_column(), meta.fixed_column());
Expand Down Expand Up @@ -239,9 +247,6 @@ impl plonk::Circuit<pallas::Base> for Circuit {
rc_b,
);

// Configuration for standard PLONK (addition and multiplication).
let plonk_config = PLONKChip::configure(meta, [advices[0], advices[1], advices[2]]);

// Configuration for a Sinsemilla hash instantiation and a
// Merkle hash instantiation using this Sinsemilla instance.
// Since the Sinsemilla config uses only 5 advice columns,
Expand Down Expand Up @@ -294,10 +299,10 @@ impl plonk::Circuit<pallas::Base> for Circuit {
Config {
primary,
q_orchard,
q_add,
advices,
ecc_config,
poseidon_config,
plonk_config,
merkle_config_1,
merkle_config_2,
sinsemilla_config_1,
Expand Down Expand Up @@ -504,32 +509,42 @@ impl plonk::Circuit<pallas::Base> for Circuit {
poseidon_output
};

// Add hash output to psi using standard PLONK
// Add hash output to psi.
// `scalar` = poseidon_hash(nk, rho_old) + psi_old.
//
let scalar = {
let scalar_val = nk_rho_old
.value()
.zip(psi_old.value())
.map(|(nk_rho_old, psi_old)| nk_rho_old + psi_old);
let scalar = self.load_private(
layouter.namespace(|| "poseidon_hash(nk, rho_old) + psi_old"),
config.advices[0],
scalar_val,
)?;

config.plonk_chip().add(
layouter.namespace(|| "poseidon_hash(nk, rho_old) + psi_old"),
nk_rho_old,
psi_old,
scalar,
Some(pallas::Base::one()),
Some(pallas::Base::one()),
Some(pallas::Base::one()),
)?;

scalar
};
let scalar = layouter.assign_region(
|| " `scalar` = poseidon_hash(nk, rho_old) + psi_old",
|mut region| {
config.q_add.enable(&mut region, 0)?;

copy(
&mut region,
|| "copy nk_rho_old",
config.advices[1],
0,
&nk_rho_old,
)?;
copy(
&mut region,
|| "copy psi_old",
config.advices[2],
0,
&psi_old,
)?;

let scalar_val = nk_rho_old
.value()
.zip(psi_old.value())
.map(|(nk_rho_old, psi_old)| nk_rho_old + psi_old);
let cell = region.assign_advice(
|| "poseidon_hash(nk, rho_old) + psi_old",
config.advices[0],
0,
|| scalar_val.ok_or(plonk::Error::SynthesisError),
)?;
Ok(CellValue::new(cell, scalar_val))
},
)?;

// Multiply scalar by NullifierK
// `product` = [poseidon_hash(nk, rho_old) + psi_old] NullifierK.
Expand Down
5 changes: 0 additions & 5 deletions src/circuit/gadget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,13 @@ use pasta_curves::pallas;
use ecc::chip::EccChip;
use poseidon::Pow5T3Chip as PoseidonChip;
use sinsemilla::{chip::SinsemillaChip, merkle::chip::MerkleChip};
use utilities::plonk::PLONKChip;

pub(crate) mod ecc;
pub(crate) mod poseidon;
pub(crate) mod sinsemilla;
pub(crate) mod utilities;

impl super::Config {
pub(super) fn plonk_chip(&self) -> PLONKChip<pallas::Base> {
PLONKChip::construct(self.plonk_config.clone())
}

pub(super) fn ecc_chip(&self) -> EccChip {
EccChip::construct(self.ecc_config.clone())
}
Expand Down
1 change: 0 additions & 1 deletion src/circuit/gadget/utilities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use std::{array, convert::TryInto, ops::Range};
pub(crate) mod cond_swap;
pub(crate) mod decompose_running_sum;
pub(crate) mod lookup_range_check;
pub(crate) mod plonk;

/// A variable representing a field element.
#[derive(Copy, Clone, Debug)]
Expand Down
Loading

0 comments on commit cba0d86

Please sign in to comment.