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 // FIXME: You wan't /*consider_skipping=*/false here, but tests need to be fixed.
141 accumulate_single_relation<Parameters, rel_index, /*consider_skipping=*/false>(
142 evaluations, relation_evaluations, relation_parameters, partial_evaluation_result);
143 });
144 }
145
159 template <typename Parameters>
161 const Parameters& relation_parameters,
162 const FF& scaling_factor)
163 {
164 RelationEvaluations result{};
165 constexpr_for<0, NUM_RELATIONS, 1>([&]<size_t rel_index>() {
166 accumulate_single_relation<Parameters, rel_index>(evaluations, result, relation_parameters, scaling_factor);
167 });
168 return result;
169 }
170
171 template <typename Parameters, size_t relation_idx, bool consider_skipping = true>
172 inline static void accumulate_single_relation(const PolynomialEvaluations& evaluations,
173 RelationEvaluations& relation_evaluations,
174 const Parameters& relation_parameters,
175 const FF& scaling_factor)
176 {
178
179 // Check if the relation is skippable to speed up accumulation
180 if constexpr (!consider_skipping || !isSkippable<Relation, decltype(evaluations)> ||
182 // If not, accumulate normally
183 Relation::accumulate(
184 std::get<relation_idx>(relation_evaluations), evaluations, relation_parameters, scaling_factor);
185 } else {
186 // If so, only compute the contribution if the relation is active
187 if (!Relation::skip(evaluations)) {
188 Relation::accumulate(
189 std::get<relation_idx>(relation_evaluations), evaluations, relation_parameters, scaling_factor);
190 }
191 }
192 }
193
203 static void zero_elements(auto& tuple)
204 {
205 auto set_to_zero = [](auto& element) { std::fill(element.begin(), element.end(), FF(0)); };
206 apply_to_tuple_of_arrays(set_to_zero, tuple);
207 };
208
215 static FF scale_and_batch_elements(auto& tuple, const SubrelationSeparators& subrelation_separators)
216 {
217 // Initialize result with the contribution from the first subrelation
218 FF result = std::get<0>(tuple)[0];
219
220 size_t idx = 0;
221
222 auto scale_by_challenges_and_accumulate = [&]<size_t outer_idx, size_t inner_idx>(auto& element) {
223 if constexpr (!(outer_idx == 0 && inner_idx == 0)) {
224 // Accumulate scaled subrelation contribution
225 result += element * subrelation_separators[idx++];
226 }
227 };
228 apply_to_tuple_of_arrays_elements(scale_by_challenges_and_accumulate, tuple);
229 return result;
230 }
231
238 template <typename Operation> static void apply_to_tuple_of_arrays(Operation&& operation, auto& tuple)
239 {
241 [&operation](auto&... elements_ref) {
242 // The comma operator ensures sequential application of the operation to each element.
243 // (void) cast is used to discard the result of std::invoke if it's not void,
244 // to prevent issues with overloaded comma operators.
245 ((void)std::invoke(std::forward<Operation>(operation), elements_ref), ...);
246 },
247 tuple);
248 }
249
258 template <typename Operation, typename tuple_type>
259 static void apply_to_tuple_of_arrays_elements(Operation&& operation, const tuple_type& tuple)
260 {
261 // Iterate over each array in the outer tuple.
262 // OuterIdx is the compile-time index of the current array in the tuple.
263 constexpr_for<0, std::tuple_size_v<tuple_type>, 1>([&]<size_t OuterIdx>() {
264 // Get a const reference to the current array from the tuple.
265 const auto& current_array = std::get<OuterIdx>(tuple);
266 constexpr size_t num_elements_in_current_array = std::tuple_size_v<std::decay_t<decltype(current_array)>>;
267
268 // Iterate over each element within the current_array.
269 // InnerIdx is the compile-time index of the element within this specific array.
270 constexpr_for<0, num_elements_in_current_array, 1>([&]<size_t InnerIdx>() {
271 // Invoke the operation.
272 // The operation is called with OuterIdx (array index in the tuple) and
273 // InnerIdx (element index in the current array) as template arguments.
274 // The current element (e.g., an FF value) is passed as an argument.
275 std::forward<Operation>(operation).template operator()<OuterIdx, InnerIdx>(current_array[InnerIdx]);
276 });
277 });
278 }
279};
280
281} // 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)
Recursive template function to apply a specific operation on each element of several arrays in a tupl...
Definition utils.hpp:259
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:203
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:160
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:172
static FF scale_and_batch_elements(auto &tuple, const SubrelationSeparators &subrelation_separators)
Scale elements, representing evaluations of subrelations, by separate challenges then sum them.
Definition utils.hpp:215
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 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:238
The templates defined herein facilitate sharing the relation arithmetic between the prover and the ve...
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