13#include <unordered_map>
14#include <unordered_set>
34 auto ultra_op = op_queue->add_accumulate(point);
57 auto ultra_op = op_queue->mul_accumulate(point, scalar);
60 ecc_op_tuple op_tuple = populate_ecc_op_wires(ultra_op, in_finalize);
74 auto ultra_op = op_queue->eq_and_reset();
77 ecc_op_tuple op_tuple = populate_ecc_op_wires(ultra_op, in_finalize);
91 auto ultra_op = op_queue->no_op_ultra_only();
110template <
typename FF>
114 op_tuple.
op = get_ecc_op_idx(ultra_op.
op_code);
115 op_tuple.
x_lo = this->add_variable(ultra_op.
x_lo);
116 op_tuple.
x_hi = this->add_variable(ultra_op.
x_hi);
117 op_tuple.
y_lo = this->add_variable(ultra_op.
y_lo);
118 op_tuple.
y_hi = this->add_variable(ultra_op.
y_hi);
119 op_tuple.
z_1 = this->add_variable(ultra_op.
z_1);
120 op_tuple.
z_2 = this->add_variable(ultra_op.
z_2);
123 uint32_t op_val_idx_1 = op_tuple.
op;
124 uint32_t op_val_idx_2 = this->zero_idx();
133 this->blocks.ecc_op.append_gate({ .wires = { op_val_idx_1, op_tuple.
x_lo, op_tuple.
x_hi, op_tuple.
y_lo } });
134 this->blocks.ecc_op.append_gate({ .wires = { op_val_idx_2, op_tuple.
y_hi, op_tuple.
z_1, op_tuple.
z_2 } });
137 update_used_witnesses(
139 update_finalize_witnesses(
156 auto ultra_op = op_queue->random_op_ultra_only();
159 (void)populate_ecc_op_wires(ultra_op);
173template <
typename FF>
177 auto ultra_op = op_queue->append_hiding_op(Px, Py);
180 populate_ecc_op_wires(ultra_op);
185 null_op_idx = this->zero_idx();
186 add_accum_op_idx = this->put_constant_variable(
FF(
EccOpCode{ .
add =
true }.value()));
187 mul_accum_op_idx = this->put_constant_variable(
FF(
EccOpCode{ .
mul =
true }.value()));
188 equality_op_idx = this->put_constant_variable(
FF(
EccOpCode{ .
eq =
true, .reset =
true }.value()));
199template <
typename FF>
202 auto& bus_vector = databus[
static_cast<size_t>(bus_idx)];
204 const uint32_t read_idx =
static_cast<uint32_t
>(
uint256_t(this->get_variable(read_idx_witness_idx)));
210 FF value = this->get_variable(bus_vector[read_idx]);
211 uint32_t value_witness_idx = this->add_variable(
value);
213 create_databus_read_gate({ read_idx_witness_idx, value_witness_idx }, bus_idx);
214 bus_vector.increment_read_count(read_idx);
216 return value_witness_idx;
221 auto& bus_vector = databus[
static_cast<size_t>(bus_idx)];
224 const uint32_t value_witness_idx = bus_vector[slot_idx];
225 const uint32_t index_witness_idx = this->put_constant_variable(
FF(
static_cast<uint64_t
>(slot_idx)));
227 create_databus_read_gate({ index_witness_idx, value_witness_idx }, bus_idx);
228 bus_vector.increment_read_count(slot_idx);
237template <
typename FF>
240 auto& block = this->blocks.busread;
242 row.
wires = { in.
value, in.
index, this->zero_idx(), this->zero_idx() };
247 &row.q_5, &row.q_c, &row.q_m };
248 const size_t idx =
static_cast<size_t>(bus_idx);
250 *databus_selectors[idx] = 1;
253 block.append_gate(row);
254 this->increment_num_gates();
262template <
typename FF>
265 auto& block = this->blocks.poseidon2;
266 block.append_gate({ .wires = { in.
a, in.
b, in.
c, in.
d },
273 this->increment_num_gates();
280template <
typename FF>
283 auto& block = this->blocks.poseidon2;
286 this->increment_num_gates();
298template <
typename FF>
301 auto& block = this->blocks.poseidon2;
304 auto& block_for_row = block;
321 block_for_row.append_gate(row);
323 this->increment_num_gates();
336template <
typename FF>
339 auto& block = this->blocks.poseidon2;
341 block.append_gate({ .wires = { in.
a, in.
b, in.
c, in.
d },
347 this->increment_num_gates();
#define BB_ASSERT_LT(left, right,...)
void set_goblin_ecc_op_code_constant_variables()
void create_poseidon2_external_gate(const poseidon2_external_gate_< FF > &in)
Poseidon2 external-round gate. Mega routes it into the shared poseidon2 block (Ultra instead uses a d...
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 create_poseidon2_quad_internal_gate(const poseidon2_quad_internal_gate_< FF > &in)
Poseidon2 K=4 compressed internal-round gate: processes FOUR consecutive internal rounds per row.
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.
void create_databus_init_read_gate(BusId bus_idx, size_t slot_idx)
Emit a busread gate at slot slot_idx whose value wire is the bus_vector entry at that slot.
ecc_op_tuple queue_ecc_no_op()
Add a no-op to the op queue and populate two zero rows in the ecc_op block.
void queue_ecc_hiding_op(const curve::BN254::BaseField &Px, const curve::BN254::BaseField &Py)
Add a hiding op with random (possibly non-curve) Px, Py values to the op queue and circuit.
void create_poseidon2_transition_entry_gate(const poseidon2_transition_entry_gate_< FF > &in)
Poseidon2 transition-entry gate: standard → K=4 compressed encoding boundary.
uint32_t read_bus_vector(BusId bus_idx, const uint32_t &read_idx_witness_idx)
Read from a databus column.
void create_poseidon2_initial_external_gate(const poseidon2_initial_external_gate_< FF > &in)
Poseidon2 initial linear layer gate, activates the q_poseidon2_external_initial selector and relation...
ecc_op_tuple populate_ecc_op_wires(const UltraOp &ultra_op, bool in_finalize=false)
Add goblin ecc op gates for a single operation.
typename ExecutionTrace::FF FF
Entry point for Barretenberg command-line interface.
@ Poseidon2QuadIntTerminal
@ Poseidon2TransitionEntry
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Defines the opcodes for ECC operations used in both the Ultra and ECCVM formats. There are three opco...
One gate: its wire indices, the non-gate selectors present on every block (see NON_GATE_SELECTORS),...
std::array< uint32_t, NUM_WIRES > wires
static constexpr std::array< std::array< FF, t >, rounds_f+rounds_p > round_constants