Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
translator_circuit_builder.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
14
15namespace bb {
70
71 // The scalar field of BN254
72 using Fr = bb::fr;
73 // The base (coordinate) field of BN254
74 using Fq = bb::fq;
75
76 public:
77 static constexpr size_t NUM_WIRES = 81;
78 static constexpr size_t NUM_SELECTORS = 0;
79
84 void create_add_gate(const add_triple_<Fr>&) override {};
85 void create_mul_gate(const mul_triple_<Fr>&) override {};
86 void create_bool_gate(const uint32_t) override {};
87 void create_poly_gate(const poly_triple_<Fr>&) override {};
88 [[nodiscard]] size_t get_num_constant_gates() const override { return 0; };
89
93 enum WireIds : size_t {
94 OP, // The first 4 wires contain the standard values from the EccQueue wire
98 P_X_LOW_LIMBS, // P.xₗₒ split into 2 68 bit limbs
99 P_X_HIGH_LIMBS, // P.xₕᵢ split into a 68 and a 50 bit limb
100 P_Y_LOW_LIMBS, // P.yₗₒ split into 2 68 bit limbs
101 P_Y_HIGH_LIMBS, // P.yₕᵢ split into a 68 and a 50 bit limb
102 Z_LOW_LIMBS, // Low limbs of z_1 and z_2 (68 bits each)
103 Z_HIGH_LIMBS, // High Limbs of z_1 and z_2 (60 bits each)
104 ACCUMULATORS_BINARY_LIMBS_0, // Contain 68-bit limbs of current and previous accumulator (previous at higher
105 // indices because of the nuances of KZG commitment).
108 ACCUMULATORS_BINARY_LIMBS_3, // Highest limb is 50 bits (254 mod 68) P_X_LOW_LIMBS_RANGE_CONSTRAINT_0, // Low
109 // limbs split further into smaller chunks for range constraints
110 QUOTIENT_LOW_BINARY_LIMBS, // Quotient limbs
112 RELATION_WIDE_LIMBS, // Limbs for checking the correctness of mod 2²⁷² relations.
113 P_X_LOW_LIMBS_RANGE_CONSTRAINT_0, // Low limbs split further into smaller chunks for range constraints
119 P_X_HIGH_LIMBS_RANGE_CONSTRAINT_0, // High limbs split into chunks for range constraints
125 P_Y_LOW_LIMBS_RANGE_CONSTRAINT_0, // Low limbs split into chunks for range constraints
131 P_Y_HIGH_LIMBS_RANGE_CONSTRAINT_0, // High limbs split into chunks for range constraints
137 Z_LOW_LIMBS_RANGE_CONSTRAINT_0, // Range constraints for low limbs of z_1 and z_2
143 Z_HIGH_LIMBS_RANGE_CONSTRAINT_0, // Range constraints for high limbs of z_1 and z_2
149
150 ACCUMULATOR_LOW_LIMBS_RANGE_CONSTRAINT_0, // Range constraints for the current accumulator limbs (no need to
151 // redo previous accumulator)
163
164 QUOTIENT_LOW_LIMBS_RANGE_CONSTRAIN_0, // Range constraints for quotient
180
182
183 };
184
185 // Basic goblin translator has the minimum minicircuit size of 2048, so optimize for that case
186 // For context, minicircuit is the part of the final polynomials fed into the proving system, where we have all the
187 // arithmetic logic. However, the full circuit is several times larger (we use a trick to bring down the degree of
188 // the permutation argument)
189 static constexpr size_t DEFAULT_TRANSLATOR_VM_LENGTH = 2048;
190
191 // Maximum size of a single limb is 68 bits
192 static constexpr size_t NUM_LIMB_BITS = 68;
193
194 // For soundness we need to constrain the highest limb so that the whole value is at most 50 bits
195 static constexpr size_t NUM_LAST_LIMB_BITS = Fq::modulus.get_msb() + 1 - 3 * NUM_LIMB_BITS;
196
197 // 128-bit z_1 and z_2 are split into 2 limbs each
198 static constexpr size_t NUM_Z_LIMBS = 2;
199
200 // Number of bits in the quotient representation
201 static constexpr size_t NUM_QUOTIENT_BITS = 256;
202
203 // Number of bits in the quotient highest limb
204 static constexpr size_t NUM_LAST_QUOTIENT_LIMB_BITS = 256 - 3 * NUM_LIMB_BITS;
205
206 // Number of bits in Z scalars
207 static constexpr size_t NUM_Z_BITS = 128;
208 // The circuit builder has a default range constraint mechanism that is used throughout. It range cosntrains the
209 // values to < 2¹⁴
210 static constexpr size_t MICRO_LIMB_BITS = 14;
211
212 // Maximum size of a micro limb used for range constraints
213 static constexpr auto MAX_MICRO_LIMB_SIZE = (uint256_t(1) << MICRO_LIMB_BITS) - 1;
214
215 // To range constrain a limb to 68 bits we need 6 limbs: 5 for 14-bit windowed chunks and 1 to range constrain the
216 // highest to a more restrictive range (0 <= a < 2¹⁴ && 0 <= 4*a < 2¹⁴ ) ~ ( 0 <= a < 2¹² )
217 static constexpr size_t NUM_MICRO_LIMBS = 6;
218
219 // Number of limbs used to decompose a 254-bit value for modular arithmetic. This will represent an Fq value as 4 Fr
220 // limbs to be representable inside a circuit defined overF r.
221 static constexpr size_t NUM_BINARY_LIMBS = 4;
222
223 // Number of limbs used for computation of a result modulo 2²⁷²
224 static constexpr size_t NUM_RELATION_WIDE_LIMBS = 2;
225
226 // Range constraint of relation limbs
227 static constexpr size_t RELATION_WIDE_LIMB_BITS = 84;
228
229 // Maximum size of each relation limb (in accordance with range constraints)
231
232 // Shift of a single micro (range constraint) limb
233 static constexpr auto MICRO_SHIFT = uint256_t(1) << MICRO_LIMB_BITS;
234
235 // Maximum size of 2 lower limbs concatenated
236 static constexpr auto MAX_LOW_WIDE_LIMB_SIZE = (uint256_t(1) << (NUM_LIMB_BITS * 2)) - 1;
237
238 // Maximum size of 2 higher limbs concatenated
239 static constexpr auto MAX_HIGH_WIDE_LIMB_SIZE = (uint256_t(1) << (NUM_LIMB_BITS + NUM_LAST_LIMB_BITS)) - 1;
240
241 // Index at which the evaluation result is stored in the circuit
242 static constexpr size_t RESULT_ROW = 2;
243
244 // How much you'd need to multiply a value by to perform a shift to a higher binary limb
245 static constexpr auto SHIFT_1 = uint256_t(1) << NUM_LIMB_BITS;
246
247 // Shift by 2 binary limbs
248 static constexpr auto SHIFT_2 = uint256_t(1) << (NUM_LIMB_BITS << 1);
249
250 // Precomputed inverse to easily divide by the shift by 2 limbs
251 static constexpr auto SHIFT_2_INVERSE = Fr(SHIFT_2).invert();
252
253 // Shift by 3 binary limbs
254 static constexpr auto SHIFT_3 = uint256_t(1) << (NUM_LIMB_BITS * 3);
255
256 // The modulus of the target emulated field as a 512-bit integer
258
259 // The binary modulus used in the CRT computation
260 static constexpr uint512_t BINARY_BASIS_MODULUS = uint512_t(1) << (NUM_LIMB_BITS << 2);
261
262 // Negated modulus of the target emulated field in the binary modulus
264
265 // Negated modulus of the target emulated field in the binary modulus split into 4 binary limbs + the final limb is
266 // the negated modulus of the target emulated field in the scalar field
274
304
305 static constexpr std::string_view NAME_STRING = "TranslatorCircuitBuilder";
306
307 // The challenge that is used for batching together evaluations of several polynomials
309
310 // The input we evaluate polynomials on
312
314
324 TranslatorCircuitBuilder(Fq batching_challenge_v_, Fq evaluation_input_x_)
326 , batching_challenge_v(batching_challenge_v_)
327 , evaluation_input_x(evaluation_input_x_) {};
328
339 TranslatorCircuitBuilder(Fq batching_challenge_v_, Fq evaluation_input_x_, std::shared_ptr<ECCOpQueue> op_queue)
340 : TranslatorCircuitBuilder(batching_challenge_v_, evaluation_input_x_)
341 {
342 PROFILE_THIS_NAME("TranslatorCircuitBuilder::constructor");
344 }
345
352 {
354 return *this;
355 };
356 ~TranslatorCircuitBuilder() override = default;
357
365 {
366 uint256_t base_uint = base;
368 Fr(base_uint.slice(0, NUM_LIMB_BITS)),
369 Fr(base_uint.slice(NUM_LIMB_BITS, 2 * NUM_LIMB_BITS)),
370 Fr(base_uint.slice(2 * NUM_LIMB_BITS, 3 * NUM_LIMB_BITS)),
371 Fr(base_uint.slice(3 * NUM_LIMB_BITS, 4 * NUM_LIMB_BITS)),
372 });
373 }
374
375 static void assert_well_formed_ultra_op(const UltraOp& ultra_op);
376
385 static void assert_well_formed_accumulation_input(const AccumulationInput& acc_step);
386
395 void create_accumulation_gate(const AccumulationInput& acc_step);
396
397 void populate_wires_from_ultra_op(const UltraOp& ultra_op);
398
399 void insert_pair_into_wire(WireIds wire_index, Fr first, Fr second)
400 {
401 auto& current_wire = wires[wire_index];
402 current_wire.push_back(add_variable(first));
403 current_wire.push_back(add_variable(second));
404 }
405
413
414 static AccumulationInput generate_witness_values(const UltraOp& ultra_op,
415 const Fq& previous_accumulator,
417 const Fq& evaluation_input_x);
418};
419
420} // namespace bb
virtual uint32_t add_variable(const FF &in)
CircuitBuilderBase & operator=(const CircuitBuilderBase &other)=default
TranslatorCircuitBuilder creates a circuit that evaluates the correctness of the evaluation of EccOpQ...
size_t get_num_constant_gates() const override
static constexpr std::array< Fr, 5 > NEGATIVE_MODULUS_LIMBS
static AccumulationInput generate_witness_values(const UltraOp &ultra_op, const Fq &previous_accumulator, const Fq &batching_challenge_v, const Fq &evaluation_input_x)
Given the transcript values from the EccOpQueue, the values of the previous accumulator,...
TranslatorCircuitBuilder(TranslatorCircuitBuilder &&other) noexcept
static void assert_well_formed_ultra_op(const UltraOp &ultra_op)
void create_accumulation_gate(const AccumulationInput &acc_step)
Create a single accumulation gate.
static std::array< Fr, NUM_BINARY_LIMBS > split_fq_into_limbs(const Fq &base)
A small function to transform a native element Fq into its bigfield representation in Fr scalars.
void feed_ecc_op_queue_into_circuit(const std::shared_ptr< ECCOpQueue > ecc_op_queue)
Generate all the gates required to prove the correctness of batched evalution of polynomials represen...
static constexpr size_t RELATION_WIDE_LIMB_BITS
static constexpr uint512_t BINARY_BASIS_MODULUS
static constexpr size_t NUM_LAST_QUOTIENT_LIMB_BITS
static constexpr size_t DEFAULT_TRANSLATOR_VM_LENGTH
~TranslatorCircuitBuilder() override=default
static constexpr std::string_view NAME_STRING
static constexpr uint256_t MAX_RELATION_WIDE_LIMB_SIZE
static constexpr uint512_t NEGATIVE_PRIME_MODULUS
TranslatorCircuitBuilder & operator=(TranslatorCircuitBuilder &&other) noexcept
TranslatorCircuitBuilder(Fq batching_challenge_v_, Fq evaluation_input_x_)
Construct a new Translator Circuit Builder object.
std::array< SlabVector< uint32_t >, NUM_WIRES > wires
void populate_wires_from_ultra_op(const UltraOp &ultra_op)
void create_add_gate(const add_triple_< Fr > &) override
void create_mul_gate(const mul_triple_< Fr > &) override
TranslatorCircuitBuilder(Fq batching_challenge_v_, Fq evaluation_input_x_, std::shared_ptr< ECCOpQueue > op_queue)
Construct a new Translator Circuit Builder object and feed op_queue inside.
static void assert_well_formed_accumulation_input(const AccumulationInput &acc_step)
Ensures the accumulation input is well-formed and can be used to create a gate.
TranslatorCircuitBuilder & operator=(const TranslatorCircuitBuilder &other)=delete
static constexpr size_t NUM_RELATION_WIDE_LIMBS
TranslatorCircuitBuilder(const TranslatorCircuitBuilder &other)=delete
void create_poly_gate(const poly_triple_< Fr > &) override
WireIds
There are so many wires that naming them has no sense, it is easier to access them with enums.
void create_bool_gate(const uint32_t) override
void insert_pair_into_wire(WireIds wire_index, Fr first, Fr second)
constexpr uint256_t slice(uint64_t start, uint64_t end) const
constexpr uint64_t get_msb() const
constexpr uintx slice(const uint64_t start, const uint64_t end) const
Definition uintx.hpp:82
uintx< uint256_t > uint512_t
Definition uintx.hpp:307
Entry point for Barretenberg command-line interface.
field< Bn254FqParams > fq
Definition fq.hpp:169
field< Bn254FrParams > fr
Definition fr.hpp:174
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
#define PROFILE_THIS_NAME(name)
Definition op_count.hpp:16
The accumulation input structure contains all the necessary values to initalize an accumulation gate ...
std::array< std::array< Fr, NUM_MICRO_LIMBS >, NUM_Z_LIMBS > z_1_microlimbs
std::array< std::array< Fr, NUM_MICRO_LIMBS >, NUM_BINARY_LIMBS > P_y_microlimbs
std::array< std::array< Fr, NUM_MICRO_LIMBS >, NUM_BINARY_LIMBS > current_accumulator_microlimbs
std::array< std::array< Fr, NUM_MICRO_LIMBS >, 2 > relation_wide_microlimbs
std::array< std::array< Fr, NUM_MICRO_LIMBS >, NUM_BINARY_LIMBS > P_x_microlimbs
std::array< std::array< Fr, NUM_MICRO_LIMBS >, NUM_BINARY_LIMBS > quotient_microlimbs
std::array< std::array< Fr, NUM_MICRO_LIMBS >, NUM_Z_LIMBS > z_2_microlimbs
std::array< Fr, NUM_RELATION_WIDE_LIMBS > relation_wide_limbs
static constexpr uint256_t modulus
constexpr field invert() const noexcept