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