Skip to content

fix basefold query verifier logic for not including last round value #985

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 21 additions & 16 deletions mpcs/src/basefold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,26 +378,31 @@ where
);
}

let max_num_var = rounds
let (min_num_var, max_num_var) = rounds
.iter()
.map(|(commit, openings)| {
let max_num_var = openings
.flat_map(|(commit, openings)| {
let (min, max) = openings
.iter()
.map(|(num_vars, _)| *num_vars)
.max()
.unwrap();
assert_eq!(
commit.log2_max_codeword_size,
max_num_var + Spec::get_rate_log()
);
max_num_var
.minmax()
.into_option()
.expect("no openings in round");

assert_eq!(commit.log2_max_codeword_size, max + Spec::get_rate_log());

[min, max] // return as iterator
})
.max()
.unwrap();
if max_num_var < Spec::get_basecode_msg_size_log() {
// all the matrices are trivial, so we can skip the folding
return Ok(());
}
.minmax()
.into_option()
.expect("no num_vars found across all rounds");

assert!(
min_num_var >= Spec::get_basecode_msg_size_log(),
"invalid input: min_num_var {} < get_basecode_msg_size_log {}",
min_num_var,
Spec::get_basecode_msg_size_log()
);

let num_rounds = max_num_var - Spec::get_basecode_msg_size_log();

// prepare folding challenges via sumcheck round msg + FRI commitment
Expand Down
28 changes: 24 additions & 4 deletions mpcs/src/basefold/query_phase.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::slice;
use std::{mem, slice};

use crate::{
Point,
Expand Down Expand Up @@ -228,7 +228,7 @@ pub fn batch_verifier_query_phase<E: ExtensionField, S: EncodingScheme<E>>(
// first folding challenge
let r = fold_challenges.first().unwrap();
let coeff = S::verifier_folding_coeffs(vp, log2_height, idx);
let (lo, hi) = reduced_openings_by_height[log2_height].unwrap();
let (lo, hi) = mem::take(&mut reduced_openings_by_height[log2_height]).unwrap();
let mut folded = codeword_fold_with_challenge(&[lo, hi], *r, coeff, inv_2);

for (
Expand All @@ -249,8 +249,10 @@ pub fn batch_verifier_query_phase<E: ExtensionField, S: EncodingScheme<E>>(
let idx_sibling = idx & 0x01;
let mut leafs = vec![*sibling_value; 2];
leafs[idx_sibling] = folded;
if let Some((lo, hi)) = reduced_openings_by_height[log2_height].as_mut() {
leafs[idx_sibling] += if idx_sibling == 1 { *hi } else { *lo };

if let Some((lo, hi)) = mem::take(&mut reduced_openings_by_height[log2_height])
{
leafs[idx_sibling] += if idx_sibling == 1 { hi } else { lo };
}

idx >>= 1;
Expand All @@ -270,6 +272,24 @@ pub fn batch_verifier_query_phase<E: ExtensionField, S: EncodingScheme<E>>(
let coeff = S::verifier_folding_coeffs(vp, log2_height, idx);
folded = codeword_fold_with_challenge(&[leafs[0], leafs[1]], *r, coeff, inv_2);
}

// in the final folding round, we add the opening value associated with
// the current `log2_height` into the folded result.
// The choice between `lo` or `hi` depends on the sibling index.
// afterward, we check that the final folded value matches the expected
// entry in the `final_codeword`, as no merkle commitment exists for last round.
log2_height -= 1;
let idx_sibling = idx & 0x01;
if let Some((lo, hi)) = mem::take(&mut reduced_openings_by_height[log2_height]) {
folded += if idx_sibling == 1 { hi } else { lo };
}

assert!(
reduced_openings_by_height.iter().all(|v| v.is_none()),
"there are unused openings remain"
);

// final value check: validate the folded result matches the final codeword entry
assert!(
final_codeword.values[idx] == folded,
"final_codeword.values[idx] value {:?} != folded {:?}",
Expand Down