diff --git a/Cargo.toml b/Cargo.toml index 663e7ccc..1a575ec6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -62,5 +62,5 @@ name = "small" harness = false [patch.crates-io] -halo2 = { git = "https://github.com/zcash/halo2.git", rev = "d5be50a8488a433a9b20f1127ff1e21f121c5a2c" } +halo2 = { git = "https://github.com/zcash/halo2.git", rev = "4a9e329ded1c54347af105210c77587bb69f3c57" } zcash_note_encryption = { git = "https://github.com/zcash/librustzcash.git", rev = "cc533a9da4f6a7209a7be05f82b12a03969152c9" } diff --git a/src/circuit.rs b/src/circuit.rs index 3203b0d4..88ecb94e 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -2,11 +2,10 @@ use std::mem; -use group::Curve; use halo2::{ circuit::{Layouter, SimpleFloorPlanner}, plonk, - poly::{EvaluationDomain, LagrangeCoeff, Polynomial, Rotation}, + poly::Rotation, transcript::{Blake2bRead, Blake2bWrite}, }; use pasta_curves::{pallas, vesta}; @@ -107,21 +106,9 @@ pub struct Instance { } impl Instance { - fn to_halo2_instance( - &self, - domain: &EvaluationDomain, - ) -> [Polynomial; 1] { + fn to_halo2_instance(&self) -> [[vesta::Scalar; 0]; 1] { // TODO - [domain.empty_lagrange()] - } - - fn to_halo2_instance_commitments(&self, vk: &VerifyingKey) -> [vesta::Affine; 1] { - [vk.params - .commit_lagrange( - &self.to_halo2_instance(vk.vk.get_domain())[0], - Default::default(), - ) - .to_affine()] + [[]] } } @@ -149,9 +136,10 @@ impl Proof { circuits: &[Circuit], instances: &[Instance], ) -> Result { - let instances: Vec<_> = instances + let instances: Vec<_> = instances.iter().map(|i| i.to_halo2_instance()).collect(); + let instances: Vec> = instances .iter() - .map(|i| i.to_halo2_instance(pk.pk.get_vk().get_domain())) + .map(|i| i.iter().map(|c| &c[..]).collect()) .collect(); let instances: Vec<_> = instances.iter().map(|i| &i[..]).collect(); @@ -162,9 +150,10 @@ impl Proof { /// Verifies this proof with the given instances. pub fn verify(&self, vk: &VerifyingKey, instances: &[Instance]) -> Result<(), plonk::Error> { - let instances: Vec<_> = instances + let instances: Vec<_> = instances.iter().map(|i| i.to_halo2_instance()).collect(); + let instances: Vec> = instances .iter() - .map(|i| i.to_halo2_instance_commitments(vk)) + .map(|i| i.iter().map(|c| &c[..]).collect()) .collect(); let instances: Vec<_> = instances.iter().map(|i| &i[..]).collect(); @@ -241,9 +230,9 @@ mod tests { K, circuit, instance - .to_halo2_instance(vk.vk.get_domain()) + .to_halo2_instance() .iter() - .map(|p| p.iter().cloned().collect()) + .map(|p| p.to_vec()) .collect() ) .unwrap() diff --git a/src/circuit/gadget/ecc.rs b/src/circuit/gadget/ecc.rs index 46237feb..70025440 100644 --- a/src/circuit/gadget/ecc.rs +++ b/src/circuit/gadget/ecc.rs @@ -422,18 +422,10 @@ mod tests { meta.advice_column(), meta.advice_column(), ]; - let constants = [meta.fixed_column(), meta.fixed_column()]; - let perm = meta.permutation( - &advices - .iter() - .map(|advice| (*advice).into()) - .chain(constants.iter().map(|fixed| (*fixed).into())) - .collect::>(), - ); - let lookup_table = meta.fixed_column(); - EccChip::configure(meta, advices, lookup_table, constants, perm) + + EccChip::configure(meta, advices, lookup_table, constants) } fn synthesize( diff --git a/src/circuit/gadget/ecc/chip.rs b/src/circuit/gadget/ecc/chip.rs index 4850e82d..1f4533b9 100644 --- a/src/circuit/gadget/ecc/chip.rs +++ b/src/circuit/gadget/ecc/chip.rs @@ -12,7 +12,7 @@ use arrayvec::ArrayVec; use group::prime::PrimeCurveAffine; use halo2::{ circuit::{Chip, Layouter}, - plonk::{Advice, Column, ConstraintSystem, Error, Fixed, Permutation, Selector}, + plonk::{Advice, Column, ConstraintSystem, Error, Fixed, Selector}, }; use pasta_curves::{arithmetic::CurveAffine, pallas}; @@ -111,12 +111,8 @@ pub struct EccConfig { /// Witness point pub q_point: Selector, - /// Shared fixed column used for loading constants. This is included in - /// the permutation so that cells in advice columns can be constrained to - /// equal cells in this fixed column. + /// Shared fixed column used for loading constants. pub constants: Column, - /// Permutation over all advice columns and the `constants` fixed column. - pub perm: Permutation, /// Lookup range check using 10-bit lookup table pub lookup_config: LookupRangeCheckConfig, /// Running sum decomposition. @@ -151,6 +147,9 @@ impl EccChip { Self { config } } + /// # Side effects + /// + /// All columns in `advices` and `constants` will be equality-enabled. #[allow(non_snake_case)] pub fn configure( meta: &mut ConstraintSystem, @@ -158,18 +157,48 @@ impl EccChip { lookup_table: Column, // TODO: Replace with public inputs API constants: [Column; 2], - perm: Permutation, ) -> >::Config { - let lookup_config = LookupRangeCheckConfig::configure( - meta, - advices[9], - constants[0], - lookup_table, - perm.clone(), - ); + // The following columns need to be equality-enabled for their use in sub-configs: + // + // add::Config and add_incomplete::Config: + // - advices[0]: x_p, + // - advices[1]: y_p, + // - advices[2]: x_qr, + // - advices[3]: y_qr, + // + // mul_fixed::Config: + // - advices[4]: window + // - advices[5]: u + // + // mul_fixed::base_field_element::Config: + // - [advices[6], advices[7], advices[8]]: canon_advices + // + // mul::overflow::Config: + // - [advices[0], advices[1], advices[2]]: advices + // + // mul::incomplete::Config + // - advices[4]: lambda1 + // - advices[9]: z + // + // mul::complete::Config: + // - advices[9]: z_complete + // + // I have not yet figured out where constants[1] is used in an equality constraint + // but we get synthesis errors without it. + // + // TODO: Refactor away from `impl From for _` so that sub-configs can + // equality-enable the columns they need to. + for column in &advices { + meta.enable_equality((*column).into()); + } + // constants[0] is also equality-enabled here. + let lookup_config = + LookupRangeCheckConfig::configure(meta, advices[9], constants[0], lookup_table); + meta.enable_equality(constants[1].into()); + let q_mul_fixed_running_sum = meta.selector(); let running_sum_config = - RunningSumConfig::configure(meta, q_mul_fixed_running_sum, advices[4], perm.clone()); + RunningSumConfig::configure(meta, q_mul_fixed_running_sum, advices[4]); let config = EccConfig { advices, @@ -197,7 +226,6 @@ impl EccChip { q_mul_fixed_running_sum, q_point: meta.selector(), constants: constants[1], - perm, lookup_config, running_sum_config, }; @@ -323,14 +351,13 @@ impl EccInstructions for EccChip { a: &Self::Point, b: &Self::Point, ) -> Result<(), Error> { - let config = self.config().clone(); layouter.assign_region( || "constrain equal", |mut region| { // Constrain x-coordinates - region.constrain_equal(&config.perm, a.x().cell(), b.x().cell())?; + region.constrain_equal(a.x().cell(), b.x().cell())?; // Constrain x-coordinates - region.constrain_equal(&config.perm, a.y().cell(), b.y().cell()) + region.constrain_equal(a.y().cell(), b.y().cell()) }, ) } diff --git a/src/circuit/gadget/ecc/chip/add.rs b/src/circuit/gadget/ecc/chip/add.rs index d2d47f12..f1d76245 100644 --- a/src/circuit/gadget/ecc/chip/add.rs +++ b/src/circuit/gadget/ecc/chip/add.rs @@ -5,7 +5,7 @@ use ff::Field; use halo2::{ arithmetic::BatchInvert, circuit::Region, - plonk::{Advice, Column, ConstraintSystem, Error, Expression, Permutation, Selector}, + plonk::{Advice, Column, ConstraintSystem, Error, Expression, Selector}, poly::Rotation, }; use pasta_curves::{arithmetic::FieldExt, pallas}; @@ -32,8 +32,6 @@ pub struct Config { gamma: Column, // δ = inv0(y_p + y_q) if x_q = x_p, 0 otherwise delta: Column, - // Permutation - perm: Permutation, } impl From<&EccConfig> for Config { @@ -49,7 +47,6 @@ impl From<&EccConfig> for Config { beta: ecc_config.advices[6], gamma: ecc_config.advices[7], delta: ecc_config.advices[8], - perm: ecc_config.perm.clone(), } } } @@ -208,12 +205,12 @@ impl Config { self.q_add.enable(region, offset)?; // Copy point `p` into `x_p`, `y_p` columns - copy(region, || "x_p", self.x_p, offset, &p.x, &self.perm)?; - copy(region, || "y_p", self.y_p, offset, &p.y, &self.perm)?; + copy(region, || "x_p", self.x_p, offset, &p.x)?; + copy(region, || "y_p", self.y_p, offset, &p.y)?; // Copy point `q` into `x_qr`, `y_qr` columns - copy(region, || "x_q", self.x_qr, offset, &q.x, &self.perm)?; - copy(region, || "y_q", self.y_qr, offset, &q.y, &self.perm)?; + copy(region, || "x_q", self.x_qr, offset, &q.x)?; + copy(region, || "y_q", self.y_qr, offset, &q.y)?; let (x_p, y_p) = (p.x.value(), p.y.value()); let (x_q, y_q) = (q.x.value(), q.y.value()); diff --git a/src/circuit/gadget/ecc/chip/add_incomplete.rs b/src/circuit/gadget/ecc/chip/add_incomplete.rs index 325f2792..e846f19a 100644 --- a/src/circuit/gadget/ecc/chip/add_incomplete.rs +++ b/src/circuit/gadget/ecc/chip/add_incomplete.rs @@ -4,7 +4,7 @@ use super::{copy, CellValue, EccConfig, EccPoint, Var}; use group::Curve; use halo2::{ circuit::Region, - plonk::{Advice, Column, ConstraintSystem, Error, Permutation, Selector}, + plonk::{Advice, Column, ConstraintSystem, Error, Selector}, poly::Rotation, }; use pasta_curves::{arithmetic::CurveAffine, pallas}; @@ -20,8 +20,6 @@ pub struct Config { pub x_qr: Column, // y-coordinate of Q or R in P + Q = R pub y_qr: Column, - // Permutation - perm: Permutation, } impl From<&EccConfig> for Config { @@ -32,7 +30,6 @@ impl From<&EccConfig> for Config { y_p: ecc_config.advices[1], x_qr: ecc_config.advices[2], y_qr: ecc_config.advices[3], - perm: ecc_config.perm.clone(), } } } @@ -99,12 +96,12 @@ impl Config { .transpose()?; // Copy point `p` into `x_p`, `y_p` columns - copy(region, || "x_p", self.x_p, offset, &p.x, &self.perm)?; - copy(region, || "y_p", self.y_p, offset, &p.y, &self.perm)?; + copy(region, || "x_p", self.x_p, offset, &p.x)?; + copy(region, || "y_p", self.y_p, offset, &p.y)?; // Copy point `q` into `x_qr`, `y_qr` columns - copy(region, || "x_q", self.x_qr, offset, &q.x, &self.perm)?; - copy(region, || "y_q", self.y_qr, offset, &q.y, &self.perm)?; + copy(region, || "x_q", self.x_qr, offset, &q.x)?; + copy(region, || "y_q", self.y_qr, offset, &q.y)?; // Compute the sum `P + Q = R` let r = { diff --git a/src/circuit/gadget/ecc/chip/mul.rs b/src/circuit/gadget/ecc/chip/mul.rs index c6e81d41..57d99913 100644 --- a/src/circuit/gadget/ecc/chip/mul.rs +++ b/src/circuit/gadget/ecc/chip/mul.rs @@ -7,7 +7,7 @@ use ff::PrimeField; use halo2::{ arithmetic::FieldExt, circuit::{Layouter, Region}, - plonk::{Column, ConstraintSystem, Error, Expression, Fixed, Permutation, Selector}, + plonk::{Column, ConstraintSystem, Error, Expression, Fixed, Selector}, poly::Rotation, }; @@ -44,8 +44,6 @@ pub struct Config { constants: Column, // Selector used to check switching logic on LSB q_mul_lsb: Selector, - // Permutation - perm: Permutation, // Configuration used in complete addition add_config: add::Config, // Configuration used for `hi` bits of the scalar @@ -63,7 +61,6 @@ impl From<&EccConfig> for Config { let config = Self { constants: ecc_config.constants, q_mul_lsb: ecc_config.q_mul_lsb, - perm: ecc_config.perm.clone(), add_config: ecc_config.into(), hi_config: ecc_config.into(), lo_config: ecc_config.into(), @@ -318,7 +315,6 @@ impl Config { self.add_config.x_p, offset + 1, &base.x(), - &self.perm, )?; copy( region, @@ -326,7 +322,6 @@ impl Config { self.add_config.y_p, offset + 1, &base.y(), - &self.perm, )?; // If `lsb` is 0, return `Acc + (-P)`. If `lsb` is 1, simply return `Acc + 0`. diff --git a/src/circuit/gadget/ecc/chip/mul/complete.rs b/src/circuit/gadget/ecc/chip/mul/complete.rs index 0c80644f..67521560 100644 --- a/src/circuit/gadget/ecc/chip/mul/complete.rs +++ b/src/circuit/gadget/ecc/chip/mul/complete.rs @@ -3,7 +3,7 @@ use super::{COMPLETE_RANGE, X, Y, Z}; use halo2::{ circuit::Region, - plonk::{Advice, Column, ConstraintSystem, Error, Expression, Permutation, Selector}, + plonk::{Advice, Column, ConstraintSystem, Error, Expression, Selector}, poly::Rotation, }; @@ -14,8 +14,6 @@ pub struct Config { q_mul_decompose_var: Selector, // Advice column used to decompose scalar in complete addition. pub z_complete: Column, - // Permutation - perm: Permutation, // Configuration used in complete addition add_config: add::Config, } @@ -25,7 +23,6 @@ impl From<&EccConfig> for Config { let config = Self { q_mul_decompose_var: ecc_config.q_mul_decompose_var, z_complete: ecc_config.advices[9], - perm: ecc_config.perm.clone(), add_config: ecc_config.into(), }; @@ -113,7 +110,6 @@ impl Config { self.z_complete, offset, &z, - &self.perm, )?; Z(z) }; @@ -150,7 +146,6 @@ impl Config { self.z_complete, row + offset + 1, &base.y, - &self.perm, )?; // If the bit is set, use `y`; if the bit is not set, use `-y` diff --git a/src/circuit/gadget/ecc/chip/mul/incomplete.rs b/src/circuit/gadget/ecc/chip/mul/incomplete.rs index 534d5e8b..4d4251eb 100644 --- a/src/circuit/gadget/ecc/chip/mul/incomplete.rs +++ b/src/circuit/gadget/ecc/chip/mul/incomplete.rs @@ -5,9 +5,7 @@ use super::{INCOMPLETE_HI_RANGE, INCOMPLETE_LO_RANGE, X, Y, Z}; use ff::Field; use halo2::{ circuit::Region, - plonk::{ - Advice, Column, ConstraintSystem, Error, Expression, Fixed, Permutation, VirtualCells, - }, + plonk::{Advice, Column, ConstraintSystem, Error, Expression, Fixed, VirtualCells}, poly::Rotation, }; @@ -30,8 +28,6 @@ pub(super) struct Config { pub(super) lambda1: Column, // lambda2 in each double-and-add iteration. pub(super) lambda2: Column, - // Permutation - pub(super) perm: Permutation, } // Columns used in processing the `hi` bits of the scalar. @@ -48,7 +44,6 @@ impl From<&EccConfig> for HiConfig { x_a: ecc_config.advices[3], lambda1: ecc_config.advices[4], lambda2: ecc_config.advices[5], - perm: ecc_config.perm.clone(), }; Self(config) } @@ -75,7 +70,6 @@ impl From<&EccConfig> for LoConfig { x_a: ecc_config.advices[7], lambda1: ecc_config.advices[8], lambda2: ecc_config.advices[2], - perm: ecc_config.perm.clone(), }; Self(config) } @@ -285,25 +279,11 @@ impl Config { // Initialise double-and-add let (mut x_a, mut y_a, mut z) = { // Initialise the running `z` sum for the scalar bits. - let z = copy(region, || "starting z", self.z, offset, &acc.2, &self.perm)?; + let z = copy(region, || "starting z", self.z, offset, &acc.2)?; // Initialise acc - let x_a = copy( - region, - || "starting x_a", - self.x_a, - offset + 1, - &acc.0, - &self.perm, - )?; - let y_a = copy( - region, - || "starting y_a", - self.lambda1, - offset, - &acc.1, - &self.perm, - )?; + let x_a = copy(region, || "starting x_a", self.x_a, offset + 1, &acc.0)?; + let y_a = copy(region, || "starting y_a", self.lambda1, offset, &acc.1)?; (x_a, y_a.value(), z) }; diff --git a/src/circuit/gadget/ecc/chip/mul/overflow.rs b/src/circuit/gadget/ecc/chip/mul/overflow.rs index 361b8020..d4336624 100644 --- a/src/circuit/gadget/ecc/chip/mul/overflow.rs +++ b/src/circuit/gadget/ecc/chip/mul/overflow.rs @@ -6,7 +6,7 @@ use crate::{ }; use halo2::{ circuit::Layouter, - plonk::{Advice, Column, ConstraintSystem, Error, Expression, Permutation, Selector}, + plonk::{Advice, Column, ConstraintSystem, Error, Expression, Selector}, poly::Rotation, }; @@ -22,8 +22,6 @@ pub struct Config { lookup_config: LookupRangeCheckConfig, // Advice columns advices: [Column; 3], - // Permutation - perm: Permutation, } impl From<&EccConfig> for Config { @@ -36,7 +34,6 @@ impl From<&EccConfig> for Config { ecc_config.advices[1], ecc_config.advices[2], ], - perm: ecc_config.perm.clone(), } } } @@ -137,14 +134,7 @@ impl Config { self.q_mul_overflow.enable(&mut region, offset + 1)?; // Copy `z_0` - copy( - &mut region, - || "copy z_0", - self.advices[0], - offset, - &*zs[0], - &self.perm, - )?; + copy(&mut region, || "copy z_0", self.advices[0], offset, &*zs[0])?; // Copy `z_130` copy( @@ -153,7 +143,6 @@ impl Config { self.advices[0], offset + 1, &*zs[130], - &self.perm, )?; // Witness η = inv0(z_130), where inv0(x) = 0 if x = 0, 1/x otherwise @@ -180,7 +169,6 @@ impl Config { self.advices[1], offset, &*zs[254], - &self.perm, )?; // Copy original alpha @@ -190,7 +178,6 @@ impl Config { self.advices[1], offset + 1, &alpha, - &self.perm, )?; // Copy weighted sum of the decomposition of s = alpha + k_254 ⋅ 2^130. @@ -200,18 +187,10 @@ impl Config { self.advices[1], offset + 2, &s_minus_lo_130, - &self.perm, )?; // Copy witnessed s to check that it was properly derived from alpha and k_254. - copy( - &mut region, - || "copy s", - self.advices[2], - offset + 1, - &s, - &self.perm, - )?; + copy(&mut region, || "copy s", self.advices[2], offset + 1, &s)?; Ok(()) }, diff --git a/src/circuit/gadget/ecc/chip/mul_fixed.rs b/src/circuit/gadget/ecc/chip/mul_fixed.rs index d93a13f7..2c6c958d 100644 --- a/src/circuit/gadget/ecc/chip/mul_fixed.rs +++ b/src/circuit/gadget/ecc/chip/mul_fixed.rs @@ -10,10 +10,7 @@ use crate::constants::{ use group::Curve; use halo2::{ circuit::Region, - plonk::{ - Advice, Column, ConstraintSystem, Error, Expression, Fixed, Permutation, Selector, - VirtualCells, - }, + plonk::{Advice, Column, ConstraintSystem, Error, Expression, Fixed, Selector, VirtualCells}, poly::Rotation, }; use lazy_static::lazy_static; @@ -94,8 +91,6 @@ pub struct Config { y_p: Column, // y-coordinate of accumulator (only used in the final row). u: Column, - // Permutation - perm: Permutation, // Configuration for `add` add_config: add::Config, // Configuration for `add_incomplete` @@ -112,7 +107,6 @@ impl From<&EccConfig> for Config { y_p: ecc_config.advices[1], window: ecc_config.advices[4], u: ecc_config.advices[5], - perm: ecc_config.perm.clone(), add_config: ecc_config.into(), add_incomplete_config: ecc_config.into(), }; diff --git a/src/circuit/gadget/ecc/chip/mul_fixed/base_field_elem.rs b/src/circuit/gadget/ecc/chip/mul_fixed/base_field_elem.rs index a77b31ff..b4e79501 100644 --- a/src/circuit/gadget/ecc/chip/mul_fixed/base_field_elem.rs +++ b/src/circuit/gadget/ecc/chip/mul_fixed/base_field_elem.rs @@ -273,8 +273,6 @@ impl Config { layouter.assign_region( || "Canonicity checks", |mut region| { - let perm = &self.super_config.perm; - // Activate canonicity check gate self.q_mul_fixed_base_field.enable(&mut region, 1)?; @@ -289,7 +287,6 @@ impl Config { self.canon_advices[0], offset, &alpha, - perm, )?; // z_84_alpha = the top three bits of alpha. @@ -299,7 +296,6 @@ impl Config { self.canon_advices[2], offset, &z_84_alpha, - perm, )?; } @@ -314,7 +310,6 @@ impl Config { self.canon_advices[0], offset, &alpha_0_prime, - perm, )?; // Decompose α into three pieces, @@ -349,7 +344,6 @@ impl Config { self.canon_advices[0], offset, &z_13_alpha_0_prime, - perm, )?; // Copy z_44_alpha @@ -359,7 +353,6 @@ impl Config { self.canon_advices[1], offset, &z_44_alpha, - perm, )?; // Copy z_43_alpha @@ -369,7 +362,6 @@ impl Config { self.canon_advices[2], offset, &z_43_alpha, - perm, )?; } diff --git a/src/circuit/gadget/ecc/chip/mul_fixed/short.rs b/src/circuit/gadget/ecc/chip/mul_fixed/short.rs index 7ed6d07c..72effbde 100644 --- a/src/circuit/gadget/ecc/chip/mul_fixed/short.rs +++ b/src/circuit/gadget/ecc/chip/mul_fixed/short.rs @@ -145,7 +145,6 @@ impl Config { self.super_config.window, offset, &scalar.sign, - &self.super_config.perm, )?; // Copy last window to `u` column. @@ -158,7 +157,6 @@ impl Config { self.super_config.u, offset, &z_21, - &self.super_config.perm, )?; // Conditionally negate `y`-coordinate @@ -406,18 +404,10 @@ pub mod tests { meta.advice_column(), meta.advice_column(), ]; - let constants = [meta.fixed_column(), meta.fixed_column()]; - let perm = meta.permutation( - &advices - .iter() - .map(|advice| (*advice).into()) - .chain(constants.iter().map(|fixed| (*fixed).into())) - .collect::>(), - ); - let lookup_table = meta.fixed_column(); - EccChip::configure(meta, advices, lookup_table, constants, perm) + + EccChip::configure(meta, advices, lookup_table, constants) } fn synthesize( diff --git a/src/circuit/gadget/poseidon/pow5t3.rs b/src/circuit/gadget/poseidon/pow5t3.rs index d6efdee7..ca8c44e2 100644 --- a/src/circuit/gadget/poseidon/pow5t3.rs +++ b/src/circuit/gadget/poseidon/pow5t3.rs @@ -1,7 +1,9 @@ +use std::iter; + use halo2::{ arithmetic::FieldExt, circuit::{Cell, Chip, Layouter, Region}, - plonk::{Advice, Column, ConstraintSystem, Error, Expression, Fixed, Permutation, Selector}, + plonk::{Advice, Column, ConstraintSystem, Error, Expression, Fixed, Selector}, poly::Rotation, }; @@ -14,7 +16,6 @@ const WIDTH: usize = 3; #[derive(Clone, Debug)] pub struct Pow5T3Config { state: [Column; WIDTH], - state_permutation: Permutation, partial_sbox: Column, rc_a: [Column; WIDTH], rc_b: [Column; WIDTH], @@ -38,6 +39,10 @@ pub struct Pow5T3Chip { impl Pow5T3Chip { /// Configures this chip for use in a circuit. + /// + /// # Side-effects + /// + /// All columns in `state` will be equality-enabled. // // TODO: Does the rate need to be hard-coded here, or only the width? It probably // needs to be known wherever we implement the hashing gadget, but it isn't strictly @@ -73,17 +78,12 @@ impl Pow5T3Chip { // every permutation round, while rc_b is empty in the initial and final full // rounds, so we use rc_b as "scratch space" for fixed values (enabling potential // layouter optimisations). - let state_permutation = Permutation::new( - meta, - &[ - state[0].into(), - state[1].into(), - state[2].into(), - rc_b[0].into(), - rc_b[1].into(), - rc_b[2].into(), - ], - ); + for column in iter::empty() + .chain(state.iter().cloned().map(|c| c.into())) + .chain(rc_b.iter().cloned().map(|c| c.into())) + { + meta.enable_equality(column); + } let s_full = meta.selector(); let s_partial = meta.selector(); @@ -195,7 +195,6 @@ impl Pow5T3Chip { Pow5T3Config { state, - state_permutation, partial_sbox, rc_a, rc_b, @@ -302,7 +301,7 @@ impl> PoseidonDuplexInstructions> PoseidonDuplexInstructions> PoseidonDuplexInstructions Pow5T3State { 0, || value.ok_or(Error::SynthesisError), )?; - region.constrain_equal(&config.state_permutation, initial_state[i].var, var)?; + region.constrain_equal(initial_state[i].var, var)?; Ok(StateWord { var, value }) }; @@ -686,7 +685,7 @@ mod tests { 0, || Ok(expected_final_state[i]), )?; - region.constrain_equal(&config.state_permutation, final_state[i].var, var) + region.constrain_equal(final_state[i].var, var) }; final_state_word(0)?; @@ -771,7 +770,7 @@ mod tests { || self.output.ok_or(Error::SynthesisError), )?; let word: StateWord<_> = output.inner; - region.constrain_equal(&config.state_permutation, word.var, expected_var) + region.constrain_equal(word.var, expected_var) }, ) } diff --git a/src/circuit/gadget/sinsemilla.rs b/src/circuit/gadget/sinsemilla.rs index 79ccab30..0865b996 100644 --- a/src/circuit/gadget/sinsemilla.rs +++ b/src/circuit/gadget/sinsemilla.rs @@ -366,32 +366,19 @@ mod tests { // Fixed columns for the Sinsemilla generator lookup table let lookup = (table_idx, meta.fixed_column(), meta.fixed_column()); - let perm = meta.permutation( - &advices - .iter() - .map(|advice| (*advice).into()) - .chain(constants_1.iter().map(|fixed| (*fixed).into())) - .chain(constants_2.iter().map(|fixed| (*fixed).into())) - .chain(ecc_constants.iter().map(|fixed| (*fixed).into())) - .collect::>(), - ); - - let ecc_config = - EccChip::configure(meta, advices, table_idx, ecc_constants, perm.clone()); + let ecc_config = EccChip::configure(meta, advices, table_idx, ecc_constants); let config1 = SinsemillaChip::configure( meta, advices[..5].try_into().unwrap(), lookup, constants_1, - perm.clone(), ); let config2 = SinsemillaChip::configure( meta, advices[5..].try_into().unwrap(), lookup, constants_2, - perm, ); (ecc_config, config1, config2) } diff --git a/src/circuit/gadget/sinsemilla/chip.rs b/src/circuit/gadget/sinsemilla/chip.rs index b1452baf..d43c4f76 100644 --- a/src/circuit/gadget/sinsemilla/chip.rs +++ b/src/circuit/gadget/sinsemilla/chip.rs @@ -15,10 +15,7 @@ use crate::{ use halo2::{ arithmetic::{CurveAffine, FieldExt}, circuit::{Chip, Layouter}, - plonk::{ - Advice, Column, ConstraintSystem, Error, Expression, Fixed, Permutation, Selector, - VirtualCells, - }, + plonk::{Advice, Column, ConstraintSystem, Error, Expression, Fixed, Selector, VirtualCells}, poly::Rotation, }; use pasta_curves::pallas; @@ -62,8 +59,6 @@ pub struct SinsemillaConfig { /// x-coordinate of the domain $Q$, which is then constrained to equal the /// initial $x_a$. pub(super) constants: Column, - /// Permutation over all advice columns and the `constants` fixed column. - pub(super) perm: Permutation, /// Configure each advice column to be able to perform lookup range checks. pub(super) lookup_config_0: LookupRangeCheckConfig, pub(super) lookup_config_1: LookupRangeCheckConfig, @@ -110,6 +105,9 @@ impl SinsemillaChip { config.generator_table.load(layouter) } + /// # Side-effects + /// + /// All columns in `advices` and `constants` will be equality-enabled. #[allow(clippy::too_many_arguments)] #[allow(non_snake_case)] pub fn configure( @@ -117,8 +115,23 @@ impl SinsemillaChip { advices: [Column; 5], lookup: (Column, Column, Column), constants: [Column; 6], // TODO: replace with public inputs API - perm: Permutation, ) -> >::Config { + // This chip requires all advice columns and the `constants` fixed column to be + // equality-enabled. The advice columns are equality-enabled by the calls to + // LookupRangeCheckConfig::configure. + let lookup_config_0 = + LookupRangeCheckConfig::configure(meta, advices[0], constants[0], lookup.0); + let lookup_config_1 = + LookupRangeCheckConfig::configure(meta, advices[1], constants[1], lookup.0); + let lookup_config_2 = + LookupRangeCheckConfig::configure(meta, advices[2], constants[2], lookup.0); + let lookup_config_3 = + LookupRangeCheckConfig::configure(meta, advices[3], constants[3], lookup.0); + let lookup_config_4 = + LookupRangeCheckConfig::configure(meta, advices[4], constants[4], lookup.0); + let constants = constants[5]; + meta.enable_equality(constants.into()); + let config = SinsemillaConfig { q_sinsemilla1: meta.selector(), q_sinsemilla2: meta.fixed_column(), @@ -133,43 +146,12 @@ impl SinsemillaChip { table_x: lookup.1, table_y: lookup.2, }, - constants: constants[5], - lookup_config_0: LookupRangeCheckConfig::configure( - meta, - advices[0], - constants[0], - lookup.0, - perm.clone(), - ), - lookup_config_1: LookupRangeCheckConfig::configure( - meta, - advices[1], - constants[1], - lookup.0, - perm.clone(), - ), - lookup_config_2: LookupRangeCheckConfig::configure( - meta, - advices[2], - constants[2], - lookup.0, - perm.clone(), - ), - lookup_config_3: LookupRangeCheckConfig::configure( - meta, - advices[3], - constants[3], - lookup.0, - perm.clone(), - ), - lookup_config_4: LookupRangeCheckConfig::configure( - meta, - advices[4], - constants[4], - lookup.0, - perm.clone(), - ), - perm, + constants, + lookup_config_0, + lookup_config_1, + lookup_config_2, + lookup_config_3, + lookup_config_4, }; // Set up lookup argument diff --git a/src/circuit/gadget/sinsemilla/chip/hash_to_point.rs b/src/circuit/gadget/sinsemilla/chip/hash_to_point.rs index c72e503e..26a6bda8 100644 --- a/src/circuit/gadget/sinsemilla/chip/hash_to_point.rs +++ b/src/circuit/gadget/sinsemilla/chip/hash_to_point.rs @@ -47,14 +47,7 @@ impl SinsemillaChip { CellValue::new(cell, Some(x_q)) }; - let x_a = copy( - region, - || "x_q", - config.x_a, - offset, - &fixed_x_q, - &config.perm, - )?; + let x_a = copy(region, || "x_q", config.x_a, offset, &fixed_x_q)?; // Constrain the initial x_a, lambda_1, lambda_2, x_p using the fixed y_q // initializer. Assign `fixed_y_q` to be zero on every other row. @@ -291,7 +284,7 @@ impl SinsemillaChip { offset, || piece.field_elem().ok_or(Error::SynthesisError), )?; - region.constrain_equal(&config.perm, piece.cell(), cell)?; + region.constrain_equal(piece.cell(), cell)?; zs.push(CellValue::new(cell, piece.field_elem())); // Assign cumulative sum such that for 0 <= i < n, diff --git a/src/circuit/gadget/sinsemilla/merkle.rs b/src/circuit/gadget/sinsemilla/merkle.rs index 5a7eaaf4..c2c75156 100644 --- a/src/circuit/gadget/sinsemilla/merkle.rs +++ b/src/circuit/gadget/sinsemilla/merkle.rs @@ -206,15 +206,6 @@ pub mod tests { meta.fixed_column(), ]; - let perm = meta.permutation( - &advices - .iter() - .map(|advice| (*advice).into()) - .chain(constants_1.iter().map(|fixed| (*fixed).into())) - .chain(constants_2.iter().map(|fixed| (*fixed).into())) - .collect::>(), - ); - // Fixed columns for the Sinsemilla generator lookup table let lookup = ( meta.fixed_column(), @@ -227,7 +218,6 @@ pub mod tests { advices[5..].try_into().unwrap(), lookup, constants_1, - perm.clone(), ); let config1 = MerkleChip::configure(meta, sinsemilla_config_1); @@ -236,7 +226,6 @@ pub mod tests { advices[..5].try_into().unwrap(), lookup, constants_2, - perm, ); let config2 = MerkleChip::configure(meta, sinsemilla_config_2); diff --git a/src/circuit/gadget/sinsemilla/merkle/chip.rs b/src/circuit/gadget/sinsemilla/merkle/chip.rs index e86d85a8..b81906ad 100644 --- a/src/circuit/gadget/sinsemilla/merkle/chip.rs +++ b/src/circuit/gadget/sinsemilla/merkle/chip.rs @@ -1,6 +1,6 @@ use halo2::{ circuit::{Chip, Layouter}, - plonk::{Advice, Column, ConstraintSystem, Error, Expression, Fixed, Permutation}, + plonk::{Advice, Column, ConstraintSystem, Error, Expression, Fixed}, poly::Rotation, }; use pasta_curves::{arithmetic::FieldExt, pallas}; @@ -26,7 +26,6 @@ use std::{array, convert::TryInto}; pub struct MerkleConfig { advices: [Column; 5], l_plus_1: Column, - perm: Permutation, pub(super) cond_swap_config: CondSwapConfig, pub(super) sinsemilla_config: SinsemillaConfig, } @@ -54,9 +53,10 @@ impl MerkleChip { meta: &mut ConstraintSystem, sinsemilla_config: SinsemillaConfig, ) -> MerkleConfig { + // TODO: Check whether these advice columns were equality-enabled by + // SinsemillaConfig. We require all five columns to be equality-enabled. let advices = sinsemilla_config.advices(); - let cond_swap_config = - CondSwapChip::configure(meta, advices, sinsemilla_config.perm.clone()); + 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 @@ -153,7 +153,6 @@ impl MerkleChip { MerkleConfig { advices, l_plus_1, - perm: sinsemilla_config.perm.clone(), cond_swap_config, sinsemilla_config, } @@ -298,7 +297,6 @@ impl MerkleInstructions { /// Assigns a cell at a specific offset within the given region, constraining it /// to the same value as another cell (which may be in any region). /// -/// Returns an error if either `column` or `copy` is not within `perm`. +/// Returns an error if either `column` or `copy` is not in a column that was passed to +/// [`ConstraintSystem::enable_equality`] during circuit configuration. +/// +/// [`ConstraintSystem::enable_equality`]: halo2::plonk::ConstraintSystem::enable_equality pub fn copy( region: &mut Region<'_, F>, annotation: A, column: Column, offset: usize, copy: &CellValue, - perm: &Permutation, ) -> Result, Error> where A: Fn() -> AR, @@ -83,7 +85,7 @@ where copy.value.ok_or(Error::SynthesisError) })?; - region.constrain_equal(perm, cell, copy.cell)?; + region.constrain_equal(cell, copy.cell)?; Ok(CellValue::new(cell, copy.value)) } @@ -203,13 +205,13 @@ mod tests { for i in 0..8 { let circuit: MyCircuit<8> = MyCircuit(i); - let prover = MockProver::::run(1, &circuit, vec![]).unwrap(); + let prover = MockProver::::run(3, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); } { let circuit: MyCircuit<8> = MyCircuit(8); - let prover = MockProver::::run(1, &circuit, vec![]).unwrap(); + let prover = MockProver::::run(3, &circuit, vec![]).unwrap(); assert_eq!( prover.verify(), Err(vec![VerifyFailure::Constraint { diff --git a/src/circuit/gadget/utilities/cond_swap.rs b/src/circuit/gadget/utilities/cond_swap.rs index c70b572d..4d387cab 100644 --- a/src/circuit/gadget/utilities/cond_swap.rs +++ b/src/circuit/gadget/utilities/cond_swap.rs @@ -1,7 +1,7 @@ use super::{copy, CellValue, UtilitiesInstructions, Var}; use halo2::{ circuit::{Chip, Layouter}, - plonk::{Advice, Column, ConstraintSystem, Error, Expression, Permutation, Selector}, + plonk::{Advice, Column, ConstraintSystem, Error, Expression, Selector}, poly::Rotation, }; use pasta_curves::arithmetic::FieldExt; @@ -50,7 +50,6 @@ pub struct CondSwapConfig { pub a_swapped: Column, pub b_swapped: Column, pub swap: Column, - pub perm: Permutation, } impl UtilitiesInstructions for CondSwapChip { @@ -74,7 +73,7 @@ impl CondSwapInstructions for CondSwapChip { config.q_swap.enable(&mut region, 0)?; // Copy in `a` value - let a = copy(&mut region, || "copy a", config.a, 0, &pair.0, &config.perm)?; + let a = copy(&mut region, || "copy a", config.a, 0, &pair.0)?; // Witness `b` value let b = { @@ -144,23 +143,26 @@ impl CondSwapInstructions for CondSwapChip { impl CondSwapChip { /// Configures this chip for use in a circuit. /// - /// `perm` must cover `advices[0..2]`, as well as any columns that will - /// be passed to this chip. + /// # Side-effects + /// + /// `advices[0]` will be equality-enabled. pub fn configure( meta: &mut ConstraintSystem, advices: [Column; 5], - perm: Permutation, ) -> CondSwapConfig { + let a = advices[0]; + // Only column a is used in an equality constraint directly by this chip. + meta.enable_equality(a.into()); + let q_swap = meta.selector(); let config = CondSwapConfig { q_swap, - a: advices[0], + a, b: advices[1], a_swapped: advices[2], b_swapped: advices[3], swap: advices[4], - perm, }; // TODO: optimise shape of gate for Merkle path validation @@ -212,7 +214,7 @@ mod tests { use halo2::{ circuit::{Layouter, SimpleFloorPlanner}, dev::MockProver, - plonk::{Any, Circuit, Column, ConstraintSystem, Error}, + plonk::{Circuit, ConstraintSystem, Error}, }; use pasta_curves::{arithmetic::FieldExt, pallas::Base}; @@ -242,14 +244,7 @@ mod tests { meta.advice_column(), ]; - let perm = meta.permutation( - &advices - .iter() - .map(|advice| (*advice).into()) - .collect::>>(), - ); - - CondSwapChip::::configure(meta, advices, perm) + CondSwapChip::::configure(meta, advices) } fn synthesize( diff --git a/src/circuit/gadget/utilities/decompose_running_sum.rs b/src/circuit/gadget/utilities/decompose_running_sum.rs index 73741c7b..2d3b5579 100644 --- a/src/circuit/gadget/utilities/decompose_running_sum.rs +++ b/src/circuit/gadget/utilities/decompose_running_sum.rs @@ -25,7 +25,7 @@ use ff::PrimeFieldBits; use halo2::{ circuit::Region, - plonk::{Advice, Column, ConstraintSystem, Error, Permutation, Selector}, + plonk::{Advice, Column, ConstraintSystem, Error, Selector}, poly::Rotation, }; @@ -48,7 +48,6 @@ pub struct RunningSumConfig, - perm: Permutation, _marker: PhantomData, } @@ -60,19 +59,23 @@ impl /// # Panics /// /// Panics if WINDOW_NUM_BITS > 3. + /// + /// # Side-effects + /// + /// `z` will be equality-enabled. pub fn configure( meta: &mut ConstraintSystem, q_range_check: Selector, z: Column, - perm: Permutation, ) -> Self { assert!(WINDOW_NUM_BITS <= 3); + meta.enable_equality(z.into()); + let config = Self { q_range_check, q_strict: meta.selector(), z, - perm, _marker: PhantomData, }; @@ -135,14 +138,7 @@ impl word_num_bits: usize, num_windows: usize, ) -> Result<(CellValue, RunningSum), Error> { - let z_0 = copy( - region, - || "copy z_0 = alpha", - self.z, - offset, - &alpha, - &self.perm, - )?; + let z_0 = copy(region, || "copy z_0 = alpha", self.z, offset, &alpha)?; self.decompose(region, offset, z_0, strict, word_num_bits, num_windows) } @@ -276,9 +272,8 @@ mod tests { fn configure(meta: &mut ConstraintSystem) -> Self::Config { let z = meta.advice_column(); let q_range_check = meta.selector(); - let perm = meta.permutation(&[z.into()]); - RunningSumConfig::::configure(meta, q_range_check, z, perm) + RunningSumConfig::::configure(meta, q_range_check, z) } fn synthesize( diff --git a/src/circuit/gadget/utilities/enable_flag.rs b/src/circuit/gadget/utilities/enable_flag.rs index aa0bdc3a..3424369e 100644 --- a/src/circuit/gadget/utilities/enable_flag.rs +++ b/src/circuit/gadget/utilities/enable_flag.rs @@ -1,7 +1,7 @@ use super::{copy, CellValue, UtilitiesInstructions}; use halo2::{ circuit::{Chip, Layouter}, - plonk::{Advice, Column, ConstraintSystem, Error, Expression, Permutation, Selector}, + plonk::{Advice, Column, ConstraintSystem, Error, Expression, Selector}, poly::Rotation, }; use pasta_curves::arithmetic::FieldExt; @@ -22,7 +22,6 @@ pub struct EnableFlagConfig { q_enable: Selector, value: Column, enable_flag: Column, - perm: Permutation, } /// A chip implementing an enable flag. @@ -73,14 +72,7 @@ impl EnableFlagInstructions for EnableFlagChip { )?; // Copy `value` - copy( - &mut region, - || "copy value", - config.value, - 0, - &value, - &config.perm, - )?; + copy(&mut region, || "copy value", config.value, 0, &value)?; Ok(()) }, @@ -91,20 +83,22 @@ impl EnableFlagInstructions for EnableFlagChip { impl EnableFlagChip { /// Configures this chip for use in a circuit. /// - /// `perm` must cover `advices[0]`, as well as any columns that will be - /// passed to this chip. + /// # Side-effects + /// + /// `advices[0]` will be equality-enabled. pub fn configure( meta: &mut ConstraintSystem, advices: [Column; 2], - perm: Permutation, ) -> EnableFlagConfig { + let value = advices[0]; + meta.enable_equality(value.into()); + let q_enable = meta.selector(); let config = EnableFlagConfig { q_enable, - value: advices[0], + value, enable_flag: advices[1], - perm, }; meta.create_gate("Enable flag", |meta| { @@ -133,7 +127,7 @@ mod tests { use halo2::{ circuit::{Layouter, SimpleFloorPlanner}, dev::{MockProver, VerifyFailure}, - plonk::{Any, Circuit, Column, ConstraintSystem, Error}, + plonk::{Circuit, ConstraintSystem, Error}, }; use pasta_curves::{arithmetic::FieldExt, pallas::Base}; @@ -156,14 +150,7 @@ mod tests { fn configure(meta: &mut ConstraintSystem) -> Self::Config { let advices = [meta.advice_column(), meta.advice_column()]; - let perm = meta.permutation( - &advices - .iter() - .map(|advice| (*advice).into()) - .collect::>>(), - ); - - EnableFlagChip::::configure(meta, advices, perm) + EnableFlagChip::::configure(meta, advices) } fn synthesize( @@ -190,7 +177,7 @@ mod tests { value: Some(Base::one()), enable_flag: Some(true), }; - let prover = MockProver::::run(1, &circuit, vec![]).unwrap(); + let prover = MockProver::::run(3, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); } @@ -200,7 +187,7 @@ mod tests { value: Some(Base::zero()), enable_flag: Some(false), }; - let prover = MockProver::::run(1, &circuit, vec![]).unwrap(); + let prover = MockProver::::run(3, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); } @@ -210,7 +197,7 @@ mod tests { value: Some(Base::zero()), enable_flag: Some(true), }; - let prover = MockProver::::run(1, &circuit, vec![]).unwrap(); + let prover = MockProver::::run(3, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); } @@ -220,7 +207,7 @@ mod tests { value: Some(Base::one()), enable_flag: Some(false), }; - let prover = MockProver::::run(1, &circuit, vec![]).unwrap(); + let prover = MockProver::::run(3, &circuit, vec![]).unwrap(); assert_eq!( prover.verify(), Err(vec![VerifyFailure::Constraint { diff --git a/src/circuit/gadget/utilities/lookup_range_check.rs b/src/circuit/gadget/utilities/lookup_range_check.rs index 36aedc1d..8008c529 100644 --- a/src/circuit/gadget/utilities/lookup_range_check.rs +++ b/src/circuit/gadget/utilities/lookup_range_check.rs @@ -4,7 +4,7 @@ use crate::spec::lebs2ip; use halo2::{ circuit::{Layouter, Region}, - plonk::{Advice, Column, ConstraintSystem, Error, Fixed, Permutation, Selector}, + plonk::{Advice, Column, ConstraintSystem, Error, Fixed, Selector}, poly::Rotation, }; use std::{convert::TryInto, marker::PhantomData}; @@ -21,7 +21,6 @@ pub struct LookupRangeCheckConfig pub running_sum: Column, constants: Column, table_idx: Column, - perm: Permutation, _marker: PhantomData, } @@ -33,13 +32,19 @@ impl LookupRangeCheckConfig /// The `table_idx` fixed column contains values from [0..2^K). Looking up /// a value in `table_idx` constrains it to be within this range. The table /// can be loaded outside this helper. + /// + /// # Side-effects + /// + /// Both the `running_sum` and `constants` columns will be equality-enabled. pub fn configure( meta: &mut ConstraintSystem, running_sum: Column, constants: Column, table_idx: Column, - perm: Permutation, ) -> Self { + meta.enable_equality(running_sum.into()); + meta.enable_equality(constants.into()); + let q_lookup = meta.selector(); let q_lookup_short = meta.selector(); let short_lookup_bitshift = meta.fixed_column(); @@ -50,7 +55,6 @@ impl LookupRangeCheckConfig running_sum, constants, table_idx, - perm, _marker: PhantomData, }; @@ -115,6 +119,9 @@ impl LookupRangeCheckConfig } /// Range check on an existing cell that is copied into this helper. + /// + /// Returns an error if `element` is not in a column that was passed to + /// [`ConstraintSystem::enable_equality`] during circuit configuration. pub fn copy_check( &self, mut layouter: impl Layouter, @@ -126,14 +133,7 @@ impl LookupRangeCheckConfig || format!("{:?} words range check", num_words), |mut region| { // Copy `element` and initialize running sum `z_0 = element` to decompose it. - let z_0 = copy( - &mut region, - || "z_0", - self.running_sum, - 0, - &element, - &self.perm, - )?; + let z_0 = copy(&mut region, || "z_0", self.running_sum, 0, &element)?; self.range_check(&mut region, z_0, num_words, strict) }, @@ -247,7 +247,7 @@ impl LookupRangeCheckConfig // Constrain the final `z` to be zero. let cell = region.assign_fixed(|| "zero", self.constants, words.len(), || Ok(F::zero()))?; - region.constrain_equal(&self.perm, z.cell(), cell)?; + region.constrain_equal(z.cell(), cell)?; } Ok(zs) @@ -269,14 +269,7 @@ impl LookupRangeCheckConfig || format!("Range check {:?} bits", num_bits), |mut region| { // Copy `element` to use in the k-bit lookup. - let element = copy( - &mut region, - || "element", - self.running_sum, - 0, - &element, - &self.perm, - )?; + let element = copy(&mut region, || "element", self.running_sum, 0, &element)?; self.short_range_check(&mut region, element, num_bits) }, @@ -397,15 +390,8 @@ mod tests { let running_sum = meta.advice_column(); let constants = meta.fixed_column(); let table_idx = meta.fixed_column(); - let perm = meta.permutation(&[running_sum.into(), constants.into()]); - LookupRangeCheckConfig::::configure( - meta, - running_sum, - constants, - table_idx, - perm, - ) + LookupRangeCheckConfig::::configure(meta, running_sum, constants, table_idx) } fn synthesize( @@ -509,15 +495,8 @@ mod tests { let running_sum = meta.advice_column(); let constants = meta.fixed_column(); let table_idx = meta.fixed_column(); - let perm = meta.permutation(&[running_sum.into()]); - LookupRangeCheckConfig::::configure( - meta, - running_sum, - constants, - table_idx, - perm, - ) + LookupRangeCheckConfig::::configure(meta, running_sum, constants, table_idx) } fn synthesize( diff --git a/src/circuit/gadget/utilities/plonk.rs b/src/circuit/gadget/utilities/plonk.rs index 5e3765e2..50d57f55 100644 --- a/src/circuit/gadget/utilities/plonk.rs +++ b/src/circuit/gadget/utilities/plonk.rs @@ -1,7 +1,7 @@ use super::{copy, CellValue, UtilitiesInstructions}; use halo2::{ circuit::{Chip, Layouter}, - plonk::{Advice, Column, ConstraintSystem, Error, Fixed, Permutation}, + plonk::{Advice, Column, ConstraintSystem, Error, Fixed}, poly::Rotation, }; use pasta_curves::arithmetic::FieldExt; @@ -44,8 +44,6 @@ pub struct PLONKConfig { sb: Column, sc: Column, sm: Column, - - perm: Permutation, } #[allow(clippy::upper_case_acronyms)] @@ -90,13 +88,13 @@ impl PLONKInstructions for PLONKChip { let config = self.config().clone(); // Copy in `a` - copy(&mut region, || "copy a", config.a, 0, &a, &config.perm)?; + copy(&mut region, || "copy a", config.a, 0, &a)?; // Copy in `b` - copy(&mut region, || "copy b", config.b, 0, &b, &config.perm)?; + copy(&mut region, || "copy b", config.b, 0, &b)?; // Copy in `c` - copy(&mut region, || "copy c", config.c, 0, &c, &config.perm)?; + copy(&mut region, || "copy c", config.c, 0, &c)?; // Assign fixed columns region.assign_fixed(|| "sc", config.sc, 0, || sc.ok_or(Error::SynthesisError))?; @@ -138,13 +136,13 @@ impl PLONKInstructions for PLONKChip { || "add", |mut region| { // Copy in `a` - copy(&mut region, || "copy a", config.a, 0, &a, &config.perm)?; + copy(&mut region, || "copy a", config.a, 0, &a)?; // Copy in `b` - copy(&mut region, || "copy b", config.b, 0, &b, &config.perm)?; + copy(&mut region, || "copy b", config.b, 0, &b)?; // Copy in `c` - copy(&mut region, || "copy c", config.c, 0, &c, &config.perm)?; + copy(&mut region, || "copy c", config.c, 0, &c)?; // Assign fixed columns region.assign_fixed(|| "a", config.sa, 0, || sa.ok_or(Error::SynthesisError))?; @@ -171,16 +169,16 @@ impl PLONKInstructions for PLONKChip { impl PLONKChip { /// Configures this chip for use in a circuit. /// - /// `perm` must cover `advices`, as well as any columns that will be passed - /// to this chip. - pub fn configure( - meta: &mut ConstraintSystem, - advices: [Column; 3], - perm: Permutation, - ) -> PLONKConfig { + /// # Side-effects + /// + /// All columns in `advices` will be equality-enabled. + pub fn configure(meta: &mut ConstraintSystem, advices: [Column; 3]) -> PLONKConfig { let a = advices[0]; let b = advices[1]; let c = advices[2]; + meta.enable_equality(a.into()); + meta.enable_equality(b.into()); + meta.enable_equality(c.into()); let sa = meta.fixed_column(); let sb = meta.fixed_column(); @@ -208,7 +206,6 @@ impl PLONKChip { sb, sc, sm, - perm, } } @@ -227,7 +224,7 @@ mod tests { use halo2::{ circuit::{Layouter, SimpleFloorPlanner}, dev::MockProver, - plonk::{Any, Circuit, Column, ConstraintSystem, Error}, + plonk::{Circuit, ConstraintSystem, Error}, }; use pasta_curves::{arithmetic::FieldExt, pallas::Base}; @@ -254,14 +251,7 @@ mod tests { meta.advice_column(), ]; - let perm = meta.permutation( - &advices - .iter() - .map(|advice| (*advice).into()) - .collect::>>(), - ); - - PLONKChip::::configure(meta, advices, perm) + PLONKChip::::configure(meta, advices) } fn synthesize( @@ -343,7 +333,7 @@ mod tests { a: Some(Base::rand()), b: Some(Base::rand()), }; - let prover = MockProver::::run(3, &circuit, vec![]).unwrap(); + let prover = MockProver::::run(4, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); } }