Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
mega_circuit_builder.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Complete, auditors: [Luke, Raju], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
7#pragma once
8#include <sstream>
9#include <utility>
10
14#include "databus.hpp"
16
17namespace bb {
18
19template <typename FF> class MegaCircuitBuilder_ : public UltraCircuitBuilder_<MegaExecutionTraceBlocks> {
20 private:
21 DataBus databus; // Container for public calldata/returndata
22
23 public:
25
26 static constexpr size_t DEFAULT_NON_NATIVE_FIELD_LIMB_BITS =
28
29 // Stores record of ecc operations and performs corresponding native operations internally
31
32 // Indices for constant variables corresponding to ECCOpQueue op codes
33 uint32_t null_op_idx;
37
38 // Functions for adding ECC op queue "gates"
40 ecc_op_tuple queue_ecc_mul_accum(const g1::affine_element& point, const FF& scalar, bool in_finalize = false);
41 ecc_op_tuple queue_ecc_eq(bool in_finalize = true);
45
46 private:
47 ecc_op_tuple populate_ecc_op_wires(const UltraOp& ultra_op, bool in_finalize = false);
50
51 public:
53 bool is_write_vk_mode = false)
55 , op_queue(std::move(op_queue_in))
56 {
57 BB_BENCH();
58 // Instantiate the subtable to be populated with goblin ecc ops from this circuit. The merge settings indicate
59 // whether the subtable should be prepended or appended to the existing subtables from prior circuits.
60 op_queue->initialize_new_subtable();
61
62 // Set indices to constants corresponding to Goblin ECC op codes
64 };
65
83 const std::vector<FF>& witness_values,
84 const std::vector<uint32_t>& public_inputs,
85 const bool is_write_vk_mode)
87 , op_queue(std::move(op_queue_in))
88 {
89 // Instantiate the subtable to be populated with goblin ecc ops from this circuit. The merge settings indicate
90 // whether the subtable should be prepended or appended to the existing subtables from prior circuits.
91 op_queue->initialize_new_subtable();
92
93 // Set indices to constants corresponding to Goblin ECC op codes
95 };
96
103 uint32_t get_ecc_op_idx(const EccOpCode& op_code)
104 {
105 if (op_code.add) {
106 return add_accum_op_idx;
107 }
108 if (op_code.mul) {
109 return mul_accum_op_idx;
110 }
111 if (op_code.eq && op_code.reset) {
112 return equality_op_idx;
113 }
114 if (!op_code.add && !op_code.mul && !op_code.eq && !op_code.reset) {
115 return null_op_idx;
116 }
117
118 throw_or_abort("Invalid op code");
119 return 0;
120 }
121
122 void finalize_circuit();
123
124 // Shadows UltraCircuitBuilder_::create_poseidon2_external_gate so Mega external rounds land in the
125 // shared `poseidon2` block alongside the internal rounds (keeping each permutation's rows contiguous).
130
131 size_t get_num_constant_gates() const override { return 0; }
132
137 void add_public_calldata(BusId bus_idx, const uint32_t& in) { return append_to_bus_vector(bus_idx, in); }
138
143 void add_public_return_data(const uint32_t& in) { return append_to_bus_vector(BusId::RETURNDATA, in); }
144
145 uint32_t read_bus_vector(BusId bus_idx, const uint32_t& read_idx_witness_idx);
146
152 void create_databus_init_read_gate(BusId bus_idx, size_t slot_idx);
153
158 uint32_t read_calldata(BusId bus_idx, const uint32_t& read_idx_witness_idx)
159 {
160 return read_bus_vector(bus_idx, read_idx_witness_idx);
161 };
162
169 uint32_t read_return_data(const uint32_t& read_idx_witness_idx)
170 {
171 return read_bus_vector(BusId::RETURNDATA, read_idx_witness_idx);
172 };
173
177 void append_to_bus_vector(const BusId bus_idx, const uint32_t& witness_idx)
178 {
179 auto& bus_vector = databus[static_cast<size_t>(bus_idx)];
180 bus_vector.append(witness_idx);
181 create_databus_init_read_gate(bus_idx, bus_vector.size() - 1);
182 }
183
184 const BusVector& get_calldata(BusId idx) const { return databus[static_cast<size_t>(idx)]; }
185 const BusVector& get_return_data() const { return databus[static_cast<size_t>(BusId::RETURNDATA)]; }
186 // Indexed access to the databus columns; enables NUM_BUS_COLUMNS-driven iteration over bus vectors.
187 const BusVector& get_bus_vector(size_t bus_idx) const { return databus[bus_idx]; }
188
195 std::string hash() const
196 {
197 using serialize::write;
198 std::vector<uint8_t> buffer;
199
200 // Hash each block's complete structure - need to const_cast to call non-const methods
201 auto& blocks_ref = const_cast<MegaExecutionTraceBlocks&>(this->blocks);
202 for (auto& block : blocks_ref.get()) {
203 // Hash all wires; implicitly contains copy constraint information
204 for (const auto& wire : block.wires) {
205 for (const auto& idx : wire) {
206 write(buffer, idx);
207 }
208 }
209
210 // Hash all selectors
211 auto selectors = block.get_selectors();
212 for (auto& selector : selectors) {
213 for (size_t i = 0; i < selector.size(); ++i) {
214 write(buffer, selector[i]);
215 }
216 }
217 }
218
219 // Compute SHA256 hash
220 auto hash_bytes = crypto::sha256(buffer);
221
222 // Convert to hex string
223 std::stringstream ss;
224 ss << hash_bytes;
225 return ss.str();
226 }
227};
228using MegaCircuitBuilder = MegaCircuitBuilder_<bb::fr>;
229} // namespace bb
#define BB_BENCH()
Definition bb_bench.hpp:268
const std::vector< uint32_t > & public_inputs() const
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 add_public_calldata(BusId bus_idx, const uint32_t &in)
Add a witness variable to the specified calldata bus.
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.
std::shared_ptr< ECCOpQueue > op_queue
const BusVector & get_bus_vector(size_t bus_idx) const
uint32_t get_ecc_op_idx(const EccOpCode &op_code)
Convert op code to the witness index for the corresponding op index in the builder.
uint32_t read_calldata(BusId bus_idx, const uint32_t &read_idx_witness_idx)
Read from the specified calldata bus and create a corresponding databus read gate.
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...
MegaCircuitBuilder_(std::shared_ptr< ECCOpQueue > op_queue_in=std::make_shared< ECCOpQueue >(), bool is_write_vk_mode=false)
void create_databus_read_gate(const databus_lookup_gate_< FF > &in, BusId bus_idx)
Create a databus lookup/read gate.
static constexpr size_t DEFAULT_NON_NATIVE_FIELD_LIMB_BITS
const BusVector & get_return_data() const
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 append_to_bus_vector(const BusId bus_idx, const uint32_t &witness_idx)
Append a witness to a bus column and bind the new slot to that witness via a busread gate.
size_t get_num_constant_gates() const override
void add_public_return_data(const uint32_t &in)
Add a witness variable to the public return_data.
void create_poseidon2_transition_entry_gate(const poseidon2_transition_entry_gate_< FF > &in)
Poseidon2 transition-entry gate: standard → K=4 compressed encoding boundary.
const BusVector & get_calldata(BusId idx) const
MegaCircuitBuilder_(std::shared_ptr< ECCOpQueue > op_queue_in, const std::vector< FF > &witness_values, const std::vector< uint32_t > &public_inputs, const bool is_write_vk_mode)
Constructor from data generated from ACIR.
uint32_t read_bus_vector(BusId bus_idx, const uint32_t &read_idx_witness_idx)
Read from a databus column.
uint32_t read_return_data(const uint32_t &read_idx_witness_idx)
Read from return_data and create a corresponding databus read gate.
std::string hash() const
Compute a hash of the circuit.
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.
Mega execution trace wrapper. MegaTraceBlockData (codegen-emitted) lists the blocks and their owned G...
std::unique_ptr< uint8_t[]> buffer
Definition engine.cpp:60
Sha256Hash sha256(const ByteContainer &input)
SHA-256 hash function (FIPS 180-4)
Definition sha256.cpp:150
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
std::array< BusVector, NUM_BUS_COLUMNS > DataBus
Definition databus.hpp:74
void write(B &buf, field2< base_field, Params > const &value)
BusId
Definition databus.hpp:75
MegaCircuitBuilder_< field< Bn254FrParams > > MegaCircuitBuilder
void write(auto &buf, const msgpack_concepts::HasMsgPack auto &obj)
Automatically derived write for any object that defines .msgpack() (implicitly defined by SERIALIZATI...
STL namespace.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
A DataBus column.
Definition databus.hpp:20
Defines the opcodes for ECC operations used in both the Ultra and ECCVM formats. There are three opco...
void throw_or_abort(std::string const &err)