Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
databus.test.cpp
Go to the documentation of this file.
1#include <cstddef>
2#include <cstdint>
3#include <gtest/gtest.h>
4
10
13
14using namespace bb;
15namespace {
17
18using FlavorTypes = ::testing::Types<MegaFlavor, MegaZKFlavor>;
19
20template <typename Flavor> class DataBusTests : public ::testing::Test {
21 protected:
22 static void SetUpTestSuite() { bb::srs::init_file_crs_factory(bb::srs::bb_crs_path()); }
23
24 using Curve = curve::BN254;
25 using FF = Curve::ScalarField;
26 using Builder = typename Flavor::CircuitBuilder;
27 using Prover = UltraProver_<Flavor>;
28 using Verifier = UltraVerifier_<Flavor>;
29
30 // Construct and verify a MegaHonk proof for a given circuit
31 static bool construct_and_verify_proof(MegaCircuitBuilder& builder)
32 {
34 auto verification_key = std::make_shared<typename Flavor::VerificationKey>(proving_key->get_precomputed());
35
36 Prover prover{ proving_key, verification_key };
37 auto proof = prover.construct_proof();
38 Verifier verifier{ verification_key };
39 bool result = verifier.template verify_proof<DefaultIO>(proof).result;
40 return result;
41 }
42
43 // Construct a Mega circuit with some arbitrary sample gates
44 static Builder construct_test_builder()
45 {
46 auto op_queue = std::make_shared<bb::ECCOpQueue>();
47 auto builder = MegaCircuitBuilder{ op_queue };
49 return builder;
50 }
51
62 static Builder construct_circuit_with_databus_reads(
64 const std::function<void(Builder&, uint32_t)>& add_bus_data,
65 const std::function<uint32_t(Builder&, uint32_t)>& read_bus_data)
66 {
67
68 const uint32_t NUM_BUS_ENTRIES = 5; // number of entries in the bus column
69 const uint32_t NUM_READS = 7; // greater than size of bus to ensure duplicates
70
71 // Add some arbitrary values to the bus column
72 for (size_t i = 0; i < NUM_BUS_ENTRIES; ++i) {
73 FF val = FF::random_element();
74 uint32_t val_witness_idx = builder.add_variable(val);
75 add_bus_data(builder, val_witness_idx);
76 }
77
78 // Read from the bus at some random indices
79 for (size_t i = 0; i < NUM_READS; ++i) {
80 uint32_t read_idx = engine.get_random_uint32() % NUM_BUS_ENTRIES;
81 uint32_t read_idx_witness_idx = builder.add_variable(read_idx);
82 read_bus_data(builder, read_idx_witness_idx);
83 }
84
85 return builder;
86 }
87
88 static Builder construct_circuit_with_calldata_reads(Builder& builder)
89 {
90 // Define interfaces for the add and read methods for databus calldata
91 auto add_method = [](Builder& builder, uint32_t witness_idx) { builder.add_public_calldata(witness_idx); };
92 auto read_method = [](Builder& builder, uint32_t witness_idx) { return builder.read_calldata(witness_idx); };
93
94 return construct_circuit_with_databus_reads(builder, add_method, read_method);
95 }
96
97 static Builder construct_circuit_with_secondary_calldata_reads(Builder& builder)
98 {
99 // Define interfaces for the add and read methods for databus secondary_calldata
100 auto add_method = [](Builder& builder, uint32_t witness_idx) {
101 builder.add_public_secondary_calldata(witness_idx);
102 };
103 auto read_method = [](Builder& builder, uint32_t witness_idx) {
104 return builder.read_secondary_calldata(witness_idx);
105 };
106
107 return construct_circuit_with_databus_reads(builder, add_method, read_method);
108 }
109
110 static Builder construct_circuit_with_return_data_reads(Builder& builder)
111 {
112 // Define interfaces for the add and read methods for databus return data
113 auto add_method = [](Builder& builder, uint32_t witness_idx) { builder.add_public_return_data(witness_idx); };
114 auto read_method = [](Builder& builder, uint32_t witness_idx) { return builder.read_return_data(witness_idx); };
115
116 return construct_circuit_with_databus_reads(builder, add_method, read_method);
117 }
118};
119
120TYPED_TEST_SUITE(DataBusTests, FlavorTypes);
121
126TYPED_TEST(DataBusTests, CallDataRead)
127{
128 typename TypeParam::CircuitBuilder builder = this->construct_test_builder();
129 this->construct_circuit_with_calldata_reads(builder);
130 EXPECT_TRUE(CircuitChecker::check(builder));
131 EXPECT_TRUE(this->construct_and_verify_proof(builder));
132}
133
138TYPED_TEST(DataBusTests, CallData2Read)
139{
140 typename TypeParam::CircuitBuilder builder = this->construct_test_builder();
141 this->construct_circuit_with_secondary_calldata_reads(builder);
142
143 EXPECT_TRUE(this->construct_and_verify_proof(builder));
144}
145
150TYPED_TEST(DataBusTests, ReturnDataRead)
151{
152 typename TypeParam::CircuitBuilder builder = this->construct_test_builder();
153 this->construct_circuit_with_return_data_reads(builder);
154
155 EXPECT_TRUE(this->construct_and_verify_proof(builder));
156}
157
162TYPED_TEST(DataBusTests, ReadAll)
163{
164 typename TypeParam::CircuitBuilder builder = this->construct_test_builder();
165 this->construct_circuit_with_calldata_reads(builder);
166 this->construct_circuit_with_secondary_calldata_reads(builder);
167 this->construct_circuit_with_return_data_reads(builder);
168
169 EXPECT_TRUE(this->construct_and_verify_proof(builder));
170}
171
177TYPED_TEST(DataBusTests, CallDataDuplicateRead)
178{
179 // Construct a circuit and add some ecc op gates and arithmetic gates
180 typename TypeParam::CircuitBuilder builder = this->construct_test_builder();
181 using FF = TypeParam::FF;
182
183 // Add some values to calldata
184
185 std::vector<FF> calldata_values = { 7, 10, 3, 12, 1 };
186 for (auto& val : calldata_values) {
187 builder.add_public_calldata(builder.add_variable(val));
188 }
189
190 // Define some read indices with a duplicate
191 std::vector<uint32_t> read_indices = { 1, 4, 1 };
192
193 // Create some calldata read gates and store the variable indices of the result for later
194 std::vector<uint32_t> result_witness_indices;
195 for (uint32_t& read_idx : read_indices) {
196 // Create a variable corresponding to the index at which we want to read into calldata
197 uint32_t read_idx_witness_idx = builder.add_variable(read_idx);
198
199 auto value_witness_idx = builder.read_calldata(read_idx_witness_idx);
200 result_witness_indices.emplace_back(value_witness_idx);
201 }
202
203 // Check that the read result is as expected and that the duplicate reads produce the same result
204 auto expected_read_result_at_1 = calldata_values[1];
205 auto expected_read_result_at_4 = calldata_values[4];
206 auto duplicate_read_result_0 = builder.get_variable(result_witness_indices[0]);
207 auto duplicate_read_result_1 = builder.get_variable(result_witness_indices[1]);
208 auto duplicate_read_result_2 = builder.get_variable(result_witness_indices[2]);
209 EXPECT_EQ(duplicate_read_result_0, expected_read_result_at_1);
210 EXPECT_EQ(duplicate_read_result_1, expected_read_result_at_4);
211 EXPECT_EQ(duplicate_read_result_2, expected_read_result_at_1);
212
213 // Construct and verify Honk proof
214 bool result = this->construct_and_verify_proof(builder);
215 EXPECT_TRUE(result);
216}
217} // namespace
static void construct_simple_circuit(MegaBuilder &builder, bool last_circuit=false)
Generate a simple test circuit with some ECC op gates and conventional arithmetic gates.
MegaCircuitBuilder CircuitBuilder
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
bb::fr ScalarField
Definition bn254.hpp:18
virtual uint32_t get_random_uint32()=0
AluTraceBuilder builder
Definition alu.test.cpp:123
numeric::RNG & engine
testing::Types< MegaFlavor, UltraFlavor, UltraZKFlavor, UltraRollupFlavor > FlavorTypes
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
Definition engine.cpp:190
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
Entry point for Barretenberg command-line interface.
TYPED_TEST_SUITE(ShpleminiTest, TestSettings)
typename Flavor::FF FF
TYPED_TEST(ShpleminiTest, CorrectnessOfMultivariateClaimBatching)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
static field random_element(numeric::RNG *engine=nullptr) noexcept