@@ -336,12 +336,13 @@ pub(crate) fn batch_verifier_query_phase<C: Config>(
336
336
. iter ( )
337
337
. enumerate ( )
338
338
{
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 ) ;
341
341
}
342
342
let zero: Ext < C :: F , C :: EF > = builder. constant ( C :: EF :: ZERO ) ;
343
343
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 ) ;
345
346
346
347
// encode_small
347
348
let final_message = & input. proof . final_message ;
@@ -615,11 +616,10 @@ pub(crate) fn batch_verifier_query_phase<C: Config>(
615
616
builder. assert_eq :: < Var < C :: N > > ( commits. len ( ) , opening_ext. len ( ) ) ;
616
617
builder. cycle_tracker_end ( "Initial folding" ) ;
617
618
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 ] ) ;
623
623
let i_plus_one = builder. eval_expr ( i + Usize :: from ( 1 ) ) ;
624
624
625
625
let sibling_value = commit_phase_step. sibling_value ;
@@ -632,12 +632,36 @@ pub(crate) fn batch_verifier_query_phase<C: Config>(
632
632
let new_involved_packed_codeword =
633
633
builder. get ( & reduced_codeword_by_height, log2_height. clone ( ) ) ;
634
634
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
+
635
658
builder. if_eq ( folded_idx, Usize :: from ( 0 ) ) . then_or_else (
636
659
|builder| {
637
660
builder. assign ( & folded, folded + new_involved_packed_codeword. low ) ;
638
661
} ,
639
662
|builder| {
640
663
builder. assign ( & folded, folded + new_involved_packed_codeword. high ) ;
664
+ builder. assign ( & coeff, -coeff) ;
641
665
} ,
642
666
) ;
643
667
@@ -665,19 +689,12 @@ pub(crate) fn batch_verifier_query_phase<C: Config>(
665
689
ext_mmcs_verify_batch :: < C > ( builder, ext_mmcs_verifier_input) ;
666
690
667
691
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
- ) ;
675
692
let left = builder. get ( & leafs, 0 ) ;
676
693
let right = builder. get ( & leafs, 1 ) ;
677
694
let new_folded =
678
695
codeword_fold_with_challenge ( builder, left, right, r, coeff, inv_2) ;
679
696
builder. assign ( & folded, new_folded) ;
680
- builder. cycle_tracker_end ( "FRI round" ) ;
697
+ builder. assign ( & i , i_plus_one ) ;
681
698
} ) ;
682
699
builder. cycle_tracker_end ( "FRI rounds" ) ;
683
700
0 commit comments