Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
relation_checker.hpp
Go to the documentation of this file.
1#pragma once
2
7
8namespace bb {
9
15template <typename Flavor> class RelationChecker {
16 public:
18 std::map<size_t,
19 uint32_t>; // key is the subrelation idx, value is the row idx.
20 // for relations which `has_linearly_dependent`, those subrelations which are "not
21 // linearly independent" (i.e., are only required to vanish on the entire execution trace)
22 // are treated as follows: if they do _not_ vanish when evaluated over the entire execution
23 // trace, we set the row_idx in this data structure to 0.
25 std::map<std::string, FirstSubrelationFailures>; // key is the name of a Relation, value is of type
26 // `FirstSubrelationFailures`. Theck if there are no failures,
27 // simply check if this hashmap is empty.
31 static AllSubrelationFailures check_all([[maybe_unused]] const auto& polynomials,
32 [[maybe_unused]] const auto& params)
33 {
34 // default
36 }
37
41 template <typename Relation, bool has_linearly_dependent = false>
42 static FirstSubrelationFailures check(const auto& polynomials,
43 const auto& params,
44 [[maybe_unused]] std::string label = "Relation")
45 {
46 FirstSubrelationFailures first_failure_per_subrelation;
47 // Define the appropriate accumulator type for the relation and initialize to zero
49 for (auto& element : result) {
50 element = 0;
51 }
52
53 for (uint32_t i = 0; i < polynomials.get_polynomial_size(); i++) {
54
55 Relation::accumulate(result, polynomials.get_row(i), params, 1);
56 size_t subrelation_idx = 0;
57
58 // Iterate over all the subrelation results and report if a linearly independent one failed
59 for (auto& element : result) {
60 if constexpr (has_linearly_dependent) {
61 if (element != 0 && Relation::SUBRELATION_LINEARLY_INDEPENDENT[subrelation_idx]) {
62 // only record the first failure for this subrelation
63 if (!first_failure_per_subrelation.contains(subrelation_idx)) {
64 first_failure_per_subrelation[subrelation_idx] = i;
65 }
66 }
67 } else {
68 if (element != 0) {
69 // only record the first failure for this subrelation
70 if (!first_failure_per_subrelation.contains(subrelation_idx)) {
71 first_failure_per_subrelation[subrelation_idx] = i;
72 }
73 }
74 }
75 subrelation_idx++;
76 }
77 }
78
79 if constexpr (has_linearly_dependent) {
80 size_t subrelation_idx = 0;
81 for (auto& element : result) {
82 // Check that linearly _dependent_ subrelation result is 0 over the entire execution trace
83 if (element != 0 && !Relation::SUBRELATION_LINEARLY_INDEPENDENT[subrelation_idx]) {
84 if (!first_failure_per_subrelation.contains(subrelation_idx)) {
85 first_failure_per_subrelation[subrelation_idx] = 0;
86 }
87 }
88 subrelation_idx++;
89 }
90 }
91 return first_failure_per_subrelation;
92 };
93};
94
95// Specialization for Ultra
96template <> class RelationChecker<bb::UltraFlavor> : public RelationChecker<void> {
98
99 public:
100 static AllSubrelationFailures check_all(const auto& polynomials, const auto& params)
101 {
102 using FF = UltraFlavor::FF;
103
104 AllSubrelationFailures all_subrelation_failures;
105
106 // Linearly independent relations (must be satisfied at each row)
107 auto ultra_arithmetic_subrelation_failures =
108 Base::check<ArithmeticRelation<FF>>(polynomials, params, "UltraArithmetic");
109 if (!ultra_arithmetic_subrelation_failures.empty()) {
110 all_subrelation_failures["UltraArithmetic"] = ultra_arithmetic_subrelation_failures;
111 }
112 auto ultra_permutation_subrelation_failures =
113 Base::check<UltraPermutationRelation<FF>>(polynomials, params, "UltraPermutation");
114 if (!ultra_permutation_subrelation_failures.empty()) {
115 all_subrelation_failures["UltraPermutation"] = ultra_permutation_subrelation_failures;
116 }
117 auto ultra_delta_range_subrelation_failures =
118 Base::check<DeltaRangeConstraintRelation<FF>>(polynomials, params, "DeltaRangeConstraint");
119 if (!ultra_delta_range_subrelation_failures.empty()) {
120 all_subrelation_failures["UltraDeltaRange"] = ultra_delta_range_subrelation_failures;
121 }
122 auto ultra_elliptic_subrelation_failures = Base::check<EllipticRelation<FF>>(polynomials, params, "Elliptic");
123 if (!ultra_elliptic_subrelation_failures.empty()) {
124 all_subrelation_failures["UltraElliptic"] = ultra_elliptic_subrelation_failures;
125 }
126 auto ultra_memory_subrelation_failures = Base::check<MemoryRelation<FF>>(polynomials, params, "Memory");
127 if (!ultra_memory_subrelation_failures.empty()) {
128 all_subrelation_failures["UltraMemory"] = ultra_memory_subrelation_failures;
129 }
130 auto ultra_non_native_field_subrelation_failures =
131 Base::check<NonNativeFieldRelation<FF>>(polynomials, params, "NonNativeField");
132 if (!ultra_non_native_field_subrelation_failures.empty()) {
133 all_subrelation_failures["NonNativeField"] = ultra_non_native_field_subrelation_failures;
134 }
135 auto ultra_poseidon2_external_subrelation_failures =
136 Base::check<Poseidon2ExternalRelation<FF>>(polynomials, params, "Poseidon2External");
137 if (!ultra_poseidon2_external_subrelation_failures.empty()) {
138 all_subrelation_failures["UltraPoseidon2External"] = ultra_poseidon2_external_subrelation_failures;
139 }
140 auto ultra_poseidon2_internal_subrelation_failures =
141 Base::check<Poseidon2InternalRelation<FF>>(polynomials, params, "Poseidon2Internal");
142 if (!ultra_poseidon2_internal_subrelation_failures.empty()) {
143 all_subrelation_failures["UltraPoseidon2Internal"] = ultra_poseidon2_internal_subrelation_failures;
144 }
145
146 // Relations that have "linearly dependent" subrelations
147 auto ultra_log_derivative_subrelation_failures =
148 Base::check<LogDerivLookupRelation<FF>, true>(polynomials, params, "LogDerivLookup");
149 if (!ultra_log_derivative_subrelation_failures.empty()) {
150 all_subrelation_failures["UltraLogDerivative"] = ultra_log_derivative_subrelation_failures;
151 }
152 return all_subrelation_failures;
153 }
154};
155
156// Specialization for Mega
157template <> class RelationChecker<MegaFlavor> : public RelationChecker<void> {
159
160 public:
161 static AllSubrelationFailures check_all(const auto& polynomials, const auto& params)
162 {
163 using FF = MegaFlavor::FF;
164
165 // Start with all relations that are shared with Ultra
166 AllSubrelationFailures all_subrelation_failures = RelationChecker<UltraFlavor>::check_all(polynomials, params);
167
168 // Mega-specific relations
169 // There is one relation that does not `have_linearly_dependent`.
170 auto mega_ecc_op_queue_subrelation_failures =
171 Base::check<EccOpQueueRelation<FF>>(polynomials, params, "EccOpQueue");
172 if (!mega_ecc_op_queue_subrelation_failures.empty()) {
173 all_subrelation_failures["MegaEccOpQueue"] = mega_ecc_op_queue_subrelation_failures;
174 }
175
176 // There is one one relation that satisfies `have_linearly_dependent`
177 auto mega_databus_lookup_subrelation_failures =
178 Base::check<DatabusLookupRelation<FF>, true>(polynomials, params, "DatabusLookup");
179 if (!mega_databus_lookup_subrelation_failures.empty()) {
180 all_subrelation_failures["MegaDatabusLookup"] = mega_databus_lookup_subrelation_failures;
181 }
182
183 return all_subrelation_failures;
184 }
185};
186} // namespace bb
187
188// namespace bb
Curve::ScalarField FF
static AllSubrelationFailures check_all(const auto &polynomials, const auto &params)
static AllSubrelationFailures check_all(const auto &polynomials, const auto &params)
A debugging utility for checking whether a set of polynomials satisfies the relations for a given Fla...
static AllSubrelationFailures check_all(const auto &polynomials, const auto &params)
Check that the provided polynomials satisfy all relations for a given Flavor.
static FirstSubrelationFailures check(const auto &polynomials, const auto &params, std::string label="Relation")
Check that a single specified relation is satisfied for a set of polynomials.
std::map< size_t, uint32_t > FirstSubrelationFailures
std::map< std::string, FirstSubrelationFailures > AllSubrelationFailures
ArrayOfValues< FF, RelationImpl::SUBRELATION_PARTIAL_LENGTHS > SumcheckArrayOfValuesOverSubrelations
Curve::ScalarField FF
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13