41 auto& circuit_builder,
43 size_t num_pair_elts_in_ROM_table = 0,
45 const size_t read_operations = 0,
46 bool final_arithmetic_gate_and_read =
true)
50 "cannot set the number of 'pairs of elements to add to the ROM table' to be greater than the "
51 "length of the table");
55 std::vector<fr> variables(array_length + 1);
56 std::vector<uint32_t> variable_witnesses(array_length + 1);
57 for (
auto [variable, witness] :
zip_view(variables, variable_witnesses)) {
59 witness = circuit_builder.add_variable(variable);
64 std::vector<uint32_t> index_witness_indices(array_length);
65 for (
size_t i = 0; i < array_length; ++i) {
66 index_witness_indices[i] = circuit_builder.put_constant_variable(
static_cast<uint64_t
>(i));
72 size_t rom_table_id = circuit_builder.create_ROM_array(array_length);
74 const size_t num_single_elts_in_ROM_table = array_length - num_pair_elts_in_ROM_table;
76 for (
size_t i = 0; i < num_single_elts_in_ROM_table; ++i) {
77 circuit_builder.set_ROM_element(rom_table_id, i, variable_witnesses[i]);
78 native_rom_table[i] = std::array{ variables[i],
fr::zero() };
81 for (
size_t i = num_single_elts_in_ROM_table; i < array_length; ++i) {
82 circuit_builder.set_ROM_element_pair(
83 rom_table_id, i, std::array{ variable_witnesses[i], variable_witnesses[i + 1] });
84 native_rom_table[i] = std::array{ variables[i], variables[i + 1] };
89 for (
size_t i = 0; i < read_operations; ++i) {
90 uint32_t random_read_index =
static_cast<uint32_t
>(
93 if (random_read_index < num_single_elts_in_ROM_table) {
94 uint32_t read_witness_index =
95 circuit_builder.read_ROM_array(rom_table_id, index_witness_indices[random_read_index]);
97 auto actually_read_value = circuit_builder.get_variable(read_witness_index);
98 auto expected_value = native_rom_table[random_read_index][0];
101 auto [read_witness_index_1, read_witness_index_2] =
102 circuit_builder.read_ROM_array_pair(rom_table_id, index_witness_indices[random_read_index]);
104 std::array<fr, 2> actually_read_values = { circuit_builder.get_variable(read_witness_index_1),
105 circuit_builder.get_variable(read_witness_index_2) };
106 auto expected_values = native_rom_table[random_read_index];
107 BB_ASSERT_EQ(actually_read_values[0], expected_values[0]);
108 BB_ASSERT_EQ(actually_read_values[1], expected_values[1]);
111 if (final_arithmetic_gate_and_read) {
122 for (
size_t i = 0; i < 3; i++) {
123 uint32_t random_index_to_check_computation =
125 random_indices_to_check_computation[i] = random_index_to_check_computation;
126 random_index_witnesses_to_check_computation[i] =
127 index_witness_indices[random_index_to_check_computation];
128 native_fr_elts_to_check_computation[i] =
129 native_rom_table[random_index_to_check_computation]
136 for (
size_t i = 0; i < 3; i++) {
137 const auto random_idx = random_indices_to_check_computation[i];
138 const auto random_idx_witness = random_index_witnesses_to_check_computation[i];
140 if (random_idx < num_single_elts_in_ROM_table) {
141 final_check_read_witnesses[i] = circuit_builder.read_ROM_array(rom_table_id, random_idx_witness);
144 auto [first, _] = circuit_builder.read_ROM_array_pair(rom_table_id, random_idx_witness);
145 final_check_read_witnesses[i] = first;
150 const fr d_value = std::accumulate(
151 native_fr_elts_to_check_computation.begin(), native_fr_elts_to_check_computation.end(),
fr::zero());
152 uint32_t d_idx = circuit_builder.add_variable(d_value);
153 circuit_builder.create_big_add_gate({
154 final_check_read_witnesses[0],
155 final_check_read_witnesses[1],
156 final_check_read_witnesses[2],
165 uint32_t random_read_index =
static_cast<uint32_t
>(
167 num_single_elts_in_ROM_table);
169 circuit_builder.read_ROM_array(rom_table_id, index_witness_indices[random_read_index]);
181 auto rom_id = circuit_builder.create_ROM_array(array_length);
182 auto zero_idx = circuit_builder.zero_idx();
184 auto random_variable_idx = circuit_builder.add_variable(random_num);
185 switch (rom_failure_type) {
188 for (
size_t i = 0; i < array_length; ++i) {
189 circuit_builder.set_ROM_element(rom_id, i, zero_idx);
196 for (
size_t i = 0; i < array_length; ++i) {
197 circuit_builder.set_ROM_element_pair(rom_id, i, std::array{ random_variable_idx, random_variable_idx });
200 circuit_builder.read_ROM_array(rom_id, zero_idx);
207 const size_t read_write_operations = 0,
208 bool final_arithmetic_gate_and_read =
true)
213 std::vector<fr> variables(array_length);
214 std::vector<uint32_t> variable_witnesses(array_length);
215 for (
auto [variable, witness] :
zip_view(variables, variable_witnesses)) {
217 witness = circuit_builder.add_variable(variable);
222 std::vector<uint32_t> index_witness_indices(array_length);
223 for (
size_t i = 0; i < array_length; ++i) {
224 index_witness_indices[i] = circuit_builder.put_constant_variable(
static_cast<uint64_t
>(i));
227 size_t ram_table_id = circuit_builder.create_RAM_array(array_length);
229 for (
size_t i = 0; i < array_length; ++i) {
230 circuit_builder.init_RAM_element(ram_table_id, i, variable_witnesses[i]);
231 native_ram_table[i] = variables[i];
235 for (
size_t i = 0; i < read_write_operations; ++i) {
239 uint32_t write_variable_witness = circuit_builder.add_variable(random_element);
240 native_ram_table[random_write_index] = random_element;
241 circuit_builder.write_RAM_array(
242 ram_table_id, index_witness_indices[random_write_index], write_variable_witness);
245 uint32_t read_witness =
246 circuit_builder.read_RAM_array(ram_table_id, index_witness_indices[random_read_index]);
247 auto read_value = circuit_builder.get_variable(read_witness);
248 auto expected_value = native_ram_table[random_read_index];
249 BB_ASSERT_EQ(read_value, expected_value,
"the value the RAM table read was not the expected value");
251 if (final_arithmetic_gate_and_read) {
259 for (
size_t i = 0; i < 3; i++) {
260 uint32_t random_index_to_check_computation =
262 random_index_witnesses_to_check_computation[i] =
263 index_witness_indices[random_index_to_check_computation];
264 native_fr_elts_to_check_computation[i] = native_ram_table[random_index_to_check_computation];
268 for (
size_t i = 0; i < 3; i++) {
269 const auto random_idx_witness = random_index_witnesses_to_check_computation[i];
270 final_check_read_witnesses[i] = circuit_builder.read_RAM_array(ram_table_id, random_idx_witness);
274 const fr d_value = std::accumulate(
275 native_fr_elts_to_check_computation.begin(), native_fr_elts_to_check_computation.end(),
fr::zero());
276 uint32_t d_idx = circuit_builder.add_variable(d_value);
277 circuit_builder.create_big_add_gate({
278 final_check_read_witnesses[0],
279 final_check_read_witnesses[1],
280 final_check_read_witnesses[2],
289 uint32_t random_read_index =
291 circuit_builder.read_RAM_array(ram_table_id, index_witness_indices[random_read_index]);