diff --git a/halo2-base/Cargo.toml b/halo2-base/Cargo.toml index 8eccd652..0e9df185 100644 --- a/halo2-base/Cargo.toml +++ b/halo2-base/Cargo.toml @@ -46,7 +46,7 @@ mimalloc = { version = "0.1", default-features = false, optional = true } default = ["halo2-axiom", "display"] asm = ["halo2_proofs_axiom?/asm"] dev-graph = ["halo2_proofs?/dev-graph", "halo2_proofs_axiom?/dev-graph", "plotters"] -halo2-pse = ["halo2_proofs"] +halo2-pse = ["halo2_proofs/circuit-params"] halo2-axiom = ["halo2_proofs_axiom"] display = [] profile = ["halo2_proofs_axiom?/profile"] diff --git a/halo2-base/benches/inner_product.rs b/halo2-base/benches/inner_product.rs index 71702bc0..b71c830b 100644 --- a/halo2-base/benches/inner_product.rs +++ b/halo2-base/benches/inner_product.rs @@ -1,10 +1,7 @@ -#![allow(unused_imports)] -#![allow(unused_variables)] -use halo2_base::gates::builder::{GateCircuitBuilder, GateThreadBuilder, RangeCircuitBuilder}; -use halo2_base::gates::flex_gate::{FlexGateConfig, GateChip, GateInstructions, GateStrategy}; +use halo2_base::gates::builder::{GateThreadBuilder, RangeCircuitBuilder}; +use halo2_base::gates::flex_gate::{GateChip, GateInstructions}; use halo2_base::halo2_proofs::{ arithmetic::Field, - circuit::*, dev::MockProver, halo2curves::bn256::{Bn256, Fr, G1Affine}, plonk::*, @@ -15,14 +12,9 @@ use halo2_base::halo2_proofs::{ transcript::{Blake2bWrite, Challenge255, TranscriptWriterBuffer}, }; use halo2_base::utils::ScalarField; -use halo2_base::{ - Context, - QuantumCell::{Existing, Witness}, - SKIP_FIRST_PASS, -}; +use halo2_base::{Context, QuantumCell::Existing}; use itertools::Itertools; use rand::rngs::OsRng; -use std::marker::PhantomData; use criterion::{criterion_group, criterion_main}; use criterion::{BenchmarkId, Criterion}; @@ -49,8 +41,8 @@ fn bench(c: &mut Criterion) { // create circuit for keygen let mut builder = GateThreadBuilder::new(false); inner_prod_bench(builder.main(0), vec![Fr::zero(); 5], vec![Fr::zero(); 5]); - builder.config(k as usize, Some(20)); - let circuit = RangeCircuitBuilder::mock(builder); + let config_params = builder.config(k as usize, Some(20), None); + let circuit = RangeCircuitBuilder::mock(builder, config_params.clone()); // check the circuit is correct just in case MockProver::run(k, &circuit, vec![]).unwrap().assert_satisfied(); @@ -73,7 +65,11 @@ fn bench(c: &mut Criterion) { let a = (0..5).map(|_| Fr::random(OsRng)).collect_vec(); let b = (0..5).map(|_| Fr::random(OsRng)).collect_vec(); inner_prod_bench(builder.main(0), a, b); - let circuit = RangeCircuitBuilder::prover(builder, break_points.clone()); + let circuit = RangeCircuitBuilder::prover( + builder, + config_params.clone(), + break_points.clone(), + ); let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); create_proof::< diff --git a/halo2-base/benches/mul.rs b/halo2-base/benches/mul.rs index d845ef20..09d3880f 100644 --- a/halo2-base/benches/mul.rs +++ b/halo2-base/benches/mul.rs @@ -36,8 +36,8 @@ fn bench(c: &mut Criterion) { // create circuit for keygen let mut builder = GateThreadBuilder::new(false); mul_bench(builder.main(0), [Fr::zero(); 2]); - builder.config(K as usize, Some(9)); - let circuit = RangeCircuitBuilder::keygen(builder); + let config_params = builder.config(K as usize, Some(9), None); + let circuit = RangeCircuitBuilder::keygen(builder, config_params.clone()); let params = ParamsKZG::::setup(K, OsRng); let vk = keygen_vk(¶ms, &circuit).expect("vk should not fail"); @@ -56,7 +56,11 @@ fn bench(c: &mut Criterion) { let mut builder = GateThreadBuilder::new(true); // do the computation mul_bench(builder.main(0), inputs); - let circuit = RangeCircuitBuilder::prover(builder, break_points.clone()); + let circuit = RangeCircuitBuilder::prover( + builder, + config_params.clone(), + break_points.clone(), + ); let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); create_proof::< diff --git a/halo2-base/examples/inner_product.rs b/halo2-base/examples/inner_product.rs index 585a8b78..8dfdd735 100644 --- a/halo2-base/examples/inner_product.rs +++ b/halo2-base/examples/inner_product.rs @@ -1,10 +1,7 @@ -#![allow(unused_imports)] -#![allow(unused_variables)] use halo2_base::gates::builder::{GateThreadBuilder, RangeCircuitBuilder}; -use halo2_base::gates::flex_gate::{FlexGateConfig, GateChip, GateInstructions, GateStrategy}; +use halo2_base::gates::flex_gate::{GateChip, GateInstructions}; use halo2_base::halo2_proofs::{ arithmetic::Field, - circuit::*, dev::MockProver, halo2curves::bn256::{Bn256, Fr, G1Affine}, plonk::*, @@ -18,21 +15,9 @@ use halo2_base::halo2_proofs::{ transcript::{Blake2bWrite, Challenge255, TranscriptWriterBuffer}, }; use halo2_base::utils::ScalarField; -use halo2_base::{ - Context, - QuantumCell::{Existing, Witness}, - SKIP_FIRST_PASS, -}; +use halo2_base::{Context, QuantumCell::Existing}; use itertools::Itertools; use rand::rngs::OsRng; -use std::marker::PhantomData; - -use criterion::{criterion_group, criterion_main}; -use criterion::{BenchmarkId, Criterion}; - -use pprof::criterion::{Output, PProfProfiler}; -// Thanks to the example provided by @jebbow in his article -// https://www.jibbow.com/posts/criterion-flamegraphs/ const K: u32 = 19; @@ -52,8 +37,8 @@ fn main() { // create circuit for keygen let mut builder = GateThreadBuilder::new(false); inner_prod_bench(builder.main(0), vec![Fr::zero(); 5], vec![Fr::zero(); 5]); - builder.config(k as usize, Some(20)); - let circuit = RangeCircuitBuilder::mock(builder); + let config_params = builder.config(k as usize, Some(20), None); + let circuit = RangeCircuitBuilder::mock(builder, config_params.clone()); // check the circuit is correct just in case MockProver::run(k, &circuit, vec![]).unwrap().assert_satisfied(); @@ -68,7 +53,7 @@ fn main() { let a = (0..5).map(|_| Fr::random(OsRng)).collect_vec(); let b = (0..5).map(|_| Fr::random(OsRng)).collect_vec(); inner_prod_bench(builder.main(0), a, b); - let circuit = RangeCircuitBuilder::prover(builder, break_points); + let circuit = RangeCircuitBuilder::prover(builder, config_params, break_points); let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); create_proof::< diff --git a/halo2-base/src/gates/builder/mod.rs b/halo2-base/src/gates/builder/mod.rs index 7e887175..4f7cf17e 100644 --- a/halo2-base/src/gates/builder/mod.rs +++ b/halo2-base/src/gates/builder/mod.rs @@ -24,16 +24,6 @@ pub type ThreadBreakPoints = Vec; /// Vector of vectors tracking the thread break points across different halo2 phases pub type MultiPhaseThreadBreakPoints = Vec; -thread_local! { - /// This is used as a thread-safe way to auto-configure a circuit's shape and then pass the configuration to `Circuit::configure`. - pub static BASE_CONFIG_PARAMS: RefCell = RefCell::new(Default::default()); -} - -/// Sets the thread-local number of bits to be range checkable via a lookup table with entries [0, 2lookup_bits) -pub fn set_lookup_bits(lookup_bits: usize) { - BASE_CONFIG_PARAMS.with(|conf| conf.borrow_mut().lookup_bits = Some(lookup_bits)); -} - /// Stores the cell values loaded during the Keygen phase of a halo2 proof and breakpoints for multi-threading #[derive(Clone, Debug, Default)] pub struct KeygenAssignments { @@ -143,7 +133,13 @@ impl GateThreadBuilder { /// /// * `k`: The number of in the circuit (i.e. numeber of rows = 2k) /// * `minimum_rows`: The minimum number of rows in the circuit that cannot be used for witness assignments and contain random `blinding factors` to ensure zk property, defaults to 0. - pub fn config(&self, k: usize, minimum_rows: Option) -> BaseConfigParams { + /// * `lookup_bits`: (Optional) Create a lookup table with values [0, 2lookup_bits) for range checks. + pub fn config( + &self, + k: usize, + minimum_rows: Option, + lookup_bits: Option, + ) -> BaseConfigParams { let max_rows = (1 << k) - minimum_rows.unwrap_or(0); let total_advice_per_phase = self .threads @@ -173,18 +169,14 @@ impl GateThreadBuilder { .len(); let num_fixed = (total_fixed + (1 << k) - 1) >> k; - let mut params = BaseConfigParams { + let params = BaseConfigParams { strategy: GateStrategy::Vertical, num_advice_per_phase, num_lookup_advice_per_phase, num_fixed, k, - lookup_bits: None, + lookup_bits, }; - BASE_CONFIG_PARAMS.with(|conf| { - params.lookup_bits = conf.borrow().lookup_bits; - *conf.borrow_mut() = params.clone(); - }); #[cfg(feature = "display")] { for phase in 0..MAX_PHASE { @@ -492,25 +484,40 @@ pub struct GateCircuitBuilder { pub builder: RefCell>, // `RefCell` is just to trick circuit `synthesize` to take ownership of the inner builder /// Break points for threads within the circuit pub break_points: RefCell, // `RefCell` allows the circuit to record break points in a keygen call of `synthesize` for use in later witness gen + /// Configuration parameters for the circuit shape + pub config_params: BaseConfigParams, } impl GateCircuitBuilder { /// Creates a new [GateCircuitBuilder] with `use_unknown` of [GateThreadBuilder] set to true. - pub fn keygen(builder: GateThreadBuilder) -> Self { - Self { builder: RefCell::new(builder.unknown(true)), break_points: RefCell::new(vec![]) } + pub fn keygen(builder: GateThreadBuilder, config_params: BaseConfigParams) -> Self { + Self { + builder: RefCell::new(builder.unknown(true)), + config_params, + break_points: Default::default(), + } } /// Creates a new [GateCircuitBuilder] with `use_unknown` of [GateThreadBuilder] set to false. - pub fn mock(builder: GateThreadBuilder) -> Self { - Self { builder: RefCell::new(builder.unknown(false)), break_points: RefCell::new(vec![]) } + pub fn mock(builder: GateThreadBuilder, config_params: BaseConfigParams) -> Self { + Self { + builder: RefCell::new(builder.unknown(false)), + config_params, + break_points: Default::default(), + } } - /// Creates a new [GateCircuitBuilder]. + /// Creates a new [GateCircuitBuilder] with a pinned circuit configuration given by `config_params` and `break_points`. pub fn prover( builder: GateThreadBuilder, + config_params: BaseConfigParams, break_points: MultiPhaseThreadBreakPoints, ) -> Self { - Self { builder: RefCell::new(builder), break_points: RefCell::new(break_points) } + Self { + builder: RefCell::new(builder), + config_params, + break_points: RefCell::new(break_points), + } } /// Synthesizes from the [GateCircuitBuilder] by populating the advice column and assigning new threads if witness generation is performed. @@ -582,27 +589,33 @@ pub struct RangeCircuitBuilder(pub GateCircuitBuilder); impl RangeCircuitBuilder { /// Creates an instance of the [RangeCircuitBuilder] and executes in keygen mode. - pub fn keygen(builder: GateThreadBuilder) -> Self { - Self(GateCircuitBuilder::keygen(builder)) + pub fn keygen(builder: GateThreadBuilder, config_params: BaseConfigParams) -> Self { + Self(GateCircuitBuilder::keygen(builder, config_params)) } /// Creates a mock instance of the [RangeCircuitBuilder]. - pub fn mock(builder: GateThreadBuilder) -> Self { - Self(GateCircuitBuilder::mock(builder)) + pub fn mock(builder: GateThreadBuilder, config_params: BaseConfigParams) -> Self { + Self(GateCircuitBuilder::mock(builder, config_params)) } /// Creates an instance of the [RangeCircuitBuilder] and executes in prover mode. pub fn prover( builder: GateThreadBuilder, + config_params: BaseConfigParams, break_points: MultiPhaseThreadBreakPoints, ) -> Self { - Self(GateCircuitBuilder::prover(builder, break_points)) + Self(GateCircuitBuilder::prover(builder, config_params, break_points)) } } impl Circuit for RangeCircuitBuilder { type Config = BaseConfig; type FloorPlanner = SimpleFloorPlanner; + type Params = BaseConfigParams; + + fn params(&self) -> Self::Params { + self.0.config_params.clone() + } /// Creates a new instance of the [RangeCircuitBuilder] without witnesses by setting the witness_gen_only flag to false fn without_witnesses(&self) -> Self { @@ -610,13 +623,14 @@ impl Circuit for RangeCircuitBuilder { } /// Configures a new circuit using [`BaseConfigParams`] - fn configure(meta: &mut ConstraintSystem) -> Self::Config { - let params = BASE_CONFIG_PARAMS - .try_with(|config| config.borrow().clone()) - .expect("You need to call config() to configure the halo2-base circuit shape first"); + fn configure_with_params(meta: &mut ConstraintSystem, params: Self::Params) -> Self::Config { BaseConfig::configure(meta, params) } + fn configure(_: &mut ConstraintSystem) -> Self::Config { + unimplemented!("You must use configure_with_params"); + } + /// Performs the actual computation on the circuit (e.g., witness generation), populating the lookup table and filling in all the advice values for a particular proof. fn synthesize( &self, @@ -662,23 +676,32 @@ impl RangeWithInstanceCircuitBuilder { /// See [`RangeCircuitBuilder::keygen`] pub fn keygen( builder: GateThreadBuilder, + config_params: BaseConfigParams, assigned_instances: Vec>, ) -> Self { - Self { circuit: RangeCircuitBuilder::keygen(builder), assigned_instances } + Self { circuit: RangeCircuitBuilder::keygen(builder, config_params), assigned_instances } } /// See [`RangeCircuitBuilder::mock`] - pub fn mock(builder: GateThreadBuilder, assigned_instances: Vec>) -> Self { - Self { circuit: RangeCircuitBuilder::mock(builder), assigned_instances } + pub fn mock( + builder: GateThreadBuilder, + config_params: BaseConfigParams, + assigned_instances: Vec>, + ) -> Self { + Self { circuit: RangeCircuitBuilder::mock(builder, config_params), assigned_instances } } /// See [`RangeCircuitBuilder::prover`] pub fn prover( builder: GateThreadBuilder, - assigned_instances: Vec>, + config_params: BaseConfigParams, break_points: MultiPhaseThreadBreakPoints, + assigned_instances: Vec>, ) -> Self { - Self { circuit: RangeCircuitBuilder::prover(builder, break_points), assigned_instances } + Self { + circuit: RangeCircuitBuilder::prover(builder, config_params, break_points), + assigned_instances, + } } /// Creates a new instance of the [RangeWithInstanceCircuitBuilder]. @@ -686,11 +709,6 @@ impl RangeWithInstanceCircuitBuilder { Self { circuit, assigned_instances } } - /// Calls [`GateThreadBuilder::config`] - pub fn config(&self, k: u32, minimum_rows: Option) -> BaseConfigParams { - self.circuit.0.builder.borrow().config(k as usize, minimum_rows) - } - /// Gets the break points of the circuit. pub fn break_points(&self) -> MultiPhaseThreadBreakPoints { self.circuit.0.break_points.borrow().clone() @@ -710,18 +728,27 @@ impl RangeWithInstanceCircuitBuilder { impl Circuit for RangeWithInstanceCircuitBuilder { type Config = PublicBaseConfig; type FloorPlanner = SimpleFloorPlanner; + type Params = BaseConfigParams; + + fn params(&self) -> Self::Params { + self.circuit.0.config_params.clone() + } fn without_witnesses(&self) -> Self { unimplemented!() } - fn configure(meta: &mut ConstraintSystem) -> Self::Config { - let base = RangeCircuitBuilder::configure(meta); + fn configure_with_params(meta: &mut ConstraintSystem, params: Self::Params) -> Self::Config { + let base = BaseConfig::configure(meta, params); let instance = meta.instance_column(); meta.enable_equality(instance); PublicBaseConfig { base, instance } } + fn configure(_: &mut ConstraintSystem) -> Self::Config { + unimplemented!("You must use configure_with_params") + } + fn synthesize( &self, config: Self::Config, diff --git a/halo2-base/src/gates/tests/general.rs b/halo2-base/src/gates/tests/general.rs index ccbfbc97..5d861b8a 100644 --- a/halo2-base/src/gates/tests/general.rs +++ b/halo2-base/src/gates/tests/general.rs @@ -56,9 +56,9 @@ fn test_multithread_gates() { builder.threads[0].extend(new_threads); // auto-tune circuit - builder.config(k, Some(9)); + let config_params = builder.config(k, Some(9), None); // create circuit - let circuit = RangeCircuitBuilder::mock(builder); + let circuit = RangeCircuitBuilder::mock(builder, config_params); MockProver::run(k as u32, &circuit, vec![]).unwrap().assert_satisfied(); } diff --git a/halo2-base/src/gates/tests/idx_to_indicator.rs b/halo2-base/src/gates/tests/idx_to_indicator.rs index 74130668..9a43b373 100644 --- a/halo2-base/src/gates/tests/idx_to_indicator.rs +++ b/halo2-base/src/gates/tests/idx_to_indicator.rs @@ -25,9 +25,8 @@ fn test_idx_to_indicator_gen(k: u32, len: usize) { let indicator = gate.idx_to_indicator(builder.main(0), dummy_idx, len); // get the offsets of the indicator cells for later 'pranking' let ind_offsets = indicator.iter().map(|ind| ind.cell.unwrap().offset).collect::>(); - // set env vars - builder.config(k as usize, Some(9)); - let circuit = RangeCircuitBuilder::keygen(builder); + let config_params = builder.config(k as usize, Some(9), None); + let circuit = RangeCircuitBuilder::keygen(builder, config_params.clone()); let params = ParamsKZG::setup(k, OsRng); // generate proving key @@ -46,7 +45,7 @@ fn test_idx_to_indicator_gen(k: u32, len: usize) { for (offset, witness) in ind_offsets.iter().zip_eq(ind_witnesses) { builder.main(0).advice[*offset] = Assigned::Trivial(*witness); } - let circuit = RangeCircuitBuilder::prover(builder, vec![vec![]]); // no break points + let circuit = RangeCircuitBuilder::prover(builder, config_params.clone(), vec![vec![]]); // no break points gen_proof(¶ms, &pk, circuit) }; diff --git a/halo2-base/src/gates/tests/neg_prop.rs b/halo2-base/src/gates/tests/neg_prop.rs index af407d55..27994ac0 100644 --- a/halo2-base/src/gates/tests/neg_prop.rs +++ b/halo2-base/src/gates/tests/neg_prop.rs @@ -1,22 +1,15 @@ use crate::{ ff::Field, - gates::builder::set_lookup_bits, gates::{ - builder::{GateThreadBuilder, RangeCircuitBuilder}, - range::{RangeChip, RangeInstructions}, - tests::{ - pos_prop::{rand_bin_witness, rand_fr, rand_witness}, - utils, - }, - GateChip, GateInstructions, + range::RangeInstructions, + tests::{pos_prop::rand_fr, utils}, + GateInstructions, }, - halo2_proofs::{dev::MockProver, halo2curves::bn256::Fr, plonk::Assigned}, - utils::{biguint_to_fe, bit_length, fe_to_biguint, ScalarField}, - QuantumCell, + halo2_proofs::halo2curves::bn256::Fr, + utils::{biguint_to_fe, bit_length, fe_to_biguint, testing::base_test, ScalarField}, QuantumCell::Witness, }; -use itertools::Itertools; use num_bigint::BigUint; use proptest::{collection::vec, prelude::*}; use rand::rngs::OsRng; @@ -35,8 +28,8 @@ prop_compose! { prop_compose! { fn select_strat(k_bounds: (usize, usize)) - (k in k_bounds.0..=k_bounds.1, a in rand_witness(), b in rand_witness(), sel in rand_bin_witness(), rand_output in rand_fr()) - -> (usize, QuantumCell, QuantumCell, QuantumCell, Fr) { + (k in k_bounds.0..=k_bounds.1, a in rand_fr(), b in rand_fr(), sel in any::(), rand_output in rand_fr()) + -> (usize, Fr, Fr, bool, Fr) { (k, a, b, sel, rand_output) } } @@ -44,8 +37,8 @@ prop_compose! { prop_compose! { fn select_by_indicator_strat(k_bounds: (usize, usize), max_size: usize) (k in k_bounds.0..=k_bounds.1, len in 2usize..=max_size) - (k in Just(k), a in vec(rand_witness(), len), idx in 0..len, rand_output in rand_fr()) - -> (usize, Vec>, usize, Fr) { + (k in Just(k), a in vec(rand_fr(), len), idx in 0..len, rand_output in rand_fr()) + -> (usize, Vec, usize, Fr) { (k, a, idx, rand_output) } } @@ -53,8 +46,8 @@ prop_compose! { prop_compose! { fn select_from_idx_strat(k_bounds: (usize, usize), max_size: usize) (k in k_bounds.0..=k_bounds.1, len in 2usize..=max_size) - (k in Just(k), cells in vec(rand_witness(), len), idx in 0..len, rand_output in rand_fr()) - -> (usize, Vec>, usize, Fr) { + (k in Just(k), cells in vec(rand_fr(), len), idx in 0..len, rand_output in rand_fr()) + -> (usize, Vec, usize, Fr) { (k, cells, idx, rand_output) } } @@ -62,8 +55,8 @@ prop_compose! { prop_compose! { fn inner_product_strat(k_bounds: (usize, usize), max_size: usize) (k in k_bounds.0..=k_bounds.1, len in 2usize..=max_size) - (k in Just(k), a in vec(rand_witness(), len), b in vec(rand_witness(), len), rand_output in rand_fr()) - -> (usize, Vec>, Vec>, Fr) { + (k in Just(k), a in vec(rand_fr(), len), b in vec(rand_fr(), len), rand_output in rand_fr()) + -> (usize, Vec, Vec, Fr) { (k, a, b, rand_output) } } @@ -71,8 +64,8 @@ prop_compose! { prop_compose! { fn inner_product_left_last_strat(k_bounds: (usize, usize), max_size: usize) (k in k_bounds.0..=k_bounds.1, len in 2usize..=max_size) - (k in Just(k), a in vec(rand_witness(), len), b in vec(rand_witness(), len), rand_output in (rand_fr(), rand_fr())) - -> (usize, Vec>, Vec>, (Fr, Fr)) { + (k in Just(k), a in vec(rand_fr(), len), b in vec(rand_fr(), len), rand_output in (rand_fr(), rand_fr())) + -> (usize, Vec, Vec, (Fr, Fr)) { (k, a, b, rand_output) } } @@ -128,265 +121,146 @@ fn check_idx_to_indicator(idx: Fr, len: usize, ind_witnesses: &[Fr]) -> bool { } // verify rand_output == a if sel == 1, rand_output == b if sel == 0 -fn check_select(a: Fr, b: Fr, sel: Fr, rand_output: Fr) -> bool { - if (sel == Fr::zero() && rand_output != b) || (sel == Fr::one() && rand_output != a) { +fn check_select(a: Fr, b: Fr, sel: bool, rand_output: Fr) -> bool { + if (!sel && rand_output != b) || (sel && rand_output != a) { return false; } true } -fn neg_test_idx_to_indicator(k: usize, len: usize, idx: usize, ind_witnesses: &[Fr]) -> bool { - let mut builder = GateThreadBuilder::mock(); - let gate = GateChip::default(); - // assign value to advice column before by assigning `idx` via ctx.load() -> use same method as ind_offsets to get offset - let dummy_idx = Witness(Fr::from(idx as u64)); - let indicator = gate.idx_to_indicator(builder.main(0), dummy_idx, len); - // get the offsets of the indicator cells for later 'pranking' - builder.config(k, Some(9)); - let ind_offsets = indicator.iter().map(|ind| ind.cell.unwrap().offset).collect::>(); - // prank the indicator cells - // TODO: prank the entire advice column with random values - for (offset, witness) in ind_offsets.iter().zip_eq(ind_witnesses) { - builder.main(0).advice[*offset] = Assigned::Trivial(*witness); - } - // Get idx and indicator from advice column - // Apply check instance function to `idx` and `ind_witnesses` - let circuit = RangeCircuitBuilder::mock(builder); // no break points - // Check soundness of witness values +fn neg_test_idx_to_indicator(k: usize, len: usize, idx: usize, ind_witnesses: &[Fr]) { + // Check soundness of witness values let is_valid_witness = check_idx_to_indicator(Fr::from(idx as u64), len, ind_witnesses); - match MockProver::run(k as u32, &circuit, vec![]).unwrap().verify() { - // if the proof is valid, then the instance should be valid -> return true - Ok(_) => is_valid_witness, - // if the proof is invalid, ignore - Err(_) => !is_valid_witness, - } + base_test().k(k as u32).expect_satisfied(is_valid_witness).run_gate(|ctx, gate| { + // assign value to advice column before by assigning `idx` via ctx.load() -> use same method as ind_offsets to get offset + let dummy_idx = Witness(Fr::from(idx as u64)); + let mut indicator = gate.idx_to_indicator(ctx, dummy_idx, len); + for (advice, prank_val) in indicator.iter_mut().zip(ind_witnesses) { + advice.debug_prank(ctx, *prank_val); + } + }); } -fn neg_test_select( - k: usize, - a: QuantumCell, - b: QuantumCell, - sel: QuantumCell, - rand_output: Fr, -) -> bool { - let mut builder = GateThreadBuilder::mock(); - let gate = GateChip::default(); - // add select gate - let select = gate.select(builder.main(0), a, b, sel); - - // Get the offset of `select`s output for later 'pranking' - builder.config(k, Some(9)); - let select_offset = select.cell.unwrap().offset; - // Prank the output - builder.main(0).advice[select_offset] = Assigned::Trivial(rand_output); - - let circuit = RangeCircuitBuilder::mock(builder); // no break points - // Check soundness of output - let is_valid_instance = check_select(*a.value(), *b.value(), *sel.value(), rand_output); - match MockProver::run(k as u32, &circuit, vec![]).unwrap().verify() { - // if the proof is valid, then the instance should be valid -> return true - Ok(_) => is_valid_instance, - // if the proof is invalid, ignore - Err(_) => !is_valid_instance, - } +fn neg_test_select(k: usize, a: Fr, b: Fr, sel: bool, prank_output: Fr) { + // Check soundness of output + let is_valid_instance = check_select(a, b, sel, prank_output); + base_test().k(k as u32).expect_satisfied(is_valid_instance).run_gate(|ctx, gate| { + let [a, b, sel] = [a, b, Fr::from(sel)].map(|x| ctx.load_witness(x)); + let select = gate.select(ctx, a, b, sel); + select.debug_prank(ctx, prank_output); + }) } -fn neg_test_select_by_indicator( - k: usize, - a: Vec>, - idx: usize, - rand_output: Fr, -) -> bool { - let mut builder = GateThreadBuilder::mock(); - let gate = GateChip::default(); - - let indicator = gate.idx_to_indicator(builder.main(0), Witness(Fr::from(idx as u64)), a.len()); - let a_idx = gate.select_by_indicator(builder.main(0), a.clone(), indicator); - builder.config(k, Some(9)); - - let a_idx_offset = a_idx.cell.unwrap().offset; - builder.main(0).advice[a_idx_offset] = Assigned::Trivial(rand_output); - let circuit = RangeCircuitBuilder::mock(builder); // no break points - // Check soundness of witness values - // retrieve the value of a[idx] and check that it is equal to rand_output - let is_valid_witness = rand_output == *a[idx].value(); - match MockProver::run(k as u32, &circuit, vec![]).unwrap().verify() { - // if the proof is valid, then the instance should be valid -> return true - Ok(_) => is_valid_witness, - // if the proof is invalid, ignore - Err(_) => !is_valid_witness, - } +fn neg_test_select_by_indicator(k: usize, a: Vec, idx: usize, prank_output: Fr) { + // retrieve the value of a[idx] and check that it is equal to rand_output + let is_valid_witness = prank_output == a[idx]; + base_test().k(k as u32).expect_satisfied(is_valid_witness).run_gate(|ctx, gate| { + let indicator = gate.idx_to_indicator(ctx, Witness(Fr::from(idx as u64)), a.len()); + let a = ctx.assign_witnesses(a); + let a_idx = gate.select_by_indicator(ctx, a, indicator); + a_idx.debug_prank(ctx, prank_output); + }); } -fn neg_test_select_from_idx( - k: usize, - cells: Vec>, - idx: usize, - rand_output: Fr, -) -> bool { - let mut builder = GateThreadBuilder::mock(); - let gate = GateChip::default(); - - let idx_val = - gate.select_from_idx(builder.main(0), cells.clone(), Witness(Fr::from(idx as u64))); - builder.config(k, Some(9)); - - let idx_offset = idx_val.cell.unwrap().offset; - builder.main(0).advice[idx_offset] = Assigned::Trivial(rand_output); - let circuit = RangeCircuitBuilder::mock(builder); // no break points - // Check soundness of witness values - let is_valid_witness = rand_output == *cells[idx].value(); - match MockProver::run(k as u32, &circuit, vec![]).unwrap().verify() { - // if the proof is valid, then the instance should be valid -> return true - Ok(_) => is_valid_witness, - // if the proof is invalid, ignore - Err(_) => !is_valid_witness, - } +fn neg_test_select_from_idx(k: usize, cells: Vec, idx: usize, prank_output: Fr) { + // Check soundness of witness values + let is_valid_witness = prank_output == cells[idx]; + base_test().k(k as u32).expect_satisfied(is_valid_witness).run_gate(|ctx, gate| { + let cells = ctx.assign_witnesses(cells); + let idx_val = gate.select_from_idx(ctx, cells, Witness(Fr::from(idx as u64))); + idx_val.debug_prank(ctx, prank_output); + }); } -fn neg_test_inner_product( - k: usize, - a: Vec>, - b: Vec>, - rand_output: Fr, -) -> bool { - let mut builder = GateThreadBuilder::mock(); - let gate = GateChip::default(); - - let inner_product = gate.inner_product(builder.main(0), a.clone(), b.clone()); - builder.config(k, Some(9)); - - let inner_product_offset = inner_product.cell.unwrap().offset; - builder.main(0).advice[inner_product_offset] = Assigned::Trivial(rand_output); - let circuit = RangeCircuitBuilder::mock(builder); // no break points - // Check soundness of witness values - let is_valid_witness = rand_output == utils::inner_product_ground_truth(&(a, b)); - match MockProver::run(k as u32, &circuit, vec![]).unwrap().verify() { - // if the proof is valid, then the instance should be valid -> return true - Ok(_) => is_valid_witness, - // if the proof is invalid, ignore - Err(_) => !is_valid_witness, - } +fn neg_test_inner_product(k: usize, a: Vec, b: Vec, prank_output: Fr) { + let is_valid_witness = prank_output == utils::inner_product_ground_truth(&a, &b); + base_test().k(k as u32).expect_satisfied(is_valid_witness).run_gate(|ctx, gate| { + let a = ctx.assign_witnesses(a); + let inner_product = gate.inner_product(ctx, a, b.into_iter().map(Witness)); + inner_product.debug_prank(ctx, prank_output); + }); } fn neg_test_inner_product_left_last( k: usize, - a: Vec>, - b: Vec>, - rand_output: (Fr, Fr), -) -> bool { - let mut builder = GateThreadBuilder::mock(); - let gate = GateChip::default(); - - let inner_product = gate.inner_product_left_last(builder.main(0), a.clone(), b.clone()); - builder.config(k, Some(9)); - - let inner_product_offset = - (inner_product.0.cell.unwrap().offset, inner_product.1.cell.unwrap().offset); - // prank the output cells - builder.main(0).advice[inner_product_offset.0] = Assigned::Trivial(rand_output.0); - builder.main(0).advice[inner_product_offset.1] = Assigned::Trivial(rand_output.1); - let circuit = RangeCircuitBuilder::mock(builder); // no break points - // Check soundness of witness values - // (inner_product_ground_truth, a[a.len()-1]) - let inner_product_ground_truth = utils::inner_product_ground_truth(&(a.clone(), b)); - let is_valid_witness = - rand_output.0 == inner_product_ground_truth && rand_output.1 == *a[a.len() - 1].value(); - match MockProver::run(k as u32, &circuit, vec![]).unwrap().verify() { - // if the proof is valid, then the instance should be valid -> return true - Ok(_) => is_valid_witness, - // if the proof is invalid, ignore - Err(_) => !is_valid_witness, - } + a: Vec, + b: Vec, + (prank_output, prank_a_last): (Fr, Fr), +) { + let is_valid_witness = prank_output == utils::inner_product_ground_truth(&a, &b) + && prank_a_last == *a.last().unwrap(); + base_test().k(k as u32).expect_satisfied(is_valid_witness).run_gate(|ctx, gate| { + let a = ctx.assign_witnesses(a); + let (inner_product, a_last) = + gate.inner_product_left_last(ctx, a, b.into_iter().map(Witness)); + inner_product.debug_prank(ctx, prank_output); + a_last.debug_prank(ctx, prank_a_last); + }); } // Range Check -fn neg_test_range_check(k: usize, range_bits: usize, lookup_bits: usize, rand_a: Fr) -> bool { - let mut builder = GateThreadBuilder::mock(); - let gate = RangeChip::default(lookup_bits); - - let a_witness = builder.main(0).load_witness(rand_a); - gate.range_check(builder.main(0), a_witness, range_bits); - - builder.config(k, Some(9)); - set_lookup_bits(lookup_bits); - let circuit = RangeCircuitBuilder::mock(builder); // no break points - // Check soundness of witness values +fn neg_test_range_check(k: usize, range_bits: usize, lookup_bits: usize, rand_a: Fr) { let correct = fe_to_biguint(&rand_a).bits() <= range_bits as u64; - - MockProver::run(k as u32, &circuit, vec![]).unwrap().verify().is_ok() == correct + base_test().k(k as u32).lookup_bits(lookup_bits).expect_satisfied(correct).run(|ctx, range| { + let a_witness = ctx.load_witness(rand_a); + range.range_check(ctx, a_witness, range_bits); + }) } // TODO: expand to prank output of is_less_than_safe() -fn neg_test_is_less_than_safe( - k: usize, - b: u64, - lookup_bits: usize, - rand_a: Fr, - prank_out: bool, -) -> bool { - let mut builder = GateThreadBuilder::mock(); - let gate = RangeChip::default(lookup_bits); - let ctx = builder.main(0); - - let a_witness = ctx.load_witness(rand_a); // cannot prank this later because this witness will be copy-constrained - let out = gate.is_less_than_safe(ctx, a_witness, b); - - let out_idx = out.cell.unwrap().offset; - ctx.advice[out_idx] = Assigned::Trivial(Fr::from(prank_out)); - - builder.config(k, Some(9)); - set_lookup_bits(lookup_bits); - let circuit = RangeCircuitBuilder::mock(builder); // no break points - // Check soundness of witness values - // println!("rand_a: {rand_a:?}, b: {b:?}"); +fn neg_test_is_less_than_safe(k: usize, b: u64, lookup_bits: usize, rand_a: Fr, prank_out: bool) { let a_big = fe_to_biguint(&rand_a); let is_lt = a_big < BigUint::from(b); let correct = (is_lt == prank_out) && (a_big.bits() as usize <= (bit_length(b) + lookup_bits - 1) / lookup_bits * lookup_bits); // circuit should always fail if `a` doesn't pass range check - MockProver::run(k as u32, &circuit, vec![]).unwrap().verify().is_ok() == correct + + base_test().k(k as u32).lookup_bits(lookup_bits).expect_satisfied(correct).run(|ctx, range| { + let a_witness = ctx.load_witness(rand_a); + let out = range.is_less_than_safe(ctx, a_witness, b); + out.debug_prank(ctx, Fr::from(prank_out)); + }); } proptest! { // Note setting the minimum value of k to 8 is intentional as it is the smallest value that will not cause an `out of columns` error. Should be noted that filtering by len * (number cells per iteration) < 2^k leads to the filtering of to many cases and the failure of the tests w/o any runs. #[test] fn prop_test_neg_idx_to_indicator((k, len, idx, witness_vals) in idx_to_indicator_strat((10,20),100)) { - prop_assert!(neg_test_idx_to_indicator(k, len, idx, witness_vals.as_slice())); + neg_test_idx_to_indicator(k, len, idx, witness_vals.as_slice()); } #[test] fn prop_test_neg_select((k, a, b, sel, rand_output) in select_strat((10,20))) { - prop_assert!(neg_test_select(k, a, b, sel, rand_output)); + neg_test_select(k, a, b, sel, rand_output); } #[test] fn prop_test_neg_select_by_indicator((k, a, idx, rand_output) in select_by_indicator_strat((12,20),100)) { - prop_assert!(neg_test_select_by_indicator(k, a, idx, rand_output)); + neg_test_select_by_indicator(k, a, idx, rand_output); } #[test] fn prop_test_neg_select_from_idx((k, cells, idx, rand_output) in select_from_idx_strat((10,20),100)) { - prop_assert!(neg_test_select_from_idx(k, cells, idx, rand_output)); + neg_test_select_from_idx(k, cells, idx, rand_output); } #[test] fn prop_test_neg_inner_product((k, a, b, rand_output) in inner_product_strat((10,20),100)) { - prop_assert!(neg_test_inner_product(k, a, b, rand_output)); + neg_test_inner_product(k, a, b, rand_output); } #[test] fn prop_test_neg_inner_product_left_last((k, a, b, rand_output) in inner_product_left_last_strat((10,20),100)) { - prop_assert!(neg_test_inner_product_left_last(k, a, b, rand_output)); + neg_test_inner_product_left_last(k, a, b, rand_output); } #[test] fn prop_test_neg_range_check((k, range_bits, lookup_bits, rand_a) in range_check_strat((10,23),90)) { - prop_assert!(neg_test_range_check(k, range_bits, lookup_bits, rand_a)); + neg_test_range_check(k, range_bits, lookup_bits, rand_a); } #[test] fn prop_test_neg_is_less_than_safe((k, b, lookup_bits, rand_a, out) in is_less_than_safe_strat((10,20))) { - prop_assert!(neg_test_is_less_than_safe(k, b, lookup_bits, rand_a, out)); + neg_test_is_less_than_safe(k, b, lookup_bits, rand_a, out); } } diff --git a/halo2-base/src/gates/tests/pos_prop.rs b/halo2-base/src/gates/tests/pos_prop.rs index 3ef91cc7..270bb015 100644 --- a/halo2-base/src/gates/tests/pos_prop.rs +++ b/halo2-base/src/gates/tests/pos_prop.rs @@ -159,14 +159,18 @@ proptest! { #[test] fn prop_test_inner_product(inputs in (vec(rand_witness(), 0..=100), vec(rand_witness(), 0..=100)).prop_filter("Input vectors must have equal length", |(a, b)| a.len() == b.len())) { - let ground_truth = inner_product_ground_truth(&inputs); + let a = inputs.0.iter().map(|x| *x.value()).collect::>(); + let b = inputs.1.iter().map(|x| *x.value()).collect::>(); + let ground_truth = inner_product_ground_truth(&a, &b); let result = flex_gate::test_inner_product(inputs); prop_assert_eq!(result, ground_truth); } #[test] fn prop_test_inner_product_left_last(inputs in (vec(rand_witness(), 1..=100), vec(rand_witness(), 1..=100)).prop_filter("Input vectors must have equal length", |(a, b)| a.len() == b.len())) { - let ground_truth = inner_product_left_last_ground_truth(&inputs); + let a = inputs.0.iter().map(|x| *x.value()).collect::>(); + let b = inputs.1.iter().map(|x| *x.value()).collect::>(); + let ground_truth = inner_product_left_last_ground_truth(&a, &b); let result = flex_gate::test_inner_product_left_last(inputs); prop_assert_eq!(result, ground_truth); } diff --git a/halo2-base/src/gates/tests/utils.rs b/halo2-base/src/gates/tests/utils.rs index 98ff7caf..8ae095da 100644 --- a/halo2-base/src/gates/tests/utils.rs +++ b/halo2-base/src/gates/tests/utils.rs @@ -39,21 +39,13 @@ pub fn div_unsafe_ground_truth(inputs: &[QuantumCell]) -> F { inputs[1].value().invert().unwrap() * *inputs[0].value() } -pub fn inner_product_ground_truth( - inputs: &(Vec>, Vec>), -) -> F { - inputs - .0 - .iter() - .zip(inputs.1.iter()) - .fold(F::ZERO, |acc, (a, b)| acc + (*a.value() * *b.value())) -} - -pub fn inner_product_left_last_ground_truth( - inputs: &(Vec>, Vec>), -) -> (F, F) { - let product = inner_product_ground_truth(inputs); - let last = *inputs.0.last().unwrap().value(); +pub fn inner_product_ground_truth(a: &[F], b: &[F]) -> F { + a.iter().zip(b.iter()).fold(F::ZERO, |acc, (&a, &b)| acc + a * b) +} + +pub fn inner_product_left_last_ground_truth(a: &[F], b: &[F]) -> (F, F) { + let product = inner_product_ground_truth(a, b); + let last = *a.last().unwrap(); (product, last) } diff --git a/halo2-base/src/lib.rs b/halo2-base/src/lib.rs index 1cc396e6..51f51316 100644 --- a/halo2-base/src/lib.rs +++ b/halo2-base/src/lib.rs @@ -127,10 +127,10 @@ impl AssignedValue { } } - /// Debug helper function for writing negative tests. This will change the **witness** value of the assigned cell - /// to `prank_value`. It does not change any constraints. - pub fn debug_prank(&mut self, prank_value: F) { - self.value = Assigned::Trivial(prank_value); + /// Debug helper function for writing negative tests. This will change the **witness** value in `ctx` corresponding to `self.offset`. + /// This assumes that `ctx` is the context that `self` lies in. + pub fn debug_prank(&self, ctx: &mut Context, prank_value: F) { + ctx.advice[self.cell.unwrap().offset] = Assigned::Trivial(prank_value); } } diff --git a/halo2-base/src/safe_types/tests.rs b/halo2-base/src/safe_types/tests.rs index ccf49930..69e2fc39 100644 --- a/halo2-base/src/safe_types/tests.rs +++ b/halo2-base/src/safe_types/tests.rs @@ -1,5 +1,4 @@ use crate::{ - gates::builder::set_lookup_bits, halo2_proofs::{halo2curves::bn256::Fr, poly::kzg::commitment::ParamsKZG}, utils::testing::{check_proof, gen_proof}, }; @@ -28,7 +27,6 @@ fn test_raw_bytes_to_gen( // first create proving and verifying key let mut builder = GateThreadBuilder::::keygen(); let lookup_bits = 3; - set_lookup_bits(lookup_bits); let range_chip = RangeChip::::default(lookup_bits); let safe_type_chip = SafeTypeChip::new(&range_chip); @@ -42,8 +40,8 @@ fn test_raw_bytes_to_gen( let safe_value_offsets = safe_value.value().iter().map(|v| v.cell.unwrap().offset).collect::>(); // set env vars - builder.config(k as usize, Some(9)); - let circuit = RangeCircuitBuilder::keygen(builder); + let config_params = builder.config(k as usize, Some(9), Some(lookup_bits)); + let circuit = RangeCircuitBuilder::keygen(builder, config_params.clone()); let params = ParamsKZG::setup(k, OsRng); // generate proving key @@ -64,7 +62,7 @@ fn test_raw_bytes_to_gen( for (offset, witness) in safe_value_offsets.iter().zip_eq(outputs) { builder.main(0).advice[*offset] = Assigned::::Trivial(*witness); } - let circuit = RangeCircuitBuilder::prover(builder, vec![vec![]]); // no break points + let circuit = RangeCircuitBuilder::prover(builder, config_params, vec![vec![]]); // no break points gen_proof(¶ms, &pk, circuit) }; let pf = gen_pf(raw_bytes, outputs); diff --git a/halo2-base/src/utils/testing.rs b/halo2-base/src/utils/testing.rs index e51b4eef..b5c25c12 100644 --- a/halo2-base/src/utils/testing.rs +++ b/halo2-base/src/utils/testing.rs @@ -1,7 +1,7 @@ //! Utilities for testing use crate::{ gates::{ - builder::{GateThreadBuilder, RangeCircuitBuilder, BASE_CONFIG_PARAMS}, + builder::{GateThreadBuilder, RangeCircuitBuilder}, GateChip, }, halo2_proofs::{ @@ -130,10 +130,6 @@ impl BaseTester { ) -> R { let mut builder = GateThreadBuilder::mock(); let range = RangeChip::default(self.lookup_bits.unwrap_or(0)); - BASE_CONFIG_PARAMS.with(|conf| { - conf.borrow_mut().k = self.k as usize; - conf.borrow_mut().lookup_bits = self.lookup_bits; - }); // run the function, mutating `builder` let res = f(&mut builder, &range); @@ -143,16 +139,12 @@ impl BaseTester { .iter() .map(|t| t.iter().map(|ctx| ctx.cells_to_lookup.len()).sum::()) .sum::(); - if t_cells_lookup == 0 { - BASE_CONFIG_PARAMS.with(|conf| { - conf.borrow_mut().lookup_bits = None; - }) - } + let lookup_bits = if t_cells_lookup == 0 { None } else { self.lookup_bits }; // configure the circuit shape, 9 blinding rows seems enough - builder.config(self.k as usize, Some(9)); + let config_params = builder.config(self.k as usize, Some(9), lookup_bits); // create circuit - let circuit = RangeCircuitBuilder::mock(builder); + let circuit = RangeCircuitBuilder::mock(builder, config_params); if self.expect_satisfied { MockProver::run(self.k, &circuit, vec![]).unwrap().assert_satisfied(); } else { diff --git a/halo2-ecc/benches/fixed_base_msm.rs b/halo2-ecc/benches/fixed_base_msm.rs index 40f108d9..4e92bea4 100644 --- a/halo2-ecc/benches/fixed_base_msm.rs +++ b/halo2-ecc/benches/fixed_base_msm.rs @@ -1,7 +1,7 @@ use ark_std::{end_timer, start_timer}; use halo2_base::gates::{ builder::{ - set_lookup_bits, CircuitBuilderStage, GateThreadBuilder, MultiPhaseThreadBreakPoints, + BaseConfigParams, CircuitBuilderStage, GateThreadBuilder, MultiPhaseThreadBreakPoints, RangeCircuitBuilder, }, RangeChip, @@ -47,7 +47,6 @@ fn fixed_base_msm_bench( bases: Vec, scalars: Vec, ) { - set_lookup_bits(params.lookup_bits); let range = RangeChip::::default(params.lookup_bits); let fp_chip = FpChip::::new(&range, params.limb_bits, params.num_limbs); let ecc_chip = EccChip::new(&fp_chip); @@ -65,28 +64,23 @@ fn fixed_base_msm_circuit( stage: CircuitBuilderStage, bases: Vec, scalars: Vec, + config_params: Option, break_points: Option, ) -> RangeCircuitBuilder { let k = params.degree as usize; - let mut builder = match stage { - CircuitBuilderStage::Mock => GateThreadBuilder::mock(), - CircuitBuilderStage::Prover => GateThreadBuilder::prover(), - CircuitBuilderStage::Keygen => GateThreadBuilder::keygen(), - }; + let mut builder = GateThreadBuilder::new(stage == CircuitBuilderStage::Prover); let start0 = start_timer!(|| format!("Witness generation for circuit in {stage:?} stage")); fixed_base_msm_bench(&mut builder, params, bases, scalars); + let config_params = + config_params.unwrap_or_else(|| builder.config(k, Some(20), Some(params.lookup_bits))); let circuit = match stage { - CircuitBuilderStage::Mock => { - builder.config(k, Some(20)); - RangeCircuitBuilder::mock(builder) - } - CircuitBuilderStage::Keygen => { - builder.config(k, Some(20)); - RangeCircuitBuilder::keygen(builder) + CircuitBuilderStage::Mock => RangeCircuitBuilder::mock(builder, config_params), + CircuitBuilderStage::Keygen => RangeCircuitBuilder::keygen(builder, config_params), + CircuitBuilderStage::Prover => { + RangeCircuitBuilder::prover(builder, config_params, break_points.unwrap()) } - CircuitBuilderStage::Prover => RangeCircuitBuilder::prover(builder, break_points.unwrap()), }; end_timer!(start0); circuit @@ -103,7 +97,9 @@ fn bench(c: &mut Criterion) { vec![G1Affine::generator(); config.batch_size], vec![Fr::zero(); config.batch_size], None, + None, ); + let config_params = circuit.0.config_params.clone(); let params = ParamsKZG::::setup(k, &mut rng); let vk = keygen_vk(¶ms, &circuit).expect("vk should not fail"); @@ -125,6 +121,7 @@ fn bench(c: &mut Criterion) { CircuitBuilderStage::Prover, bases.clone(), scalars.clone(), + Some(config_params.clone()), Some(break_points.clone()), ); diff --git a/halo2-ecc/benches/fp_mul.rs b/halo2-ecc/benches/fp_mul.rs index 249b57c0..d4fe1871 100644 --- a/halo2-ecc/benches/fp_mul.rs +++ b/halo2-ecc/benches/fp_mul.rs @@ -2,7 +2,7 @@ use ark_std::{end_timer, start_timer}; use halo2_base::{ gates::{ builder::{ - set_lookup_bits, CircuitBuilderStage, GateThreadBuilder, MultiPhaseThreadBreakPoints, + BaseConfigParams, CircuitBuilderStage, GateThreadBuilder, MultiPhaseThreadBreakPoints, RangeCircuitBuilder, }, RangeChip, @@ -41,7 +41,6 @@ fn fp_mul_bench( _a: Fq, _b: Fq, ) { - set_lookup_bits(lookup_bits); let range = RangeChip::::default(lookup_bits); let chip = FpChip::::new(&range, limb_bits, num_limbs); @@ -55,9 +54,11 @@ fn fp_mul_circuit( stage: CircuitBuilderStage, a: Fq, b: Fq, + config_params: Option, break_points: Option, ) -> RangeCircuitBuilder { let k = K as usize; + let lookup_bits = k - 1; let mut builder = match stage { CircuitBuilderStage::Mock => GateThreadBuilder::mock(), CircuitBuilderStage::Prover => GateThreadBuilder::prover(), @@ -65,25 +66,24 @@ fn fp_mul_circuit( }; let start0 = start_timer!(|| format!("Witness generation for circuit in {stage:?} stage")); - fp_mul_bench(builder.main(0), k - 1, 88, 3, a, b); + fp_mul_bench(builder.main(0), lookup_bits, 88, 3, a, b); + let config_params = + config_params.unwrap_or_else(|| builder.config(k, Some(20), Some(lookup_bits))); let circuit = match stage { - CircuitBuilderStage::Mock => { - builder.config(k, Some(20)); - RangeCircuitBuilder::mock(builder) + CircuitBuilderStage::Mock => RangeCircuitBuilder::mock(builder, config_params), + CircuitBuilderStage::Keygen => RangeCircuitBuilder::keygen(builder, config_params), + CircuitBuilderStage::Prover => { + RangeCircuitBuilder::prover(builder, config_params, break_points.unwrap()) } - CircuitBuilderStage::Keygen => { - builder.config(k, Some(20)); - RangeCircuitBuilder::keygen(builder) - } - CircuitBuilderStage::Prover => RangeCircuitBuilder::prover(builder, break_points.unwrap()), }; end_timer!(start0); circuit } fn bench(c: &mut Criterion) { - let circuit = fp_mul_circuit(CircuitBuilderStage::Keygen, Fq::zero(), Fq::zero(), None); + let circuit = fp_mul_circuit(CircuitBuilderStage::Keygen, Fq::zero(), Fq::zero(), None, None); + let config_params = circuit.0.config_params.clone(); let params = ParamsKZG::::setup(K, OsRng); let vk = keygen_vk(¶ms, &circuit).expect("vk should not fail"); @@ -99,8 +99,13 @@ fn bench(c: &mut Criterion) { &(¶ms, &pk, a, b), |bencher, &(params, pk, a, b)| { bencher.iter(|| { - let circuit = - fp_mul_circuit(CircuitBuilderStage::Prover, a, b, Some(break_points.clone())); + let circuit = fp_mul_circuit( + CircuitBuilderStage::Prover, + a, + b, + Some(config_params.clone()), + Some(break_points.clone()), + ); let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); create_proof::< diff --git a/halo2-ecc/benches/msm.rs b/halo2-ecc/benches/msm.rs index aa5a0e6b..fd5efda7 100644 --- a/halo2-ecc/benches/msm.rs +++ b/halo2-ecc/benches/msm.rs @@ -1,7 +1,7 @@ use ark_std::{end_timer, start_timer}; use halo2_base::gates::{ builder::{ - set_lookup_bits, CircuitBuilderStage, GateThreadBuilder, MultiPhaseThreadBreakPoints, + BaseConfigParams, CircuitBuilderStage, GateThreadBuilder, MultiPhaseThreadBreakPoints, RangeCircuitBuilder, }, RangeChip, @@ -53,7 +53,6 @@ fn msm_bench( bases: Vec, scalars: Vec, ) { - set_lookup_bits(params.lookup_bits); let range = RangeChip::::default(params.lookup_bits); let fp_chip = FpChip::::new(&range, params.limb_bits, params.num_limbs); let ecc_chip = EccChip::new(&fp_chip); @@ -81,6 +80,7 @@ fn msm_circuit( stage: CircuitBuilderStage, bases: Vec, scalars: Vec, + config_params: Option, break_points: Option, ) -> RangeCircuitBuilder { let start0 = start_timer!(|| format!("Witness generation for circuit in {stage:?} stage")); @@ -93,16 +93,14 @@ fn msm_circuit( msm_bench(&mut builder, params, bases, scalars); + let config_params = + config_params.unwrap_or_else(|| builder.config(k, Some(20), Some(params.lookup_bits))); let circuit = match stage { - CircuitBuilderStage::Mock => { - builder.config(k, Some(20)); - RangeCircuitBuilder::mock(builder) + CircuitBuilderStage::Mock => RangeCircuitBuilder::mock(builder, config_params), + CircuitBuilderStage::Keygen => RangeCircuitBuilder::keygen(builder, config_params), + CircuitBuilderStage::Prover => { + RangeCircuitBuilder::prover(builder, config_params, break_points.unwrap()) } - CircuitBuilderStage::Keygen => { - builder.config(k, Some(20)); - RangeCircuitBuilder::keygen(builder) - } - CircuitBuilderStage::Prover => RangeCircuitBuilder::prover(builder, break_points.unwrap()), }; end_timer!(start0); circuit @@ -119,7 +117,9 @@ fn bench(c: &mut Criterion) { vec![G1Affine::generator(); config.batch_size], vec![Fr::one(); config.batch_size], None, + None, ); + let config_params = circuit.0.config_params.clone(); let params = ParamsKZG::::setup(k, &mut rng); let vk = keygen_vk(¶ms, &circuit).expect("vk should not fail"); @@ -141,6 +141,7 @@ fn bench(c: &mut Criterion) { CircuitBuilderStage::Prover, bases.clone(), scalars.clone(), + Some(config_params.clone()), Some(break_points.clone()), ); diff --git a/halo2-ecc/src/bn254/tests/ec_add.rs b/halo2-ecc/src/bn254/tests/ec_add.rs index 46053c25..e3eb1a3a 100644 --- a/halo2-ecc/src/bn254/tests/ec_add.rs +++ b/halo2-ecc/src/bn254/tests/ec_add.rs @@ -6,7 +6,7 @@ use super::*; use crate::fields::{FieldChip, FpStrategy}; use crate::group::cofactor::CofactorCurveAffine; use crate::halo2_proofs::halo2curves::bn256::G2Affine; -use halo2_base::gates::builder::{set_lookup_bits, GateThreadBuilder, RangeCircuitBuilder}; +use halo2_base::gates::builder::{GateThreadBuilder, RangeCircuitBuilder}; use halo2_base::gates::RangeChip; use halo2_base::utils::fs::gen_srs; use halo2_base::utils::BigPrimeField; @@ -32,7 +32,6 @@ fn g2_add_test( params: CircuitParams, _points: Vec, ) { - set_lookup_bits(params.lookup_bits); let range = RangeChip::::default(params.lookup_bits); let fp_chip = FpChip::::new(&range, params.limb_bits, params.num_limbs); let fp2_chip = Fp2Chip::::new(&fp_chip); @@ -64,8 +63,8 @@ fn test_ec_add() { let mut builder = GateThreadBuilder::::mock(); g2_add_test(builder.main(0), params, points); - builder.config(k as usize, Some(20)); - let circuit = RangeCircuitBuilder::mock(builder); + let config_params = builder.config(k as usize, Some(20), Some(params.lookup_bits)); + let circuit = RangeCircuitBuilder::mock(builder, config_params); MockProver::run(k, &circuit, vec![]).unwrap().assert_satisfied(); } @@ -97,8 +96,8 @@ fn bench_ec_add() -> Result<(), Box> { let points = vec![G2Affine::generator(); bench_params.batch_size]; let mut builder = GateThreadBuilder::::keygen(); g2_add_test(builder.main(0), bench_params, points); - builder.config(k as usize, Some(20)); - RangeCircuitBuilder::keygen(builder) + let cp = builder.config(k as usize, Some(20), Some(bench_params.lookup_bits)); + RangeCircuitBuilder::keygen(builder, cp) }; end_timer!(start0); @@ -118,8 +117,8 @@ fn bench_ec_add() -> Result<(), Box> { let proof_circuit = { let mut builder = GateThreadBuilder::::prover(); g2_add_test(builder.main(0), bench_params, points); - builder.config(k as usize, Some(20)); - RangeCircuitBuilder::prover(builder, break_points) + let cp = builder.config(k as usize, Some(20), Some(bench_params.lookup_bits)); + RangeCircuitBuilder::prover(builder, cp, break_points) }; let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); create_proof::< diff --git a/halo2-ecc/src/bn254/tests/fixed_base_msm.rs b/halo2-ecc/src/bn254/tests/fixed_base_msm.rs index 9650e36b..679b4fea 100644 --- a/halo2-ecc/src/bn254/tests/fixed_base_msm.rs +++ b/halo2-ecc/src/bn254/tests/fixed_base_msm.rs @@ -10,7 +10,7 @@ use super::*; use halo2_base::{ gates::{ builder::{ - set_lookup_bits, CircuitBuilderStage, GateThreadBuilder, MultiPhaseThreadBreakPoints, + BaseConfigParams, CircuitBuilderStage, GateThreadBuilder, MultiPhaseThreadBreakPoints, RangeCircuitBuilder, }, RangeChip, @@ -42,7 +42,6 @@ fn fixed_base_msm_test( bases: Vec, scalars: Vec, ) { - set_lookup_bits(params.lookup_bits); let range = RangeChip::::default(params.lookup_bits); let fp_chip = FpChip::::new(&range, params.limb_bits, params.num_limbs); let ecc_chip = EccChip::new(&fp_chip); @@ -70,6 +69,7 @@ fn random_fixed_base_msm_circuit( params: FixedMSMCircuitParams, bases: Vec, // bases are fixed in vkey so don't randomly generate stage: CircuitBuilderStage, + config_params: Option, break_points: Option, ) -> RangeCircuitBuilder { let k = params.degree as usize; @@ -83,16 +83,14 @@ fn random_fixed_base_msm_circuit( let start0 = start_timer!(|| format!("Witness generation for circuit in {stage:?} stage")); fixed_base_msm_test(&mut builder, params, bases, scalars); + let config_params = + config_params.unwrap_or_else(|| builder.config(k, Some(20), Some(params.lookup_bits))); let circuit = match stage { - CircuitBuilderStage::Mock => { - builder.config(k, Some(20)); - RangeCircuitBuilder::mock(builder) + CircuitBuilderStage::Mock => RangeCircuitBuilder::mock(builder, config_params), + CircuitBuilderStage::Keygen => RangeCircuitBuilder::keygen(builder, config_params), + CircuitBuilderStage::Prover => { + RangeCircuitBuilder::prover(builder, config_params, break_points.unwrap()) } - CircuitBuilderStage::Keygen => { - builder.config(k, Some(20)); - RangeCircuitBuilder::keygen(builder) - } - CircuitBuilderStage::Prover => RangeCircuitBuilder::prover(builder, break_points.unwrap()), }; end_timer!(start0); circuit @@ -107,7 +105,8 @@ fn test_fixed_base_msm() { .unwrap(); let bases = (0..params.batch_size).map(|_| G1Affine::random(OsRng)).collect_vec(); - let circuit = random_fixed_base_msm_circuit(params, bases, CircuitBuilderStage::Mock, None); + let circuit = + random_fixed_base_msm_circuit(params, bases, CircuitBuilderStage::Mock, None, None); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); } @@ -123,8 +122,8 @@ fn test_fixed_msm_minus_1() { let mut builder = GateThreadBuilder::mock(); fixed_base_msm_test(&mut builder, params, vec![base], vec![-Fr::one()]); - builder.config(k, Some(20)); - let circuit = RangeCircuitBuilder::mock(builder); + let config_params = builder.config(k, Some(20), Some(params.lookup_bits)); + let circuit = RangeCircuitBuilder::mock(builder, config_params); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); } @@ -157,7 +156,9 @@ fn bench_fixed_base_msm() -> Result<(), Box> { bases.clone(), CircuitBuilderStage::Keygen, None, + None, ); + let cp = circuit.0.config_params.clone(); let vk_time = start_timer!(|| "Generating vkey"); let vk = keygen_vk(¶ms, &circuit)?; @@ -175,6 +176,7 @@ fn bench_fixed_base_msm() -> Result<(), Box> { bench_params, bases, CircuitBuilderStage::Prover, + Some(cp), Some(break_points), ); let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); diff --git a/halo2-ecc/src/bn254/tests/msm.rs b/halo2-ecc/src/bn254/tests/msm.rs index 0e144a03..c2e54358 100644 --- a/halo2-ecc/src/bn254/tests/msm.rs +++ b/halo2-ecc/src/bn254/tests/msm.rs @@ -1,9 +1,10 @@ use crate::ff::{Field, PrimeField}; use crate::fields::FpStrategy; +use halo2_base::gates::builder::BaseConfigParams; use halo2_base::{ gates::{ builder::{ - set_lookup_bits, CircuitBuilderStage, GateThreadBuilder, MultiPhaseThreadBreakPoints, + CircuitBuilderStage, GateThreadBuilder, MultiPhaseThreadBreakPoints, RangeCircuitBuilder, }, RangeChip, @@ -39,7 +40,6 @@ fn msm_test( scalars: Vec, window_bits: usize, ) { - set_lookup_bits(params.lookup_bits); let range = RangeChip::::default(params.lookup_bits); let fp_chip = FpChip::::new(&range, params.limb_bits, params.num_limbs); let ecc_chip = EccChip::new(&fp_chip); @@ -78,6 +78,7 @@ fn msm_test( fn random_msm_circuit( params: MSMCircuitParams, stage: CircuitBuilderStage, + config_params: Option, break_points: Option, ) -> RangeCircuitBuilder { let k = params.degree as usize; @@ -92,16 +93,14 @@ fn random_msm_circuit( let start0 = start_timer!(|| format!("Witness generation for circuit in {stage:?} stage")); msm_test(&mut builder, params, bases, scalars, params.window_bits); + let config_params = + config_params.unwrap_or_else(|| builder.config(k, Some(20), Some(params.lookup_bits))); let circuit = match stage { - CircuitBuilderStage::Mock => { - builder.config(k, Some(20)); - RangeCircuitBuilder::mock(builder) + CircuitBuilderStage::Mock => RangeCircuitBuilder::mock(builder, config_params), + CircuitBuilderStage::Keygen => RangeCircuitBuilder::keygen(builder, config_params), + CircuitBuilderStage::Prover => { + RangeCircuitBuilder::prover(builder, config_params, break_points.unwrap()) } - CircuitBuilderStage::Keygen => { - builder.config(k, Some(20)); - RangeCircuitBuilder::keygen(builder) - } - CircuitBuilderStage::Prover => RangeCircuitBuilder::prover(builder, break_points.unwrap()), }; end_timer!(start0); circuit @@ -115,7 +114,7 @@ fn test_msm() { ) .unwrap(); - let circuit = random_msm_circuit(params, CircuitBuilderStage::Mock, None); + let circuit = random_msm_circuit(params, CircuitBuilderStage::Mock, None, None); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); } @@ -141,7 +140,7 @@ fn bench_msm() -> Result<(), Box> { let params = gen_srs(k); println!("{bench_params:?}"); - let circuit = random_msm_circuit(bench_params, CircuitBuilderStage::Keygen, None); + let circuit = random_msm_circuit(bench_params, CircuitBuilderStage::Keygen, None, None); let vk_time = start_timer!(|| "Generating vkey"); let vk = keygen_vk(¶ms, &circuit)?; @@ -151,12 +150,17 @@ fn bench_msm() -> Result<(), Box> { let pk = keygen_pk(¶ms, vk, &circuit)?; end_timer!(pk_time); + let config_params = circuit.0.config_params.clone(); let break_points = circuit.0.break_points.take(); drop(circuit); // create a proof let proof_time = start_timer!(|| "Proving time"); - let circuit = - random_msm_circuit(bench_params, CircuitBuilderStage::Prover, Some(break_points)); + let circuit = random_msm_circuit( + bench_params, + CircuitBuilderStage::Prover, + Some(config_params), + Some(break_points), + ); let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); create_proof::< KZGCommitmentScheme, diff --git a/halo2-ecc/src/bn254/tests/msm_sum_infinity.rs b/halo2-ecc/src/bn254/tests/msm_sum_infinity.rs index e0e4261b..64e05e37 100644 --- a/halo2-ecc/src/bn254/tests/msm_sum_infinity.rs +++ b/halo2-ecc/src/bn254/tests/msm_sum_infinity.rs @@ -1,7 +1,7 @@ use crate::ff::PrimeField; use halo2_base::gates::{ builder::{ - set_lookup_bits, CircuitBuilderStage, GateThreadBuilder, MultiPhaseThreadBreakPoints, + BaseConfigParams, CircuitBuilderStage, GateThreadBuilder, MultiPhaseThreadBreakPoints, RangeCircuitBuilder, }, RangeChip, @@ -18,7 +18,6 @@ fn msm_test( scalars: Vec, window_bits: usize, ) { - set_lookup_bits(params.lookup_bits); let range = RangeChip::::default(params.lookup_bits); let fp_chip = FpChip::::new(&range, params.limb_bits, params.num_limbs); let ecc_chip = EccChip::new(&fp_chip); @@ -57,6 +56,7 @@ fn msm_test( fn custom_msm_circuit( params: MSMCircuitParams, stage: CircuitBuilderStage, + config_params: Option, break_points: Option, bases: Vec, scalars: Vec, @@ -71,16 +71,14 @@ fn custom_msm_circuit( let start0 = start_timer!(|| format!("Witness generation for circuit in {stage:?} stage")); msm_test(&mut builder, params, bases, scalars, params.window_bits); + let config_params = + config_params.unwrap_or_else(|| builder.config(k, Some(20), Some(params.lookup_bits))); let circuit = match stage { - CircuitBuilderStage::Mock => { - builder.config(k, Some(20)); - RangeCircuitBuilder::mock(builder) + CircuitBuilderStage::Mock => RangeCircuitBuilder::mock(builder, config_params), + CircuitBuilderStage::Keygen => RangeCircuitBuilder::keygen(builder, config_params), + CircuitBuilderStage::Prover => { + RangeCircuitBuilder::prover(builder, config_params, break_points.unwrap()) } - CircuitBuilderStage::Keygen => { - builder.config(k, Some(20)); - RangeCircuitBuilder::keygen(builder) - } - CircuitBuilderStage::Prover => RangeCircuitBuilder::prover(builder, break_points.unwrap()), }; end_timer!(start0); circuit @@ -99,7 +97,7 @@ fn test_msm1() { let bases = vec![random_point, random_point, random_point]; let scalars = vec![Fr::one(), Fr::one(), -Fr::one() - Fr::one()]; - let circuit = custom_msm_circuit(params, CircuitBuilderStage::Mock, None, bases, scalars); + let circuit = custom_msm_circuit(params, CircuitBuilderStage::Mock, None, None, bases, scalars); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); } @@ -116,7 +114,7 @@ fn test_msm2() { let bases = vec![random_point, random_point, (random_point + random_point).to_affine()]; let scalars = vec![Fr::one(), Fr::one(), -Fr::one()]; - let circuit = custom_msm_circuit(params, CircuitBuilderStage::Mock, None, bases, scalars); + let circuit = custom_msm_circuit(params, CircuitBuilderStage::Mock, None, None, bases, scalars); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); } @@ -138,7 +136,7 @@ fn test_msm3() { ]; let scalars = vec![Fr::one(), Fr::one(), Fr::one(), -Fr::one()]; - let circuit = custom_msm_circuit(params, CircuitBuilderStage::Mock, None, bases, scalars); + let circuit = custom_msm_circuit(params, CircuitBuilderStage::Mock, None, None, bases, scalars); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); } @@ -160,7 +158,7 @@ fn test_msm4() { ]; let scalars = vec![Fr::one(), Fr::one(), Fr::one(), -Fr::one()]; - let circuit = custom_msm_circuit(params, CircuitBuilderStage::Mock, None, bases, scalars); + let circuit = custom_msm_circuit(params, CircuitBuilderStage::Mock, None, None, bases, scalars); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); } @@ -179,6 +177,6 @@ fn test_msm5() { vec![random_point, random_point, random_point, (random_point + random_point).to_affine()]; let scalars = vec![-Fr::one(), -Fr::one(), Fr::one(), Fr::one()]; - let circuit = custom_msm_circuit(params, CircuitBuilderStage::Mock, None, bases, scalars); + let circuit = custom_msm_circuit(params, CircuitBuilderStage::Mock, None, None, bases, scalars); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); } diff --git a/halo2-ecc/src/bn254/tests/msm_sum_infinity_fixed_base.rs b/halo2-ecc/src/bn254/tests/msm_sum_infinity_fixed_base.rs index 4309a6c4..3d9c7add 100644 --- a/halo2-ecc/src/bn254/tests/msm_sum_infinity_fixed_base.rs +++ b/halo2-ecc/src/bn254/tests/msm_sum_infinity_fixed_base.rs @@ -1,7 +1,7 @@ use crate::ff::PrimeField; use halo2_base::gates::{ builder::{ - set_lookup_bits, CircuitBuilderStage, GateThreadBuilder, MultiPhaseThreadBreakPoints, + BaseConfigParams, CircuitBuilderStage, GateThreadBuilder, MultiPhaseThreadBreakPoints, RangeCircuitBuilder, }, RangeChip, @@ -18,7 +18,6 @@ fn msm_test( scalars: Vec, window_bits: usize, ) { - set_lookup_bits(params.lookup_bits); let range = RangeChip::::default(params.lookup_bits); let fp_chip = FpChip::::new(&range, params.limb_bits, params.num_limbs); let ecc_chip = EccChip::new(&fp_chip); @@ -57,6 +56,7 @@ fn msm_test( fn custom_msm_circuit( params: MSMCircuitParams, stage: CircuitBuilderStage, + config_params: Option, break_points: Option, bases: Vec, scalars: Vec, @@ -70,17 +70,14 @@ fn custom_msm_circuit( let start0 = start_timer!(|| format!("Witness generation for circuit in {stage:?} stage")); msm_test(&mut builder, params, bases, scalars, params.window_bits); - + let config_params = + config_params.unwrap_or_else(|| builder.config(k, Some(20), Some(params.lookup_bits))); let circuit = match stage { - CircuitBuilderStage::Mock => { - builder.config(k, Some(20)); - RangeCircuitBuilder::mock(builder) - } - CircuitBuilderStage::Keygen => { - builder.config(k, Some(20)); - RangeCircuitBuilder::keygen(builder) + CircuitBuilderStage::Mock => RangeCircuitBuilder::mock(builder, config_params), + CircuitBuilderStage::Keygen => RangeCircuitBuilder::keygen(builder, config_params), + CircuitBuilderStage::Prover => { + RangeCircuitBuilder::prover(builder, config_params, break_points.unwrap()) } - CircuitBuilderStage::Prover => RangeCircuitBuilder::prover(builder, break_points.unwrap()), }; end_timer!(start0); circuit @@ -99,7 +96,7 @@ fn test_fb_msm1() { let bases = vec![random_point, random_point, random_point]; let scalars = vec![Fr::one(), Fr::one(), -Fr::one() - Fr::one()]; - let circuit = custom_msm_circuit(params, CircuitBuilderStage::Mock, None, bases, scalars); + let circuit = custom_msm_circuit(params, CircuitBuilderStage::Mock, None, None, bases, scalars); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); } @@ -116,7 +113,7 @@ fn test_fb_msm2() { let bases = vec![random_point, random_point, (random_point + random_point).to_affine()]; let scalars = vec![Fr::one(), Fr::one(), -Fr::one()]; - let circuit = custom_msm_circuit(params, CircuitBuilderStage::Mock, None, bases, scalars); + let circuit = custom_msm_circuit(params, CircuitBuilderStage::Mock, None, None, bases, scalars); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); } @@ -138,7 +135,7 @@ fn test_fb_msm3() { ]; let scalars = vec![Fr::one(), Fr::one(), Fr::one(), -Fr::one()]; - let circuit = custom_msm_circuit(params, CircuitBuilderStage::Mock, None, bases, scalars); + let circuit = custom_msm_circuit(params, CircuitBuilderStage::Mock, None, None, bases, scalars); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); } @@ -160,7 +157,7 @@ fn test_fb_msm4() { ]; let scalars = vec![Fr::one(), Fr::one(), Fr::one(), -Fr::one()]; - let circuit = custom_msm_circuit(params, CircuitBuilderStage::Mock, None, bases, scalars); + let circuit = custom_msm_circuit(params, CircuitBuilderStage::Mock, None, None, bases, scalars); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); } @@ -179,6 +176,6 @@ fn test_fb_msm5() { vec![random_point, random_point, random_point, (random_point + random_point).to_affine()]; let scalars = vec![-Fr::one(), -Fr::one(), Fr::one(), Fr::one()]; - let circuit = custom_msm_circuit(params, CircuitBuilderStage::Mock, None, bases, scalars); + let circuit = custom_msm_circuit(params, CircuitBuilderStage::Mock, None, None, bases, scalars); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); } diff --git a/halo2-ecc/src/bn254/tests/pairing.rs b/halo2-ecc/src/bn254/tests/pairing.rs index 0273c399..8214e0c2 100644 --- a/halo2-ecc/src/bn254/tests/pairing.rs +++ b/halo2-ecc/src/bn254/tests/pairing.rs @@ -9,7 +9,7 @@ use crate::{fields::FpStrategy, halo2_proofs::halo2curves::bn256::G2Affine}; use halo2_base::{ gates::{ builder::{ - set_lookup_bits, CircuitBuilderStage, GateThreadBuilder, MultiPhaseThreadBreakPoints, + BaseConfigParams, CircuitBuilderStage, GateThreadBuilder, MultiPhaseThreadBreakPoints, RangeCircuitBuilder, }, RangeChip, @@ -38,7 +38,6 @@ fn pairing_test( P: G1Affine, Q: G2Affine, ) { - set_lookup_bits(params.lookup_bits); let range = RangeChip::::default(params.lookup_bits); let fp_chip = FpChip::::new(&range, params.limb_bits, params.num_limbs); let chip = PairingChip::new(&fp_chip); @@ -61,6 +60,7 @@ fn pairing_test( fn random_pairing_circuit( params: PairingCircuitParams, stage: CircuitBuilderStage, + config_params: Option, break_points: Option, ) -> RangeCircuitBuilder { let k = params.degree as usize; @@ -76,16 +76,14 @@ fn random_pairing_circuit( let start0 = start_timer!(|| format!("Witness generation for circuit in {stage:?} stage")); pairing_test::(builder.main(0), params, P, Q); + let config_params = + config_params.unwrap_or_else(|| builder.config(k, Some(20), Some(params.lookup_bits))); let circuit = match stage { - CircuitBuilderStage::Mock => { - builder.config(k, Some(20)); - RangeCircuitBuilder::mock(builder) + CircuitBuilderStage::Mock => RangeCircuitBuilder::mock(builder, config_params), + CircuitBuilderStage::Keygen => RangeCircuitBuilder::keygen(builder, config_params), + CircuitBuilderStage::Prover => { + RangeCircuitBuilder::prover(builder, config_params, break_points.unwrap()) } - CircuitBuilderStage::Keygen => { - builder.config(k, Some(20)); - RangeCircuitBuilder::keygen(builder) - } - CircuitBuilderStage::Prover => RangeCircuitBuilder::prover(builder, break_points.unwrap()), }; end_timer!(start0); circuit @@ -99,7 +97,7 @@ fn test_pairing() { ) .unwrap(); - let circuit = random_pairing_circuit(params, CircuitBuilderStage::Mock, None); + let circuit = random_pairing_circuit(params, CircuitBuilderStage::Mock, None, None); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); } @@ -124,7 +122,7 @@ fn bench_pairing() -> Result<(), Box> { println!("---------------------- degree = {k} ------------------------------",); let params = gen_srs(k); - let circuit = random_pairing_circuit(bench_params, CircuitBuilderStage::Keygen, None); + let circuit = random_pairing_circuit(bench_params, CircuitBuilderStage::Keygen, None, None); let vk_time = start_timer!(|| "Generating vkey"); let vk = keygen_vk(¶ms, &circuit)?; @@ -135,11 +133,16 @@ fn bench_pairing() -> Result<(), Box> { end_timer!(pk_time); let break_points = circuit.0.break_points.take(); + let config_params = circuit.0.config_params.clone(); drop(circuit); // create a proof let proof_time = start_timer!(|| "Proving time"); - let circuit = - random_pairing_circuit(bench_params, CircuitBuilderStage::Prover, Some(break_points)); + let circuit = random_pairing_circuit( + bench_params, + CircuitBuilderStage::Prover, + Some(config_params), + Some(break_points), + ); let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); create_proof::< KZGCommitmentScheme, diff --git a/halo2-ecc/src/ecc/tests.rs b/halo2-ecc/src/ecc/tests.rs index 0402220a..d53cbb89 100644 --- a/halo2-ecc/src/ecc/tests.rs +++ b/halo2-ecc/src/ecc/tests.rs @@ -8,7 +8,7 @@ use crate::halo2_proofs::{ halo2curves::bn256::{Fq, Fr, G1Affine, G2Affine, G1, G2}, plonk::*, }; -use halo2_base::gates::builder::{set_lookup_bits, RangeCircuitBuilder}; +use halo2_base::gates::builder::RangeCircuitBuilder; use halo2_base::gates::RangeChip; use halo2_base::utils::bigint_to_fe; use halo2_base::SKIP_FIRST_PASS; @@ -26,7 +26,6 @@ fn basic_g1_tests( P: G1Affine, Q: G1Affine, ) { - set_lookup_bits(lookup_bits); let range = RangeChip::::default(lookup_bits); let fp_chip = FpChip::::new(&range, limb_bits, num_limbs); let chip = EccChip::new(&fp_chip); @@ -66,10 +65,11 @@ fn test_ecc() { let Q = G1Affine::random(OsRng); let mut builder = GateThreadBuilder::::mock(); - basic_g1_tests(builder.main(0), k - 1, 88, 3, P, Q); + let lookup_bits = k - 1; + basic_g1_tests(builder.main(0), lookup_bits, 88, 3, P, Q); - builder.config(k, Some(20)); - let circuit = RangeCircuitBuilder::mock(builder); + let config_params = builder.config(k, Some(20), Some(lookup_bits)); + let circuit = RangeCircuitBuilder::mock(builder, config_params); MockProver::run(k as u32, &circuit, vec![]).unwrap().assert_satisfied(); } @@ -90,8 +90,8 @@ fn plot_ecc() { let mut builder = GateThreadBuilder::::keygen(); basic_g1_tests(builder.main(0), 22, 88, 3, P, Q); - builder.config(k, Some(10)); - let circuit = RangeCircuitBuilder::mock(builder); + let config_params = builder.config(k, Some(10), Some(22)); + let circuit = RangeCircuitBuilder::mock(builder, config_params); halo2_proofs::dev::CircuitLayout::default().render(k, &circuit, &root).unwrap(); } diff --git a/halo2-ecc/src/fields/tests/fp/assert_eq.rs b/halo2-ecc/src/fields/tests/fp/assert_eq.rs index cc32232f..88ffa087 100644 --- a/halo2-ecc/src/fields/tests/fp/assert_eq.rs +++ b/halo2-ecc/src/fields/tests/fp/assert_eq.rs @@ -3,7 +3,7 @@ use crate::{bn254::FpChip, fields::FieldChip}; use halo2_base::{ gates::{ - builder::{set_lookup_bits, GateThreadBuilder, RangeCircuitBuilder}, + builder::{GateThreadBuilder, RangeCircuitBuilder}, RangeChip, }, halo2_proofs::{ @@ -17,7 +17,6 @@ use rand::thread_rng; // soundness checks for `` function fn test_fp_assert_eq_gen(k: u32, lookup_bits: usize, num_tries: usize) { let mut rng = thread_rng(); - set_lookup_bits(lookup_bits); // first create proving and verifying key let mut builder = GateThreadBuilder::keygen(); @@ -28,9 +27,8 @@ fn test_fp_assert_eq_gen(k: u32, lookup_bits: usize, num_tries: usize) { let a = chip.load_private(ctx, Fq::zero()); let b = chip.load_private(ctx, Fq::zero()); chip.assert_equal(ctx, &a, &b); - // set env vars - builder.config(k as usize, Some(9)); - let circuit = RangeCircuitBuilder::keygen(builder); + let config_params = builder.config(k as usize, Some(9), Some(lookup_bits)); + let circuit = RangeCircuitBuilder::keygen(builder, config_params.clone()); let params = ParamsKZG::setup(k, &mut rng); // generate proving key @@ -48,7 +46,7 @@ fn test_fp_assert_eq_gen(k: u32, lookup_bits: usize, num_tries: usize) { let ctx = builder.main(0); let [a, b] = [a, b].map(|x| chip.load_private(ctx, x)); chip.assert_equal(ctx, &a, &b); - let circuit = RangeCircuitBuilder::prover(builder, vec![vec![]]); // no break points + let circuit = RangeCircuitBuilder::prover(builder, config_params.clone(), vec![vec![]]); // no break points gen_proof(¶ms, &pk, circuit) }; diff --git a/halo2-ecc/src/fields/tests/fp/mod.rs b/halo2-ecc/src/fields/tests/fp/mod.rs index c30d0bc9..291405fa 100644 --- a/halo2-ecc/src/fields/tests/fp/mod.rs +++ b/halo2-ecc/src/fields/tests/fp/mod.rs @@ -6,7 +6,7 @@ use crate::halo2_proofs::{ halo2curves::bn256::{Fq, Fr}, }; -use halo2_base::gates::builder::{set_lookup_bits, GateThreadBuilder, RangeCircuitBuilder}; +use halo2_base::gates::builder::{GateThreadBuilder, RangeCircuitBuilder}; use halo2_base::gates::RangeChip; use halo2_base::utils::biguint_to_fe; use halo2_base::utils::{fe_to_biguint, modulus}; @@ -24,15 +24,14 @@ fn fp_chip_test( num_limbs: usize, f: impl Fn(&mut Context, &FpChip), ) { - set_lookup_bits(lookup_bits); let range = RangeChip::::default(lookup_bits); let chip = FpChip::::new(&range, limb_bits, num_limbs); let mut builder = GateThreadBuilder::mock(); f(builder.main(0), &chip); - builder.config(k, Some(10)); - let circuit = RangeCircuitBuilder::mock(builder); + let config_params = builder.config(k, Some(10), Some(lookup_bits)); + let circuit = RangeCircuitBuilder::mock(builder, config_params); MockProver::run(k as u32, &circuit, vec![]).unwrap().assert_satisfied(); } @@ -85,7 +84,7 @@ fn plot_fp() { let mut builder = GateThreadBuilder::keygen(); fp_mul_test(builder.main(0), k - 1, 88, 3, a, b); - builder.config(k, Some(10)); - let circuit = RangeCircuitBuilder::keygen(builder); + let config_params = builder.config(k, Some(10), Some(k - 1)); + let circuit = RangeCircuitBuilder::keygen(builder, config_params); halo2_proofs::dev::CircuitLayout::default().render(k as u32, &circuit, &root).unwrap(); } diff --git a/halo2-ecc/src/fields/tests/fp12/mod.rs b/halo2-ecc/src/fields/tests/fp12/mod.rs index 6c57bb51..20b847d6 100644 --- a/halo2-ecc/src/fields/tests/fp12/mod.rs +++ b/halo2-ecc/src/fields/tests/fp12/mod.rs @@ -6,7 +6,7 @@ use crate::halo2_proofs::{ dev::MockProver, halo2curves::bn256::{Fq, Fq12, Fr}, }; -use halo2_base::gates::builder::{set_lookup_bits, GateThreadBuilder, RangeCircuitBuilder}; +use halo2_base::gates::builder::{GateThreadBuilder, RangeCircuitBuilder}; use halo2_base::gates::RangeChip; use halo2_base::utils::BigPrimeField; use halo2_base::Context; @@ -22,7 +22,6 @@ fn fp12_mul_test( _a: Fq12, _b: Fq12, ) { - set_lookup_bits(lookup_bits); let range = RangeChip::::default(lookup_bits); let fp_chip = FpChip::::new(&range, limb_bits, num_limbs); let chip = Fp12Chip::::new(&fp_chip); @@ -43,10 +42,11 @@ fn test_fp12() { let b = Fq12::random(OsRng); let mut builder = GateThreadBuilder::::mock(); - fp12_mul_test(builder.main(0), k - 1, 88, 3, a, b); + let lookup_bits = k - 1; + fp12_mul_test(builder.main(0), lookup_bits, 88, 3, a, b); - builder.config(k, Some(20)); - let circuit = RangeCircuitBuilder::mock(builder); + let config_params = builder.config(k, Some(20), Some(lookup_bits)); + let circuit = RangeCircuitBuilder::mock(builder, config_params); MockProver::run(k as u32, &circuit, vec![]).unwrap().assert_satisfied(); } @@ -66,10 +66,11 @@ fn plot_fp12() { let b = Fq12::zero(); let mut builder = GateThreadBuilder::::mock(); - fp12_mul_test(builder.main(0), k - 1, 88, 3, a, b); + let lookup_bits = k - 1; + fp12_mul_test(builder.main(0), lookup_bits, 88, 3, a, b); - builder.config(k, Some(20)); - let circuit = RangeCircuitBuilder::mock(builder); + let config_params = builder.config(k, Some(20), Some(lookup_bits)); + let circuit = RangeCircuitBuilder::mock(builder, config_params); halo2_proofs::dev::CircuitLayout::default().render(k, &circuit, &root).unwrap(); } diff --git a/halo2-ecc/src/secp256k1/tests/ecdsa.rs b/halo2-ecc/src/secp256k1/tests/ecdsa.rs index 91ea7ca6..77ad0d49 100644 --- a/halo2-ecc/src/secp256k1/tests/ecdsa.rs +++ b/halo2-ecc/src/secp256k1/tests/ecdsa.rs @@ -25,7 +25,7 @@ use crate::{ }; use ark_std::{end_timer, start_timer}; use halo2_base::gates::builder::{ - set_lookup_bits, CircuitBuilderStage, GateThreadBuilder, MultiPhaseThreadBreakPoints, + BaseConfigParams, CircuitBuilderStage, GateThreadBuilder, MultiPhaseThreadBreakPoints, RangeCircuitBuilder, }; use halo2_base::gates::RangeChip; @@ -59,7 +59,6 @@ fn ecdsa_test( msghash: Fq, pk: Secp256k1Affine, ) { - set_lookup_bits(params.lookup_bits); let range = RangeChip::::default(params.lookup_bits); let fp_chip = FpChip::::new(&range, params.limb_bits, params.num_limbs); let fq_chip = FqChip::::new(&range, params.limb_bits, params.num_limbs); @@ -78,6 +77,7 @@ fn ecdsa_test( fn random_ecdsa_circuit( params: CircuitParams, stage: CircuitBuilderStage, + config_params: Option, break_points: Option, ) -> RangeCircuitBuilder { let mut builder = match stage { @@ -101,16 +101,15 @@ fn random_ecdsa_circuit( let start0 = start_timer!(|| format!("Witness generation for circuit in {stage:?} stage")); ecdsa_test(builder.main(0), params, r, s, msg_hash, pubkey); + let config_params = config_params.unwrap_or_else(|| { + builder.config(params.degree as usize, Some(20), Some(params.lookup_bits)) + }); let circuit = match stage { - CircuitBuilderStage::Mock => { - builder.config(params.degree as usize, Some(20)); - RangeCircuitBuilder::mock(builder) + CircuitBuilderStage::Mock => RangeCircuitBuilder::mock(builder, config_params), + CircuitBuilderStage::Keygen => RangeCircuitBuilder::keygen(builder, config_params), + CircuitBuilderStage::Prover => { + RangeCircuitBuilder::prover(builder, config_params, break_points.unwrap()) } - CircuitBuilderStage::Keygen => { - builder.config(params.degree as usize, Some(20)); - RangeCircuitBuilder::keygen(builder) - } - CircuitBuilderStage::Prover => RangeCircuitBuilder::prover(builder, break_points.unwrap()), }; end_timer!(start0); circuit @@ -124,7 +123,7 @@ fn test_secp256k1_ecdsa() { ) .unwrap(); - let circuit = random_ecdsa_circuit(params, CircuitBuilderStage::Mock, None); + let circuit = random_ecdsa_circuit(params, CircuitBuilderStage::Mock, None, None); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); } @@ -149,7 +148,7 @@ fn bench_secp256k1_ecdsa() -> Result<(), Box> { let params = gen_srs(k); println!("{bench_params:?}"); - let circuit = random_ecdsa_circuit(bench_params, CircuitBuilderStage::Keygen, None); + let circuit = random_ecdsa_circuit(bench_params, CircuitBuilderStage::Keygen, None, None); let vk_time = start_timer!(|| "Generating vkey"); let vk = keygen_vk(¶ms, &circuit)?; @@ -160,11 +159,16 @@ fn bench_secp256k1_ecdsa() -> Result<(), Box> { end_timer!(pk_time); let break_points = circuit.0.break_points.take(); + let config_params = circuit.0.config_params.clone(); drop(circuit); // create a proof let proof_time = start_timer!(|| "Proving time"); - let circuit = - random_ecdsa_circuit(bench_params, CircuitBuilderStage::Prover, Some(break_points)); + let circuit = random_ecdsa_circuit( + bench_params, + CircuitBuilderStage::Prover, + Some(config_params), + Some(break_points), + ); let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); create_proof::< KZGCommitmentScheme, diff --git a/halo2-ecc/src/secp256k1/tests/ecdsa_tests.rs b/halo2-ecc/src/secp256k1/tests/ecdsa_tests.rs index 54b50772..5beebdf7 100644 --- a/halo2-ecc/src/secp256k1/tests/ecdsa_tests.rs +++ b/halo2-ecc/src/secp256k1/tests/ecdsa_tests.rs @@ -12,10 +12,10 @@ use crate::{ fields::FieldChip, }; use ark_std::{end_timer, start_timer}; +use halo2_base::gates::builder::BaseConfigParams; use halo2_base::{ gates::builder::{ - set_lookup_bits, CircuitBuilderStage, GateThreadBuilder, MultiPhaseThreadBreakPoints, - RangeCircuitBuilder, + CircuitBuilderStage, GateThreadBuilder, MultiPhaseThreadBreakPoints, RangeCircuitBuilder, }, utils::BigPrimeField, }; @@ -38,7 +38,6 @@ fn ecdsa_test( msghash: Fq, pk: Secp256k1Affine, ) { - set_lookup_bits(params.lookup_bits); let range = RangeChip::::default(params.lookup_bits); let fp_chip = FpChip::::new(&range, params.limb_bits, params.num_limbs); let fq_chip = FqChip::::new(&range, params.limb_bits, params.num_limbs); @@ -97,6 +96,7 @@ fn ecdsa_circuit( pubkey: Secp256k1Affine, params: CircuitParams, stage: CircuitBuilderStage, + config_params: Option, break_points: Option, ) -> RangeCircuitBuilder { let mut builder = match stage { @@ -107,16 +107,15 @@ fn ecdsa_circuit( let start0 = start_timer!(|| format!("Witness generation for circuit in {stage:?} stage")); ecdsa_test(builder.main(0), params, r, s, msg_hash, pubkey); + let config_params = config_params.unwrap_or_else(|| { + builder.config(params.degree as usize, Some(20), Some(params.lookup_bits)) + }); let circuit = match stage { - CircuitBuilderStage::Mock => { - builder.config(params.degree as usize, Some(20)); - RangeCircuitBuilder::mock(builder) + CircuitBuilderStage::Mock => RangeCircuitBuilder::mock(builder, config_params), + CircuitBuilderStage::Keygen => RangeCircuitBuilder::keygen(builder, config_params), + CircuitBuilderStage::Prover => { + RangeCircuitBuilder::prover(builder, config_params, break_points.unwrap()) } - CircuitBuilderStage::Keygen => { - builder.config(params.degree as usize, Some(20)); - RangeCircuitBuilder::keygen(builder) - } - CircuitBuilderStage::Prover => RangeCircuitBuilder::prover(builder, break_points.unwrap()), }; end_timer!(start0); circuit @@ -133,7 +132,8 @@ fn test_ecdsa_msg_hash_zero() { let (r, s, msg_hash, pubkey) = custom_parameters_ecdsa(random::(), 0, random::()); - let circuit = ecdsa_circuit(r, s, msg_hash, pubkey, params, CircuitBuilderStage::Mock, None); + let circuit = + ecdsa_circuit(r, s, msg_hash, pubkey, params, CircuitBuilderStage::Mock, None, None); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); } @@ -148,7 +148,8 @@ fn test_ecdsa_private_key_zero() { let (r, s, msg_hash, pubkey) = custom_parameters_ecdsa(0, random::(), random::()); - let circuit = ecdsa_circuit(r, s, msg_hash, pubkey, params, CircuitBuilderStage::Mock, None); + let circuit = + ecdsa_circuit(r, s, msg_hash, pubkey, params, CircuitBuilderStage::Mock, None, None); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); } @@ -162,7 +163,8 @@ fn test_ecdsa_random_valid_inputs() { let (r, s, msg_hash, pubkey) = random_parameters_ecdsa(); - let circuit = ecdsa_circuit(r, s, msg_hash, pubkey, params, CircuitBuilderStage::Mock, None); + let circuit = + ecdsa_circuit(r, s, msg_hash, pubkey, params, CircuitBuilderStage::Mock, None, None); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); } @@ -176,7 +178,8 @@ fn test_ecdsa_custom_valid_inputs(sk: u64, msg_hash: u64, k: u64) { let (r, s, msg_hash, pubkey) = custom_parameters_ecdsa(sk, msg_hash, k); - let circuit = ecdsa_circuit(r, s, msg_hash, pubkey, params, CircuitBuilderStage::Mock, None); + let circuit = + ecdsa_circuit(r, s, msg_hash, pubkey, params, CircuitBuilderStage::Mock, None, None); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); } @@ -191,6 +194,7 @@ fn test_ecdsa_custom_valid_inputs_negative_s(sk: u64, msg_hash: u64, k: u64) { let (r, s, msg_hash, pubkey) = custom_parameters_ecdsa(sk, msg_hash, k); let s = -s; - let circuit = ecdsa_circuit(r, s, msg_hash, pubkey, params, CircuitBuilderStage::Mock, None); + let circuit = + ecdsa_circuit(r, s, msg_hash, pubkey, params, CircuitBuilderStage::Mock, None, None); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); } diff --git a/halo2-ecc/src/secp256k1/tests/mod.rs b/halo2-ecc/src/secp256k1/tests/mod.rs index 1759b66a..96459491 100644 --- a/halo2-ecc/src/secp256k1/tests/mod.rs +++ b/halo2-ecc/src/secp256k1/tests/mod.rs @@ -6,7 +6,7 @@ use crate::group::Curve; use halo2_base::{ gates::{ builder::{ - set_lookup_bits, CircuitBuilderStage, GateThreadBuilder, MultiPhaseThreadBreakPoints, + BaseConfigParams, CircuitBuilderStage, GateThreadBuilder, MultiPhaseThreadBreakPoints, RangeCircuitBuilder, }, RangeChip, @@ -53,7 +53,6 @@ fn sm_test( scalar: Fq, window_bits: usize, ) { - set_lookup_bits(params.lookup_bits); let range = RangeChip::::default(params.lookup_bits); let fp_chip = FpChip::::new(&range, params.limb_bits, params.num_limbs); let fq_chip = FqChip::::new(&range, params.limb_bits, params.num_limbs); @@ -81,6 +80,7 @@ fn sm_test( fn sm_circuit( params: CircuitParams, stage: CircuitBuilderStage, + config_params: Option, break_points: Option, base: Secp256k1Affine, scalar: Fq, @@ -90,16 +90,14 @@ fn sm_circuit( sm_test(builder.main(0), params, base, scalar, 4); + let config_params = + config_params.unwrap_or_else(|| builder.config(k, Some(20), Some(params.lookup_bits))); match stage { - CircuitBuilderStage::Mock => { - builder.config(k, Some(20)); - RangeCircuitBuilder::mock(builder) + CircuitBuilderStage::Mock => RangeCircuitBuilder::mock(builder, config_params), + CircuitBuilderStage::Keygen => RangeCircuitBuilder::keygen(builder, config_params), + CircuitBuilderStage::Prover => { + RangeCircuitBuilder::prover(builder, config_params, break_points.unwrap()) } - CircuitBuilderStage::Keygen => { - builder.config(k, Some(20)); - RangeCircuitBuilder::keygen(builder) - } - CircuitBuilderStage::Prover => RangeCircuitBuilder::prover(builder, break_points.unwrap()), } } @@ -115,6 +113,7 @@ fn test_secp_sm_random() { params, CircuitBuilderStage::Mock, None, + None, Secp256k1Affine::random(OsRng), Fq::random(OsRng), ); @@ -133,7 +132,7 @@ fn test_secp_sm_minus_1() { let mut s = -Fq::one(); let mut n = fe_to_biguint(&s); loop { - let circuit = sm_circuit(params, CircuitBuilderStage::Mock, None, base, s); + let circuit = sm_circuit(params, CircuitBuilderStage::Mock, None, None, base, s); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); if &n % BigUint::from(2usize) == BigUint::from(0usize) { break; @@ -153,10 +152,10 @@ fn test_secp_sm_0_1() { let base = Secp256k1Affine::random(OsRng); let s = Fq::zero(); - let circuit = sm_circuit(params, CircuitBuilderStage::Mock, None, base, s); + let circuit = sm_circuit(params, CircuitBuilderStage::Mock, None, None, base, s); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); let s = Fq::one(); - let circuit = sm_circuit(params, CircuitBuilderStage::Mock, None, base, s); + let circuit = sm_circuit(params, CircuitBuilderStage::Mock, None, None, base, s); MockProver::run(params.degree, &circuit, vec![]).unwrap().assert_satisfied(); }