Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
circuit_builder_base_impl.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
11
12namespace bb {
13template <typename FF_>
15 : _is_write_vk_mode(is_write_vk_mode)
16{}
17
18template <typename FF_> size_t CircuitBuilderBase<FF_>::get_num_finalized_gates() const
19{
20 return _num_gates;
21}
22
23template <typename FF_> size_t CircuitBuilderBase<FF_>::get_num_variables() const
24{
25 return variables.size();
26}
27
28template <typename FF_> uint32_t CircuitBuilderBase<FF_>::get_first_variable_in_class(uint32_t index) const
29{
30 while (prev_var_index[index] != FIRST_VARIABLE_IN_CLASS) {
31 index = prev_var_index[index];
32 }
33 return index;
34}
35
36template <typename FF_>
37void CircuitBuilderBase<FF_>::update_real_variable_indices(uint32_t index, uint32_t new_real_index)
38{
39 auto cur_index = index;
40 do {
41 real_variable_index[cur_index] = new_real_index;
42 cur_index = next_var_index[cur_index];
43 } while (cur_index != REAL_VARIABLE);
44}
45
46template <typename FF_> uint32_t CircuitBuilderBase<FF_>::add_variable(const FF& in)
47{
48 variables.emplace_back(in);
49 const uint32_t index = static_cast<uint32_t>(variables.size()) - 1U;
50 real_variable_index.emplace_back(index);
51 next_var_index.emplace_back(REAL_VARIABLE);
52 prev_var_index.emplace_back(FIRST_VARIABLE_IN_CLASS);
53 real_variable_tags.emplace_back(DEFAULT_TAG);
54 return index;
55}
56
57// Only used in SMT verification
58template <typename FF_> void CircuitBuilderBase<FF_>::set_variable_name(uint32_t index, const std::string& name)
59{
60 BB_ASSERT_DEBUG(variables.size() > index);
61 uint32_t first_idx = get_first_variable_in_class(index);
62
63 if (variable_names.contains(first_idx)) {
64 failure("Attempted to assign a name to a variable that already has a name");
65 return;
66 }
67 variable_names.insert({ first_idx, name });
68}
69
70template <typename FF_> size_t CircuitBuilderBase<FF_>::get_circuit_subgroup_size(const size_t _num_gates) const
71{
72 auto log2_n = static_cast<size_t>(numeric::get_msb(_num_gates));
73 if ((1UL << log2_n) != (_num_gates)) {
74 ++log2_n;
75 }
76 return 1UL << log2_n;
77}
78
79template <typename FF_> msgpack::sbuffer CircuitBuilderBase<FF_>::export_circuit()
80{
81 info("not implemented");
82 return { 0 };
83}
84
85template <typename FF_> uint32_t CircuitBuilderBase<FF_>::add_public_variable(const FF& in)
86{
87 const uint32_t index = add_variable(in);
88 BB_ASSERT_EQ(_public_inputs_finalized, false, "Cannot add to public inputs after they have been finalized.");
89 _public_inputs.emplace_back(index);
90 return index;
91}
92
93template <typename FF_> uint32_t CircuitBuilderBase<FF_>::set_public_input(const uint32_t witness_index)
94{
95 for (const uint32_t public_input : public_inputs()) {
96 if (public_input == witness_index) {
97 if (!failed()) {
98 failure("Attempted to set a public input that is already public!");
99 }
100 return 0;
101 }
102 }
103 uint32_t public_input_index = static_cast<uint32_t>(num_public_inputs());
104 BB_ASSERT_EQ(_public_inputs_finalized, false, "Cannot add to public inputs after they have been finalized.");
105 _public_inputs.emplace_back(witness_index);
106
107 return public_input_index;
108}
109
117template <typename FF>
118void CircuitBuilderBase<FF>::assert_equal(const uint32_t a_variable_idx,
119 const uint32_t b_variable_idx,
120 std::string const& msg)
121{
122 assert_valid_variables({ a_variable_idx, b_variable_idx });
123 bool values_equal = (get_variable(a_variable_idx) == get_variable(b_variable_idx));
124 if (!values_equal && !failed()) {
125 failure(msg);
126 }
127 uint32_t a_real_idx = real_variable_index[a_variable_idx];
128 uint32_t b_real_idx = real_variable_index[b_variable_idx];
129 // If a==b is already enforced, exit method
130 if (a_real_idx == b_real_idx) {
131 return;
132 }
133 // Otherwise update the real_idx of b-chain members to that of a
134
135 auto b_start_idx = get_first_variable_in_class(b_variable_idx);
136 update_real_variable_indices(b_start_idx, a_real_idx);
137 // Now merge equivalence classes of a and b by tying last (= real) element of b-chain to first element of a-chain
138 auto a_start_idx = get_first_variable_in_class(a_variable_idx);
139 next_var_index[b_real_idx] = a_start_idx;
140 prev_var_index[a_start_idx] = b_real_idx;
141 bool no_tag_clash =
142 (real_variable_tags[a_real_idx] == DEFAULT_TAG || real_variable_tags[b_real_idx] == DEFAULT_TAG ||
143 real_variable_tags[a_real_idx] == real_variable_tags[b_real_idx]);
144 if (!no_tag_clash && !failed()) {
145 failure(msg);
146 }
147 if (real_variable_tags[a_real_idx] == DEFAULT_TAG) {
148 real_variable_tags[a_real_idx] = real_variable_tags[b_real_idx];
149 }
150}
151
152template <typename FF_>
153void CircuitBuilderBase<FF_>::assert_valid_variables([[maybe_unused]] const std::vector<uint32_t>& variable_indices)
154{
155#ifndef NDEBUG
156 for (const auto& variable_index : variable_indices) {
157 BB_ASSERT_LT(variable_index, variables.size());
158 }
159#endif
160}
161
162template <typename FF_> bool CircuitBuilderBase<FF_>::failed() const
163{
164 return _failed;
165}
166
167template <typename FF_> const std::string& CircuitBuilderBase<FF_>::err() const
168{
169 return _err;
170}
171
172template <typename FF_> void CircuitBuilderBase<FF_>::failure(std::string msg)
173{
174#ifndef FUZZING_DISABLE_WARNINGS
175 if (!_is_write_vk_mode) {
176 // Not a catch-all error log. We have a builder failure when we have real witnesses which is a mistake.
177 info("(Experimental) WARNING: Builder failure when we have real witnesses! Ignore if writing vk.");
178 }
179#endif
180 _failed = true;
181 _err = msg;
182}
183} // namespace bb
#define BB_ASSERT_DEBUG(expression,...)
Definition assert.hpp:55
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:93
#define BB_ASSERT_LT(left, right,...)
Definition assert.hpp:153
virtual size_t get_num_finalized_gates() const
const std::string & err() const
virtual uint32_t add_variable(const FF &in)
Add a variable to variables.
CircuitBuilderBase(bool is_write_vk_mode=false)
virtual msgpack::sbuffer export_circuit()
Export the existing circuit as msgpack compatible buffer.
virtual uint32_t set_public_input(uint32_t witness_index)
Make a witness variable public.
void assert_valid_variables(const std::vector< uint32_t > &variable_indices)
Check whether each variable index points to a witness value in the variables array.
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
virtual void set_variable_name(uint32_t index, const std::string &name)
Assign a name to a variable (equivalence class)
uint32_t get_first_variable_in_class(uint32_t index) const
Get the index of the first variable in class.
void update_real_variable_indices(uint32_t index, uint32_t new_real_index)
Update all variables from index in equivalence class to have real variable new_real_index.
virtual uint32_t add_public_variable(const FF &in)
Add a public variable to variables.
size_t get_circuit_subgroup_size(size_t num_gates) const
void info(Args... args)
Definition log.hpp:89
constexpr T get_msb(const T in)
Definition get_msb.hpp:47
Entry point for Barretenberg command-line interface.
Definition api.hpp:5