17 for (
size_t i = 0; i < array_size; ++i) {
18 new_transcript.
state.emplace_back(
19 std::array<uint32_t, 2>{ UNINITIALIZED_MEMORY_RECORD, UNINITIALIZED_MEMORY_RECORD });
21 rom_arrays.emplace_back(new_transcript);
22 return rom_arrays.size() - 1;
36template <
typename ExecutionTrace>
39 const size_t index_value,
40 const uint32_t value_witness)
44 const uint32_t index_witness =
45 (index_value == 0) ?
builder->zero_idx() :
builder->put_constant_variable((uint64_t)index_value);
51 .value_column1_witness = value_witness,
52 .value_column2_witness =
builder->zero_idx(),
53 .index =
static_cast<uint32_t
>(index_value),
57 rom_array.
state[index_value][0] = value_witness;
59 create_ROM_gate(
builder, new_record);
60 rom_array.
records.emplace_back(new_record);
65template <
typename ExecutionTrace>
68 const size_t index_value,
69 const std::array<uint32_t, 2>& value_witnesses)
73 const uint32_t index_witness =
builder->put_constant_variable((uint64_t)index_value);
78 .value_column1_witness = value_witnesses[0],
79 .value_column2_witness = value_witnesses[1],
80 .index =
static_cast<uint32_t
>(index_value),
84 rom_array.
state[index_value][0] = value_witnesses[0];
85 rom_array.
state[index_value][1] = value_witnesses[1];
87 create_ROM_gate(
builder, new_record);
88 rom_array.
records.emplace_back(new_record);
91template <
typename ExecutionTrace>
94 const uint32_t index_witness)
102 const uint32_t value_witness =
builder->add_variable(
value);
105 .value_column1_witness = value_witness,
106 .value_column2_witness =
builder->zero_idx(),
111 create_ROM_gate(
builder, new_record);
112 rom_array.
records.emplace_back(new_record);
114 return value_witness;
117template <
typename ExecutionTrace>
120 const uint32_t index_witness)
122 std::array<uint32_t, 2> value_witnesses;
132 value_witnesses[0] =
builder->add_variable(value1);
133 value_witnesses[1] =
builder->add_variable(value2);
136 .value_column1_witness = value_witnesses[0],
137 .value_column2_witness = value_witnesses[1],
142 create_ROM_gate(
builder, new_record);
143 rom_array.
records.emplace_back(new_record);
145 return value_witnesses;
152template <
typename ExecutionTrace>
157 builder->apply_memory_selectors(CircuitBuilder::MEMORY_SELECTORS::ROM_READ);
158 builder->blocks.memory.populate_wires(
162 builder->check_selector_length_consistency();
163 builder->increment_num_gates();
166template <
typename ExecutionTrace>
172 builder->apply_memory_selectors(CircuitBuilder::MEMORY_SELECTORS::ROM_CONSISTENCY_CHECK);
173 builder->blocks.memory.populate_wires(
177 builder->check_selector_length_consistency();
178 builder->increment_num_gates();
181template <
typename ExecutionTrace>
184 auto& rom_array = rom_arrays[rom_id];
188 const auto read_tag =
builder->get_new_tag();
189 const auto sorted_list_tag =
builder->get_new_tag();
190 builder->set_tau_transposition(read_tag, sorted_list_tag);
193 for (
size_t i = 0; i < rom_array.state.size(); ++i) {
194 if (rom_array.state[i][0] == UNINITIALIZED_MEMORY_RECORD) {
195 set_ROM_element_pair(
201 std::sort(rom_array.records.begin(), rom_array.records.end());
203 std::sort(std::execution::par_unseq, rom_array.records.begin(), rom_array.records.end());
206 for (
const RomRecord& record : rom_array.records) {
207 const auto index = record.index;
208 const auto value1 =
builder->get_variable(record.value_column1_witness);
209 const auto value2 =
builder->get_variable(record.value_column2_witness);
210 const auto index_witness =
builder->add_variable(
FF((uint64_t)
index));
211 builder->update_used_witnesses(index_witness);
212 const auto value1_witness =
builder->add_variable(value1);
213 const auto value2_witness =
builder->add_variable(value2);
218 .value_column1_witness = value1_witness,
219 .value_column2_witness = value2_witness,
225 create_sorted_ROM_gate(
builder, sorted_record);
227 builder->assign_tag(record.record_witness, read_tag);
228 builder->assign_tag(sorted_record.record_witness, sorted_list_tag);
240 builder->memory_read_records.push_back(
static_cast<uint32_t
>(sorted_record.gate_index));
241 builder->memory_read_records.push_back(
static_cast<uint32_t
>(record.gate_index));
248 FF max_index_value((uint64_t)rom_array.state.size());
249 uint32_t max_index =
builder->add_variable(max_index_value);
251 builder->create_unconstrained_gate(
272 for (
size_t i = 0; i < rom_arrays.size(); ++i) {
280 for (
size_t i = 0; i < array_size; ++i) {
281 new_transcript.
state.emplace_back(UNINITIALIZED_MEMORY_RECORD);
283 ram_arrays.emplace_back(new_transcript);
284 return ram_arrays.size() - 1;
301template <
typename ExecutionTrace>
304 const size_t index_value,
305 const uint32_t value_witness)
309 const uint32_t index_witness =
310 (index_value == 0) ?
builder->zero_idx() :
builder->put_constant_variable((uint64_t)index_value);
315 .value_witness = value_witness,
316 .index =
static_cast<uint32_t
>(index_value),
317 .timestamp =
static_cast<uint32_t
>(ram_array.
access_count),
321 ram_array.
state[index_value] = value_witness;
324 create_RAM_gate(
builder, new_record);
325 ram_array.
records.emplace_back(new_record);
328template <
typename ExecutionTrace>
331 const uint32_t index_witness)
339 const uint32_t value_witness =
builder->add_variable(
value);
343 .value_witness = value_witness,
345 .timestamp =
static_cast<uint32_t
>(ram_array.
access_count),
351 create_RAM_gate(
builder, new_record);
352 ram_array.
records.emplace_back(new_record);
358 return value_witness;
372template <
typename ExecutionTrace>
375 const uint32_t index_witness,
376 const uint32_t value_witness)
386 .value_witness = value_witness,
388 .timestamp =
static_cast<uint32_t
>(ram_array.
access_count),
393 create_RAM_gate(
builder, new_record);
394 ram_array.
records.emplace_back(new_record);
403template <
typename ExecutionTrace>
412 ? CircuitBuilder::MEMORY_SELECTORS::RAM_READ
413 : CircuitBuilder::MEMORY_SELECTORS::RAM_WRITE);
414 builder->blocks.memory.populate_wires(
419 builder->increment_num_gates();
422template <
typename ExecutionTrace>
426 builder->apply_memory_selectors(CircuitBuilder::MEMORY_SELECTORS::RAM_CONSISTENCY_CHECK);
427 builder->blocks.memory.populate_wires(
431 builder->check_selector_length_consistency();
432 builder->increment_num_gates();
435template <
typename ExecutionTrace>
438 const size_t ram_array_size)
462 -
FF(
static_cast<uint64_t
>(ram_array_size) - 1),
466template <
typename ExecutionTrace>
470 const auto access_tag =
builder->get_new_tag();
471 const auto sorted_list_tag =
builder->get_new_tag();
475 builder->set_tau_transposition(access_tag, sorted_list_tag);
481 for (
size_t i = 0; i < ram_array.
state.size(); ++i) {
495 for (
size_t i = 0; i < ram_array.
records.size(); ++i) {
500 const auto index_witness =
builder->add_variable(
FF((uint64_t)
index));
502 const auto value_witness =
builder->add_variable(
value);
507 .timestamp_witness = timestamp_witess,
508 .value_witness = value_witness,
517 sorted_ram_records.emplace_back(sorted_record);
521 if (i < ram_array.
records.size() - 1) {
522 create_sorted_RAM_gate(
builder, sorted_record);
526 create_final_sorted_RAM_gate(
builder, sorted_record, ram_array.
state.size());
531 builder->assign_tag(sorted_record.record_witness, sorted_list_tag);
543 builder->memory_read_records.push_back(
static_cast<uint32_t
>(sorted_record.gate_index));
544 builder->memory_read_records.push_back(
static_cast<uint32_t
>(record.
gate_index));
548 builder->memory_write_records.push_back(
static_cast<uint32_t
>(sorted_record.gate_index));
549 builder->memory_write_records.push_back(
static_cast<uint32_t
>(record.
gate_index));
560 std::vector<uint32_t> timestamp_deltas;
562 if (sorted_ram_records.size() <= 1) {
565 for (
size_t i = 0; i < sorted_ram_records.size() - 1; ++i) {
566 const auto& current = sorted_ram_records[i];
567 const auto& next = sorted_ram_records[i + 1];
569 const bool share_index = current.index == next.index;
571 FF timestamp_delta = 0;
574 timestamp_delta =
FF(next.timestamp - current.timestamp);
577 uint32_t timestamp_delta_witness =
builder->add_variable(timestamp_delta);
581 builder->apply_memory_selectors(CircuitBuilder::MEMORY_SELECTORS::RAM_TIMESTAMP_CHECK);
582 builder->blocks.memory.populate_wires(
583 current.index_witness, current.timestamp_witness, timestamp_delta_witness,
builder->zero_idx());
585 builder->increment_num_gates();
589 timestamp_deltas.push_back(timestamp_delta_witness);
594 const auto& last = sorted_ram_records[ram_array.
records.size() - 1];
595 builder->create_unconstrained_gate(
596 builder->blocks.memory, last.index_witness, last.timestamp_witness,
builder->zero_idx(),
builder->zero_idx());
602 const size_t max_timestamp = ram_array.
access_count - 1;
603 for (
auto& w : timestamp_deltas) {
604 builder->create_small_range_constraint(w, max_timestamp);
610 for (
size_t i = 0; i < ram_arrays.size(); ++i) {
#define BB_ASSERT(expression,...)
#define BB_ASSERT_GT(left, right,...)
#define BB_ASSERT_NEQ(actual, expected,...)
#define BB_ASSERT_EQ(actual, expected,...)
bb::field< bb::Bn254FrParams > FF
ROM/RAM logic handler for UltraCircuitBuilder.
size_t create_ROM_array(const size_t array_size)
Create a new read-only memory region.
uint32_t read_ROM_array(CircuitBuilder *builder, const size_t rom_id, const uint32_t index_witness)
Read a single element from ROM.
void process_ROM_array(CircuitBuilder *builder, const size_t rom_id)
Compute additional gates required to validate ROM reads. Called when generating the proving key.
void create_sorted_RAM_gate(CircuitBuilder *builder, RamRecord &record)
Gate that performs consistency checks to validate that a claimed RAM read/write value is correct.
void process_ROM_arrays(CircuitBuilder *builder)
Process all of the ROM arrays.
std::array< uint32_t, 2 > read_ROM_array_pair(CircuitBuilder *builder, const size_t rom_id, const uint32_t index_witness)
Read a pair of elements from ROM.
void set_ROM_element(CircuitBuilder *builder, const size_t rom_id, const size_t index_value, const uint32_t value_witness)
Initialize a rom cell to equal value_witness
void create_final_sorted_RAM_gate(CircuitBuilder *builder, RamRecord &record, const size_t ram_array_size)
Performs consistency checks to validate that a claimed RAM read/write value is correct....
void process_RAM_arrays(CircuitBuilder *builder)
void init_RAM_element(CircuitBuilder *builder, const size_t ram_id, const size_t index_value, const uint32_t value_witness)
Initialize a RAM cell to equal value_witness
void create_sorted_ROM_gate(CircuitBuilder *builder, RomRecord &record)
Gate that performs consistency checks to validate that a claimed ROM read value is correct.
void write_RAM_array(CircuitBuilder *builder, const size_t ram_id, const uint32_t index_witness, const uint32_t value_witness)
Write a cell in a RAM array.
void set_ROM_element_pair(CircuitBuilder *builder, const size_t rom_id, const size_t index_value, const std::array< uint32_t, 2 > &value_witnesses)
Initialize a ROM array element with a pair of witness values.
void create_ROM_gate(CircuitBuilder *builder, RomRecord &record)
Gate that'reads' from a ROM table, i.e., the table index is a witness not precomputed.
uint32_t read_RAM_array(CircuitBuilder *builder, const size_t ram_id, const uint32_t index_witness)
typename ExecutionTrace::FF FF
void create_RAM_gate(CircuitBuilder *builder, RamRecord &record)
Gate that performs a read/write operation into a RAM table, i.e. table index is a witness not precomp...
void process_RAM_array(CircuitBuilder *builder, const size_t ram_id)
Compute additional gates required to validate RAM read/writes. Called when generating the proving key...
size_t create_RAM_array(const size_t array_size)
Create a new updatable memory region.
Entry point for Barretenberg command-line interface.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
A RAM memory record that can be ordered, first by index, then by timestamp.
uint32_t timestamp_witness
RamTranscript contains the RamRecords for a particular RAM table (recording READ and WRITE operations...
std::vector< RamRecord > records
std::vector< uint32_t > state
A ROM memory record that can be ordered, where the ordering is given by the index (a....
uint32_t value_column1_witness
uint32_t value_column2_witness
RomTranscript contains the RomRecords for a particular ROM table as well as the vector whose ith entr...
std::vector< std::array< uint32_t, 2 > > state
std::vector< RomRecord > records
void throw_or_abort(std::string const &err)