Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
rom_table.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
7#include "rom_table.hpp"
8
9#include "../circuit_builders/circuit_builders.hpp"
11
12using namespace bb;
13
14namespace bb::stdlib {
15
23template <IsUltraOrMegaBuilder Builder>
25 : raw_entries(table_entries)
26 , length(raw_entries.size())
28{
29 // For consistency with the other constructor, we delegate the initialization of the table to the first read
30 // operation.
31
32 // Initialize tags
33 _tags.resize(raw_entries.size());
34 for (size_t i = 0; i < length; ++i) {
35 _tags[i] = raw_entries[i].get_origin_tag();
36 }
37}
38
47template <IsUltraOrMegaBuilder Builder>
49 : raw_entries(table_entries)
50 , length(raw_entries.size())
51{
52 // get the builder context
53 for (const auto& entry : table_entries) {
54 if (entry.get_context() != nullptr) {
55 context = entry.get_context();
56 break;
57 }
58 }
59
60 // Do not initialize the table yet. The input entries might all be constant,
61 // if this is the case we might not have a valid pointer to a Builder
62 // We get around this, by initializing the table when `operator[]` is called
63 // with a non-const field element.
64
65 // Initialize tags
66 _tags.resize(raw_entries.size());
67 for (size_t i = 0; i < length; ++i) {
68 _tags[i] = raw_entries[i].get_origin_tag();
69 }
70}
71
80template <IsUltraOrMegaBuilder Builder> void rom_table<Builder>::initialize_table() const
81{
82 if (initialized) {
83 return;
84 }
85 BB_ASSERT(context != nullptr);
86 // populate table. Table entries must be normalized and cannot be constants
87 for (const auto& entry : raw_entries) {
88 if (entry.is_constant()) {
89 auto fixed_witness =
90 field_pt::from_witness_index(context, context->put_constant_variable(entry.get_value()));
91 fixed_witness.set_origin_tag(entry.get_origin_tag());
92 entries.emplace_back(fixed_witness);
93
94 } else {
95 entries.emplace_back(entry);
96 }
97 }
98 rom_id = context->create_ROM_array(length);
99
100 for (size_t i = 0; i < length; ++i) {
101 context->set_ROM_element(rom_id, i, entries[i].get_witness_index());
102 }
103
104 // Preserve tags to restore them in the future lookups
105 _tags.resize(raw_entries.size());
106 for (size_t i = 0; i < length; ++i) {
107 _tags[i] = raw_entries[i].get_origin_tag();
108 }
109 initialized = true;
110}
111
112template <IsUltraOrMegaBuilder Builder> rom_table<Builder>::rom_table(const rom_table& other) = default;
113template <IsUltraOrMegaBuilder Builder> rom_table<Builder>::rom_table(rom_table&& other) = default;
114template <IsUltraOrMegaBuilder Builder>
116template <IsUltraOrMegaBuilder Builder> rom_table<Builder>& rom_table<Builder>::operator=(rom_table&& other) = default;
117
118template <IsUltraOrMegaBuilder Builder> field_t<Builder> rom_table<Builder>::operator[](const size_t index) const
119{
120 if (index >= length) {
121 BB_ASSERT(context != nullptr);
122 context->failure("rom_rable: ROM array access out of bounds");
123 }
124
125 return entries[index];
126}
127
128template <IsUltraOrMegaBuilder Builder> field_t<Builder> rom_table<Builder>::operator[](const field_pt& index) const
129{
130 if (context == nullptr) {
133 context,
134 nullptr,
135 "rom_table: Performing a read operation without providing a context. We cannot initialize the table.");
136 }
137
138 // When we perform the first read operation, we initialize the table
139 initialize_table();
140
141 if (index.is_constant()) {
142 return operator[](static_cast<size_t>(uint256_t(index.get_value()).data[0]));
143 }
144
145 const auto native_index = uint256_t(index.get_value());
146 if (native_index >= length) {
147 context->failure("rom_table: ROM array access out of bounds");
148 }
149
150 uint32_t output_idx = context->read_ROM_array(rom_id, index.get_witness_index());
151 auto element = field_pt::from_witness_index(context, output_idx);
152
153 const size_t cast_index = static_cast<size_t>(static_cast<uint64_t>(native_index));
154
155 // If the index is legitimate, restore the tag
156 if (native_index < length) {
157
158 element.set_origin_tag(_tags[cast_index]);
159 }
160 return element;
161}
162
165} // namespace bb::stdlib
#define BB_ASSERT(expression,...)
Definition assert.hpp:67
#define BB_ASSERT_NEQ(actual, expected,...)
Definition assert.hpp:92
static field_t from_witness_index(Builder *ctx, uint32_t witness_index)
Definition field.cpp:62
Builder * get_context() const
Definition field.hpp:419
std::vector< OriginTag > _tags
Definition rom_table.hpp:47
void initialize_table() const
Initialize the table once we perform a read.
Definition rom_table.cpp:80
rom_table & operator=(const rom_table &other)
std::vector< field_pt > raw_entries
Definition rom_table.hpp:43
field_pt operator[](const size_t index) const
AluTraceBuilder builder
Definition alu.test.cpp:124
StrictMock< MockContext > context
uint8_t const size_t length
Definition data_store.hpp:9
std::conditional_t< IsGoblinBigGroup< C, Fq, Fr, G >, element_goblin::goblin_element< C, goblin_field< C >, Fr, G >, element_default::element< C, Fq, Fr, G > > element
element wraps either element_default::element or element_goblin::goblin_element depending on parametr...
Definition biggroup.hpp:995
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13