Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
databus.test.cpp
Go to the documentation of this file.
2#include <cstddef>
3#include <cstdint>
4#include <gtest/gtest.h>
5
12
15
16using namespace bb;
17namespace {
19
20// DataBusTests only run against flavors that include the databus relation in their tuple.
21// MegaZKFlavor deliberately drops databus; q_busread is identically zero in the hiding kernel.
22using FlavorTypes = ::testing::Types<MegaFlavor>;
23
24template <typename Flavor> class DataBusTests : public ::testing::Test {
25 protected:
26 static void SetUpTestSuite() { bb::srs::init_file_crs_factory(bb::srs::bb_crs_path()); }
27
28 using Curve = curve::BN254;
29 using FF = Curve::ScalarField;
30 using Builder = typename Flavor::CircuitBuilder;
31 using Prover = UltraProver_<Flavor>;
32 using Verifier = UltraVerifier_<Flavor, DefaultIO>;
33
34 // Construct and verify a MegaHonk proof for a given circuit
35 static bool construct_and_verify_proof(MegaCircuitBuilder& builder)
36 {
38 auto verification_key = std::make_shared<typename Flavor::VerificationKey>(prover_instance->get_precomputed());
39 auto vk_and_hash = std::make_shared<typename Flavor::VKAndHash>(verification_key);
40
41 Prover prover{ prover_instance, verification_key };
42 auto proof = prover.construct_proof();
43 Verifier verifier{ vk_and_hash };
44 bool result = verifier.verify_proof(proof).result;
45 return result;
46 }
47
48 // Construct a Mega circuit with some arbitrary sample gates
49 static Builder construct_test_builder()
50 {
51 auto op_queue = std::make_shared<bb::ECCOpQueue>();
52 auto builder = MegaCircuitBuilder{ op_queue };
54 return builder;
55 }
56
66 static Builder construct_circuit_with_databus_reads(Builder& builder, const BusId& bus_idx)
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 builder.add_public_calldata(bus_idx, 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 builder.read_calldata(bus_idx, read_idx_witness_idx);
84 }
85
86 return builder;
87 }
88};
89
90TYPED_TEST_SUITE(DataBusTests, FlavorTypes);
91
96TYPED_TEST(DataBusTests, KernelCallDataRead)
97{
98 typename TypeParam::CircuitBuilder builder = this->construct_test_builder();
99 this->construct_circuit_with_databus_reads(builder, BusId::KERNEL_CALLDATA);
100 EXPECT_TRUE(CircuitChecker::check(builder));
101 EXPECT_TRUE(this->construct_and_verify_proof(builder));
102}
103
108TYPED_TEST(DataBusTests, AppCallDataRead)
109{
110 for (size_t idx = 0; idx < MAX_APPS_PER_KERNEL; ++idx) {
111 typename TypeParam::CircuitBuilder builder = this->construct_test_builder();
112 this->construct_circuit_with_databus_reads(builder, static_cast<BusId>(idx + 1));
113
114 EXPECT_TRUE(CircuitChecker::check(builder)) << "Circuit check failed for app calldata bus with index " << idx;
115 EXPECT_TRUE(this->construct_and_verify_proof(builder)) << "Failed for app calldata bus with index " << idx;
116 }
117}
118
123TYPED_TEST(DataBusTests, ReturnDataRead)
124{
125 typename TypeParam::CircuitBuilder builder = this->construct_test_builder();
126 this->construct_circuit_with_databus_reads(builder, BusId::RETURNDATA);
127
128 EXPECT_TRUE(CircuitChecker::check(builder));
129 EXPECT_TRUE(this->construct_and_verify_proof(builder));
130}
131
136TYPED_TEST(DataBusTests, ReadAll)
137{
138 typename TypeParam::CircuitBuilder builder = this->construct_test_builder();
139 this->construct_circuit_with_databus_reads(builder, BusId::KERNEL_CALLDATA);
140 for (size_t idx = 0; idx < MAX_APPS_PER_KERNEL; ++idx) {
141 this->construct_circuit_with_databus_reads(builder, static_cast<BusId>(idx + 1));
142 }
143 this->construct_circuit_with_databus_reads(builder, BusId::RETURNDATA);
144
145 EXPECT_TRUE(CircuitChecker::check(builder));
146 EXPECT_TRUE(this->construct_and_verify_proof(builder));
147}
148
154TYPED_TEST(DataBusTests, CallDataDuplicateRead)
155{
156 // Construct a circuit and add some ecc op gates and arithmetic gates
157 typename TypeParam::CircuitBuilder builder = this->construct_test_builder();
158 using FF = TypeParam::FF;
159
160 // Add some values to kernel calldata
161
162 std::vector<FF> calldata_values = { 7, 10, 3, 12, 1 };
163 for (auto& val : calldata_values) {
164 builder.add_public_calldata(BusId::KERNEL_CALLDATA, builder.add_variable(val));
165 }
166
167 // Define some read indices with a duplicate
168 std::vector<uint32_t> read_indices = { 1, 4, 1 };
169
170 // Create some kernel calldata read gates and store the variable indices of the result for later
171 std::vector<uint32_t> result_witness_indices;
172 for (uint32_t& read_idx : read_indices) {
173 // Create a variable corresponding to the index at which we want to read into kernel calldata
174 uint32_t read_idx_witness_idx = builder.add_variable(FF(read_idx));
175
176 auto value_witness_idx = builder.read_calldata(BusId::KERNEL_CALLDATA, read_idx_witness_idx);
177 result_witness_indices.emplace_back(value_witness_idx);
178 }
179
180 // Check that the read result is as expected and that the duplicate reads produce the same result
181 auto expected_read_result_at_1 = calldata_values[1];
182 auto expected_read_result_at_4 = calldata_values[4];
183 auto duplicate_read_result_0 = builder.get_variable(result_witness_indices[0]);
184 auto duplicate_read_result_1 = builder.get_variable(result_witness_indices[1]);
185 auto duplicate_read_result_2 = builder.get_variable(result_witness_indices[2]);
186 EXPECT_EQ(duplicate_read_result_0, expected_read_result_at_1);
187 EXPECT_EQ(duplicate_read_result_1, expected_read_result_at_4);
188 EXPECT_EQ(duplicate_read_result_2, expected_read_result_at_1);
189
190 // Construct and verify Honk proof
191 bool result = this->construct_and_verify_proof(builder);
192 EXPECT_TRUE(result);
193}
194} // 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< UltraFlavor, UltraKeccakFlavor, MegaFlavor > FlavorTypes
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
Definition engine.cpp:245
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(CommitmentKeyTest, Curves)
BusId
Definition databus.hpp:75
TYPED_TEST(CommitmentKeyTest, CommitToZeroPoly)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
static field random_element(numeric::RNG *engine=nullptr) noexcept
VectorField result