Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
mega_honk.test.cpp
Go to the documentation of this file.
1#include <cstddef>
2#include <cstdint>
3#include <gtest/gtest.h>
4
14
15using namespace bb;
16
18
19using FlavorTypes = ::testing::Types<MegaFlavor, MegaZKFlavor>;
20
21template <typename Flavor> class MegaHonkTests : public ::testing::Test {
22 public:
24
34
40 {
41 auto prover_instance = std::make_shared<ProverInstance>(builder);
42 auto verification_key = std::make_shared<VerificationKey>(prover_instance->get_precomputed());
43 auto vk_and_hash = std::make_shared<typename Flavor::VKAndHash>(verification_key);
44 Prover prover(prover_instance, verification_key);
45 Verifier verifier(vk_and_hash);
46 auto proof = prover.construct_proof();
47 bool verified = verifier.verify_proof(proof).result;
48
49 return verified;
50 }
51};
52
54
64TYPED_TEST(MegaHonkTests, ProofLengthCheck)
65{
66 using Flavor = TypeParam;
69
70 auto builder = Builder{};
72
73 // Construct a mega proof and ensure its size matches expectation; if not, the constant may need to be updated
75 auto verification_key = std::make_shared<typename Flavor::VerificationKey>(prover_instance->get_precomputed());
76 UltraProver_<Flavor> prover(prover_instance, verification_key);
77 HonkProof mega_proof = prover.construct_proof();
78 EXPECT_EQ(mega_proof.size(),
81}
82
89{
90 using Flavor = TypeParam;
92
94
95 // Construct and verify Honk proof
96 bool honk_verified = this->construct_and_verify_honk_proof(builder);
97 EXPECT_TRUE(honk_verified);
98}
99
105TYPED_TEST(MegaHonkTests, DynamicVirtualSizeIncrease)
106{
107 using Flavor = TypeParam;
108
109 // In MegaZKFlavor, we mask witness polynomials by placing random values at the indices `dyadic_circuit_size`-i for
110 // i=1,2,3. This mechanism does not work with structured polynomials yet.
112 GTEST_SKIP() << "Skipping 'DynamicVirtualSizeIncrease' test for MegaZKFlavor.";
113 }
115 using Prover = UltraProver_<Flavor>;
116 using Verifier = UltraVerifier_<Flavor, DefaultIO>;
117
119
120 auto builder_copy = builder;
121
122 // Construct and verify Honk proof using a structured trace
123 auto prover_instance = std::make_shared<ProverInstance_<Flavor>>(builder);
124 auto prover_instance_copy = std::make_shared<ProverInstance_<Flavor>>(builder_copy);
125 auto circuit_size = prover_instance->dyadic_size();
126
127 auto doubled_circuit_size = 2 * circuit_size;
128 prover_instance_copy->polynomials.increase_polynomials_virtual_size(doubled_circuit_size);
129 // TODO(https://github.com/AztecProtocol/barretenberg/issues/1158)
130 // prover_instance_copy->dyadic_circuit_size = doubled_circuit_size;
131
132 auto verification_key = std::make_shared<typename Flavor::VerificationKey>(prover_instance->get_precomputed());
133 Prover prover(prover_instance, verification_key);
134
135 auto verification_key_copy = std::make_shared<typename Flavor::VerificationKey>(prover_instance->get_precomputed());
136 Prover prover_copy(prover_instance_copy, verification_key_copy);
137
138 for (auto [entry, entry_copy] : zip_view(verification_key->get_all(), verification_key_copy->get_all())) {
139 EXPECT_EQ(entry, entry_copy);
140 }
141
142 auto vk_and_hash = std::make_shared<typename Flavor::VKAndHash>(verification_key);
143 Verifier verifier(vk_and_hash);
144 auto proof = prover.construct_proof();
145
146 auto relation_failures =
147 RelationChecker<Flavor>::check_all(prover_instance->polynomials, prover_instance->relation_parameters);
148 EXPECT_TRUE(relation_failures.empty());
149 bool result = verifier.verify_proof(proof).result;
150 EXPECT_TRUE(result);
151
152 auto vk_and_hash_copy = std::make_shared<typename Flavor::VKAndHash>(verification_key_copy);
153 Verifier verifier_copy(vk_and_hash_copy);
154 auto proof_copy = prover_copy.construct_proof();
155
156 auto relation_failures_copy =
157 RelationChecker<Flavor>::check_all(prover_instance->polynomials, prover_instance->relation_parameters);
158 EXPECT_TRUE(relation_failures.empty());
159 bool result_copy = verifier_copy.verify_proof(proof_copy).result;
160 EXPECT_TRUE(result_copy);
161}
162
171{
172 using Flavor = TypeParam;
173 // In MegaZKFlavor, we mask witness polynomials by placing random values at the indices `dyadic_circuit_size`-i, for
174 // i=1,2,3. This mechanism does not work with structured polynomials yet.
176 GTEST_SKIP() << "Skipping 'PolySwap' test for MegaZKFlavor.";
177 }
179
180 // Construct a simple circuit and make a copy of it
183 auto builder_copy = builder;
184
185 // Construct two identical proving keys
187 auto prover_instance_2 = std::make_shared<typename TestFixture::ProverInstance>(builder_copy);
188
189 // Tamper with the polys of pkey 1 in such a way that verification should fail
190 for (size_t i = 0; i < prover_instance_1->dyadic_size(); ++i) {
191 if (prover_instance_1->polynomials.q_arith[i] != 0) {
192 prover_instance_1->polynomials.w_l.at(i) += 1;
193 break;
194 }
195 }
196
197 // Swap the polys of the two proving keys; result should be pkey 1 is valid and pkey 2 should fail
198 std::swap(prover_instance_1->polynomials, prover_instance_2->polynomials);
199
200 { // Verification based on pkey 1 should succeed
201 auto verification_key =
202 std::make_shared<typename TestFixture::VerificationKey>(prover_instance_1->get_precomputed());
203 auto vk_and_hash = std::make_shared<typename Flavor::VKAndHash>(verification_key);
204 typename TestFixture::Prover prover(prover_instance_1, verification_key);
205 typename TestFixture::Verifier verifier(vk_and_hash);
206 auto proof = prover.construct_proof();
207 bool result = verifier.verify_proof(proof).result;
208 EXPECT_TRUE(result);
209 }
210
211 { // Verification based on pkey 2 should fail
212 auto verification_key =
213 std::make_shared<typename TestFixture::VerificationKey>(prover_instance_2->get_precomputed());
214 auto vk_and_hash = std::make_shared<typename Flavor::VKAndHash>(verification_key);
215 typename TestFixture::Prover prover(prover_instance_2, verification_key);
216 typename TestFixture::Verifier verifier(vk_and_hash);
217 auto proof = prover.construct_proof();
218 bool result = verifier.verify_proof(proof).result;
219 EXPECT_FALSE(result);
220 }
221}
222
230TYPED_TEST(MegaHonkTests, DyadicSizeJumpsToProtectMaskingArea)
231{
232 using Flavor = TypeParam;
233 if constexpr (!Flavor::HasZK) {
234 GTEST_SKIP() << "Masking area only exists for ZK flavors";
235 } else {
236 using Builder = typename Flavor::CircuitBuilder;
238
239 // Determine the baseline dyadic size (with ECC ops + finalization overhead, no extra user gates)
240 Builder baseline_builder;
242 auto baseline_instance = std::make_shared<ProverInstance>(baseline_builder);
243 const size_t baseline_dyadic = baseline_instance->dyadic_size();
244
245 // Add gates one at a time until the dyadic size doubles
246 size_t prev_dyadic = 0;
247 size_t prev_final_active_idx = 0;
248 bool found_jump = false;
249 for (size_t num_extra_gates = 0; num_extra_gates <= baseline_dyadic; num_extra_gates++) {
252 if (num_extra_gates > 0) {
254 }
255 auto prover_instance = std::make_shared<ProverInstance>(builder);
256
257 const size_t dyadic_size = prover_instance->dyadic_size();
258 const size_t final_active_idx = prover_instance->get_final_active_wire_idx();
259 const size_t first_masked_row = dyadic_size - NUM_MASKED_ROWS;
260
261 // Invariant: lagrange_last must be strictly before the masking area
262 ASSERT_LT(final_active_idx, first_masked_row)
263 << "lagrange_last (at " << final_active_idx << ") overlaps masking area (starting at "
264 << first_masked_row << ") with num_extra_gates=" << num_extra_gates;
265
266 // Sufficient headroom for disabled rows
267 ASSERT_GE(dyadic_size - final_active_idx - 1, static_cast<size_t>(NUM_DISABLED_ROWS_IN_SUMCHECK));
268
269 if (prev_dyadic != 0 && dyadic_size > prev_dyadic) {
270 EXPECT_EQ(dyadic_size, 2 * prev_dyadic);
271 EXPECT_LE(prev_dyadic - prev_final_active_idx - 1,
272 2 * static_cast<size_t>(NUM_DISABLED_ROWS_IN_SUMCHECK));
273
274 // Prove and verify at the tightest packing (right before the jump)
275 Builder tight_builder;
277 MockCircuits::add_arithmetic_gates(tight_builder, num_extra_gates - 1);
278 auto tight_instance = std::make_shared<ProverInstance>(tight_builder);
279 bool verified = this->construct_and_verify_honk_proof(tight_builder);
280 EXPECT_TRUE(verified);
281
282 found_jump = true;
283 break;
284 }
285
286 prev_dyadic = dyadic_size;
287 prev_final_active_idx = final_active_idx;
288 }
289
290 EXPECT_TRUE(found_jump) << "should have found a dyadic size jump within " << baseline_dyadic << " extra gates";
291 }
292}
Curve::AffineElement Point
typename Flavor::VerificationKey VerificationKey
static void SetUpTestSuite()
bool construct_and_verify_honk_proof(auto &builder)
Construct and a verify a Honk proof.
CommitmentKey object over a pairing group 𝔾₁.
Manages the data that is propagated on the public inputs of an application/function circuit.
static constexpr size_t PUBLIC_INPUTS_SIZE
static void add_default(Builder &builder)
Add default IO values to a circuit builder (for native tests)
static constexpr bool HasZK
ECCVMCircuitBuilder CircuitBuilder
FixedVKAndHash_< PrecomputedEntities< Commitment >, BF, ECCVMHardcodedVKAndHash > VerificationKey
The verification key stores commitments to the precomputed polynomials used by the verifier.
static void construct_simple_circuit(MegaBuilder &builder)
Generate a simple test circuit with some ECC op gates and conventional arithmetic gates.
static void add_arithmetic_gates(Builder &builder, const size_t num_gates=4)
Add a specified number of arithmetic gates to the provided circuit.
Contains all the information required by a Honk prover to create a proof, constructed from a finalize...
static AllSubrelationFailures check_all(const auto &polynomials, const auto &params)
Check that the provided polynomials satisfy all relations for a given Flavor.
Output verify_proof(const Proof &proof)
Perform ultra verification.
The VerifierInstance encapsulates all the necessary information for a Honk Verifier to verify a proof...
typename Group::affine_element AffineElement
Definition bn254.hpp:22
bb::fr ScalarField
Definition bn254.hpp:18
Manages the data that is propagated on the public inputs of an application/function circuit.
AluTraceBuilder builder
Definition alu.test.cpp:124
testing::Types< UltraFlavor, UltraKeccakFlavor, MegaFlavor > FlavorTypes
auto & engine
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
Definition engine.cpp:217
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
std::vector< fr > HonkProof
Definition proof.hpp:15
TYPED_TEST_SUITE(CommitmentKeyTest, Curves)
TYPED_TEST(CommitmentKeyTest, CommitToZeroPoly)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
Full Honk proof layout (used by UltraVerifier).