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