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
23template <>
25 const BlockConstraint& constraint,
26 bool has_valid_witness_assignments)
27{
29
31 init.reserve(constraint.init.size());
32 for (const auto idx : constraint.init) {
34 }
35
36 switch (constraint.type) {
37 // Note: CallData/ReturnData require DataBus, which is only available in Mega and in particular is _not_ supported
38 // by Ultra. If we encounter them in an Ultra circuit, we return an error.
39 case BlockType::ROM:
40 process_ROM_operations(builder, constraint, has_valid_witness_assignments, init);
41 break;
42 case BlockType::RAM:
43 process_RAM_operations(builder, constraint, has_valid_witness_assignments, init);
44 break;
48 "UltraCircuitBuilder (standalone Noir application) does not support CallData/ReturnData "
49 "block constraints. Use MegaCircuitBuilder (Aztec app) or fall back to RAM and ROM operations.");
50 break;
51 default:
52 bb::assert_failure("Unexpected block constraint type.");
53 break;
54 }
55}
56
61template <>
63 const BlockConstraint& constraint,
64 bool has_valid_witness_assignments)
65{
67
69 init.reserve(constraint.init.size());
70 for (const auto idx : constraint.init) {
72 }
73
74 switch (constraint.type) {
75 case BlockType::ROM: {
76 process_ROM_operations(builder, constraint, has_valid_witness_assignments, init);
77 } break;
78 case BlockType::RAM: {
79 process_RAM_operations(builder, constraint, has_valid_witness_assignments, init);
80 } break;
82 process_call_data_operations(builder, constraint, has_valid_witness_assignments, init);
83 } break;
86 } break;
87 default:
88 bb::assert_failure("Unexpected block constraint type.");
89 break;
90 }
91}
92
93template <typename Builder>
95 const BlockConstraint& constraint,
96 bool has_valid_witness_assignments,
98{
101
102 rom_table_ct table(&builder, init);
103 for (const auto& op : constraint.trace) {
104 field_ct value = to_field_ct(op.value, builder);
105 field_ct index = to_field_ct(op.index, builder);
106
107 // In case of invalid witness assignment, we set the value of index value to zero to not hit out of bound in
108 // ROM table
109 if (!has_valid_witness_assignments && !index.is_constant()) {
110 builder.set_variable(index.get_witness_index(), 0);
111 }
112
113 switch (op.access_type) {
114 case AccessType::Read:
115 value.assert_equal(table[index]);
116 break;
117 default:
118 bb::assert_failure("Invalid AccessType for ROM memory operation.");
119 break;
120 }
121 }
122}
123
124template <typename Builder>
126 const BlockConstraint& constraint,
127 bool has_valid_witness_assignments,
129{
132
133 ram_table_ct table(&builder, init);
134 for (const auto& op : constraint.trace) {
135 field_ct value = to_field_ct(op.value, builder);
136 field_ct index = to_field_ct(op.index, builder);
137
138 // In case of invalid witness assignment, we set the value of index value to zero to not hit an out-of-bounds
139 // index in the RAM table
140 if (!has_valid_witness_assignments && !index.is_constant()) {
141 builder.set_variable(index.get_witness_index(), 0);
142 }
143
144 switch (op.access_type) {
145 case AccessType::Read:
146 value.assert_equal(table.read(index));
147 break;
149 table.write(index, value);
150 break;
151 default:
152 bb::assert_failure("Invalid AccessType for RAM memory operation.");
153 break;
154 }
155 }
156}
157
158template <typename Builder>
160 const BlockConstraint& constraint,
161 bool has_valid_witness_assignments,
163{
166
168
169 // Method for processing operations on a generic databus calldata array
170 auto process_calldata = [&](auto& calldata_array) {
171 calldata_array.set_context(&builder);
172 calldata_array.set_values(init); // Initialize the data in the bus array
173
174 for (const auto& op : constraint.trace) {
175 field_ct value = to_field_ct(op.value, builder);
176 field_ct index = to_field_ct(op.index, builder);
177
178 // In case of invalid witness assignment, we set the value of index value to zero to not hit out of bound in
179 // ROM table
180 if (!has_valid_witness_assignments && !index.is_constant()) {
181 builder.set_variable(index.get_witness_index(), 0);
182 }
183
184 switch (op.access_type) {
185 case AccessType::Read:
186 value.assert_equal(calldata_array[index]);
187 break;
188 default:
189 bb::assert_failure("Invalid AccessType for CallData memory operation.");
190 break;
191 }
192 }
193 };
194
195 // Process primary or secondary calldata based on calldata_id
196 switch (constraint.calldata_id) {
198 process_calldata(databus.calldata);
199 break;
201 process_calldata(databus.secondary_calldata);
202 break;
203 default:
204 bb::assert_failure("Databus only supports two calldata arrays.");
205 break;
206 }
207}
208
209template <typename Builder>
211 const BlockConstraint& constraint,
213{
215 // Return data opcodes simply copy the data from the initialization vector to the return data vector in the databus.
216 // There is no operation happening.
217 BB_ASSERT_EQ(constraint.trace.size(), 0U, "Return data opcodes should have empty traces");
218
220
222 // Populate the returndata in the databus
224 // For each entry of the return data, explicitly assert equality with the initialization value. This implicitly
225 // creates the return data read gates that are required to connect witness values in the main wires to witness
226 // values in the databus return data column.
227 size_t c = 0;
228 for (const auto& value : init) {
229 value.assert_equal(databus.return_data[c]);
230 c++;
231 }
232}
233
234} // namespace acir_format
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:77
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
void set_context(Builder *builder_context)
Definition databus.hpp:51
bus_vector return_data
Definition databus.hpp:64
bus_vector calldata
Definition databus.hpp:62
bus_vector secondary_calldata
Definition databus.hpp:63
static field_t from_witness_index(Builder *ctx, uint32_t witness_index)
Definition field.cpp:62
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:124
const auto init
Definition fr.bench.cpp:141
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)
void process_return_data_operations(Builder &builder, const BlockConstraint &constraint, std::vector< bb::stdlib::field_t< Builder > > &init)
bb::stdlib::field_t< Builder > to_field_ct(const WitnessOrConstant< typename Builder::FF > &input, Builder &builder)
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
void assert_failure(std::string const &err)
Definition assert.cpp:11
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
Struct holding the data required to add memory constraints to a circuit.
std::vector< uint32_t > init