Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
block_constraint.cpp
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
13
14namespace acir_format {
15
16using namespace bb;
17
18template <typename Builder> stdlib::field_t<Builder> poly_to_field_ct(const poly_triple poly, Builder& builder)
19{
21
22 BB_ASSERT_EQ(poly.q_m, 0);
23 BB_ASSERT_EQ(poly.q_r, 0);
24 BB_ASSERT_EQ(poly.q_o, 0);
25 if (poly.q_l == 0) {
26 return field_ct(poly.q_c);
27 }
29 x.additive_constant = poly.q_c;
31 return x;
32}
33
39template <>
41 const BlockConstraint& constraint,
42 bool has_valid_witness_assignments)
43{
45
47 for (auto i : constraint.init) {
49 init.push_back(value);
50 }
51
52 switch (constraint.type) {
53 // Note: CallData/ReturnData not supported by Ultra; interpreted as ROM ops instead
56 case BlockType::ROM: {
57 process_ROM_operations(builder, constraint, has_valid_witness_assignments, init);
58 } break;
59 case BlockType::RAM: {
60 process_RAM_operations(builder, constraint, has_valid_witness_assignments, init);
61 } break;
62 default:
63 throw_or_abort("Unexpected block constraint type.");
64 break;
65 }
66}
67
72template <>
74 const BlockConstraint& constraint,
75 bool has_valid_witness_assignments)
76{
78
80 for (auto i : constraint.init) {
82 init.push_back(value);
83 }
84
85 switch (constraint.type) {
86 case BlockType::ROM: {
87 process_ROM_operations(builder, constraint, has_valid_witness_assignments, init);
88 } break;
89 case BlockType::RAM: {
90 process_RAM_operations(builder, constraint, has_valid_witness_assignments, init);
91 } break;
93 process_call_data_operations(builder, constraint, has_valid_witness_assignments, init);
94 } break;
97 } break;
98 default:
99 throw_or_abort("Unexpected block constraint type.");
100 break;
101 }
102}
103
104template <typename Builder>
106 const BlockConstraint& constraint,
107 bool has_valid_witness_assignments,
109{
112
113 rom_table_ct table(init);
114 for (auto& op : constraint.trace) {
115 BB_ASSERT_EQ(op.access_type, 0);
117 field_ct index = poly_to_field_ct(op.index, builder);
118 // For a ROM table, constant read should be optimized out:
119 // The rom_table won't work with a constant read because the table may not be initialized
120 ASSERT(op.index.q_l != 0);
121 // We create a new witness w to avoid issues with non-valid witness assignements:
122 // if witness are not assigned, then w will be zero and table[w] will work
123 fr w_value = 0;
124 if (has_valid_witness_assignments) {
125 // If witness are assigned, we use the correct value for w
126 w_value = index.get_value();
127 }
129 value.assert_equal(table[w]);
130 w.assert_equal(index);
131 }
132}
133
134template <typename Builder>
136 const BlockConstraint& constraint,
137 bool has_valid_witness_assignments,
139{
142
143 ram_table_ct table(init);
144 for (auto& op : constraint.trace) {
146 field_ct index = poly_to_field_ct(op.index, builder);
147
148 // We create a new witness w to avoid issues with non-valid witness assignements.
149 // If witness are not assigned, then index will be zero and table[index] won't hit bounds check.
150 fr index_value = has_valid_witness_assignments ? index.get_value() : 0;
151 // Create new witness and ensure equal to index.
152 field_ct::from_witness(&builder, index_value).assert_equal(index);
153
154 if (op.access_type == 0) {
155 value.assert_equal(table.read(index));
156 } else {
157 BB_ASSERT_EQ(op.access_type, 1);
158 table.write(index, value);
159 }
160 }
161}
162
163template <typename Builder>
165 const BlockConstraint& constraint,
166 bool has_valid_witness_assignments,
168{
171
173
174 // Method for processing operations on a generic databus calldata array
175 auto process_calldata = [&](auto& calldata_array) {
176 calldata_array.set_values(init); // Initialize the data in the bus array
177
178 for (const auto& op : constraint.trace) {
179 BB_ASSERT_EQ(op.access_type, 0);
181 field_ct index = poly_to_field_ct(op.index, builder);
182 fr w_value = 0;
183 if (has_valid_witness_assignments) {
184 // If witness are assigned, we use the correct value for w
185 w_value = index.get_value();
186 }
188 value.assert_equal(calldata_array[w]);
189 w.assert_equal(index);
190 }
191 };
192
193 // Process primary or secondary calldata based on calldata_id
194 if (constraint.calldata_id == 0) {
195 process_calldata(databus.calldata);
196 } else if (constraint.calldata_id == 1) {
197 process_calldata(databus.secondary_calldata);
198 } else {
199 throw_or_abort("Databus only supports two calldata arrays.");
200 }
201}
202
203template <typename Builder>
205{
207
209 // Populate the returndata in the databus
211 // For each entry of the return data, explicitly assert equality with the initialization value. This implicitly
212 // creates the return data read gates that are required to connect witness values in the main wires to witness
213 // values in the databus return data column.
214 size_t c = 0;
215 for (const auto& value : init) {
216 value.assert_equal(databus.return_data[c]);
217 c++;
218 }
219 BB_ASSERT_EQ(constraint.trace.size(), 0U);
220}
221
222} // namespace acir_format
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:59
#define ASSERT(expression,...)
Definition assert.hpp:49
void set_values(const std::vector< field_pt > &entries_in)
Set the entries of the bus vector from possibly unnormalized or constant inputs.
Definition databus.cpp:14
bus_vector return_data
Definition databus.hpp:64
bus_vector calldata
Definition databus.hpp:62
bus_vector secondary_calldata
Definition databus.hpp:63
void assert_equal(const field_t &rhs, std::string const &msg="field_t::assert_equal") const
Copy constraint: constrain that *this field is equal to rhs element.
Definition field.cpp:929
static field_t from_witness_index(Builder *ctx, uint32_t witness_index)
Definition field.cpp:59
bb::fr additive_constant
Definition field.hpp:88
bb::fr multiplicative_constant
Definition field.hpp:89
bb::fr get_value() const
Given a := *this, compute its value given by a.v * a.mul + a.add.
Definition field.cpp:827
static field_t from_witness(Builder *ctx, const bb::fr &input)
Definition field.hpp:424
field_pt read(const field_pt &index) const
Read a field element from the RAM table at an index value.
void write(const field_pt &index, const field_pt &value)
Write a field element from the RAM table at an index value.
AluTraceBuilder builder
Definition alu.test.cpp:123
const auto init
Definition fr.bench.cpp:141
stdlib::field_t< Builder > poly_to_field_ct(const poly_triple poly, Builder &builder)
void process_RAM_operations(Builder &builder, const BlockConstraint &constraint, bool has_valid_witness_assignments, std::vector< bb::stdlib::field_t< Builder > > &init)
void create_block_constraints(UltraCircuitBuilder &builder, const BlockConstraint &constraint, bool has_valid_witness_assignments)
Create block constraints; Specialization for Ultra arithmetization.
void process_ROM_operations(Builder &builder, const BlockConstraint &constraint, bool has_valid_witness_assignments, std::vector< bb::stdlib::field_t< Builder > > &init)
void process_call_data_operations(Builder &builder, const BlockConstraint &constraint, bool has_valid_witness_assignments, std::vector< bb::stdlib::field_t< Builder > > &init)
stdlib::field_t< Builder > field_ct
void process_return_data_operations(const BlockConstraint &constraint, std::vector< bb::stdlib::field_t< Builder > > &init)
Entry point for Barretenberg command-line interface.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
stdlib::databus< Builder > databus_ct
std::vector< bb::poly_triple > init
void throw_or_abort(std::string const &err)