Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
circuit_builder_base.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
15#include <utility>
16
17#include <unordered_map>
18
19namespace bb {
20static constexpr uint32_t DUMMY_TAG = 0;
21
22template <typename FF_> class CircuitBuilderBase {
23 public:
24 using FF = FF_;
26
27 private:
28 // A container for all of the witness values used by the circuit
29 std::vector<FF> variables;
30
31 std::vector<uint32_t> public_inputs_;
32
33 bool public_inputs_finalized_ = false; // Addition of new public inputs disallowed after this is set to true.
34
35 public:
36 size_t num_gates = 0;
37 // true if we have dummy witnesses (in the write_vk case)
38 bool has_dummy_witnesses = false;
39
40 std::unordered_map<uint32_t, std::string> variable_names;
41
42 // index of next variable in equivalence class (=REAL_VARIABLE if you're last)
43 std::vector<uint32_t> next_var_index;
44 // index of previous variable in equivalence class (=FIRST if you're in a cycle alone)
45 std::vector<uint32_t> prev_var_index;
46 // The "real_variable_index" acts as a map from a "witness index" (e.g. the one stored by a stdlib object) to an
47 // index into the variables array. This extra layer of indirection is used to support copy constraints by allowing,
48 // for example, two witnesses with differing witness indices to have the same "real variable index" and thus the
49 // same witness value. If the witness is not involved in any copy constraints, then real_variable_index[index] ==
50 // index, i.e. it is the identity map.
51 std::vector<uint32_t> real_variable_index;
52 std::vector<uint32_t> real_variable_tags;
53 uint32_t current_tag = DUMMY_TAG;
54 // The permutation on variable tags. See
55 // https://github.com/AztecProtocol/plonk-with-lookups-private/blob/new-stuff/GenPermuations.pdf
56 // DOCTODO(#231): replace with the relevant wiki link.
57 std::map<uint32_t, uint32_t> tau;
58
59 // We know from the CLI arguments during proving whether a circuit should use a prover which produces
60 // proofs that are friendly to verify in a circuit themselves. A verifier does not need a full circuit
61 // description and should be able to verify a proof with just the verification key and the proof.
62 // This field exists to later set the same field in the verification key, and make sure
63 // that we are using the correct prover/verifier.
65
66 bool _failed = false;
67 std::string _err;
68 static constexpr uint32_t REAL_VARIABLE = UINT32_MAX - 1;
69 static constexpr uint32_t FIRST_VARIABLE_IN_CLASS = UINT32_MAX - 2;
70
71 CircuitBuilderBase(size_t size_hint = 0, bool has_dummy_witnesses = false);
72
73 CircuitBuilderBase(const CircuitBuilderBase& other) = default;
74 CircuitBuilderBase(CircuitBuilderBase&& other) noexcept = default;
76 CircuitBuilderBase& operator=(CircuitBuilderBase&& other) noexcept = default;
77 virtual ~CircuitBuilderBase() = default;
78
79 bool operator==(const CircuitBuilderBase& other) const = default;
80
81 virtual size_t get_num_finalized_gates() const;
82 virtual size_t get_estimated_num_finalized_gates() const;
83 virtual void print_num_estimated_finalized_gates() const;
84 virtual size_t get_num_variables() const;
85 // TODO(#216)(Adrian): Feels wrong to let the zero_idx be changed.
86 uint32_t zero_idx = 0;
87 uint32_t one_idx = 1;
88
89 virtual void create_add_gate(const add_triple_<FF>& in) = 0;
90 virtual void create_mul_gate(const mul_triple_<FF>& in) = 0;
91 virtual void create_bool_gate(const uint32_t a) = 0;
92 virtual void create_poly_gate(const poly_triple_<FF>& in) = 0;
93 virtual size_t get_num_constant_gates() const = 0;
94
95 const std::vector<FF>& get_variables() const { return variables; }
96
104 uint32_t get_first_variable_in_class(uint32_t index) const;
111 void update_real_variable_indices(uint32_t index, uint32_t new_real_index);
112
119 inline FF get_variable(const uint32_t index) const
120 {
122 return variables[real_variable_index[index]];
123 }
124
136 inline void set_variable(const uint32_t index, const FF& value)
137 {
140 }
141
150 inline const FF& get_variable_reference(const uint32_t index) const
151 {
152 BB_ASSERT_GT(variables.size(), index);
153 return variables[real_variable_index[index]];
154 }
155
156 uint32_t get_public_input_index(const uint32_t witness_index) const;
157
158 FF get_public_input(const uint32_t index) const;
159
160 const std::vector<uint32_t>& public_inputs() const { return public_inputs_; };
161
168
175 void initialize_public_inputs(const std::vector<uint32_t>& public_inputs) { this->public_inputs_ = public_inputs; }
176
183 virtual uint32_t add_variable(const FF& in);
184
192 virtual void set_variable_name(uint32_t index, const std::string& name);
193
201 virtual void update_variable_names(uint32_t index);
202
208 virtual msgpack::sbuffer export_circuit();
209
219 virtual uint32_t add_public_variable(const FF& in);
220
227 virtual uint32_t set_public_input(uint32_t witness_index);
228 virtual void assert_equal(uint32_t a_idx, uint32_t b_idx, std::string const& msg = "assert_equal");
229
230 size_t get_circuit_subgroup_size(size_t num_gates) const;
231
232 size_t num_public_inputs() const { return public_inputs_.size(); }
233
234 // Check whether each variable index points to a witness in the composer
235 //
236 // Any variable whose index does not point to witness value is deemed invalid.
237 //
238 // This implicitly checks whether a variable index
239 // is equal to IS_CONSTANT; assuming that we will never have
240 // uint32::MAX number of variables
241 void assert_valid_variables(const std::vector<uint32_t>& variable_indices);
242
243 bool failed() const;
244 const std::string& err() const;
245
246 void set_err(std::string msg);
247 void failure(std::string msg);
248};
249
301} // namespace bb
302
303// TODO(#217)(Cody): This will need updating based on the approach we take to ensure no multivariate is zero.
#define BB_ASSERT_GT(left, right,...)
Definition assert.hpp:87
std::vector< uint32_t > public_inputs_
virtual size_t get_num_finalized_gates() const
uint32_t get_public_input_index(const uint32_t witness_index) const
void set_variable(const uint32_t index, const FF &value)
Set the value of the variable pointed to by a witness index.
const std::string & err() const
virtual uint32_t add_variable(const FF &in)
virtual void create_add_gate(const add_triple_< FF > &in)=0
virtual void create_mul_gate(const mul_triple_< FF > &in)=0
CircuitBuilderBase(const CircuitBuilderBase &other)=default
void initialize_public_inputs(const std::vector< uint32_t > &public_inputs)
Directly initialize the public inputs vector.
CircuitBuilderBase & operator=(const CircuitBuilderBase &other)=default
virtual msgpack::sbuffer export_circuit()
bool operator==(const CircuitBuilderBase &other) const =default
static constexpr uint32_t FIRST_VARIABLE_IN_CLASS
virtual void create_poly_gate(const poly_triple_< FF > &in)=0
virtual uint32_t set_public_input(uint32_t witness_index)
Make a witness variable public.
const std::vector< uint32_t > & public_inputs() const
std::unordered_map< uint32_t, std::string > variable_names
void finalize_public_inputs()
Set the public_inputs_finalized_ to true to prevent any new public inputs from being added.
std::conditional_t< std::same_as< FF, bb::g1::Fq >, curve::BN254, curve::Grumpkin > EmbeddedCurve
std::vector< uint32_t > prev_var_index
virtual size_t get_estimated_num_finalized_gates() const
void assert_valid_variables(const std::vector< uint32_t > &variable_indices)
CircuitBuilderBase & operator=(CircuitBuilderBase &&other) noexcept=default
FF get_public_input(const uint32_t index) const
const std::vector< FF > & get_variables() const
std::vector< uint32_t > next_var_index
std::vector< uint32_t > real_variable_tags
virtual void assert_equal(uint32_t a_idx, uint32_t b_idx, std::string const &msg="assert_equal")
virtual size_t get_num_variables() const
FF get_variable(const uint32_t index) const
Get the value of the variable v_{index}.
virtual ~CircuitBuilderBase()=default
virtual void print_num_estimated_finalized_gates() const
virtual size_t get_num_constant_gates() const =0
virtual void create_bool_gate(const uint32_t a)=0
virtual void set_variable_name(uint32_t index, const std::string &name)
CircuitBuilderBase(CircuitBuilderBase &&other) noexcept=default
uint32_t get_first_variable_in_class(uint32_t index) const
void update_real_variable_indices(uint32_t index, uint32_t new_real_index)
const FF & get_variable_reference(const uint32_t index) const
virtual void update_variable_names(uint32_t index)
static constexpr uint32_t REAL_VARIABLE
std::map< uint32_t, uint32_t > tau
std::vector< uint32_t > real_variable_index
virtual uint32_t add_public_variable(const FF &in)
size_t get_circuit_subgroup_size(size_t num_gates) const
FF a
Entry point for Barretenberg command-line interface.
typename Flavor::FF FF
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
Serialized state of a circuit.
std::vector< std::vector< std::vector< FF > > > selectors
std::vector< uint32_t > real_variable_index
std::unordered_map< uint32_t, uint64_t > range_tags
std::unordered_map< uint32_t, std::string > vars_of_interest
std::vector< std::vector< uint32_t > > ram_states
std::vector< std::vector< std::array< uint32_t, 2 > > > rom_states
MSGPACK_FIELDS(modulus, public_inps, vars_of_interest, variables, selectors, wires, real_variable_index, lookup_tables, real_variable_tags, range_tags, rom_records, rom_states, ram_records, ram_states, circuit_finalized)
std::vector< std::vector< std::vector< uint32_t > > > ram_records
std::vector< std::vector< std::vector< uint32_t > > > rom_records
std::vector< std::vector< std::vector< FF > > > lookup_tables
std::vector< uint32_t > real_variable_tags
std::vector< uint32_t > public_inps
std::vector< std::vector< std::vector< uint32_t > > > wires