Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
multilinear_batching_verifier.cpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
12
13#include <optional>
14
15namespace bb {
16
17template <typename Flavor_>
19 const std::shared_ptr<Transcript>& transcript)
20 : transcript(transcript)
21{}
22
23template <typename Flavor_>
25 Flavor_>::compute_target_sum(const FF& alpha,
26 const std::vector<VerifierClaim>& claims,
27 const std::span<const FF> scalars) const
28{
29 FF non_shifted_target(0);
30 FF shifted_target(0);
31 for (size_t idx = 0; idx < NUM_CLAIMS; ++idx) {
32 non_shifted_target += claims[idx].non_shifted_evaluation * scalars[idx];
33 shifted_target += claims[idx].shifted_evaluation * scalars[idx];
34 }
35 return non_shifted_target + shifted_target * alpha;
36}
37
38template <typename Flavor_>
40 Flavor_>::compute_new_claim(const SumcheckOutput<Flavor>& sumcheck_result,
41 const std::vector<VerifierClaim>& claims,
42 std::vector<FF> scalars)
43{
44 std::vector<Commitment> non_shifted_commitments;
45 std::vector<Commitment> shifted_commitments;
46 non_shifted_commitments.reserve(NUM_CLAIMS);
47 shifted_commitments.reserve(NUM_CLAIMS);
48 for (size_t idx = 0; idx < NUM_CLAIMS; ++idx) {
49 non_shifted_commitments.emplace_back(claims[idx].non_shifted_commitment);
50 shifted_commitments.emplace_back(claims[idx].shifted_commitment);
51 }
52
53 Commitment non_shifted_commitment = Curve::Element::batch_mul(non_shifted_commitments, scalars);
54 Commitment shifted_commitment = Curve::Element::batch_mul(shifted_commitments, scalars);
55
56 FF non_shifted_evaluation(0);
57 FF shifted_evaluation(0);
58 for (size_t idx = 0; idx < NUM_CLAIMS; ++idx) {
59 non_shifted_evaluation += scalars[idx] * sumcheck_result.claimed_evaluations.non_shifted(idx);
60 shifted_evaluation += scalars[idx] * sumcheck_result.claimed_evaluations.shifted(idx);
61 }
62
63 return VerifierClaim{ .challenge = sumcheck_result.challenge,
64 .non_shifted_evaluation = non_shifted_evaluation,
65 .shifted_evaluation = shifted_evaluation,
66 .non_shifted_commitment = non_shifted_commitment,
67 .shifted_commitment = shifted_commitment };
68}
69
70template <typename Flavor_>
72 const std::vector<VerifierClaim>& claims)
73{
74 bool verified = true;
75 for (size_t idx = 0; idx < NUM_CLAIMS; ++idx) {
76 auto eq_diff = sumcheck_result.claimed_evaluations.eq(idx) -
77 VerifierEqPolynomial<FF>::eval(claims[idx].challenge, sumcheck_result.challenge);
78 if constexpr (IsRecursive) {
79 verified &= eq_diff.get_value() == 0;
80 eq_diff.assert_equal(FF(0), "MultilinearBatchingVerifier: eq polynomial mismatch");
81 } else {
82 verified &= eq_diff == FF(0);
83 }
84 }
85 return verified;
86}
87
88template <typename Flavor_>
91{
92 BB_BENCH_NAME("MultilinearBatchingVerifier::verify_proof");
93 BB_ASSERT_EQ(claims.size(), NUM_CLAIMS, "MultilinearBatchingVerifier: claim count must equal the width");
94
95 // The batching sumcheck is read from the shared transcript, which already holds the group's instance sumchecks
96 // followed by the loaded batching proof.
97 //
98 // γ separates the input claims: it weights the target sum (i-th evaluation by γ^i) and is fed to the relation as a
99 // public coefficient. It is NOT used to merge the output claims — that is done with the fresh ρ below.
100 const FF claim_batching_challenge = transcript->template get_challenge<FF>("claim_batching_challenge");
101 RelationParameters<FF> relation_parameters;
102 relation_parameters.compute_multilinear_batching_challenges(claim_batching_challenge, NUM_CLAIMS);
103 const std::span<const FF> batching_scalars(relation_parameters.multilinear_batching_challenges.data(), NUM_CLAIMS);
104
105 const FF alpha = transcript->template get_challenge<FF>("Sumcheck:alpha");
106 FF target_sum = compute_target_sum(alpha, claims, batching_scalars);
107
108 Sumcheck sumcheck(transcript, alpha, Flavor::VIRTUAL_LOG_N, target_sum);
109 const auto sumcheck_result = sumcheck.verify(relation_parameters, /*gate_challenges=*/{});
110
111 bool eq_consistent = check_eq_consistency(sumcheck_result, claims);
112
113 // Draw the merge challenge only now, after the sumcheck's claimed evaluations are bound to the transcript, so that
114 // the single opening of the combined accumulator commitment binds each P_i(r) individually.
115 const FF claim_merge_challenge = transcript->template get_challenge<FF>("claim_merge_challenge");
116 std::vector<FF> merge_scalars(NUM_CLAIMS);
117 merge_scalars[0] = FF(1);
118 for (size_t idx = 1; idx < NUM_CLAIMS; ++idx) {
119 merge_scalars[idx] = merge_scalars[idx - 1] * claim_merge_challenge;
120 }
121
122 VerifierClaim verifier_claim = compute_new_claim(sumcheck_result, claims, std::move(merge_scalars));
123 bool verified = sumcheck_result.verified && eq_consistent;
124
125 return { verified, std::move(verifier_claim) };
126}
127
128template <bool IsRecursive_>
130 : transcript(transcript)
131{}
132
133template <bool IsRecursive_>
134template <size_t NumClaims>
136 IsRecursive_>::verify_with_width(const std::vector<VerifierClaim>& claims)
137{
138 using Flavor = std::conditional_t<IsRecursive_,
142 return internal.verify_proof(claims);
143}
144
145template <bool IsRecursive_>
147 IsRecursive_>::verify_proof(const std::vector<VerifierClaim>& claims)
148{
149 // Dispatch the runtime claim count to the matching compile-time width. The range is derived from
150 // CHONK_MAX_CLAIMS_PER_KERNEL, so every supported width is instantiated automatically and bumping the constant
151 // cannot leave a width unhandled.
153 constexpr_for<2, CHONK_MAX_CLAIMS_PER_KERNEL + 1, 1>([&]<size_t Width>() {
154 if (claims.size() == Width) {
155 result = this->template verify_with_width<Width>(claims);
156 }
157 });
158 if (!result.has_value()) {
159 throw_or_abort("MultilinearBatchingVerifier: unsupported batch width");
160 }
161 return std::move(*result);
162}
163
166
167} // namespace bb
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:83
bb::field< bb::Bn254FrParams > FF
Definition field.cpp:24
#define BB_BENCH_NAME(name)
Definition bb_bench.hpp:264
Native flavor for multilinear batching sumcheck with NumClaims polynomials.
Public entrypoint for multilinear batching verification.
MultilinearBatchingVerifier(const std::shared_ptr< Transcript > &transcript)
Internal verifier for multilinear batching sumcheck over a fixed number of claims.
bool check_eq_consistency(const SumcheckOutput< Flavor > &sumcheck_result, const std::vector< VerifierClaim > &claims)
MultilinearBatchingVerifierInternal(const std::shared_ptr< Transcript > &transcript)
std::pair< bool, VerifierClaim > verify_proof(const std::vector< VerifierClaim > &claims)
Implementation of the sumcheck Verifier for statements of the form for multilinear polynomials .
Definition sumcheck.hpp:802
SumcheckOutput< Flavor > verify(const bb::RelationParameters< FF > &relation_parameters, const std::vector< FF > &gate_challenges)
The Sumcheck verification method. First it extracts round univariate, checks sum (the sumcheck univar...
Definition sumcheck.hpp:859
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
std::vector< Fr > batching_scalars(const Fr &challenge, const size_t count)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
Verifier's claim for multilinear batching - contains commitments and evaluation claims.
Container for parameters used by the grand product (permutation, lookup) Honk relations.
std::array< T, NUM_MULTILINEAR_BATCHING_CHALLENGES > multilinear_batching_challenges
void compute_multilinear_batching_challenges(const T &batching_challenge, const size_t num_claims)
Contains the evaluations of multilinear polynomials at the challenge point . These are computed by S...
ClaimedEvaluations claimed_evaluations
std::vector< FF > challenge
static FF eval(std::span< const FF > r_in, std::span< const FF > u)
void throw_or_abort(std::string const &err)
VectorField result