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),
321 ram_array.
state[index_value] = value_witness;
325 create_RAM_gate(
builder, new_record);
326 ram_array.
records.emplace_back(new_record);
329template <
typename ExecutionTrace>
332 const uint32_t index_witness)
340 const uint32_t value_witness =
builder->add_variable(
value);
344 .value_witness = value_witness,
352 create_RAM_gate(
builder, new_record);
353 ram_array.
records.emplace_back(new_record);
360 return value_witness;
374template <
typename ExecutionTrace>
377 const uint32_t index_witness,
378 const uint32_t value_witness)
388 .value_witness = value_witness,
395 create_RAM_gate(
builder, new_record);
396 ram_array.
records.emplace_back(new_record);
406template <
typename ExecutionTrace>
415 ? CircuitBuilder::MEMORY_SELECTORS::RAM_READ
416 : CircuitBuilder::MEMORY_SELECTORS::RAM_WRITE);
417 builder->blocks.memory.populate_wires(
422 builder->increment_num_gates();
425template <
typename ExecutionTrace>
429 builder->apply_memory_selectors(CircuitBuilder::MEMORY_SELECTORS::RAM_CONSISTENCY_CHECK);
430 builder->blocks.memory.populate_wires(
434 builder->check_selector_length_consistency();
435 builder->increment_num_gates();
438template <
typename ExecutionTrace>
441 const size_t ram_array_size)
465 -
FF(
static_cast<uint64_t
>(ram_array_size) - 1),
482template <
typename ExecutionTrace>
486 const auto access_tag =
builder->get_new_tag();
487 const auto sorted_list_tag =
builder->get_new_tag();
491 builder->set_tau_transposition(access_tag, sorted_list_tag);
497 for (
size_t i = 0; i < ram_array.
state.size(); ++i) {
511 for (
size_t i = 0; i < ram_array.
records.size(); ++i) {
516 const auto index_witness =
builder->add_variable(
FF((uint64_t)
index));
518 const auto value_witness =
builder->add_variable(
value);
523 .timestamp_witness = timestamp_witess,
524 .value_witness = value_witness,
533 sorted_ram_records.emplace_back(sorted_record);
537 if (i < ram_array.
records.size() - 1) {
538 create_sorted_RAM_gate(
builder, sorted_record);
542 create_final_sorted_RAM_gate(
builder, sorted_record, ram_array.
state.size());
547 builder->assign_tag(sorted_record.record_witness, sorted_list_tag);
559 builder->memory_read_records.push_back(
static_cast<uint32_t
>(sorted_record.gate_index));
560 builder->memory_read_records.push_back(
static_cast<uint32_t
>(record.
gate_index));
564 builder->memory_write_records.push_back(
static_cast<uint32_t
>(sorted_record.gate_index));
565 builder->memory_write_records.push_back(
static_cast<uint32_t
>(record.
gate_index));
576 std::vector<uint32_t> timestamp_deltas;
578 if (sorted_ram_records.size() <= 1) {
581 for (
size_t i = 0; i < sorted_ram_records.size() - 1; ++i) {
582 const auto& current = sorted_ram_records[i];
583 const auto& next = sorted_ram_records[i + 1];
585 const bool share_index = current.index == next.index;
587 FF timestamp_delta = 0;
590 timestamp_delta =
FF(next.timestamp - current.timestamp);
593 uint32_t timestamp_delta_witness =
builder->add_variable(timestamp_delta);
597 builder->apply_memory_selectors(CircuitBuilder::MEMORY_SELECTORS::RAM_TIMESTAMP_CHECK);
598 builder->blocks.memory.populate_wires(
599 current.index_witness, current.timestamp_witness, timestamp_delta_witness,
builder->zero_idx());
601 builder->increment_num_gates();
605 timestamp_deltas.push_back(timestamp_delta_witness);
610 const auto& last = sorted_ram_records[ram_array.
records.size() - 1];
611 builder->create_unconstrained_gate(
612 builder->blocks.memory, last.index_witness, last.timestamp_witness,
builder->zero_idx(),
builder->zero_idx());
618 const uint32_t max_timestamp = ram_array.
access_count - 1;
619 for (
auto& w : timestamp_deltas) {
620 builder->create_small_range_constraint(w, max_timestamp);
626 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,...)
#define BB_ASSERT_LT(left, right,...)
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)