Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
claim_batcher.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
7#pragma once
11#include <optional>
12
13namespace bb {
14
27template <typename Curve> struct ClaimBatcher_ {
28 using Fr = typename Curve::ScalarField;
30
31 struct Batch {
34 // scalar used for batching the claims, excluding the power of batching challenge \rho
36 };
44
45 std::optional<Batch> unshifted; // commitments and evaluations of unshifted polynomials
46 std::optional<Batch> shifted; // commitments of to-be-shifted-by-1 polys, evals of their shifts
47 std::optional<Batch> right_shifted_by_k; // commitments of to-be-right-shifted-by-k polys, evals of their shifts
48 std::optional<InterleavedBatch> interleaved; // commitments to groups of polynomials to be combined by interleaving
49 // and evaluations of the resulting interleaved polynomials
50
52 Batch get_shifted() { return (shifted) ? *shifted : Batch{}; }
56 {
57 return (interleaved) ? static_cast<uint32_t>(interleaved->commitments_groups[0].size()) : 0;
58 }
59
60 uint32_t k_shift_magnitude = 0; // magnitude of right-shift-by-k (assumed even)
61
62 Fr get_unshifted_batch_scalar() const { return unshifted ? unshifted->scalar : Fr{ 0 }; }
63
90 const Fr& nu_challenge,
91 const Fr& r_challenge)
92 {
93 const Fr& inverse_vanishing_eval_pos = inverted_vanishing_evals[0];
94 const Fr& inverse_vanishing_eval_neg = inverted_vanishing_evals[1];
95
96 if (unshifted) {
97 // (1/(z−r) + ν/(z+r))
98 unshifted->scalar = inverse_vanishing_eval_pos + nu_challenge * inverse_vanishing_eval_neg;
99 }
100 if (shifted) {
101 // r⁻¹ ⋅ (1/(z−r) − ν/(z+r))
102 shifted->scalar =
103 r_challenge.invert() * (inverse_vanishing_eval_pos - nu_challenge * inverse_vanishing_eval_neg);
104 }
105 if (right_shifted_by_k) {
106 // r^k ⋅ (1/(z−r) + ν/(z+r))
107 right_shifted_by_k->scalar = r_challenge.pow(k_shift_magnitude) *
108 (inverse_vanishing_eval_pos + nu_challenge * inverse_vanishing_eval_neg);
109 }
110
111 if (interleaved) {
112 const size_t interleaving_denominator_index = 2 * numeric::get_msb(get_groups_to_be_interleaved_size());
113
114 if (get_groups_to_be_interleaved_size() % 2 != 0) {
115 throw_or_abort("Interleaved groups size must be even");
116 }
117
118 Fr r_shift_pos = Fr(1);
119 Fr r_shift_neg = Fr(1);
120 interleaved->shplonk_denominator = inverted_vanishing_evals[interleaving_denominator_index];
121 for (size_t i = 0; i < get_groups_to_be_interleaved_size(); i++) {
122 interleaved->scalars_pos.push_back(r_shift_pos);
123 interleaved->scalars_neg.push_back(r_shift_neg);
124 if (i < get_groups_to_be_interleaved_size() - 1) {
125 // to avoid unnecessary multiplication gates in a circuit
126 r_shift_pos *= r_challenge;
127 r_shift_neg *= (-r_challenge);
128 }
129 }
130 }
131 }
145 void update_batch_mul_inputs_and_batched_evaluation(std::vector<Commitment>& commitments,
146 std::vector<Fr>& scalars,
147 Fr& batched_evaluation,
148 const Fr& rho,
149 Fr& rho_power,
150 Fr shplonk_batching_pos = { 0 },
151 Fr shplonk_batching_neg = { 0 })
152 {
153 // Append the commitments/scalars from a given batch to the corresponding containers; update the batched
154 // evaluation and the running batching challenge in place
155 auto aggregate_claim_data_and_update_batched_evaluation = [&](const Batch& batch, Fr& rho_power) {
156 for (auto [commitment, evaluation] : zip_view(batch.commitments, batch.evaluations)) {
157 commitments.emplace_back(std::move(commitment));
158 scalars.emplace_back(-batch.scalar * rho_power);
159 batched_evaluation += evaluation * rho_power;
160 rho_power *= rho;
161 }
162 };
163
164 // Incorporate the claim data from each batch of claims that is present in the vectors of commitments and
165 // scalars for the batch mul
166 if (unshifted) {
167 // i-th Unshifted commitment will be multiplied by ρ^i and (1/(z−r) + ν/(z+r))
168 aggregate_claim_data_and_update_batched_evaluation(*unshifted, rho_power);
169 }
170 if (shifted) {
171 // i-th shifted commitments will be multiplied by p^{k+i} and r⁻¹ ⋅ (1/(z−r) − ν/(z+r))
172 aggregate_claim_data_and_update_batched_evaluation(*shifted, rho_power);
173 }
174 if (right_shifted_by_k) {
175 // i-th right-shifted-by-k commitments will be multiplied by ρ^{k+m+i} and r^k ⋅ (1/(z−r) + ν/(z+r))
176 aggregate_claim_data_and_update_batched_evaluation(*right_shifted_by_k, rho_power);
177 }
178 if (interleaved) {
179 if (get_groups_to_be_interleaved_size() % 2 != 0) {
180 throw_or_abort("Interleaved groups size must be even");
181 }
182
183 size_t group_idx = 0;
184 for (size_t j = 0; j < interleaved->commitments_groups.size(); j++) {
185 for (size_t i = 0; i < get_groups_to_be_interleaved_size(); i++) {
186 // The j-th commitment in group i is multiplied by ρ^{k+m+i} and ν^{n+1} \cdot r^j + ν^{n+2} ⋅(-r)^j
187 // where k is the number of unshifted, m is number of shifted and n is the log_circuit_size
188 // (assuming to right-shifted-by-k commitments in this example)
189 commitments.emplace_back(std::move(interleaved->commitments_groups[j][i]));
190 scalars.emplace_back(-rho_power * interleaved->shplonk_denominator *
191 (shplonk_batching_pos * interleaved->scalars_pos[i] +
192 shplonk_batching_neg * interleaved->scalars_neg[i]));
193 }
194 batched_evaluation += interleaved->evaluations[group_idx] * rho_power;
195 if (j != interleaved->commitments_groups.size() - 1) {
196 rho_power *= rho;
197 }
198 group_idx++;
199 }
200 }
201 }
202};
203
204} // namespace bb
A template class for a reference vector. Behaves as if std::vector<T&> was possible.
typename Group::affine_element AffineElement
Definition grumpkin.hpp:56
constexpr T get_msb(const T in)
Definition get_msb.hpp:47
Entry point for Barretenberg command-line interface.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
RefVector< Commitment > commitments
RefVector< Fr > evaluations
std::vector< RefVector< Commitment > > commitments_groups
Logic to support batching opening claims for unshifted and shifted polynomials in Shplemini.
std::optional< Batch > unshifted
std::optional< Batch > shifted
uint32_t get_groups_to_be_interleaved_size()
void compute_scalars_for_each_batch(std::span< const Fr > inverted_vanishing_evals, const Fr &nu_challenge, const Fr &r_challenge)
Compute scalars used to batch each set of claims, excluding contribution from batching challenge \rho...
typename Curve::ScalarField Fr
Batch get_right_shifted_by_k()
void update_batch_mul_inputs_and_batched_evaluation(std::vector< Commitment > &commitments, std::vector< Fr > &scalars, Fr &batched_evaluation, const Fr &rho, Fr &rho_power, Fr shplonk_batching_pos={ 0 }, Fr shplonk_batching_neg={ 0 })
Append the commitments and scalars from each batch of claims to the Shplemini, vectors which subseque...
InterleavedBatch get_interleaved()
std::optional< Batch > right_shifted_by_k
std::optional< InterleavedBatch > interleaved
Fr get_unshifted_batch_scalar() const
typename Curve::AffineElement Commitment
void throw_or_abort(std::string const &err)