11#include <unordered_map>
12#include <unordered_set>
21 if (ensure_nonzero && !this->circuit_finalized) {
24 add_mega_gates_to_ensure_all_polys_are_non_zero();
48 auto raw_read_idx =
static_cast<uint32_t
>(get_calldata().size()) - 1;
49 auto read_idx = this->add_variable(raw_read_idx);
50 update_finalize_witnesses({ read_idx, read_calldata(read_idx) });
54 raw_read_idx =
static_cast<uint32_t
>(get_secondary_calldata().size()) - 1;
55 read_idx = this->add_variable(raw_read_idx);
56 update_finalize_witnesses({ read_idx, read_secondary_calldata(read_idx) });
60 raw_read_idx =
static_cast<uint32_t
>(get_return_data().size()) - 1;
61 read_idx = this->add_variable(raw_read_idx);
62 update_finalize_witnesses({ read_idx, read_return_data(read_idx) });
64 if (op_queue->get_current_subtable_size() == 0) {
68 this->queue_ecc_eq(
true);
86 add_mega_gates_to_ensure_all_polys_are_non_zero();
97 auto ultra_op = op_queue->add_accumulate(point);
100 ecc_op_tuple op_tuple = populate_ecc_op_wires(ultra_op);
114template <
typename FF>
120 auto ultra_op = op_queue->mul_accumulate(point, scalar);
123 ecc_op_tuple op_tuple = populate_ecc_op_wires(ultra_op, in_finalize);
137 auto ultra_op = op_queue->eq_and_reset();
140 ecc_op_tuple op_tuple = populate_ecc_op_wires(ultra_op, in_finalize);
153 auto ultra_op = op_queue->no_op_ultra_only();
156 ecc_op_tuple op_tuple = populate_ecc_op_wires(ultra_op);
168template <
typename FF>
172 op_tuple.
op = get_ecc_op_idx(ultra_op.
op_code);
173 op_tuple.
x_lo = this->add_variable(ultra_op.
x_lo);
174 op_tuple.
x_hi = this->add_variable(ultra_op.
x_hi);
175 op_tuple.
y_lo = this->add_variable(ultra_op.
y_lo);
176 op_tuple.
y_hi = this->add_variable(ultra_op.
y_hi);
177 op_tuple.
z_1 = this->add_variable(ultra_op.
z_1);
178 op_tuple.
z_2 = this->add_variable(ultra_op.
z_2);
181 uint32_t op_val_idx_1 = op_tuple.
op;
182 uint32_t op_val_idx_2 = this->zero_idx();
189 this->blocks.ecc_op.populate_wires(op_val_idx_1, op_tuple.
x_lo, op_tuple.
x_hi, op_tuple.
y_lo);
190 for (
auto& selector : this->blocks.ecc_op.get_selectors()) {
191 selector.emplace_back(0);
194 this->blocks.ecc_op.populate_wires(op_val_idx_2, op_tuple.
y_hi, op_tuple.
z_1, op_tuple.
z_2);
195 for (
auto& selector : this->blocks.ecc_op.get_selectors()) {
196 selector.emplace_back(0);
200 update_used_witnesses(
202 update_finalize_witnesses(
219 auto ultra_op = op_queue->random_op_ultra_only();
222 (void)populate_ecc_op_wires(ultra_op);
227 null_op_idx = this->zero_idx();
228 add_accum_op_idx = this->put_constant_variable(
FF(
EccOpCode{ .
add =
true }.value()));
229 mul_accum_op_idx = this->put_constant_variable(
FF(
EccOpCode{ .
mul =
true }.value()));
230 equality_op_idx = this->put_constant_variable(
FF(
EccOpCode{ .
eq =
true, .reset =
true }.value()));
241template <
typename FF>
244 auto& bus_vector = databus[
static_cast<size_t>(bus_idx)];
246 const uint32_t read_idx =
static_cast<uint32_t
>(
uint256_t(this->get_variable(read_idx_witness_idx)));
252 FF value = this->get_variable(bus_vector[read_idx]);
253 uint32_t value_witness_idx = this->add_variable(
value);
255 create_databus_read_gate({ read_idx_witness_idx, value_witness_idx }, bus_idx);
256 bus_vector.increment_read_count(read_idx);
258 return value_witness_idx;
267template <
typename FF>
270 auto& block = this->blocks.busread;
271 block.populate_wires(in.
value, in.
index, this->zero_idx(), this->zero_idx());
272 apply_databus_selectors(bus_idx);
274 this->check_selector_length_consistency();
280 auto& block = this->blocks.busread;
283 block.q_1().emplace_back(1);
284 block.q_2().emplace_back(0);
285 block.q_3().emplace_back(0);
289 block.q_1().emplace_back(0);
290 block.q_2().emplace_back(1);
291 block.q_3().emplace_back(0);
295 block.q_1().emplace_back(0);
296 block.q_2().emplace_back(0);
297 block.q_3().emplace_back(1);
301 block.q_4().emplace_back(0);
302 block.q_m().emplace_back(0);
303 block.q_c().emplace_back(0);
304 block.set_gate_selector(1);
#define BB_ASSERT_LT(left, right,...)
void set_goblin_ecc_op_code_constant_variables()
void queue_ecc_random_op()
Mechanism for populating two rows with randomness. This "operation" doesn't return a tuple representi...
ecc_op_tuple queue_ecc_add_accum(const g1::affine_element &point)
Add simple point addition operation to the op queue and add corresponding gates.
ecc_op_tuple queue_ecc_mul_accum(const g1::affine_element &point, const FF &scalar, bool in_finalize=false)
Add point mul-then-accumulate operation to the op queue and add corresponding gates.
void apply_databus_selectors(BusId bus_idx)
void add_mega_gates_to_ensure_all_polys_are_non_zero()
Ensure all polynomials have at least one non-zero coefficient to avoid commiting to the zero-polynomi...
void add_ultra_and_mega_gates_to_ensure_all_polys_are_non_zero()
Ensure all polynomials have at least one non-zero coefficient to avoid commiting to the zero-polynomi...
ecc_op_tuple queue_ecc_eq(bool in_finalize=true)
Add point equality operation to the op queue based on the value of the internal accumulator and add c...
void create_databus_read_gate(const databus_lookup_gate_< FF > &in, BusId bus_idx)
Create a databus lookup/read gate.
ecc_op_tuple queue_ecc_no_op()
Logic for a no-op operation.
void finalize_circuit(const bool ensure_nonzero)
uint32_t read_bus_vector(BusId bus_idx, const uint32_t &read_idx_witness_idx)
Read from a databus column.
ecc_op_tuple populate_ecc_op_wires(const UltraOp &ultra_op, bool in_finalize=false)
Add goblin ecc op gates for a single operation.
void add_gates_to_ensure_all_polys_are_non_zero()
Ensure all polynomials have at least one non-zero coefficient to avoid commiting to the zero-polynomi...
typename ExecutionTrace::FF FF
void finalize_circuit(const bool ensure_nonzero)
static constexpr element one
Entry point for Barretenberg command-line interface.
static constexpr bb::fr DEFAULT_VALUE
Defines the opcodes for ECC operations used in both the Ultra and ECCVM formats. There are three opco...