binius_core/protocols/greedy_evalcheck/
verify.rs1use binius_field::TowerField;
4use binius_math::EvaluationOrder;
5use binius_utils::bail;
6use itertools::izip;
7
8use super::error::Error;
9use crate::{
10 fiat_shamir::Challenger,
11 oracle::MultilinearOracleSet,
12 protocols::{
13 evalcheck::{ConstraintSetsEqIndPoints, EvalcheckMultilinearClaim, EvalcheckVerifier},
14 sumcheck::{
15 self, MLEcheckClaimsWithMeta, SumcheckClaimsWithMeta, constraint_set_mlecheck_claims,
16 constraint_set_sumcheck_claims,
17 eq_ind::{self, ClaimsSortingOrder, reduce_to_regular_sumchecks},
18 front_loaded,
19 },
20 },
21 transcript::VerifierTranscript,
22};
23
24pub fn verify<F, Challenger_>(
25 oracles: &mut MultilinearOracleSet<F>,
26 claims: impl IntoIterator<Item = EvalcheckMultilinearClaim<F>>,
27 transcript: &mut VerifierTranscript<Challenger_>,
28) -> Result<Vec<EvalcheckMultilinearClaim<F>>, Error>
29where
30 F: TowerField,
31 Challenger_: Challenger,
32{
33 let mut evalcheck_verifier = EvalcheckVerifier::new(oracles);
34
35 evalcheck_verifier.verify(claims, transcript)?;
37
38 loop {
39 let mut new_evalcheck_claims = Vec::new();
40
41 let SumcheckClaimsWithMeta {
42 claims: new_bivariate_sumchecks_claims,
43 metas,
44 } = constraint_set_sumcheck_claims(evalcheck_verifier.take_new_sumcheck_constraints()?)?;
45
46 if !new_bivariate_sumchecks_claims.is_empty() {
47 let batch_sumcheck_verifier =
50 front_loaded::BatchVerifier::new(&new_bivariate_sumchecks_claims, transcript)?;
51 let mut sumcheck_output = batch_sumcheck_verifier.run(transcript)?;
52
53 sumcheck_output.challenges.reverse();
55
56 let evalcheck_claims =
57 sumcheck::make_eval_claims(EvaluationOrder::HighToLow, metas, sumcheck_output)?;
58 new_evalcheck_claims.extend(evalcheck_claims)
59 }
60
61 let ConstraintSetsEqIndPoints {
62 eq_ind_challenges,
63 constraint_sets,
64 } = evalcheck_verifier.take_new_mlechecks_constraints()?;
65
66 let MLEcheckClaimsWithMeta {
67 claims: mlecheck_claims,
68 metas,
69 } = constraint_set_mlecheck_claims(constraint_sets)?;
70
71 if !mlecheck_claims.is_empty() {
72 for (eq_ind_challenges, mlecheck_claim, meta) in
75 izip!(eq_ind_challenges, mlecheck_claims, metas)
76 {
77 let mlecheck_claim = vec![mlecheck_claim];
78
79 let batch_sumcheck_verifier = front_loaded::BatchVerifier::new(
80 &reduce_to_regular_sumchecks(&mlecheck_claim)?,
81 transcript,
82 )?;
83 let mut sumcheck_output = batch_sumcheck_verifier.run(transcript)?;
84
85 sumcheck_output.challenges.reverse();
87
88 let eq_ind_output = eq_ind::verify_sumcheck_outputs(
89 ClaimsSortingOrder::AscendingVars,
90 &mlecheck_claim,
91 &eq_ind_challenges,
92 sumcheck_output,
93 )?;
94
95 let evalcheck_claims = sumcheck::make_eval_claims(
96 EvaluationOrder::HighToLow,
97 vec![meta],
98 eq_ind_output,
99 )?;
100 new_evalcheck_claims.extend(evalcheck_claims)
101 }
102 }
103
104 if new_evalcheck_claims.is_empty() {
105 break;
106 }
107
108 evalcheck_verifier.verify(new_evalcheck_claims, transcript)?;
109 }
110
111 let new_sumchecks = evalcheck_verifier.take_new_sumcheck_constraints()?;
112 if !new_sumchecks.is_empty() {
113 bail!(Error::MissingVirtualOpeningProof);
114 }
115
116 let committed_claims = evalcheck_verifier
117 .committed_eval_claims_mut()
118 .drain(..)
119 .collect::<Vec<_>>();
120 Ok(committed_claims)
121}