@@ -54,6 +54,7 @@ trait NumericInstructions<F: Field>: Chip<F> {
5454 layouter : impl Layouter < F > ,
5555 num : & Self :: Num ,
5656 row : usize ,
57+ instance_col : usize ,
5758 ) -> Result < ( ) , Error > ;
5859}
5960// ANCHOR_END: instructions
@@ -75,13 +76,18 @@ struct AddChip<F: Field> {
7576}
7677// ANCHOR_END: chip
7778
79+ const NB_INSTANCE_COLS : usize = 5 ;
80+
81+ #[ cfg( feature = "committed-instances" ) ]
82+ const NB_INSTANCE_COMS : usize = 2 ;
83+
7884// ANCHOR: chip-config
7985/// Chip state is stored in a config struct. This is generated by the chip
8086/// during configuration, and then stored inside the chip.
8187#[ derive( Clone , Debug ) ]
8288struct FieldConfig {
8389 advice : [ Column < Advice > ; 3 ] ,
84- instance : Column < Instance > ,
90+ instance_cols : [ Column < Instance > ; NB_INSTANCE_COLS ] ,
8591 s : Selector ,
8692}
8793
@@ -96,9 +102,11 @@ impl<F: Field> MultChip<F> {
96102 fn configure (
97103 meta : & mut ConstraintSystem < F > ,
98104 advice : [ Column < Advice > ; 3 ] ,
99- instance : Column < Instance > ,
105+ instance_cols : [ Column < Instance > ; NB_INSTANCE_COLS ] ,
100106 ) -> <Self as Chip < F > >:: Config {
101- meta. enable_equality ( instance) ;
107+ for column in & instance_cols {
108+ meta. enable_equality ( * column) ;
109+ }
102110 for column in & advice {
103111 meta. enable_equality ( * column) ;
104112 }
@@ -116,7 +124,7 @@ impl<F: Field> MultChip<F> {
116124
117125 FieldConfig {
118126 advice,
119- instance ,
127+ instance_cols ,
120128 s,
121129 }
122130 }
@@ -133,9 +141,11 @@ impl<F: Field> AddChip<F> {
133141 fn configure (
134142 meta : & mut ConstraintSystem < F > ,
135143 advice : [ Column < Advice > ; 3 ] ,
136- instance : Column < Instance > ,
144+ instance_cols : [ Column < Instance > ; NB_INSTANCE_COLS ] ,
137145 ) -> <Self as Chip < F > >:: Config {
138- meta. enable_equality ( instance) ;
146+ for column in & instance_cols {
147+ meta. enable_equality ( * column) ;
148+ }
139149 for column in & advice {
140150 meta. enable_equality ( * column) ;
141151 }
@@ -153,7 +163,7 @@ impl<F: Field> AddChip<F> {
153163
154164 FieldConfig {
155165 advice,
156- instance ,
166+ instance_cols ,
157167 s,
158168 }
159169 }
@@ -268,10 +278,11 @@ impl<F: Field> NumericInstructions<F> for MultChip<F> {
268278 mut layouter : impl Layouter < F > ,
269279 num : & Self :: Num ,
270280 row : usize ,
281+ instance_col : usize ,
271282 ) -> Result < ( ) , Error > {
272283 let config = self . config ( ) ;
273284
274- layouter. constrain_instance ( num. 0 . cell ( ) , config. instance , row)
285+ layouter. constrain_instance ( num. 0 . cell ( ) , config. instance_cols [ instance_col ] , row)
275286 }
276287}
277288// ANCHOR_END: instructions-impl
@@ -350,10 +361,11 @@ impl<F: Field> NumericInstructions<F> for AddChip<F> {
350361 mut layouter : impl Layouter < F > ,
351362 num : & Self :: Num ,
352363 row : usize ,
364+ instance_col : usize ,
353365 ) -> Result < ( ) , Error > {
354366 let config = self . config ( ) ;
355367
356- layouter. constrain_instance ( num. 0 . cell ( ) , config. instance , row)
368+ layouter. constrain_instance ( num. 0 . cell ( ) , config. instance_cols [ instance_col ] , row)
357369 }
358370}
359371
@@ -383,9 +395,9 @@ impl<F: Field> Circuit<F> for MulCircuit<F> {
383395 ] ;
384396
385397 // We also need an instance column to store public inputs.
386- let instance = meta. instance_column ( ) ;
398+ let instance_cols = std :: array :: from_fn ( |_| meta. instance_column ( ) ) ;
387399
388- MultChip :: configure ( meta, advice, instance )
400+ MultChip :: configure ( meta, advice, instance_cols )
389401 }
390402
391403 fn synthesize (
@@ -403,7 +415,12 @@ impl<F: Field> Circuit<F> for MulCircuit<F> {
403415
404416 for ( i, c) in ab. iter ( ) . enumerate ( ) {
405417 // Expose the result as a public input to the circuit.
406- field_chip. expose_public ( layouter. namespace ( || "expose c" ) , c, i) ?;
418+ field_chip. expose_public (
419+ layouter. namespace ( || "expose c" ) ,
420+ c,
421+ i / NB_INSTANCE_COLS ,
422+ i % NB_INSTANCE_COLS ,
423+ ) ?;
407424 }
408425 Ok ( ( ) )
409426 }
@@ -436,9 +453,9 @@ impl<F: Field> Circuit<F> for AddCircuit<F> {
436453 ] ;
437454
438455 // We also need an instance column to store public inputs.
439- let instance = meta. instance_column ( ) ;
456+ let instance_cols = std :: array :: from_fn ( |_| meta. instance_column ( ) ) ;
440457
441- AddChip :: configure ( meta, advice, instance )
458+ AddChip :: configure ( meta, advice, instance_cols )
442459 }
443460
444461 fn synthesize (
@@ -456,7 +473,12 @@ impl<F: Field> Circuit<F> for AddCircuit<F> {
456473
457474 for ( i, c) in ab. iter ( ) . enumerate ( ) {
458475 // Expose the result as a public input to the circuit.
459- field_chip. expose_public ( layouter. namespace ( || "expose c" ) , c, i) ?;
476+ field_chip. expose_public (
477+ layouter. namespace ( || "expose c" ) ,
478+ c,
479+ i / NB_INSTANCE_COLS ,
480+ i % NB_INSTANCE_COLS ,
481+ ) ?;
460482 }
461483 Ok ( ( ) )
462484 }
@@ -480,7 +502,20 @@ where
480502{
481503 let params: ParamsKZG < E > = ParamsKZG :: unsafe_setup ( k, OsRng ) ;
482504 let vk = keygen_vk_with_k ( & params, & circuit, k) . unwrap ( ) ;
483- let pk = keygen_pk ( vk, & circuit) . unwrap ( ) ;
505+ let pk = keygen_pk ( vk. clone ( ) , & circuit) . unwrap ( ) ;
506+
507+ let mut public_inputs = vec ! [ vec![ ] ; NB_INSTANCE_COLS ] ;
508+ for i in 0 ..instances. len ( ) {
509+ public_inputs[ i % NB_INSTANCE_COLS ] . push ( instances[ i] ) ;
510+ }
511+ let public_inputs: Vec < & [ E :: Fr ] > = public_inputs. iter ( ) . map ( |v| v. as_slice ( ) ) . collect ( ) ;
512+
513+ #[ cfg( feature = "committed-instances" ) ]
514+ let instance_commitments = public_inputs
515+ . iter ( )
516+ . take ( NB_INSTANCE_COMS )
517+ . map ( |v| commit_to_instances :: < E :: Fr , KZGCommitmentScheme < E > > ( & params, vk. get_domain ( ) , v) )
518+ . collect :: < Vec < _ > > ( ) ;
484519
485520 let proof = {
486521 let mut transcript = CircuitTranscript :: < State > :: init ( ) ;
@@ -489,7 +524,9 @@ where
489524 & params,
490525 & pk,
491526 & [ circuit] ,
492- & [ & [ & instances] ] ,
527+ #[ cfg( feature = "committed-instances" ) ]
528+ NB_INSTANCE_COMS ,
529+ & [ & public_inputs] ,
493530 OsRng ,
494531 & mut transcript,
495532 )
@@ -501,9 +538,18 @@ where
501538 let accepted = {
502539 let mut transcript = CircuitTranscript :: < State > :: init_from_bytes ( & proof[ ..] ) ;
503540
504- prepare :: < E :: Fr , KZGCommitmentScheme < E > , _ > ( pk. get_vk ( ) , & [ & [ & instances] ] , & mut transcript)
505- . unwrap ( )
506- . verify ( & params. verifier_params ( ) )
541+ prepare :: < E :: Fr , KZGCommitmentScheme < E > , _ > (
542+ pk. get_vk ( ) ,
543+ #[ cfg( feature = "committed-instances" ) ]
544+ & [ & instance_commitments] ,
545+ #[ cfg( feature = "committed-instances" ) ]
546+ & [ & public_inputs[ NB_INSTANCE_COMS ..] ] ,
547+ #[ cfg( not( feature = "committed-instances" ) ) ]
548+ & [ & public_inputs] ,
549+ & mut transcript,
550+ )
551+ . unwrap ( )
552+ . verify ( & params. verifier_params ( ) )
507553 } ;
508554
509555 assert_eq ! ( accepted. is_ok( ) , expected) ;
@@ -520,8 +566,8 @@ fn main() {
520566 let k = 7 ;
521567
522568 // Prepare the inputs to the circuit!
523- let a = [ Fr :: from ( 2 ) ; N ] ;
524- let b = [ Fr :: from ( 3 ) ; N ] ;
569+ let a: [ Fr ; N ] = std :: array :: from_fn ( |i| Fr :: from ( i as u64 ) ) ;
570+ let b: [ Fr ; N ] = std :: array :: from_fn ( |i| Fr :: from ( 2 * i as u64 ) ) ;
525571 let c_mul: Vec < Fr > = a. iter ( ) . zip ( b) . map ( |( & a, b) | a * b) . collect ( ) ;
526572 let c_add: Vec < Fr > = a. iter ( ) . zip ( b) . map ( |( & a, b) | a + b) . collect ( ) ;
527573
0 commit comments