1- use std:: slice;
1+ use std:: { mem , slice} ;
22
33use crate :: {
44 Point ,
@@ -228,7 +228,7 @@ pub fn batch_verifier_query_phase<E: ExtensionField, S: EncodingScheme<E>>(
228228 // first folding challenge
229229 let r = fold_challenges. first ( ) . unwrap ( ) ;
230230 let coeff = S :: verifier_folding_coeffs ( vp, log2_height, idx) ;
231- let ( lo, hi) = reduced_openings_by_height[ log2_height] . unwrap ( ) ;
231+ let ( lo, hi) = mem :: take ( & mut reduced_openings_by_height[ log2_height] ) . unwrap ( ) ;
232232 let mut folded = codeword_fold_with_challenge ( & [ lo, hi] , * r, coeff, inv_2) ;
233233
234234 for (
@@ -249,8 +249,10 @@ pub fn batch_verifier_query_phase<E: ExtensionField, S: EncodingScheme<E>>(
249249 let idx_sibling = idx & 0x01 ;
250250 let mut leafs = vec ! [ * sibling_value; 2 ] ;
251251 leafs[ idx_sibling] = folded;
252- if let Some ( ( lo, hi) ) = reduced_openings_by_height[ log2_height] . as_mut ( ) {
253- leafs[ idx_sibling] += if idx_sibling == 1 { * hi } else { * lo } ;
252+
253+ if let Some ( ( lo, hi) ) = mem:: take ( & mut reduced_openings_by_height[ log2_height] )
254+ {
255+ leafs[ idx_sibling] += if idx_sibling == 1 { hi } else { lo } ;
254256 }
255257
256258 idx >>= 1 ;
@@ -270,6 +272,24 @@ pub fn batch_verifier_query_phase<E: ExtensionField, S: EncodingScheme<E>>(
270272 let coeff = S :: verifier_folding_coeffs ( vp, log2_height, idx) ;
271273 folded = codeword_fold_with_challenge ( & [ leafs[ 0 ] , leafs[ 1 ] ] , * r, coeff, inv_2) ;
272274 }
275+
276+ // in the final folding round, we add the opening value associated with
277+ // the current `log2_height` into the folded result.
278+ // The choice between `lo` or `hi` depends on the sibling index.
279+ // afterward, we check that the final folded value matches the expected
280+ // entry in the `final_codeword`, as no merkle commitment exists for last round.
281+ log2_height -= 1 ;
282+ let idx_sibling = idx & 0x01 ;
283+ if let Some ( ( lo, hi) ) = mem:: take ( & mut reduced_openings_by_height[ log2_height] ) {
284+ folded += if idx_sibling == 1 { hi } else { lo } ;
285+ }
286+
287+ assert ! (
288+ reduced_openings_by_height. iter( ) . all( |v| v. is_none( ) ) ,
289+ "there are unused openings remain"
290+ ) ;
291+
292+ // final value check: validate the folded result matches the final codeword entry
273293 assert ! (
274294 final_codeword. values[ idx] == folded,
275295 "final_codeword.values[idx] value {:?} != folded {:?}" ,
0 commit comments