@@ -41,32 +41,44 @@ fn context_eval<E: MultiMillerLoop, R: io::Read>(
41
41
instance_commitments : & [ & [ E :: G1Affine ] ] ,
42
42
t : & mut [ & mut PoseidonChipRead < R , E :: G1Affine > ] ,
43
43
circuit : & mut NativeScalarEccContext < E :: G1Affine > ,
44
+ // Expose hash of constant value to instance to uniform the aggregator circuit
45
+ constants_hasher : & mut PoseidonChipRead < R , E :: G1Affine > ,
44
46
) -> Result <
45
47
(
46
48
Vec < AssignedPoint < E :: G1Affine , E :: Scalar > > ,
47
49
Vec < AssignedPoint < E :: G1Affine , E :: Scalar > > ,
50
+ AssignedValue < E :: Scalar > ,
48
51
) ,
49
52
UnsafeError ,
50
53
> {
51
54
let mut it: Vec < (
52
55
Option < AssignedPoint < E :: G1Affine , E :: Scalar > > ,
53
56
Option < AssignedValue < E :: Scalar > > ,
54
57
) > = vec ! [ ] ;
55
-
56
58
let const_scalars = {
57
59
c. const_scalars
58
60
. iter ( )
59
- . map ( |c| circuit. base_integer_chip ( ) . base_chip ( ) . assign_constant ( * c) )
61
+ . map ( |c| circuit. base_integer_chip ( ) . base_chip ( ) . assign ( * c) )
60
62
. collect :: < Vec < _ > > ( )
61
63
} ;
62
64
65
+ for c in const_scalars. iter ( ) {
66
+ constants_hasher. common_scalar ( circuit, c) ;
67
+ }
68
+
63
69
let const_points = {
64
70
c. const_points
65
71
. iter ( )
66
- . map ( |c| circuit. assign_constant_point ( & c. to_curve ( ) ) )
72
+ . map ( |c| circuit. assign_point ( & c. to_curve ( ) ) )
67
73
. collect :: < Vec < _ > > ( )
68
74
} ;
69
75
76
+ for c in const_points. iter ( ) {
77
+ constants_hasher. common_point ( circuit, c) ;
78
+ }
79
+
80
+ let constants_hash = constants_hasher. squeeze ( circuit) ;
81
+
70
82
let instance_commitments = {
71
83
instance_commitments
72
84
. iter ( )
@@ -214,6 +226,7 @@ fn context_eval<E: MultiMillerLoop, R: io::Read>(
214
226
. map ( |x| circuit. ecc_reduce ( it[ * x] . 0 . as_ref ( ) . unwrap ( ) ) )
215
227
. collect ( ) ,
216
228
instance_commitments. concat ( ) ,
229
+ constants_hash,
217
230
) )
218
231
}
219
232
@@ -225,6 +238,9 @@ pub fn build_single_proof_verify_circuit<E: MultiMillerLoop + G2AffineBaseHelper
225
238
hash : TranscriptHash ,
226
239
expose : Vec < [ usize ; 2 ] > ,
227
240
absorb : Vec < ( [ usize ; 3 ] , [ usize ; 2 ] ) > , // the index of instance + the index of advices
241
+ target_aggregator_constant_hash_instance_offset : Vec < ( [ usize ; 4 ] ) > , // (proof_index, layer_idx, instance_col, instance_row)
242
+ all_constant_hash : & mut Vec < E :: Scalar > ,
243
+ layer_idx : usize ,
228
244
) -> ( AggregatorCircuit < E :: G1Affine > , Vec < E :: Scalar > )
229
245
where
230
246
NativeScalarEccContext < E :: G1Affine > : PairingChipOps < E :: G1Affine , E :: Scalar > ,
@@ -238,6 +254,9 @@ where
238
254
vec ! [ ] ,
239
255
expose,
240
256
absorb,
257
+ target_aggregator_constant_hash_instance_offset,
258
+ all_constant_hash,
259
+ layer_idx,
241
260
)
242
261
}
243
262
@@ -249,7 +268,10 @@ pub fn build_aggregate_verify_circuit<E: MultiMillerLoop + G2AffineBaseHelper>(
249
268
hash : TranscriptHash ,
250
269
commitment_check : Vec < [ usize ; 4 ] > ,
251
270
expose : Vec < [ usize ; 2 ] > ,
252
- absorb : Vec < ( [ usize ; 3 ] , [ usize ; 2 ] ) > , // the index of instance + the index of advices
271
+ absorb : Vec < ( [ usize ; 3 ] , [ usize ; 2 ] ) > , // the index of instance + the index of advices,
272
+ target_aggregator_constant_hash_instance_offset : Vec < ( [ usize ; 4 ] ) > , // (proof_index, layer_idx, instance_col, instance_row)
273
+ all_constant_hash : & mut Vec < E :: Scalar > ,
274
+ layer_idx : usize ,
253
275
) -> ( AggregatorCircuit < E :: G1Affine > , Vec < E :: Scalar > )
254
276
where
255
277
NativeScalarEccContext < E :: G1Affine > : PairingChipOps < E :: G1Affine , E :: Scalar > ,
@@ -267,6 +289,9 @@ where
267
289
& commitment_check,
268
290
& expose,
269
291
& absorb,
292
+ & target_aggregator_constant_hash_instance_offset,
293
+ all_constant_hash,
294
+ layer_idx,
270
295
)
271
296
. ok ( ) ;
272
297
rest_tries -= 1 ;
@@ -290,6 +315,12 @@ impl G2AffineBaseHelper for Bn256 {
290
315
}
291
316
}
292
317
318
+ /* expose: expose target circuits' commitments to current aggregator circuits' instance
319
+ * absorb: absorb target circuits' commitments to target aggregator circuits' instance
320
+ * target_aggregator_constant_hash_instance: instance_offset of target_aggregator for constant_hash
321
+ * prev_constant_hash: all previous constant_hash (hash of all circuits' constant values) of aggregators layer
322
+ * layer_idx: current aggregator's layer index
323
+ */
293
324
pub fn _build_aggregate_verify_circuit < E : MultiMillerLoop + G2AffineBaseHelper > (
294
325
params : & ParamsVerifier < E > ,
295
326
vkey : & [ & VerifyingKey < E :: G1Affine > ] ,
@@ -299,6 +330,9 @@ pub fn _build_aggregate_verify_circuit<E: MultiMillerLoop + G2AffineBaseHelper>(
299
330
commitment_check : & Vec < [ usize ; 4 ] > ,
300
331
expose : & Vec < [ usize ; 2 ] > ,
301
332
absorb : & Vec < ( [ usize ; 3 ] , [ usize ; 2 ] ) > , // the index of instance + the index of advices
333
+ target_aggregator_constant_hash_instance_offset : & Vec < ( [ usize ; 4 ] ) > , // (proof_index, layer_idx, instance_col, instance_row)
334
+ all_constant_hash : & mut Vec < E :: Scalar > ,
335
+ layer_idx : usize ,
302
336
) -> Result < ( AggregatorCircuit < E :: G1Affine > , Vec < E :: Scalar > ) , UnsafeError >
303
337
where
304
338
NativeScalarEccContext < E :: G1Affine > : PairingChipOps < E :: G1Affine , E :: Scalar > ,
@@ -330,7 +364,7 @@ where
330
364
}
331
365
332
366
let c = EvalContext :: translate ( & targets[ ..] ) ;
333
- let ( pl, mut il) = match hash {
367
+ let ( pl, mut il, assigned_constant_hash ) = match hash {
334
368
TranscriptHash :: Poseidon => {
335
369
let mut t = vec ! [ ] ;
336
370
for i in 0 ..proofs. len ( ) {
@@ -341,6 +375,9 @@ where
341
375
let it = PoseidonRead :: init ( & empty[ ..] ) ;
342
376
t. push ( PoseidonChipRead :: init ( it, & mut ctx) ) ;
343
377
378
+ let mut constant_hasher =
379
+ PoseidonChipRead :: init ( PoseidonRead :: init ( & empty[ ..] ) , & mut ctx) ;
380
+
344
381
context_eval :: < E , _ > (
345
382
c,
346
383
& instance_commitments
@@ -349,15 +386,57 @@ where
349
386
. collect :: < Vec < _ > > ( ) [ ..] ,
350
387
& mut t. iter_mut ( ) . collect :: < Vec < _ > > ( ) ,
351
388
& mut ctx,
389
+ & mut constant_hasher,
352
390
) ?
353
391
}
354
392
_ => unreachable ! ( ) ,
355
393
} ;
356
394
395
+ let mut hashes = vec ! [ ] ;
396
+ // assign for constant_hashes
397
+ for h in all_constant_hash. iter ( ) {
398
+ let v = ctx. base_integer_chip ( ) . base_chip ( ) . assign ( * h) ;
399
+ hashes. push ( v) ;
400
+ }
401
+
402
+ if layer_idx < hashes. len ( ) {
403
+ ctx. base_integer_chip ( )
404
+ . base_chip ( )
405
+ . assert_equal ( & hashes[ layer_idx] , & assigned_constant_hash) ;
406
+ } else {
407
+ all_constant_hash. push ( assigned_constant_hash. val ) ;
408
+ hashes. push ( assigned_constant_hash) ;
409
+ }
410
+
357
411
for check in pl[ 0 ..absorb_start_idx] . chunks ( 2 ) . skip ( 1 ) {
358
412
ctx. ecc_assert_equal ( & check[ 0 ] , & check[ 1 ] ) ;
359
413
}
360
414
415
+ // il[target_aggregator_circuit's hash instance col] -= msm(params[?..? + target_layer_index + 1], hashes[0..target_aggregator_circuit_layer_index + 1])
416
+ for [ proof_index, layer_idx, instance_col, instance_row_start] in
417
+ target_aggregator_constant_hash_instance_offset
418
+ {
419
+ let mut instance_index = * instance_col;
420
+ for i in instances[ 0 ..* proof_index] . iter ( ) {
421
+ instance_index += i. len ( )
422
+ }
423
+ let mut points = vec ! [ ] ;
424
+ let mut scalars = vec ! [ ] ;
425
+ for i in 0 ..* layer_idx {
426
+ points. push (
427
+ ctx. assign_constant_point ( & params. g_lagrange [ i + instance_row_start] . to_curve ( ) ) ,
428
+ ) ;
429
+ scalars. push ( hashes[ i] ) ;
430
+ }
431
+
432
+ let msm_c = ctx. msm ( & points, & scalars) ;
433
+ let diff_commit = ctx. ecc_neg ( & msm_c) ;
434
+ let instance_commit = il[ instance_index] . clone ( ) ;
435
+ let instance_commit_curv = ctx. to_point_with_curvature ( instance_commit) ;
436
+ let update_commit = ctx. ecc_add ( & instance_commit_curv, & diff_commit) ;
437
+ il[ instance_index] = update_commit;
438
+ }
439
+
361
440
for ( i, c) in pl[ absorb_start_idx..expose_start_idx] . iter ( ) . enumerate ( ) {
362
441
let encoded_c = ctx. ecc_encode ( c) ;
363
442
let [ proof_index, instance_offset, g_index] = absorb[ i] . 0 ;
@@ -442,13 +521,17 @@ where
442
521
ctx. check_pairing ( & [ ( & pl[ 0 ] , & assigned_s_g2) , ( & pl[ 1 ] , & assigned_g2) ] ) ;
443
522
}
444
523
445
- let assigned_instances = vec ! [ & il[ ..] , & pl[ expose_start_idx..pl. len( ) ] ]
524
+ let mut assigned_instances = vec ! [ & il[ ..] , & pl[ expose_start_idx..pl. len( ) ] ]
446
525
. concat ( )
447
526
. iter ( )
448
527
. map ( |p| ctx. ecc_encode ( p) )
449
528
. collect :: < Vec < _ > > ( )
450
529
. concat ( ) ;
451
530
531
+ assigned_instances. append ( & mut hashes) ;
532
+
533
+ assigned_instances. push ( assigned_constant_hash) ;
534
+
452
535
for ai in assigned_instances. iter ( ) {
453
536
ctx. 0
454
537
. ctx
@@ -461,7 +544,10 @@ where
461
544
462
545
let instances = assigned_instances. iter ( ) . map ( |x| x. val ) . collect :: < Vec < _ > > ( ) ;
463
546
let ctx: Context < _ > = ctx. into ( ) ;
464
- println ! ( "offset {} {} {}" , ctx. base_offset, ctx. range_offset, ctx. select_offset) ;
547
+ println ! (
548
+ "offset {} {} {}" ,
549
+ ctx. base_offset, ctx. range_offset, ctx. select_offset
550
+ ) ;
465
551
466
552
Ok ( (
467
553
AggregatorCircuit :: new (
0 commit comments