39 auto& circuit_builder,
41 size_t num_pair_elts_in_ROM_table = 0,
43 const size_t read_operations = 0,
44 bool final_arithmetic_gate_and_read =
true)
48 "cannot set the number of 'pairs of elements to add to the ROM table' to be greater than the "
49 "length of the table");
53 std::vector<fr> variables(array_length + 1);
54 std::vector<uint32_t> variable_witnesses(array_length + 1);
55 for (
auto [variable, witness] :
zip_view(variables, variable_witnesses)) {
57 witness = circuit_builder.add_variable(variable);
62 std::vector<uint32_t> index_witness_indices(array_length);
63 for (
size_t i = 0; i < array_length; ++i) {
64 index_witness_indices[i] = circuit_builder.put_constant_variable(
static_cast<uint64_t
>(i));
70 size_t rom_table_id = circuit_builder.create_ROM_array(array_length);
72 const size_t num_single_elts_in_ROM_table = array_length - num_pair_elts_in_ROM_table;
74 for (
size_t i = 0; i < num_single_elts_in_ROM_table; ++i) {
75 circuit_builder.set_ROM_element(rom_table_id, i, variable_witnesses[i]);
76 native_rom_table[i] = std::array{ variables[i],
fr::zero() };
79 for (
size_t i = num_single_elts_in_ROM_table; i < array_length; ++i) {
80 circuit_builder.set_ROM_element_pair(
81 rom_table_id, i, std::array{ variable_witnesses[i], variable_witnesses[i + 1] });
82 native_rom_table[i] = std::array{ variables[i], variables[i + 1] };
87 for (
size_t i = 0; i < read_operations; ++i) {
88 uint32_t random_read_index =
static_cast<uint32_t
>(
91 if (random_read_index < num_single_elts_in_ROM_table) {
92 uint32_t read_witness_index =
93 circuit_builder.read_ROM_array(rom_table_id, index_witness_indices[random_read_index]);
95 auto actually_read_value = circuit_builder.get_variable(read_witness_index);
96 auto expected_value = native_rom_table[random_read_index][0];
99 auto [read_witness_index_1, read_witness_index_2] =
100 circuit_builder.read_ROM_array_pair(rom_table_id, index_witness_indices[random_read_index]);
102 std::array<fr, 2> actually_read_values = { circuit_builder.get_variable(read_witness_index_1),
103 circuit_builder.get_variable(read_witness_index_2) };
104 auto expected_values = native_rom_table[random_read_index];
105 BB_ASSERT_EQ(actually_read_values[0], expected_values[0]);
106 BB_ASSERT_EQ(actually_read_values[1], expected_values[1]);
109 if (final_arithmetic_gate_and_read) {
120 for (
size_t i = 0; i < 3; i++) {
121 uint32_t random_index_to_check_computation =
123 random_indices_to_check_computation[i] = random_index_to_check_computation;
124 random_index_witnesses_to_check_computation[i] =
125 index_witness_indices[random_index_to_check_computation];
126 native_fr_elts_to_check_computation[i] =
127 native_rom_table[random_index_to_check_computation]
134 for (
size_t i = 0; i < 3; i++) {
135 const auto random_idx = random_indices_to_check_computation[i];
136 const auto random_idx_witness = random_index_witnesses_to_check_computation[i];
138 if (random_idx < num_single_elts_in_ROM_table) {
139 final_check_read_witnesses[i] = circuit_builder.read_ROM_array(rom_table_id, random_idx_witness);
142 auto [first, _] = circuit_builder.read_ROM_array_pair(rom_table_id, random_idx_witness);
143 final_check_read_witnesses[i] = first;
148 const fr d_value = std::accumulate(
149 native_fr_elts_to_check_computation.begin(), native_fr_elts_to_check_computation.end(),
fr::zero());
150 uint32_t d_idx = circuit_builder.add_variable(d_value);
151 circuit_builder.create_big_add_gate({
152 final_check_read_witnesses[0],
153 final_check_read_witnesses[1],
154 final_check_read_witnesses[2],
163 uint32_t random_read_index =
static_cast<uint32_t
>(
165 num_single_elts_in_ROM_table);
167 circuit_builder.read_ROM_array(rom_table_id, index_witness_indices[random_read_index]);
179 auto rom_id = circuit_builder.create_ROM_array(array_length);
180 auto zero_idx = circuit_builder.zero_idx();
182 auto random_variable_idx = circuit_builder.add_variable(random_num);
183 switch (rom_failure_type) {
186 for (
size_t i = 0; i < array_length; ++i) {
187 circuit_builder.set_ROM_element(rom_id, i, zero_idx);
194 for (
size_t i = 0; i < array_length; ++i) {
195 circuit_builder.set_ROM_element_pair(rom_id, i, std::array{ random_variable_idx, random_variable_idx });
198 circuit_builder.read_ROM_array(rom_id, zero_idx);
205 const size_t read_write_operations = 0,
206 bool final_arithmetic_gate_and_read =
true)
211 std::vector<fr> variables(array_length);
212 std::vector<uint32_t> variable_witnesses(array_length);
213 for (
auto [variable, witness] :
zip_view(variables, variable_witnesses)) {
215 witness = circuit_builder.add_variable(variable);
220 std::vector<uint32_t> index_witness_indices(array_length);
221 for (
size_t i = 0; i < array_length; ++i) {
222 index_witness_indices[i] = circuit_builder.put_constant_variable(
static_cast<uint64_t
>(i));
225 size_t ram_table_id = circuit_builder.create_RAM_array(array_length);
227 for (
size_t i = 0; i < array_length; ++i) {
228 circuit_builder.init_RAM_element(ram_table_id, i, variable_witnesses[i]);
229 native_ram_table[i] = variables[i];
233 for (
size_t i = 0; i < read_write_operations; ++i) {
237 uint32_t write_variable_witness = circuit_builder.add_variable(random_element);
238 native_ram_table[random_write_index] = random_element;
239 circuit_builder.write_RAM_array(
240 ram_table_id, index_witness_indices[random_write_index], write_variable_witness);
243 uint32_t read_witness =
244 circuit_builder.read_RAM_array(ram_table_id, index_witness_indices[random_read_index]);
245 auto read_value = circuit_builder.get_variable(read_witness);
246 auto expected_value = native_ram_table[random_read_index];
247 BB_ASSERT_EQ(read_value, expected_value,
"the value the RAM table read was not the expected value");
249 if (final_arithmetic_gate_and_read) {
257 for (
size_t i = 0; i < 3; i++) {
258 uint32_t random_index_to_check_computation =
260 random_index_witnesses_to_check_computation[i] =
261 index_witness_indices[random_index_to_check_computation];
262 native_fr_elts_to_check_computation[i] = native_ram_table[random_index_to_check_computation];
266 for (
size_t i = 0; i < 3; i++) {
267 const auto random_idx_witness = random_index_witnesses_to_check_computation[i];
268 final_check_read_witnesses[i] = circuit_builder.read_RAM_array(ram_table_id, random_idx_witness);
272 const fr d_value = std::accumulate(
273 native_fr_elts_to_check_computation.begin(), native_fr_elts_to_check_computation.end(),
fr::zero());
274 uint32_t d_idx = circuit_builder.add_variable(d_value);
275 circuit_builder.create_big_add_gate({
276 final_check_read_witnesses[0],
277 final_check_read_witnesses[1],
278 final_check_read_witnesses[2],
287 uint32_t random_read_index =
289 static_cast<uint32_t
>(array_length);
290 circuit_builder.read_RAM_array(ram_table_id, index_witness_indices[random_read_index]);