Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
ecc_op_queue.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
8
14namespace bb {
15
29 using Fq = Curve::BaseField; // Grumpkin's scalar field
31 Point point_at_infinity = Curve::Group::affine_point_at_infinity;
32
33 // The operations written to the queue are also performed natively; the result is stored in accumulator
35
36 EccvmOpsTable eccvm_ops_table; // table of ops in the ECCVM format
37 UltraEccOpsTable ultra_ops_table; // table of ops in the Ultra-arithmetization format
38
39 // Storage for the reconstructed eccvm ops table in contiguous memory. (Intended to be constructed once and for all
40 // prior to ECCVM construction to avoid repeated prepending of subtables in physical memory).
41 std::vector<ECCVMOperation> eccvm_ops_reconstructed;
42
43 // Storage for the reconstructed ultra ops table in contiguous memory. (Intended to be constructed once and for all
44 // prior to Translator circuit construction to avoid repeated prepending of subtables in physical memory).
45 std::vector<UltraOp> ultra_ops_reconstructed;
46
47 // Tracks number of muls and size of eccvm in real time as the op queue is updated
49
50 public:
55
65
67 {
68 eccvm_ops_table.merge(settings);
69 ultra_ops_table.merge(settings, ultra_fixed_offset);
70 }
71
72 // Construct polynomials corresponding to the columns of the full aggregate ultra ecc ops table
77
78 // Construct polys corresponding to the columns of the aggregate ultra ops table, excluding the most recent subtable
83
84 // Construct polynomials corresponding to the columns of the current subtable of ultra ecc ops
89
90 // Reconstruct the full table of eccvm ops in contiguous memory from the independent subtables
92
93 // Reconstruct the full table of ultra ops in contiguous memory from the independent subtables
95
99
100 // TODO(https://github.com/AztecProtocol/barretenberg/issues/1339): Consider making the ultra and eccvm ops getters
101 // more memory efficient
102
103 // Get the full table of ECCVM ops in contiguous memory; construct it if it has not been constructed already
104 std::vector<ECCVMOperation>& get_eccvm_ops()
105 {
106 if (eccvm_ops_reconstructed.empty()) {
108 }
110 }
111
112 std::vector<UltraOp>& get_ultra_ops()
113 {
114 if (ultra_ops_reconstructed.empty()) {
116 }
118 }
119
124
128 size_t get_num_rows() const { return eccvm_row_tracker.get_num_rows(); }
129
134
139 void set_eccvm_ops_for_fuzzing(std::vector<ECCVMOperation>& eccvm_ops_in)
140 {
141 eccvm_ops_reconstructed = eccvm_ops_in;
142 }
143
150 {
151 EccOpCode op_code{ .eq = true, .reset = true };
152 append_eccvm_op(ECCVMOperation{ .op_code = op_code, .base_point = Point::random_element() });
153 }
154
161 {
163 accumulator.self_set_infinity();
164 }
165
167
174 {
175 // Update the accumulator natively
176 accumulator = accumulator + to_add;
177 EccOpCode op_code{ .add = true };
178 // Store the eccvm operation
179 append_eccvm_op(ECCVMOperation{ .op_code = op_code, .base_point = to_add });
180
181 // Construct and store the operation in the ultra op format
182 return construct_and_populate_ultra_ops(op_code, to_add);
183 }
184
190 UltraOp mul_accumulate(const Point& to_mul, const Fr& scalar)
191 {
192 // Update the accumulator natively
193 accumulator = accumulator + to_mul * scalar;
194 EccOpCode op_code{ .mul = true };
195
196 // Construct and store the operation in the ultra op format
197 UltraOp ultra_op = construct_and_populate_ultra_ops(op_code, to_mul, scalar);
198
199 // Store the eccvm operation
201 .op_code = op_code,
202 .base_point = to_mul,
203 .z1 = ultra_op.z_1,
204 .z2 = ultra_op.z_2,
205 .mul_scalar_full = scalar,
206 });
207
208 return ultra_op;
209 }
210
219 {
220 UltraOp no_op{};
221 ultra_ops_table.push(no_op);
222 return no_op;
223 }
224
233 {
234 UltraOp random_op{ .op_code = EccOpCode{ .is_random_op = true,
235 .random_value_1 = Fr::random_element(),
236 .random_value_2 = Fr::random_element() },
237 .x_lo = Fr::random_element(),
238 .x_hi = Fr::random_element(),
239 .y_lo = Fr::random_element(),
240 .y_hi = Fr::random_element(),
241 .z_1 = Fr::random_element(),
242 .z_2 = Fr::random_element(),
243 .return_is_infinity = false };
244 ultra_ops_table.push(random_op);
245 return random_op;
246 }
247
254 {
255 auto expected = accumulator;
256 accumulator.self_set_infinity();
257 EccOpCode op_code{ .eq = true, .reset = true };
258 // Store eccvm operation
259 append_eccvm_op(ECCVMOperation{ .op_code = op_code, .base_point = expected });
260
261 // Construct and store the operation in the ultra op format
262 return construct_and_populate_ultra_ops(op_code, expected);
263 }
264
265 private:
283 UltraOp construct_and_populate_ultra_ops(EccOpCode op_code, const Point& point, const Fr& scalar = Fr::zero())
284 {
285 UltraOp ultra_op;
286 ultra_op.op_code = op_code;
287
288 // Decompose point coordinates (Fq) into hi-lo chunks (Fr)
289 const size_t CHUNK_SIZE = 2 * stdlib::NUM_LIMB_BITS_IN_FIELD_SIMULATION;
290 uint256_t x_256(point.x);
291 uint256_t y_256(point.y);
292 ultra_op.return_is_infinity = point.is_point_at_infinity();
293 // if we have a point at infinity, set x/y to zero
294 // in the biggroup_goblin class we use `assert_equal` statements to validate
295 // the original in-circuit coordinate values are also zero
296 if (point.is_point_at_infinity()) {
297 x_256 = 0;
298 y_256 = 0;
299 }
300 ultra_op.x_lo = Fr(x_256.slice(0, CHUNK_SIZE));
301 ultra_op.x_hi = Fr(x_256.slice(CHUNK_SIZE, CHUNK_SIZE * 2));
302 ultra_op.y_lo = Fr(y_256.slice(0, CHUNK_SIZE));
303 ultra_op.y_hi = Fr(y_256.slice(CHUNK_SIZE, CHUNK_SIZE * 2));
304
305 // Split scalar into 128 bit endomorphism scalars
306 Fr z_1 = 0;
307 Fr z_2 = 0;
308 auto converted = scalar.from_montgomery_form();
309 uint256_t converted_u256(scalar);
310 if (converted_u256.get_msb() <= 128) {
311 ultra_op.z_1 = scalar;
312 ultra_op.z_2 = 0;
313 } else {
314 Fr::split_into_endomorphism_scalars(converted, z_1, z_2);
315 ultra_op.z_1 = z_1.to_montgomery_form();
316 ultra_op.z_2 = z_2.to_montgomery_form();
317 }
318
319 ultra_ops_table.push(ultra_op);
320
321 return ultra_op;
322 }
323};
324
325} // namespace bb
Used to construct execution trace representations of elliptic curve operations.
Curve::ScalarField Fr
Curve::AffineElement Point
size_t get_num_rows() const
Get the number of rows for the current ECCVM circuit.
EccvmOpsTable eccvm_ops_table
std::vector< ECCVMOperation > eccvm_ops_reconstructed
void construct_full_eccvm_ops_table()
UltraOp add_accumulate(const Point &to_add)
Write point addition op to queue and natively perform addition.
std::array< Polynomial< Fr >, ULTRA_TABLE_WIDTH > construct_ultra_ops_table_columns() const
void initialize_new_subtable()
Initialize a new subtable for eccvm and ultra ops with the given merge settings.
Point get_accumulator()
size_t get_ultra_ops_table_num_rows() const
void merge(MergeSettings settings=MergeSettings::PREPEND, std::optional< size_t > ultra_fixed_offset=std::nullopt)
void construct_full_ultra_ops_table()
UltraEccOpsTable ultra_ops_table
void append_eccvm_op(const ECCVMOperation &op)
Append an eccvm operation to the eccvm ops table; update the eccvm row tracker.
uint32_t get_number_of_muls() const
get number of muls for the current ECCVM circuit
std::vector< ECCVMOperation > & get_eccvm_ops()
size_t get_num_msm_rows() const
Get the number of rows in the 'msm' column section, for all msms in the circuit.
std::vector< UltraOp > ultra_ops_reconstructed
std::array< Polynomial< Fr >, ULTRA_TABLE_WIDTH > construct_current_ultra_ops_subtable_columns() const
size_t get_current_ultra_ops_subtable_num_rows() const
UltraOp construct_and_populate_ultra_ops(EccOpCode op_code, const Point &point, const Fr &scalar=Fr::zero())
Given an ecc operation and its inputs, decompose into ultra format and populate ultra_ops.
UltraOp mul_accumulate(const Point &to_mul, const Fr &scalar)
Write multiply and add op to queue and natively perform operation.
std::vector< UltraOp > & get_ultra_ops()
std::array< Polynomial< Fr >, ULTRA_TABLE_WIDTH > construct_previous_ultra_ops_table_columns() const
UltraOp random_op_ultra_only()
Writes randomness to the ultra ops table but adds no eccvm operations.
UltraOp no_op_ultra_only()
Writes a no op (i.e. two zero rows) to the ultra ops table but adds no eccvm operations.
UltraOp eq_and_reset()
Write equality op using internal accumulator point.
void empty_row_for_testing()
Write empty row to queue.
ECCOpQueue()
Instantiate an initial ECC op subtable.
void set_eccvm_ops_for_fuzzing(std::vector< ECCVMOperation > &eccvm_ops_in)
A fuzzing only method for setting eccvm ops directly.
EccvmRowTracker eccvm_row_tracker
void add_erroneous_equality_op_for_testing()
A testing only method that adds an erroneous equality op to the eccvm ops.
size_t get_previous_ultra_ops_table_num_rows() const
static constexpr size_t ULTRA_TABLE_WIDTH
void create_new_subtable(size_t size_hint=0)
std::vector< OpFormat > get_reconstructed() const
void merge(MergeSettings settings=MergeSettings::PREPEND)
void push(const OpFormat &op)
Class for tracking the number of rows in the ECCVM circuit and the number of muls performed as the op...
size_t get_num_rows() const
Get the number of rows for the current ECCVM circuit.
size_t get_num_msm_rows() const
Get the number of rows in the 'msm' column section, for all msms in the circuit.
uint32_t get_number_of_muls() const
void update_cached_msms(const ECCVMOperation &op)
Update cached_active_msm_count or update other row counts and reset cached_active_msm_count.
Stores a table of elliptic curve operations represented in the Ultra format.
void push(const UltraOp &op)
ColumnPolynomials construct_current_ultra_ops_subtable_columns() const
ColumnPolynomials construct_table_columns() const
ColumnPolynomials construct_previous_table_columns() const
void create_new_subtable(size_t size_hint=0)
size_t current_ultra_subtable_size() const
size_t previous_ultra_table_size() const
std::vector< UltraOp > get_reconstructed() const
static constexpr size_t TABLE_WIDTH
size_t ultra_table_size() const
void merge(MergeSettings settings=MergeSettings::PREPEND, std::optional< size_t > offset=std::nullopt)
bb::fq BaseField
Definition bn254.hpp:19
typename Group::affine_element AffineElement
Definition bn254.hpp:22
bb::fr ScalarField
Definition bn254.hpp:18
constexpr uint256_t slice(uint64_t start, uint64_t end) const
constexpr uint64_t get_msb() const
Entry point for Barretenberg command-line interface.
MergeSettings
The MergeSettings define whether an current subtable will be added at the beginning (PREPEND) or at t...
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
AffineElement base_point
Defines the opcodes for ECC operations used in both the Ultra and ECCVM formats. There are three opco...
bool return_is_infinity
EccOpCode op_code
BB_INLINE constexpr field to_montgomery_form() const noexcept
static void split_into_endomorphism_scalars(const field &k, field &k1, field &k2)
static field random_element(numeric::RNG *engine=nullptr) noexcept
BB_INLINE constexpr field from_montgomery_form() const noexcept
static constexpr field zero()