@@ -34,6 +34,7 @@ use crate::{
3434use ceno_zkvm:: structs:: { ComposedConstrainSystem , VerifyingKey , ZKVMVerifyingKey } ;
3535use ff_ext:: BabyBearExt4 ;
3636
37+ use crate :: transcript:: { challenger_add_forked_index, clone_challenger_state} ;
3738use gkr_iop:: {
3839 evaluation:: EvalExpression ,
3940 gkr:: {
@@ -234,7 +235,7 @@ pub fn verify_zkvm_proof<C: Config<F = F>>(
234235 // not each chip has witness or fixed opening
235236 // therefore we need to truncate these two opening arrays
236237 let witin_openings: Array < C , RoundOpeningVariable < C > > = builder. dyn_array ( proofs_len. clone ( ) ) ;
237- let fixed_openings: Array < C , RoundOpeningVariable < C > > = builder. dyn_array ( proofs_len) ;
238+ let fixed_openings: Array < C , RoundOpeningVariable < C > > = builder. dyn_array ( proofs_len. clone ( ) ) ;
238239
239240 let shard_ec_sum = SepticPointVariable {
240241 x : SepticExtensionVariable {
@@ -260,6 +261,10 @@ pub fn verify_zkvm_proof<C: Config<F = F>>(
260261 builder. set ( & chip_indices, i, chip_idx) ;
261262 } ) ;
262263
264+ // collect fork sampling result
265+ let forked_samples: Array < C , Ext < C :: F , C :: EF > > = builder. dyn_array ( proofs_len. get_var ( ) ) ;
266+ let forked_sample_index: Usize < C :: N > = builder. eval ( C :: N :: ZERO ) ;
267+
263268 for ( i, ( circuit_name, chip_vk) ) in vk. circuit_vks . iter ( ) . enumerate ( ) {
264269 let circuit_vk = & vk. circuit_vks [ circuit_name] ;
265270 let chip_id: Var < C :: N > = builder. get ( & chip_indices, num_chips_verified. get_var ( ) ) ;
@@ -270,6 +275,9 @@ pub fn verify_zkvm_proof<C: Config<F = F>>(
270275
271276 iter_zip ! ( builder, chip_proofs) . for_each ( |ptr_vec, builder| {
272277 let chip_proof = builder. iter_ptr_get ( & chip_proofs, ptr_vec[ 0 ] ) ;
278+ // fork transcript to support chip concurrently proved
279+ let mut chip_challenger = clone_challenger_state ( builder, & challenger) ;
280+ challenger_add_forked_index ( builder, & mut chip_challenger, & forked_sample_index) ;
273281 builder. assert_usize_eq (
274282 chip_proof. wits_in_evals . len ( ) ,
275283 Usize :: from ( circuit_vk. get_cs ( ) . num_witin ( ) ) ,
@@ -302,7 +310,7 @@ pub fn verify_zkvm_proof<C: Config<F = F>>(
302310 builder. assign ( & chip_logup_sum, chip_logup_sum + p1 * q1. inverse ( ) ) ;
303311 builder. assign ( & chip_logup_sum, chip_logup_sum + p2 * q2. inverse ( ) ) ;
304312 } ) ;
305- challenger . observe ( builder, chip_proof. idx_felt ) ;
313+ chip_challenger . observe ( builder, chip_proof. idx_felt ) ;
306314
307315 if circuit_vk. get_cs ( ) . is_with_lk_table ( ) {
308316 builder. assign ( & logup_sum, logup_sum - chip_logup_sum) ;
@@ -344,7 +352,7 @@ pub fn verify_zkvm_proof<C: Config<F = F>>(
344352 let ( input_opening_point, chip_shard_ec_sum) = verify_chip_proof (
345353 circuit_name,
346354 builder,
347- & mut challenger ,
355+ & mut chip_challenger ,
348356 & chip_proof,
349357 & zkvm_proof_input. pi_evals ,
350358 & zkvm_proof_input. raw_pi ,
@@ -396,6 +404,10 @@ pub fn verify_zkvm_proof<C: Config<F = F>>(
396404 . then ( |builder| {
397405 add_septic_points_in_place ( builder, & shard_ec_sum, & chip_shard_ec_sum) ;
398406 } ) ;
407+
408+ let chip_sample = chip_challenger. sample_ext ( builder) ;
409+ builder. set ( & forked_samples, forked_sample_index. get_var ( ) , chip_sample) ;
410+ builder. inc ( & forked_sample_index) ;
399411 } ) ;
400412 builder. inc ( & num_chips_verified) ;
401413 } ) ;
@@ -414,6 +426,13 @@ pub fn verify_zkvm_proof<C: Config<F = F>>(
414426 logup_sum - dummy_table_item_multiplicity * dummy_table_item. inverse ( ) ,
415427 ) ;
416428
429+ // merge forked transcripts into transcript
430+ iter_zip ! ( builder, forked_samples) . for_each ( |ptr_vec, builder| {
431+ let sample = builder. iter_ptr_get ( & forked_samples, ptr_vec[ 0 ] ) ;
432+ let sample_felts = builder. ext2felt ( sample) ;
433+ challenger. observe_slice ( builder, sample_felts) ;
434+ } ) ;
435+
417436 let rounds: Array < C , RoundVariable < C > > = if num_fixed_opening > 0 {
418437 builder. dyn_array ( 2 )
419438 } else {
0 commit comments