Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
rom_table.test.cpp
Go to the documentation of this file.
1#include "rom_table.hpp"
9
10#include <gtest/gtest.h>
11using namespace bb;
12
13template <typename Builder> class RomTableTests : public ::testing::Test {
14 public:
18};
19using BuilderTypes = testing::Types<UltraCircuitBuilder, MegaCircuitBuilder>;
20namespace {
22}
24
29TEST(RomTable, TagCorrectness)
30{
36 std::vector<field_ct> table_values;
37 // Create random witness elements
41
42 // Tag all 3 with different tags
43 entry_1.set_origin_tag(submitted_value_origin_tag);
44 entry_2.set_origin_tag(challenge_origin_tag);
45 // The last one is "poisoned" (calculating with this element should result in runtime error)
46 entry_3.set_origin_tag(instant_death_tag);
47
48 table_values.emplace_back(entry_1);
49 table_values.emplace_back(entry_2);
50 table_values.emplace_back(entry_3);
51
52 // Initialize the table with them
53 rom_table_ct table(table_values);
54
55 // Check that the tags of the first two are preserved
56 EXPECT_EQ(table[field_ct(witness_ct(&builder, 0))].get_origin_tag(), submitted_value_origin_tag);
57 EXPECT_EQ(table[field_ct(witness_ct(&builder, 1))].get_origin_tag(), challenge_origin_tag);
58
59#ifndef NDEBUG
60 // Check that computing the sum with the last once crashes the program
61 EXPECT_THROW(table[0] + table[2], std::runtime_error);
62#endif
63}
64
66// tests basic functionality, as well as the number of gates added per ROM read (not including the
67// finalization/processing): one gate per variable lookup, zero gates per constant lookup.
68TYPED_TEST(RomTableTests, RomTableReadWriteConsistency)
69{
70 using Builder = TypeParam;
71 using field_ct = typename TestFixture::field_ct;
72 using witness_ct = typename TestFixture::witness_ct;
73 using rom_table_ct = typename TestFixture::rom_table_ct;
74
76
77 const size_t table_size = 10;
78 std::vector<field_ct> table_values;
79 for (size_t i = 0; i < table_size; ++i) {
80 table_values.emplace_back(witness_ct(&builder, bb::fr::random_element()));
81 }
82
83 rom_table_ct table(table_values);
84
86 fr expected(0);
87
88 for (size_t i = 0; i < table_size; ++i) {
89 // if `i` is even, do a variable lookup (i.e., the index witness is _not constant_), if `i` is odd, do a
90 // constant lookup.
91 if (i % 2 == 0) {
92 field_ct index(witness_ct(&builder, static_cast<uint64_t>(i)));
93 const auto before_n = builder.num_gates();
94 const auto to_add = table[index];
95 const auto after_n = builder.num_gates();
96 // should cost 1 gate (the ROM read adds 1 extra gate when the proving key is constructed, i.e., before
97 // finalization), but not for first entry, the first ROM read also builts the ROM table, which will cost
98 // table_size * 2 gates.
99 if (i != 0) {
100 EXPECT_EQ(after_n - before_n, 1ULL);
101 }
102 result += to_add; // variable lookup
103 } else {
104 const auto before_n = builder.num_gates();
105 const auto to_add = table[i]; // constant lookup
106 const auto after_n = builder.num_gates();
107 // should cost 0 gates. Constant lookups are free
108 EXPECT_EQ(after_n - before_n, 0ULL);
109 result += to_add;
110 }
111 expected += table_values[i].get_value();
112 }
113
114 EXPECT_EQ(result.get_value(), expected);
115 EXPECT_EQ(CircuitChecker::check(builder), true);
116}
117// tests that copying the ROM table works as expected.
119{
120 using Builder = TypeParam;
121 using field_ct = typename TestFixture::field_ct;
122 using witness_ct = typename TestFixture::witness_ct;
123 using rom_table_ct = typename TestFixture::rom_table_ct;
124
126
127 std::vector<field_ct> table_values;
128 const size_t table_size = 5;
129 for (size_t i = 0; i < table_size; ++i) {
130 table_values.emplace_back(witness_ct(&builder, bb::fr::random_element()));
131 }
132
133 rom_table_ct table(table_values);
134 const auto copied_rom_table = table;
135 field_ct result(0);
136 fr expected(0);
137
138 for (size_t i = 0; i < table_size; ++i) {
139
140 field_ct index(witness_ct(&builder, static_cast<uint64_t>(i)));
141 const auto to_add = (i % 2 == 0) ? copied_rom_table[index] : table[index];
142 result += to_add;
143 expected += table_values[i].get_value();
144 }
145 EXPECT_EQ(result.get_value(), expected);
146
147 bool verified = CircuitChecker::check(builder);
148 EXPECT_EQ(verified, true);
149}
150
151// Verifies the LogUp scheme's per-operation cost: an array of N entries with N reads occupies exactly
152// 2N rows in the memory block (one table row per init + one read row per access).
153TYPED_TEST(RomTableTests, RomLogupGateCount)
154{
155 using Builder = TypeParam;
156 using field_ct = typename TestFixture::field_ct;
157 using witness_ct = typename TestFixture::witness_ct;
158 using rom_table_ct = typename TestFixture::rom_table_ct;
159
160 constexpr size_t table_size = 16;
162
163 const size_t memory_block_size_before = builder.blocks.memory.size();
164
165 std::vector<field_ct> table_values;
166 for (size_t i = 0; i < table_size; ++i) {
167 table_values.emplace_back(witness_ct(&builder, bb::fr::random_element()));
168 }
169 rom_table_ct table(table_values);
170 for (size_t i = 0; i < table_size; ++i) {
171 field_ct index(witness_ct(&builder, static_cast<uint64_t>(i)));
172 (void)table[index];
173 }
174
175 // Finalize so process_ROM_arrays runs; the row count below confirms it adds no rows for a LogUp array.
176 builder.finalize_circuit();
177
178 const size_t memory_block_rows = builder.blocks.memory.size() - memory_block_size_before;
179 // table_size inits + table_size reads = exactly 2 * table_size LogUp rows; finalization adds no
180 // further rows for a LogUp array.
181 EXPECT_EQ(memory_block_rows, 2 * table_size) << "LogUp ROM expected exactly 2N rows; got " << memory_block_rows;
182}
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
void set_origin_tag(const OriginTag &new_tag) const
Definition field.hpp:358
size_t size() const
Definition rom_table.hpp:37
AluTraceBuilder builder
Definition alu.test.cpp:124
numeric::RNG & engine
stdlib::witness_t< Builder > witness_ct
stdlib::field_t< Builder > field_ct
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
Definition engine.cpp:245
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
TYPED_TEST_SUITE(CommitmentKeyTest, Curves)
TYPED_TEST(CommitmentKeyTest, CommitToZeroPoly)
UltraCircuitBuilder_< UltraExecutionTraceBlocks > UltraCircuitBuilder
TEST(BoomerangMegaCircuitBuilder, BasicCircuit)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
This file contains part of the logic for the Origin Tag mechanism that tracks the use of in-circuit p...
#define STANDARD_TESTING_TAGS
::testing::Types< UltraCircuitBuilder, MegaCircuitBuilder > BuilderTypes
static field random_element(numeric::RNG *engine=nullptr) noexcept
VectorField result