@@ -336,12 +336,13 @@ pub(crate) fn batch_verifier_query_phase<C: Config>(
336336 . iter ( )
337337 . enumerate ( )
338338 {
339- let generator = builder. constant ( C :: F :: from_canonical_usize ( * val) . inverse ( ) ) ;
340- builder. set_value ( & two_adic_generators_inverses, index, generator ) ;
339+ let generator_inverse = builder. constant ( C :: F :: from_canonical_usize ( * val) . inverse ( ) ) ;
340+ builder. set_value ( & two_adic_generators_inverses, index, generator_inverse ) ;
341341 }
342342 let zero: Ext < C :: F , C :: EF > = builder. constant ( C :: EF :: ZERO ) ;
343343 let zero_flag = builder. constant ( C :: N :: ZERO ) ;
344- let two: Var < C :: N > = builder. constant ( C :: N :: from_canonical_usize ( 2 ) ) ;
344+ let two: Var < C :: N > = builder. constant ( C :: N :: TWO ) ;
345+ let two_felt: Felt < C :: F > = builder. constant ( C :: F :: TWO ) ;
345346
346347 // encode_small
347348 let final_message = & input. proof . final_message ;
@@ -615,11 +616,10 @@ pub(crate) fn batch_verifier_query_phase<C: Config>(
615616 builder. assert_eq :: < Var < C :: N > > ( commits. len ( ) , opening_ext. len ( ) ) ;
616617 builder. cycle_tracker_end ( "Initial folding" ) ;
617618 builder. cycle_tracker_start ( "FRI rounds" ) ;
618- builder. range ( 0 , commits. len ( ) ) . for_each ( |i_vec, builder| {
619- builder. cycle_tracker_start ( "FRI round" ) ;
620- let i = i_vec[ 0 ] ;
621- let commit = builder. get ( & commits, i) ;
622- let commit_phase_step = builder. get ( & opening_ext, i) ;
619+ let i: Var < C :: N > = builder. constant ( C :: N :: ZERO ) ;
620+ iter_zip ! ( builder, commits, opening_ext) . for_each ( |ptr_vec, builder| {
621+ let commit = builder. iter_ptr_get ( & commits, ptr_vec[ 0 ] ) ;
622+ let commit_phase_step = builder. iter_ptr_get ( & opening_ext, ptr_vec[ 1 ] ) ;
623623 let i_plus_one = builder. eval_expr ( i + Usize :: from ( 1 ) ) ;
624624
625625 let sibling_value = commit_phase_step. sibling_value ;
@@ -632,12 +632,36 @@ pub(crate) fn batch_verifier_query_phase<C: Config>(
632632 let new_involved_packed_codeword =
633633 builder. get ( & reduced_codeword_by_height, log2_height. clone ( ) ) ;
634634
635+ // Note that previous coeff is
636+ // 1/2 * generator_of_order(2^{level + 2})^{-prev_index}
637+ // = 1/2 * generator_of_order(2^{level + 2})^{-(index+2^level*prev_bit)}
638+ // = 1/2 * omega^{-2^(MAX - (level + 2)) * (index+2^level*prev_bit)}
639+ // where generator_of_order(2^k) returns the generator of order 2^k, which is omega^{2^(MAX - k)}
640+ // since omega is the generator of order 2^MAX, where MAX is the two-adicity of this field.
641+ // Here prev_bit is the most significant bit of prev_index, and index is removing this bit
642+ // from prev_index.
643+ //
644+ // So prev ^ 2 = 1/4 * omega^{-2^(MAX - (level + 2)) * 2 * (index+2^level*prev_bit)}
645+ // = 1/4 * omega^{-2^(MAX - (level + 1)) * (index+2^level*prev_bit)}
646+ // = 1/4 * omega^{-2^(MAX - (level + 1)) * index - 2^(MAX - (level + 1)) * 2^level*prev_bit}
647+ // = 1/2 * curr * omeag^{- 2^(MAX - 1) * prev_bit}
648+ // = 1/2 * curr * generator_of_order(2)^{-prev_bit}
649+ // Note that generator_of_order(2) is exactly -1, so
650+ // prev ^ 2 = 1/2 * curr * (-1)^{-prev_bit}
651+ // which gives us
652+ // curr = 2 * prev^2 * (-1)^{prev_bit}
653+ // Note that we haven't multplied the (-1)^{prev_bit} in the following line.
654+ // Because `folded_idx` is just the `prev_bit`, so we reuse the following `if_eq` and multiply -1
655+ // in the branch where `folded_idx` is != 0.
656+ builder. assign ( & coeff, coeff * coeff * two_felt) ;
657+
635658 builder. if_eq ( folded_idx, Usize :: from ( 0 ) ) . then_or_else (
636659 |builder| {
637660 builder. assign ( & folded, folded + new_involved_packed_codeword. low ) ;
638661 } ,
639662 |builder| {
640663 builder. assign ( & folded, folded + new_involved_packed_codeword. high ) ;
664+ builder. assign ( & coeff, -coeff) ;
641665 } ,
642666 ) ;
643667
@@ -665,19 +689,12 @@ pub(crate) fn batch_verifier_query_phase<C: Config>(
665689 ext_mmcs_verify_batch :: < C > ( builder, ext_mmcs_verifier_input) ;
666690
667691 let r = builder. get ( & input. fold_challenges , i_plus_one) ;
668- let coeff = verifier_folding_coeffs_level (
669- builder,
670- & two_adic_generators_inverses,
671- log2_height,
672- & idx_pair,
673- inv_2,
674- ) ;
675692 let left = builder. get ( & leafs, 0 ) ;
676693 let right = builder. get ( & leafs, 1 ) ;
677694 let new_folded =
678695 codeword_fold_with_challenge ( builder, left, right, r, coeff, inv_2) ;
679696 builder. assign ( & folded, new_folded) ;
680- builder. cycle_tracker_end ( "FRI round" ) ;
697+ builder. assign ( & i , i_plus_one ) ;
681698 } ) ;
682699 builder. cycle_tracker_end ( "FRI rounds" ) ;
683700
0 commit comments