binius_core/protocols/greedy_evalcheck/
verify.rs

1// Copyright 2024-2025 Irreducible Inc.
2
3use binius_field::TowerField;
4use binius_math::EvaluationOrder;
5use binius_utils::bail;
6
7use super::error::Error;
8use crate::{
9	fiat_shamir::Challenger,
10	oracle::MultilinearOracleSet,
11	protocols::{
12		evalcheck::{deserialize_evalcheck_proof, EvalcheckMultilinearClaim, EvalcheckVerifier},
13		sumcheck::{self, batch_verify, constraint_set_sumcheck_claims, SumcheckClaimsWithMeta},
14	},
15	transcript::{read_u64, VerifierTranscript},
16};
17
18pub fn verify<F, Challenger_>(
19	oracles: &mut MultilinearOracleSet<F>,
20	claims: impl IntoIterator<Item = EvalcheckMultilinearClaim<F>>,
21	transcript: &mut VerifierTranscript<Challenger_>,
22) -> Result<Vec<EvalcheckMultilinearClaim<F>>, Error>
23where
24	F: TowerField,
25	Challenger_: Challenger,
26{
27	let mut evalcheck_verifier = EvalcheckVerifier::new(oracles);
28
29	// Verify the initial evalcheck claims
30	let claims = claims.into_iter().collect::<Vec<_>>();
31
32	let len_initial_evalcheck_proofs = read_u64(&mut transcript.decommitment())? as usize;
33	let mut initial_evalcheck_proofs = Vec::with_capacity(len_initial_evalcheck_proofs);
34	let mut reader = transcript.message();
35	for _ in 0..len_initial_evalcheck_proofs {
36		let eval_check_proof = deserialize_evalcheck_proof(&mut reader)?;
37		initial_evalcheck_proofs.push(eval_check_proof);
38	}
39
40	evalcheck_verifier.verify(claims, initial_evalcheck_proofs)?;
41
42	loop {
43		let SumcheckClaimsWithMeta { claims, metas } = constraint_set_sumcheck_claims(
44			evalcheck_verifier.take_new_sumcheck_constraints().unwrap(),
45		)?;
46
47		if claims.is_empty() {
48			break;
49		}
50
51		// Reduce the new sumcheck claims for virtual polynomial openings to new evalcheck claims.
52		let sumcheck_output = batch_verify(EvaluationOrder::HighToLow, &claims, transcript)?;
53
54		let new_evalcheck_claims =
55			sumcheck::make_eval_claims(EvaluationOrder::HighToLow, metas, sumcheck_output)?;
56
57		let mut evalcheck_proofs = Vec::with_capacity(new_evalcheck_claims.len());
58		let mut reader = transcript.message();
59		for _ in 0..new_evalcheck_claims.len() {
60			let evalcheck_proof = deserialize_evalcheck_proof(&mut reader)?;
61			evalcheck_proofs.push(evalcheck_proof)
62		}
63
64		evalcheck_verifier.verify(new_evalcheck_claims, evalcheck_proofs)?;
65	}
66
67	let new_sumchecks = evalcheck_verifier.take_new_sumcheck_constraints().unwrap();
68	if !new_sumchecks.is_empty() {
69		bail!(Error::MissingVirtualOpeningProof);
70	}
71
72	let committed_claims = evalcheck_verifier
73		.committed_eval_claims_mut()
74		.drain(..)
75		.collect::<Vec<_>>();
76	Ok(committed_claims)
77}