Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
utils.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Planned, auditors: [], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
7#pragma once
8
9#include <tuple>
10#include <type_traits>
11#include <utility>
12
19
20namespace bb {
21
22template <typename Flavor> class RelationUtils {
23 public:
24 using FF = typename Flavor::FF;
25 using Relations = typename Flavor::Relations;
27 using RelationEvaluations = decltype(create_tuple_of_arrays_of_values<typename Flavor::Relations>());
28
29 static constexpr size_t NUM_RELATIONS = Flavor::NUM_RELATIONS;
30 static constexpr size_t NUM_SUBRELATIONS = Flavor::NUM_SUBRELATIONS;
31
32 using SubrelationSeparators = std::array<FF, NUM_SUBRELATIONS - 1>;
33
44 template <class Operation> static void apply_to_tuple_of_tuples(auto& tuple, Operation&& operation)
45 {
46 constexpr size_t outer_tuple_size = std::tuple_size_v<std::decay_t<decltype(tuple)>>;
47 constexpr_for<0, outer_tuple_size, 1>([&]<size_t outer_idx>() {
48 auto& inner_tuple = std::get<outer_idx>(tuple);
49 constexpr size_t inner_tuple_size = std::tuple_size_v<std::decay_t<decltype(inner_tuple)>>;
50 constexpr_for<0, inner_tuple_size, 1>([&]<size_t inner_idx>() {
51 std::forward<Operation>(operation).operator()(std::get<inner_idx>(inner_tuple));
52 });
53 });
54 }
55
61 static void zero_univariates(auto& tuple)
62 {
63 auto set_to_zero = [](auto&&... elements) {
64 (std::fill(elements.evaluations.begin(), elements.evaluations.end(), FF(0)), ...);
65 };
66 flat_tuple::apply([&](auto&&... args) { (flat_tuple::apply(set_to_zero, args), ...); }, tuple);
67 }
68
76 static void scale_univariates(auto& tuple, const SubrelationSeparators& subrelation_separators)
77 {
78 size_t idx = 0;
79 auto scale_by_challenges = [&](auto& element) {
80 // Don't need to scale first univariate
81 if (idx != 0) {
82 element *= subrelation_separators[idx - 1];
83 }
84 idx++;
85 };
86 apply_to_tuple_of_tuples(tuple, scale_by_challenges);
87 }
88
98 template <typename Tuple> static constexpr void add_tuples(Tuple& tuple_1, const Tuple& tuple_2)
99 {
100 auto add_tuples_helper = [&]<std::size_t... I>(std::index_sequence<I...>) {
101 ((std::get<I>(tuple_1) += std::get<I>(tuple_2)), ...);
102 };
103
105 }
106
118 template <typename Tuple> static constexpr void add_nested_tuples(Tuple& tuple_1, const Tuple& tuple_2)
119 {
120 constexpr_for<0, std::tuple_size_v<Tuple>, 1>(
121 [&]<size_t Index>() { add_tuples(std::get<Index>(tuple_1), std::get<Index>(tuple_2)); });
122 }
123
133 template <typename Parameters>
135 RelationEvaluations& relation_evaluations,
136 const Parameters& relation_parameters,
137 const FF& partial_evaluation_result)
138 {
139 constexpr_for<0, NUM_RELATIONS, 1>([&]<size_t rel_index>() {
140 // Skipping is disabled here because this path evaluates the relations at the random sumcheck
141 // challenge: the per-row skip optimization is only valid on the boolean hypercube (where a
142 // witness selector may be exactly zero), not at an arbitrary evaluation point.
143 accumulate_single_relation<Parameters, rel_index, /*consider_skipping=*/false>(
144 evaluations, relation_evaluations, relation_parameters, partial_evaluation_result);
145 });
146 }
147
161 template <typename Parameters>
163 const Parameters& relation_parameters,
164 const FF& scaling_factor)
165 {
167 constexpr_for<0, NUM_RELATIONS, 1>([&]<size_t rel_index>() {
168 accumulate_single_relation<Parameters, rel_index>(evaluations, result, relation_parameters, scaling_factor);
169 });
170 return result;
171 }
172
173 template <typename Parameters, size_t relation_idx, bool consider_skipping = true>
174 inline static void accumulate_single_relation(const PolynomialEvaluations& evaluations,
175 RelationEvaluations& relation_evaluations,
176 const Parameters& relation_parameters,
177 const FF& scaling_factor)
178 {
180
181 // Check if the relation is skippable to speed up accumulation
182 if constexpr (!consider_skipping || !isSkippable<Relation, decltype(evaluations)> ||
184 // If not, accumulate normally
185 Relation::accumulate(
186 std::get<relation_idx>(relation_evaluations), evaluations, relation_parameters, scaling_factor);
187 } else {
188 // If so, only compute the contribution if the relation is active
189 if (!Relation::skip(evaluations)) {
190 Relation::accumulate(
191 std::get<relation_idx>(relation_evaluations), evaluations, relation_parameters, scaling_factor);
192 }
193 }
194 }
195
205 static void zero_elements(auto& tuple)
206 {
207 auto set_to_zero = [](auto& element) { std::fill(element.begin(), element.end(), FF(0)); };
208 apply_to_tuple_of_arrays(set_to_zero, tuple);
209 };
210
225 static FF scale_and_batch_elements(auto& tuple,
226 const SubrelationSeparators& subrelation_separators,
227 const FF& main_factor = FF{ 1 },
228 const FF& offset_factor = FF{ 0 })
229 {
230 FF result{ 0 };
231 size_t idx = 0;
232
233 auto process = [&]<size_t outer_idx, size_t inner_idx>(auto& element) {
235 const FF& rd_factor = IsOffsetOnlyRelation<Relation> ? offset_factor : main_factor;
236 if constexpr (outer_idx == 0 && inner_idx == 0) {
237 // α_{0,0} = 1 by convention.
238 result += element * rd_factor;
239 } else {
240 result += element * subrelation_separators[idx++] * rd_factor;
241 }
242 };
243 apply_to_tuple_of_arrays_elements(process, tuple);
244 return result;
245 }
246
253 template <typename Operation> static void apply_to_tuple_of_arrays(Operation&& operation, auto& tuple)
254 {
256 [&operation](auto&... elements_ref) {
257 // The comma operator ensures sequential application of the operation to each element.
258 // (void) cast is used to discard the result of std::invoke if it's not void,
259 // to prevent issues with overloaded comma operators.
260 ((void)std::invoke(std::forward<Operation>(operation), elements_ref), ...);
261 },
262 tuple);
263 }
264
273 template <typename Operation, typename tuple_type>
274 static void apply_to_tuple_of_arrays_elements(Operation&& operation, const tuple_type& tuple)
275 {
276 // Iterate over each array in the outer tuple.
277 // OuterIdx is the compile-time index of the current array in the tuple.
278 constexpr_for<0, std::tuple_size_v<tuple_type>, 1>([&]<size_t OuterIdx>() {
279 // Get a const reference to the current array from the tuple.
280 const auto& current_array = std::get<OuterIdx>(tuple);
281 constexpr size_t num_elements_in_current_array = std::tuple_size_v<std::decay_t<decltype(current_array)>>;
282
283 // Iterate over each element within the current_array.
284 // InnerIdx is the compile-time index of the element within this specific array.
285 constexpr_for<0, num_elements_in_current_array, 1>([&]<size_t InnerIdx>() {
286 // Invoke the operation.
287 // The operation is called with OuterIdx (array index in the tuple) and
288 // InnerIdx (element index in the current array) as template arguments.
289 // The current element (e.g., an FF value) is passed as an argument.
290 std::forward<Operation>(operation).template operator()<OuterIdx, InnerIdx>(current_array[InnerIdx]);
291 });
292 });
293 }
294};
295
296} // namespace bb
A field element for each entity of the flavor. These entities represent the prover polynomials evalua...
typename Curve::ScalarField FF
static constexpr size_t NUM_SUBRELATIONS
static constexpr size_t NUM_RELATIONS
Relations_< FF > Relations
A wrapper for Relations to expose methods used by the Sumcheck prover or verifier to add the contribu...
static constexpr size_t NUM_RELATIONS
Definition utils.hpp:29
static void apply_to_tuple_of_arrays_elements(Operation &&operation, const tuple_type &tuple)
Apply a specific operation on each element of several arrays in a tuple.
Definition utils.hpp:274
typename Flavor::Relations Relations
Definition utils.hpp:25
static void scale_univariates(auto &tuple, const SubrelationSeparators &subrelation_separators)
Scale Univariates, each representing a subrelation, by different challenges.
Definition utils.hpp:76
static void zero_elements(auto &tuple)
Set each element in a tuple of arrays to zero.
Definition utils.hpp:205
static void zero_univariates(auto &tuple)
Set all coefficients of Univariates to zero.
Definition utils.hpp:61
static constexpr void add_nested_tuples(Tuple &tuple_1, const Tuple &tuple_2)
Componentwise addition of nested tuples (tuples of tuples)
Definition utils.hpp:118
typename Flavor::FF FF
Definition utils.hpp:24
static constexpr void add_tuples(Tuple &tuple_1, const Tuple &tuple_2)
Componentwise addition of two tuples.
Definition utils.hpp:98
static RelationEvaluations accumulate_relation_evaluations(const PolynomialEvaluations &evaluations, const Parameters &relation_parameters, const FF &scaling_factor)
Calculate the contribution of each relation to the expected value of the full Honk relation.
Definition utils.hpp:162
static void apply_to_tuple_of_tuples(auto &tuple, Operation &&operation)
General purpose method for applying an operation to a tuple of tuples of Univariates.
Definition utils.hpp:44
static void accumulate_single_relation(const PolynomialEvaluations &evaluations, RelationEvaluations &relation_evaluations, const Parameters &relation_parameters, const FF &scaling_factor)
Definition utils.hpp:174
decltype(create_tuple_of_arrays_of_values< typename Flavor::Relations >()) RelationEvaluations
Definition utils.hpp:27
std::array< FF, NUM_SUBRELATIONS - 1 > SubrelationSeparators
Definition utils.hpp:32
static void accumulate_relation_evaluations_without_skipping(const PolynomialEvaluations &evaluations, RelationEvaluations &relation_evaluations, const Parameters &relation_parameters, const FF &partial_evaluation_result)
Calculate the contribution of each relation to the expected value of the full Honk relation.
Definition utils.hpp:134
static FF scale_and_batch_elements(auto &tuple, const SubrelationSeparators &subrelation_separators, const FF &main_factor=FF{ 1 }, const FF &offset_factor=FF{ 0 })
Scale per-subrelation evaluations by α powers and row-disabling factors, then sum.
Definition utils.hpp:225
static constexpr size_t NUM_SUBRELATIONS
Definition utils.hpp:30
typename Flavor::AllValues PolynomialEvaluations
Definition utils.hpp:26
static void apply_to_tuple_of_arrays(Operation &&operation, auto &tuple)
General purpose method for applying a tuple of arrays (of FFs)
Definition utils.hpp:253
The templates defined herein facilitate sharing the relation arithmetic between the prover and the ve...
std::conditional_t< IsGoblinBigGroup< C, Fq, Fr, G >, element_goblin::goblin_element< C, goblin_field< C >, Fr, G >, element_default::element< C, Fq, Fr, G > > element
element wraps either element_default::element or element_goblin::goblin_element depending on parametr...
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
TUPLET_INLINE constexpr decltype(auto) apply(F &&func, Tup &&tup)
Definition tuplet.hpp:1032
VectorField result