barretenberg
Loading...
Searching...
No Matches
ultra_recursive.hpp
1#pragma once
2#include "barretenberg/commitment_schemes/commitment_key.hpp"
3#include "barretenberg/commitment_schemes/kzg/kzg.hpp"
4#include "barretenberg/ecc/curves/bn254/g1.hpp"
6#include "barretenberg/flavor/flavor_macros.hpp"
7#include "barretenberg/flavor/ultra.hpp"
8#include "barretenberg/polynomials/barycentric.hpp"
9#include "barretenberg/polynomials/evaluation_domain.hpp"
10#include "barretenberg/polynomials/polynomial.hpp"
11#include "barretenberg/polynomials/univariate.hpp"
12#include "barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp"
13#include "barretenberg/relations/auxiliary_relation.hpp"
14#include "barretenberg/relations/elliptic_relation.hpp"
15#include "barretenberg/relations/gen_perm_sort_relation.hpp"
16#include "barretenberg/relations/lookup_relation.hpp"
17#include "barretenberg/relations/permutation_relation.hpp"
18#include "barretenberg/relations/ultra_arithmetic_relation.hpp"
19#include "barretenberg/srs/factories/crs_factory.hpp"
20#include "barretenberg/stdlib/recursion/honk/transcript/transcript.hpp"
21#include "barretenberg/transcript/transcript.hpp"
22
23#include <array>
24#include <concepts>
25#include <span>
26#include <string>
27#include <type_traits>
28#include <vector>
29
30#include "barretenberg/stdlib/primitives/curves/bn254.hpp"
31#include "barretenberg/stdlib/primitives/field/field.hpp"
32
33namespace proof_system::honk::flavor {
34
49template <typename BuilderType> class UltraRecursive_ {
50 public:
51 using CircuitBuilder = BuilderType; // Determines arithmetization of circuit instantiated with this flavor
53 using GroupElement = typename Curve::Element;
54 using Commitment = typename Curve::Element;
55 using CommitmentHandle = typename Curve::Element;
56 using FF = typename Curve::ScalarField;
58
59 // Note(luke): Eventually this may not be needed at all
61
62 static constexpr size_t NUM_WIRES = flavor::Ultra::NUM_WIRES;
63 // The number of multivariate polynomials on which a sumcheck prover sumcheck operates (including shifts). We often
64 // need containers of this size to hold related data, so we choose a name more agnostic than `NUM_POLYNOMIALS`.
65 // Note: this number does not include the individual sorted list polynomials.
66 static constexpr size_t NUM_ALL_ENTITIES = 43;
67 // The number of polynomials precomputed to describe a circuit and to aid a prover in constructing a satisfying
68 // assignment of witnesses. We again choose a neutral name.
69 static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 25;
70 // The total number of witness entities not including shifts.
71 static constexpr size_t NUM_WITNESS_ENTITIES = 7;
72
73 // define the tuple of Relations that comprise the Sumcheck relation
74 using Relations = std::tuple<proof_system::UltraArithmeticRelation<FF>,
80
81 static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length<Relations>();
82
83 // BATCHED_RELATION_PARTIAL_LENGTH = algebraic degree of sumcheck relation *after* multiplying by the `pow_zeta`
84 // random polynomial e.g. For \sum(x) [A(x) * B(x) + C(x)] * PowZeta(X), relation length = 2 and random relation
85 // length = 3
86 static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 1;
87 static constexpr size_t NUM_RELATIONS = std::tuple_size<Relations>::value;
88
89 // define the container for storing the univariate contribution from each relation in Sumcheck
90 using SumcheckTupleOfTuplesOfUnivariates = decltype(create_sumcheck_tuple_of_tuples_of_univariates<Relations>());
91 using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values<Relations>());
92
93 private:
94 template <typename DataType>
99 class PrecomputedEntities : public PrecomputedEntitiesBase {
100 public:
101 DEFINE_FLAVOR_MEMBERS(DataType,
102 q_m, // column 0
103 q_c, // column 1
104 q_l, // column 2
105 q_r, // column 3
106 q_o, // column 4
107 q_4, // column 5
108 q_arith, // column 6
109 q_sort, // column 7
110 q_elliptic, // column 8
111 q_aux, // column 9
112 q_lookup, // column 10
113 sigma_1, // column 11
114 sigma_2, // column 12
115 sigma_3, // column 13
116 sigma_4, // column 14
117 id_1, // column 15
118 id_2, // column 16
119 id_3, // column 17
120 id_4, // column 18
121 table_1, // column 19
122 table_2, // column 20
123 table_3, // column 21
124 table_4, // column 22
125 lagrange_first, // column 23
126 lagrange_last); // column 24
127
128 RefVector<DataType> get_selectors()
129 {
130 return { q_m, q_c, q_l, q_r, q_o, q_4, q_arith, q_sort, q_elliptic, q_aux, q_lookup };
131 };
132 RefVector<DataType> get_sigma_polynomials() { return { sigma_1, sigma_2, sigma_3, sigma_4 }; };
133 RefVector<DataType> get_id_polynomials() { return { id_1, id_2, id_3, id_4 }; };
134
135 RefVector<DataType> get_table_polynomials() { return { table_1, table_2, table_3, table_4 }; };
136 };
137
142 template <typename DataType> class WitnessEntities {
143 public:
144 DEFINE_FLAVOR_MEMBERS(DataType,
145 w_l, // column 0
146 w_r, // column 1
147 w_o, // column 2
148 w_4, // column 3
149 sorted_accum, // column 4
150 z_perm, // column 5
151 z_lookup // column 6
152
153 );
154
155 RefVector<DataType> get_wires() { return { w_l, w_r, w_o, w_4 }; };
156 };
157
167 template <typename DataType> class AllEntities {
168 public:
169 DEFINE_FLAVOR_MEMBERS(DataType,
170 q_c, // column 0
171 q_l, // column 1
172 q_r, // column 2
173 q_o, // column 3
174 q_4, // column 4
175 q_m, // column 5
176 q_arith, // column 6
177 q_sort, // column 7
178 q_elliptic, // column 8
179 q_aux, // column 9
180 q_lookup, // column 10
181 sigma_1, // column 11
182 sigma_2, // column 12
183 sigma_3, // column 13
184 sigma_4, // column 14
185 id_1, // column 15
186 id_2, // column 16
187 id_3, // column 17
188 id_4, // column 18
189 table_1, // column 19
190 table_2, // column 20
191 table_3, // column 21
192 table_4, // column 22
193 lagrange_first, // column 23
194 lagrange_last, // column 24
195 w_l, // column 25
196 w_r, // column 26
197 w_o, // column 27
198 w_4, // column 28
199 sorted_accum, // column 29
200 z_perm, // column 30
201 z_lookup, // column 31
202 table_1_shift, // column 32
203 table_2_shift, // column 33
204 table_3_shift, // column 34
205 table_4_shift, // column 35
206 w_l_shift, // column 36
207 w_r_shift, // column 37
208 w_o_shift, // column 38
209 w_4_shift, // column 39
210 sorted_accum_shift, // column 40
211 z_perm_shift, // column 41
212 z_lookup_shift // column 42
213 );
214
215 RefVector<DataType> get_wires() { return { w_l, w_r, w_o, w_4 }; };
216 // Gemini-specific getters.
217 RefVector<DataType> get_unshifted()
218 {
219 return { q_m, q_c, q_l, q_r, q_o, q_4, q_arith, q_sort,
220 q_elliptic, q_aux, q_lookup, sigma_1, sigma_2, sigma_3, sigma_4, id_1,
221 id_2, id_3, id_4, table_1, table_2, table_3, table_4, lagrange_first,
222 lagrange_last, w_l, w_r, w_o, w_4, sorted_accum, z_perm, z_lookup
223
224 };
225 };
226 RefVector<DataType> get_to_be_shifted()
227 {
228 return { table_1, table_2, table_3, table_4, w_l, w_r, w_o, w_4, sorted_accum, z_perm, z_lookup };
229 };
230 RefVector<DataType> get_shifted()
231 {
232 return { table_1_shift, table_2_shift, table_3_shift, table_4_shift, w_l_shift, w_r_shift,
233 w_o_shift, w_4_shift, sorted_accum_shift, z_perm_shift, z_lookup_shift };
234 };
235 };
236
237 public:
246 class VerificationKey : public VerificationKey_<PrecomputedEntities<Commitment>> {
247 public:
254 VerificationKey(CircuitBuilder* builder, const std::shared_ptr<NativeVerificationKey>& native_key)
255 : VerificationKey_<PrecomputedEntities<Commitment>>(native_key->circuit_size, native_key->num_public_inputs)
256 {
257 this->q_m = Commitment::from_witness(builder, native_key->q_m);
258 this->q_l = Commitment::from_witness(builder, native_key->q_l);
259 this->q_r = Commitment::from_witness(builder, native_key->q_r);
260 this->q_o = Commitment::from_witness(builder, native_key->q_o);
261 this->q_4 = Commitment::from_witness(builder, native_key->q_4);
262 this->q_c = Commitment::from_witness(builder, native_key->q_c);
263 this->q_arith = Commitment::from_witness(builder, native_key->q_arith);
264 this->q_sort = Commitment::from_witness(builder, native_key->q_sort);
265 this->q_elliptic = Commitment::from_witness(builder, native_key->q_elliptic);
266 this->q_aux = Commitment::from_witness(builder, native_key->q_aux);
267 this->q_lookup = Commitment::from_witness(builder, native_key->q_lookup);
268 this->sigma_1 = Commitment::from_witness(builder, native_key->sigma_1);
269 this->sigma_2 = Commitment::from_witness(builder, native_key->sigma_2);
270 this->sigma_3 = Commitment::from_witness(builder, native_key->sigma_3);
271 this->sigma_4 = Commitment::from_witness(builder, native_key->sigma_4);
272 this->id_1 = Commitment::from_witness(builder, native_key->id_1);
273 this->id_2 = Commitment::from_witness(builder, native_key->id_2);
274 this->id_3 = Commitment::from_witness(builder, native_key->id_3);
275 this->id_4 = Commitment::from_witness(builder, native_key->id_4);
276 this->table_1 = Commitment::from_witness(builder, native_key->table_1);
277 this->table_2 = Commitment::from_witness(builder, native_key->table_2);
278 this->table_3 = Commitment::from_witness(builder, native_key->table_3);
279 this->table_4 = Commitment::from_witness(builder, native_key->table_4);
280 this->lagrange_first = Commitment::from_witness(builder, native_key->lagrange_first);
281 this->lagrange_last = Commitment::from_witness(builder, native_key->lagrange_last);
282 };
283 };
284
289 class AllValues : public AllEntities<FF> {
290 public:
291 using Base = AllEntities<FF>;
292 using Base::Base;
293 AllValues(std::array<FF, NUM_ALL_ENTITIES> _data_in) { this->_data = _data_in; }
294 };
295
302 class CommitmentLabels : public AllEntities<std::string> {
303 public:
305 {
306 this->w_l = "W_L";
307 this->w_r = "W_R";
308 this->w_o = "W_O";
309 this->w_4 = "W_4";
310 this->z_perm = "Z_PERM";
311 this->z_lookup = "Z_LOOKUP";
312 this->sorted_accum = "SORTED_ACCUM";
313
314 // The ones beginning with "__" are only used for debugging
315 this->q_c = "__Q_C";
316 this->q_l = "__Q_L";
317 this->q_r = "__Q_R";
318 this->q_o = "__Q_O";
319 this->q_4 = "__Q_4";
320 this->q_m = "__Q_M";
321 this->q_arith = "__Q_ARITH";
322 this->q_sort = "__Q_SORT";
323 this->q_elliptic = "__Q_ELLIPTIC";
324 this->q_aux = "__Q_AUX";
325 this->q_lookup = "__Q_LOOKUP";
326 this->sigma_1 = "__SIGMA_1";
327 this->sigma_2 = "__SIGMA_2";
328 this->sigma_3 = "__SIGMA_3";
329 this->sigma_4 = "__SIGMA_4";
330 this->id_1 = "__ID_1";
331 this->id_2 = "__ID_2";
332 this->id_3 = "__ID_3";
333 this->id_4 = "__ID_4";
334 this->table_1 = "__TABLE_1";
335 this->table_2 = "__TABLE_2";
336 this->table_3 = "__TABLE_3";
337 this->table_4 = "__TABLE_4";
338 this->lagrange_first = "__LAGRANGE_FIRST";
339 this->lagrange_last = "__LAGRANGE_LAST";
340 };
341 };
342
343 class VerifierCommitments : public AllEntities<Commitment> {
344 public:
345 VerifierCommitments(const std::shared_ptr<VerificationKey>& verification_key)
346 {
347 this->q_m = verification_key->q_m;
348 this->q_l = verification_key->q_l;
349 this->q_r = verification_key->q_r;
350 this->q_o = verification_key->q_o;
351 this->q_4 = verification_key->q_4;
352 this->q_c = verification_key->q_c;
353 this->q_arith = verification_key->q_arith;
354 this->q_sort = verification_key->q_sort;
355 this->q_elliptic = verification_key->q_elliptic;
356 this->q_aux = verification_key->q_aux;
357 this->q_lookup = verification_key->q_lookup;
358 this->sigma_1 = verification_key->sigma_1;
359 this->sigma_2 = verification_key->sigma_2;
360 this->sigma_3 = verification_key->sigma_3;
361 this->sigma_4 = verification_key->sigma_4;
362 this->id_1 = verification_key->id_1;
363 this->id_2 = verification_key->id_2;
364 this->id_3 = verification_key->id_3;
365 this->id_4 = verification_key->id_4;
366 this->table_1 = verification_key->table_1;
367 this->table_2 = verification_key->table_2;
368 this->table_3 = verification_key->table_3;
369 this->table_4 = verification_key->table_4;
370 this->lagrange_first = verification_key->lagrange_first;
371 this->lagrange_last = verification_key->lagrange_last;
372 }
373 };
374
376};
377
378} // namespace proof_system::honk::flavor
A template class for a reference vector. Behaves as if std::vector<T&> was possible.
Definition: ref_vector.hpp:20
The templates defined herein facilitate sharing the relation arithmetic between the prover and the ve...
Definition: relation_types.hpp:121
Base class template containing circuit-specifying data.
Definition: flavor.hpp:85
A field element for each entity of the flavor. These entities represent the prover polynomials evalua...
Definition: ultra_recursive.hpp:289
A container for commitment labels.
Definition: ultra_recursive.hpp:302
The verification key is responsible for storing the the commitments to the precomputed (non-witnessk)...
Definition: ultra_recursive.hpp:246
VerificationKey(CircuitBuilder *builder, const std::shared_ptr< NativeVerificationKey > &native_key)
Construct a new Verification Key with stdlib types from a provided native verification key.
Definition: ultra_recursive.hpp:254
The recursive counterpart to the "native" Ultra flavor.
Definition: ultra_recursive.hpp:49
VerificationKey_< PrecomputedEntities< Commitment > > VerificationKey
The verification key is responsible for storing the the commitments to the precomputed (non-witnessk)...
Definition: ultra.hpp:290
Definition: verification_key.hpp:25
Definition: biggroup.hpp:22
Definition: field.hpp:10
Base class templates for structures that contain data parameterized by the fundamental polynomials of...
Definition: bn254.hpp:10