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: Complete, auditors: [Raju], commit: 05a381f8b31ae4648e480f1369e911b148216e8b}
3// external_1: { status: Complete, auditors: [Sherlock], commit: e6694849223 }
4// external_2: { status: not started, auditors: [], commit: }
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 <typename 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 <typename 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 <typename 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 <typename Builder> rom_table<Builder>::rom_table(const rom_table& other) = default;
113
114template <typename Builder>
116 : raw_entries(std::move(other.raw_entries))
117 , entries(std::move(other.entries))
118 , _tags(std::move(other._tags))
119 , length(other.length)
120 , rom_id(other.rom_id)
121 , initialized(other.initialized)
122 , context(other.context)
123{
124 other.length = 0;
125 other.rom_id = 0;
126 other.initialized = false;
127 other.context = nullptr;
128}
129
130template <typename Builder> rom_table<Builder>& rom_table<Builder>::operator=(const rom_table& other) = default;
131
132template <typename Builder> rom_table<Builder>& rom_table<Builder>::operator=(rom_table&& other) noexcept
133{
134 if (this != &other) {
135 raw_entries = std::move(other.raw_entries);
136 entries = std::move(other.entries);
137 _tags = std::move(other._tags);
138 length = other.length;
139 rom_id = other.rom_id;
140 initialized = other.initialized;
141 context = other.context;
142
143 other.length = 0;
144 other.rom_id = 0;
145 other.initialized = false;
146 other.context = nullptr;
147 }
148 return *this;
149}
150
151template <typename Builder> field_t<Builder> rom_table<Builder>::operator[](const size_t index) const
152{
153 if (index >= length) {
154 BB_ASSERT(context != nullptr);
155 context->failure("rom_table: ROM array access out of bounds");
156 }
157
158 return raw_entries[index];
159}
160
161template <typename Builder> field_t<Builder> rom_table<Builder>::operator[](const field_pt& index) const
162{
163 if (context == nullptr) {
166 context,
167 nullptr,
168 "rom_table: Performing a read operation without providing a context. We cannot initialize the table.");
169 }
170
171 // When we perform the first read operation, we initialize the table
172 initialize_table();
173
174 if (index.is_constant()) {
175 return operator[](static_cast<size_t>(uint256_t(index.get_value()).data[0]));
176 }
177
178 const auto native_index = uint256_t(index.get_value());
179 if (native_index >= length) {
180 context->failure("rom_table: ROM array access out of bounds");
181 }
182
183 uint32_t output_idx = context->read_ROM_array(rom_id, index.get_witness_index());
184 auto element = field_pt::from_witness_index(context, output_idx);
185
186 const size_t cast_index = static_cast<size_t>(static_cast<uint64_t>(native_index));
187
188 // If the index is legitimate, restore the tag
189 if (native_index < length) {
190
191 element.set_origin_tag(_tags[cast_index]);
192 }
193 return element;
194}
195
198} // namespace bb::stdlib
#define BB_ASSERT(expression,...)
Definition assert.hpp:70
#define BB_ASSERT_NEQ(actual, expected,...)
Definition assert.hpp:98
static field_t from_witness_index(Builder *ctx, uint32_t witness_index)
Definition field.cpp:67
Builder * get_context() const
Definition field.hpp:431
std::vector< OriginTag > _tags
Definition rom_table.hpp:46
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:42
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...
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13