Skip to content

Commit b26a0ae

Browse files
ed255Velaciela
authored andcommitted
Extend Circuit trait to take parameters in config (privacy-scaling-explorations#168)
* Extend Circuit trait to take parameters in config The Circuit trait is extended with the following: ``` pub trait Circuit<F: Field> { /// [...] type Params: Default; fn params(&self) -> Self::Params { Self::Params::default() } fn configure_with_params(meta: &mut ConstraintSystem<F>, params: &Self::Params) -> Self::Config { Self::configure(meta) } fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config; } ``` This allows runtime parametrization of the circuit configuration. The extension to the Circuit trait has been designed to minimize the breaking change: existing circuits only need to define the associated `type Params`. Unfortunately "Associated type defaults" are unstable in Rust, otherwise this would be a non-breaking change. See rust-lang/rust#29661 * Implement circuit params under feature flag * Don't overwrite configure method * Fix doc test
1 parent 6adc633 commit b26a0ae

36 files changed

+163
-9
lines changed

halo2_gadgets/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ bench = false
4949

5050
[features]
5151
dev-graph = ["halo2_proofs/dev-graph", "plotters"]
52+
circuit-params = ["halo2_proofs/circuit-params"]
5253
test-dependencies = ["proptest"]
5354
unstable = []
5455

halo2_gadgets/benches/poseidon.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ where
5353
{
5454
type Config = MyConfig<WIDTH, RATE, L>;
5555
type FloorPlanner = SimpleFloorPlanner;
56+
#[cfg(feature = "circuit-params")]
57+
type Params = ();
5658

5759
fn without_witnesses(&self) -> Self {
5860
Self {

halo2_gadgets/benches/sha256.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ fn bench(name: &str, k: u32, c: &mut Criterion) {
3737
impl Circuit<pallas::Base> for MyCircuit {
3838
type Config = Table16Config;
3939
type FloorPlanner = SimpleFloorPlanner;
40+
#[cfg(feature = "circuit-params")]
41+
type Params = ();
4042

4143
fn without_witnesses(&self) -> Self {
4244
Self::default()

halo2_gadgets/src/ecc.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,8 @@ pub(crate) mod tests {
731731
impl Circuit<pallas::Base> for MyCircuit {
732732
type Config = EccConfig<TestFixedBases>;
733733
type FloorPlanner = SimpleFloorPlanner;
734+
#[cfg(feature = "circuit-params")]
735+
type Params = ();
734736

735737
fn without_witnesses(&self) -> Self {
736738
MyCircuit { test_errors: false }

halo2_gadgets/src/ecc/chip/mul_fixed/short.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,8 @@ pub mod tests {
434434
impl Circuit<pallas::Base> for MyCircuit {
435435
type Config = EccConfig<TestFixedBases>;
436436
type FloorPlanner = SimpleFloorPlanner;
437+
#[cfg(feature = "circuit-params")]
438+
type Params = ();
437439

438440
fn without_witnesses(&self) -> Self {
439441
Self::default()

halo2_gadgets/src/poseidon/pow5.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,8 @@ mod tests {
620620
{
621621
type Config = Pow5Config<Fp, WIDTH, RATE>;
622622
type FloorPlanner = SimpleFloorPlanner;
623+
#[cfg(feature = "circuit-params")]
624+
type Params = ();
623625

624626
fn without_witnesses(&self) -> Self {
625627
PermuteCircuit::<S, WIDTH, RATE>(PhantomData)
@@ -735,6 +737,8 @@ mod tests {
735737
{
736738
type Config = Pow5Config<Fp, WIDTH, RATE>;
737739
type FloorPlanner = SimpleFloorPlanner;
740+
#[cfg(feature = "circuit-params")]
741+
type Params = ();
738742

739743
fn without_witnesses(&self) -> Self {
740744
Self {

halo2_gadgets/src/sha256/table16.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,8 @@ mod tests {
468468
impl Circuit<pallas::Base> for MyCircuit {
469469
type Config = Table16Config;
470470
type FloorPlanner = SimpleFloorPlanner;
471+
#[cfg(feature = "circuit-params")]
472+
type Params = ();
471473

472474
fn without_witnesses(&self) -> Self {
473475
MyCircuit {}

halo2_gadgets/src/sha256/table16/compression.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,8 @@ mod tests {
954954
impl Circuit<pallas::Base> for MyCircuit {
955955
type Config = Table16Config;
956956
type FloorPlanner = SimpleFloorPlanner;
957+
#[cfg(feature = "circuit-params")]
958+
type Params = ();
957959

958960
fn without_witnesses(&self) -> Self {
959961
MyCircuit {}

halo2_gadgets/src/sha256/table16/message_schedule.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,8 @@ mod tests {
411411
impl Circuit<pallas::Base> for MyCircuit {
412412
type Config = Table16Config;
413413
type FloorPlanner = SimpleFloorPlanner;
414+
#[cfg(feature = "circuit-params")]
415+
type Params = ();
414416

415417
fn without_witnesses(&self) -> Self {
416418
MyCircuit {}

halo2_gadgets/src/sha256/table16/spread_table.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,8 @@ mod tests {
304304
impl<F: PrimeField> Circuit<F> for MyCircuit {
305305
type Config = SpreadTableConfig;
306306
type FloorPlanner = SimpleFloorPlanner;
307+
#[cfg(feature = "circuit-params")]
308+
type Params = ();
307309

308310
fn without_witnesses(&self) -> Self {
309311
MyCircuit {}

halo2_gadgets/src/sinsemilla.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,8 @@ pub(crate) mod tests {
525525
SinsemillaConfig<TestHashDomain, TestCommitDomain, TestFixedBases>,
526526
);
527527
type FloorPlanner = SimpleFloorPlanner;
528+
#[cfg(feature = "circuit-params")]
529+
type Params = ();
528530

529531
fn without_witnesses(&self) -> Self {
530532
MyCircuit {}

halo2_gadgets/src/sinsemilla/merkle.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ pub mod tests {
213213
MerkleConfig<TestHashDomain, TestCommitDomain, TestFixedBases>,
214214
);
215215
type FloorPlanner = SimpleFloorPlanner;
216+
#[cfg(feature = "circuit-params")]
217+
type Params = ();
216218

217219
fn without_witnesses(&self) -> Self {
218220
Self::default()

halo2_gadgets/src/utilities.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,8 @@ mod tests {
271271
impl<const RANGE: usize> Circuit<pallas::Base> for MyCircuit<RANGE> {
272272
type Config = Config;
273273
type FloorPlanner = SimpleFloorPlanner;
274+
#[cfg(feature = "circuit-params")]
275+
type Params = ();
274276

275277
fn without_witnesses(&self) -> Self {
276278
MyCircuit(self.0)

halo2_gadgets/src/utilities/cond_swap.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ mod tests {
217217
impl<F: PrimeField> Circuit<F> for MyCircuit<F> {
218218
type Config = CondSwapConfig;
219219
type FloorPlanner = SimpleFloorPlanner;
220+
#[cfg(feature = "circuit-params")]
221+
type Params = ();
220222

221223
fn without_witnesses(&self) -> Self {
222224
Self::default()

halo2_gadgets/src/utilities/decompose_running_sum.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,8 @@ mod tests {
243243
{
244244
type Config = RunningSumConfig<F, WINDOW_NUM_BITS>;
245245
type FloorPlanner = SimpleFloorPlanner;
246+
#[cfg(feature = "circuit-params")]
247+
type Params = ();
246248

247249
fn without_witnesses(&self) -> Self {
248250
Self {

halo2_gadgets/src/utilities/lookup_range_check.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,8 @@ mod tests {
410410
impl<F: PrimeFieldBits> Circuit<F> for MyCircuit<F> {
411411
type Config = LookupRangeCheckConfig<F, K>;
412412
type FloorPlanner = SimpleFloorPlanner;
413+
#[cfg(feature = "circuit-params")]
414+
type Params = ();
413415

414416
fn without_witnesses(&self) -> Self {
415417
*self
@@ -506,6 +508,8 @@ mod tests {
506508
impl<F: PrimeFieldBits> Circuit<F> for MyCircuit<F> {
507509
type Config = LookupRangeCheckConfig<F, K>;
508510
type FloorPlanner = SimpleFloorPlanner;
511+
#[cfg(feature = "circuit-params")]
512+
type Params = ();
509513

510514
fn without_witnesses(&self) -> Self {
511515
MyCircuit {

halo2_proofs/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ parallel_syn = []
9191
phase-check = []
9292
profile = ["ark-std/print-trace"]
9393
mock-batch-inv = []
94+
circuit-params = []
9495

9596
[lib]
9697
bench = false

halo2_proofs/benches/dev_lookup.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ fn criterion_benchmark(c: &mut Criterion) {
2828
impl<F: PrimeField> Circuit<F> for MyCircuit<F> {
2929
type Config = MyConfig;
3030
type FloorPlanner = SimpleFloorPlanner;
31+
#[cfg(feature = "circuit-params")]
32+
type Params = ();
3133

3234
fn without_witnesses(&self) -> Self {
3335
Self::default()

halo2_proofs/benches/plonk.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,8 @@ fn criterion_benchmark(c: &mut Criterion) {
183183
impl<F: Field> Circuit<F> for MyCircuit<F> {
184184
type Config = PlonkConfig;
185185
type FloorPlanner = SimpleFloorPlanner;
186+
#[cfg(feature = "circuit-params")]
187+
type Params = ();
186188

187189
fn without_witnesses(&self) -> Self {
188190
Self {

halo2_proofs/examples/circuit-layout.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ impl<FF: Field> StandardCs<FF> for StandardPlonk<FF> {
161161
impl<F: Field> Circuit<F> for MyCircuit<F> {
162162
type Config = PlonkConfig;
163163
type FloorPlanner = SimpleFloorPlanner;
164+
#[cfg(feature = "circuit-params")]
165+
type Params = ();
164166

165167
fn without_witnesses(&self) -> Self {
166168
Self {

halo2_proofs/examples/serialization.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ struct StandardPlonk(Fr);
8686
impl Circuit<Fr> for StandardPlonk {
8787
type Config = StandardPlonkConfig;
8888
type FloorPlanner = SimpleFloorPlanner;
89+
#[cfg(feature = "circuit-params")]
90+
type Params = ();
8991

9092
fn without_witnesses(&self) -> Self {
9193
Self::default()
@@ -140,8 +142,14 @@ fn main() {
140142

141143
let f = File::open("serialization-test.pk").unwrap();
142144
let mut reader = BufReader::new(f);
143-
let pk = ProvingKey::<G1Affine>::read::<_, StandardPlonk>(&mut reader, SerdeFormat::RawBytes)
144-
.unwrap();
145+
#[allow(clippy::unit_arg)]
146+
let pk = ProvingKey::<G1Affine>::read::<_, StandardPlonk>(
147+
&mut reader,
148+
SerdeFormat::RawBytes,
149+
#[cfg(feature = "circuit-params")]
150+
circuit.params(),
151+
)
152+
.unwrap();
145153

146154
std::fs::remove_file("serialization-test.pk").unwrap();
147155

halo2_proofs/examples/shuffle.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ impl<F: Field, const W: usize, const H: usize> MyCircuit<F, W, H> {
136136
impl<F: Field, const W: usize, const H: usize> Circuit<F> for MyCircuit<F, W, H> {
137137
type Config = MyConfig<W>;
138138
type FloorPlanner = V1;
139+
#[cfg(feature = "circuit-params")]
140+
type Params = ();
139141

140142
fn without_witnesses(&self) -> Self {
141143
Self::default()

halo2_proofs/examples/simple-example.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,8 @@ impl<F: Field> Circuit<F> for MyCircuit<F> {
248248
// Since we are using a single chip for everything, we can just reuse its config.
249249
type Config = FieldConfig;
250250
type FloorPlanner = SimpleFloorPlanner;
251+
#[cfg(feature = "circuit-params")]
252+
type Params = ();
251253

252254
fn without_witnesses(&self) -> Self {
253255
Self::default()

halo2_proofs/examples/two-chip.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,8 @@ impl<F: Field> Circuit<F> for MyCircuit<F> {
458458
// Since we are using a single chip for everything, we can just reuse its config.
459459
type Config = FieldConfig;
460460
type FloorPlanner = SimpleFloorPlanner;
461+
#[cfg(feature = "circuit-params")]
462+
type Params = ();
461463

462464
fn without_witnesses(&self) -> Self {
463465
Self::default()

halo2_proofs/src/circuit/floor_planner/single_pass.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,8 @@ mod tests {
681681
impl Circuit<vesta::Scalar> for MyCircuit {
682682
type Config = Column<Advice>;
683683
type FloorPlanner = SimpleFloorPlanner;
684+
#[cfg(feature = "circuit-params")]
685+
type Params = ();
684686

685687
fn without_witnesses(&self) -> Self {
686688
MyCircuit {}

halo2_proofs/src/circuit/floor_planner/v1.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,8 @@ mod tests {
546546
impl Circuit<vesta::Scalar> for MyCircuit {
547547
type Config = Column<Advice>;
548548
type FloorPlanner = super::V1;
549+
#[cfg(feature = "circuit-params")]
550+
type Params = ();
549551

550552
fn without_witnesses(&self) -> Self {
551553
MyCircuit {}

halo2_proofs/src/dev.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,8 @@ impl<F: Field> Mul<F> for Value<F> {
346346
/// impl<F: PrimeField> Circuit<F> for MyCircuit {
347347
/// type Config = MyConfig;
348348
/// type FloorPlanner = SimpleFloorPlanner;
349+
/// #[cfg(feature = "circuit-params")]
350+
/// type Params = ();
349351
///
350352
/// fn without_witnesses(&self) -> Self {
351353
/// Self::default()
@@ -925,6 +927,9 @@ impl<'a, F: FromUniformBytes<64> + Ord> MockProver<'a, F> {
925927
let n = 1 << k;
926928

927929
let mut cs = ConstraintSystem::default();
930+
#[cfg(feature = "circuit-params")]
931+
let config = ConcreteCircuit::configure_with_params(&mut cs, circuit.params());
932+
#[cfg(not(feature = "circuit-params"))]
928933
let config = ConcreteCircuit::configure(&mut cs);
929934
let cs = cs;
930935

@@ -1983,6 +1988,8 @@ mod tests {
19831988
impl Circuit<Fp> for FaultyCircuit {
19841989
type Config = FaultyCircuitConfig;
19851990
type FloorPlanner = SimpleFloorPlanner;
1991+
#[cfg(feature = "circuit-params")]
1992+
type Params = ();
19861993

19871994
fn configure(meta: &mut ConstraintSystem<Fp>) -> Self::Config {
19881995
let a = meta.advice_column();
@@ -2069,6 +2076,8 @@ mod tests {
20692076
impl Circuit<Fp> for FaultyCircuit {
20702077
type Config = FaultyCircuitConfig;
20712078
type FloorPlanner = SimpleFloorPlanner;
2079+
#[cfg(feature = "circuit-params")]
2080+
type Params = ();
20722081

20732082
fn configure(meta: &mut ConstraintSystem<Fp>) -> Self::Config {
20742083
let a = meta.advice_column();
@@ -2238,6 +2247,8 @@ mod tests {
22382247
impl Circuit<Fp> for FaultyCircuit {
22392248
type Config = FaultyCircuitConfig;
22402249
type FloorPlanner = SimpleFloorPlanner;
2250+
#[cfg(feature = "circuit-params")]
2251+
type Params = ();
22412252

22422253
fn configure(meta: &mut ConstraintSystem<Fp>) -> Self::Config {
22432254
let a = meta.advice_column();
@@ -2372,6 +2383,8 @@ mod tests {
23722383
impl Circuit<Fp> for FaultyCircuit {
23732384
type Config = FaultyCircuitConfig;
23742385
type FloorPlanner = SimpleFloorPlanner;
2386+
#[cfg(feature = "circuit-params")]
2387+
type Params = ();
23752388

23762389
fn configure(meta: &mut ConstraintSystem<Fp>) -> Self::Config {
23772390
let a = meta.advice_column();

halo2_proofs/src/dev/cost.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@ impl<G: PrimeGroup, ConcreteCircuit: Circuit<G::Scalar>> CircuitCost<G, Concrete
159159
pub fn measure(k: usize, circuit: &ConcreteCircuit) -> Self {
160160
// Collect the layout details.
161161
let mut cs = ConstraintSystem::default();
162+
#[cfg(feature = "circuit-params")]
163+
let config = ConcreteCircuit::configure_with_params(&mut cs, circuit.params());
164+
#[cfg(not(feature = "circuit-params"))]
162165
let config = ConcreteCircuit::configure(&mut cs);
163166
let mut assembly = Assembly {
164167
selectors: vec![vec![false; 1 << k]; cs.num_selectors],

halo2_proofs/src/dev/gates.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ struct Gate {
4949
/// impl<F: Field> Circuit<F> for MyCircuit {
5050
/// type Config = MyConfig;
5151
/// type FloorPlanner = SimpleFloorPlanner;
52+
/// #[cfg(feature = "circuit-params")]
53+
/// type Params = ();
5254
///
5355
/// fn without_witnesses(&self) -> Self {
5456
/// Self::default()
@@ -79,6 +81,9 @@ struct Gate {
7981
/// }
8082
/// }
8183
///
84+
/// #[cfg(feature = "circuit-params")]
85+
/// let gates = CircuitGates::collect::<pallas::Base, MyCircuit>(());
86+
/// #[cfg(not(feature = "circuit-params"))]
8287
/// let gates = CircuitGates::collect::<pallas::Base, MyCircuit>();
8388
/// assert_eq!(
8489
/// format!("{}", gates),
@@ -103,9 +108,14 @@ pub struct CircuitGates {
103108

104109
impl CircuitGates {
105110
/// Collects the gates from within the circuit.
106-
pub fn collect<F: PrimeField, C: Circuit<F>>() -> Self {
111+
pub fn collect<F: PrimeField, C: Circuit<F>>(
112+
#[cfg(feature = "circuit-params")] params: C::Params,
113+
) -> Self {
107114
// Collect the graph details.
108115
let mut cs = ConstraintSystem::default();
116+
#[cfg(feature = "circuit-params")]
117+
let _ = C::configure_with_params(&mut cs, params);
118+
#[cfg(not(feature = "circuit-params"))]
109119
let _ = C::configure(&mut cs);
110120

111121
let gates = cs

halo2_proofs/src/dev/graph.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ pub fn circuit_dot_graph<F: Field, ConcreteCircuit: Circuit<F>>(
2323
) -> String {
2424
// Collect the graph details.
2525
let mut cs = ConstraintSystem::default();
26+
#[cfg(feature = "circuit-params")]
27+
let config = ConcreteCircuit::configure_with_params(&mut cs, circuit.params());
28+
#[cfg(not(feature = "circuit-params"))]
2629
let config = ConcreteCircuit::configure(&mut cs);
2730
let mut graph = Graph::default();
2831
ConcreteCircuit::FloorPlanner::synthesize(&mut graph, circuit, config, cs.constants).unwrap();

halo2_proofs/src/dev/graph/layout.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ impl CircuitLayout {
9797
let n = 1 << k;
9898
// Collect the layout details.
9999
let mut cs = ConstraintSystem::default();
100+
#[cfg(feature = "circuit-params")]
101+
let config = ConcreteCircuit::configure_with_params(&mut cs, circuit.params());
102+
#[cfg(not(feature = "circuit-params"))]
100103
let config = ConcreteCircuit::configure(&mut cs);
101104
let mut layout = Layout::new(k, n, cs.num_selectors);
102105
ConcreteCircuit::FloorPlanner::synthesize(

0 commit comments

Comments
 (0)