17#include "gtest/gtest.h"
21static constexpr size_t SMALL_LOG_2_NUM_GATES = 5;
48 Commitment commitment = FrCodec::deserialize_from_fields<Commitment>(
49 std::span{ proof }.subspan(public_inputs_offset, FrCodec::template calc_num_fields<Commitment>()));
50 commitment = commitment + Commitment::one();
51 auto commitment_frs = FrCodec::serialize_to_fields<Commitment>(commitment);
52 for (
size_t idx = 0; idx < 4; ++idx) {
53 proof[public_inputs_offset + idx] = commitment_frs[idx];
58 size_t num_app_circuits,
TestSettings settings = {},
bool check_circuit_sizes =
false)
61 const size_t num_circuits = circuit_producer.total_num_circuits;
62 Chonk ivc{ num_circuits };
64 for (
size_t j = 0; j < num_circuits; ++j) {
65 circuit_producer.construct_and_accumulate_next_circuit(ivc, settings, check_circuit_sizes);
67 return { ivc.
prove(), ivc.get_hiding_kernel_vk_and_hash() };
73 return verifier.
verify(proof);
95 const size_t NUM_APP_CIRCUITS = 2;
97 const size_t NUM_CIRCUITS = circuit_producer.total_num_circuits;
98 Chonk ivc{ NUM_CIRCUITS };
99 TestSettings settings{ .log2_num_gates = SMALL_LOG_2_NUM_GATES };
101 for (
size_t idx = 0; idx < NUM_CIRCUITS; ++idx) {
102 auto [circuit,
vk] = circuit_producer.create_next_circuit_and_vk(ivc, settings);
103 ivc.accumulate(circuit,
vk);
107 EXPECT_EQ(ivc.verification_queue.size(), 2);
109 auto& app_entry = ivc.verification_queue[1];
110 ASSERT_FALSE(app_entry.is_kernel) <<
"Expected second queue entry to be an app";
113 size_t num_public_inputs = app_entry.honk_vk->num_public_inputs;
114 AppIOSerde app_io = AppIOSerde::from_proof(app_entry.proof, num_public_inputs);
117 app_io.pairing_inputs.P0 = app_io.pairing_inputs.P0 + app_io.pairing_inputs.P0;
118 app_io.pairing_inputs.P1 = app_io.pairing_inputs.P1 + app_io.pairing_inputs.P1;
120 EXPECT_TRUE(app_io.pairing_inputs.check());
122 app_io.to_proof(app_entry.proof, num_public_inputs);
126 auto proof = ivc.prove();
127 EXPECT_FALSE(
verify_chonk(proof, ivc.get_hiding_kernel_vk_and_hash()));
139 const size_t NUM_APP_CIRCUITS = 2;
141 const size_t NUM_CIRCUITS = circuit_producer.total_num_circuits;
142 Chonk ivc{ NUM_CIRCUITS };
143 TestSettings settings{ .log2_num_gates = SMALL_LOG_2_NUM_GATES };
145 for (
size_t idx = 0; idx < NUM_CIRCUITS; ++idx) {
146 auto [circuit,
vk] = circuit_producer.create_next_circuit_and_vk(ivc, settings);
147 ivc.accumulate(circuit,
vk);
151 EXPECT_EQ(ivc.verification_queue.size(), 2);
153 auto& kernel_entry = ivc.verification_queue[0];
154 ASSERT_TRUE(kernel_entry.is_kernel) <<
"Expected first queue entry to be a kernel";
157 size_t num_public_inputs = kernel_entry.honk_vk->num_public_inputs;
158 KernelIOSerde kernel_io = KernelIOSerde::from_proof(kernel_entry.proof, num_public_inputs);
161 switch (field_to_tamper) {
165 kernel_io.pairing_inputs.P0 =
Commitment(DEFAULT_PAIRING_POINTS_P0_X, DEFAULT_PAIRING_POINTS_P0_Y);
166 kernel_io.pairing_inputs.P1 =
Commitment(DEFAULT_PAIRING_POINTS_P1_X, DEFAULT_PAIRING_POINTS_P1_Y);
167 EXPECT_TRUE(kernel_io.pairing_inputs.check());
171 kernel_io.output_hn_accum_hash +=
FF(1);
174 kernel_io.kernel_return_data = kernel_io.kernel_return_data + Commitment::one();
177 kernel_io.app_return_data = kernel_io.app_return_data + Commitment::one();
180 kernel_io.ecc_op_tables[0] = kernel_io.ecc_op_tables[0] + Commitment::one();
184 kernel_io.to_proof(kernel_entry.proof, num_public_inputs);
188 auto proof = ivc.prove();
189 EXPECT_FALSE(
verify_chonk(proof, ivc.get_hiding_kernel_vk_and_hash()));
206 const size_t NUM_APP_CIRCUITS = 2;
208 const size_t NUM_CIRCUITS = circuit_producer.total_num_circuits;
209 Chonk ivc{ NUM_CIRCUITS };
210 TestSettings settings{ .log2_num_gates = SMALL_LOG_2_NUM_GATES };
213 for (
size_t idx = 0; idx < NUM_CIRCUITS; ++idx) {
214 auto [circuit,
vk] = circuit_producer.create_next_circuit_and_vk(ivc, settings);
215 ivc.accumulate(circuit,
vk);
219 HidingKernelIOSerde tail_io;
220 for (
auto& it : std::ranges::reverse_view(ivc.verification_queue)) {
222 size_t num_public_inputs = it.honk_vk->num_public_inputs;
223 ASSERT_EQ(num_public_inputs, HidingKernelIOSerde::PUBLIC_INPUTS_SIZE)
224 <<
"Tail kernel should use HidingKernelIO format";
225 tail_io = HidingKernelIOSerde::from_proof(it.proof, num_public_inputs);
231 auto proof = ivc.prove();
232 auto vk_and_hash = ivc.get_hiding_kernel_vk_and_hash();
235 size_t hiding_kernel_pub_inputs = vk_and_hash->vk->num_public_inputs;
236 ASSERT_EQ(hiding_kernel_pub_inputs, HidingKernelIOSerde::PUBLIC_INPUTS_SIZE)
237 <<
"HidingKernel should use HidingKernelIO format";
238 HidingKernelIOSerde hiding_io = HidingKernelIOSerde::from_proof(proof.mega_proof, hiding_kernel_pub_inputs);
241 switch (field_to_test) {
243 EXPECT_EQ(tail_io.pairing_inputs.P0, hiding_io.pairing_inputs.P0)
244 <<
"P0 mismatch: Tail has " << tail_io.pairing_inputs.P0 <<
" but HidingKernel has "
245 << hiding_io.pairing_inputs.P0;
246 EXPECT_EQ(tail_io.pairing_inputs.P1, hiding_io.pairing_inputs.P1)
247 <<
"P1 mismatch: Tail has " << tail_io.pairing_inputs.P1 <<
" but HidingKernel has "
248 << hiding_io.pairing_inputs.P1;
251 EXPECT_EQ(tail_io.kernel_return_data, hiding_io.kernel_return_data)
252 <<
"kernel_return_data mismatch: Tail has " << tail_io.kernel_return_data <<
" but HidingKernel has "
253 << hiding_io.kernel_return_data;
256 for (
size_t i = 0; i < tail_io.ecc_op_tables.size(); ++i) {
257 EXPECT_EQ(tail_io.ecc_op_tables[i], hiding_io.ecc_op_tables[i])
258 <<
"M_tail[" << i <<
"] mismatch: Tail has " << tail_io.ecc_op_tables[i] <<
" but HidingKernel has "
259 << hiding_io.ecc_op_tables[i];
275 const size_t NUM_APP_CIRCUITS = 2;
279 auto [proof,
vk] = accumulate_and_prove_ivc(NUM_APP_CIRCUITS, {},
true);
280 EXPECT_TRUE(verify_chonk(proof,
vk));
286 accumulate_and_prove_ivc(NUM_APP_CIRCUITS, { .log2_num_gates = SMALL_LOG_2_NUM_GATES },
true);
287 EXPECT_TRUE(verify_chonk(proof,
vk));
299 const size_t NUM_APP_CIRCUITS = 2;
300 auto [proof,
vk] = accumulate_and_prove_ivc(NUM_APP_CIRCUITS);
302 EXPECT_TRUE(verify_chonk(proof,
vk));
316 const size_t NUM_APP_CIRCUITS = 2;
320 CircuitProducer circuit_producer(NUM_APP_CIRCUITS);
321 const size_t NUM_CIRCUITS = circuit_producer.total_num_circuits;
322 Chonk ivc{ NUM_CIRCUITS };
323 TestSettings settings{ .log2_num_gates = SMALL_LOG_2_NUM_GATES };
326 for (
size_t idx = 0; idx < NUM_CIRCUITS; ++idx) {
327 circuit_producer.construct_and_accumulate_next_circuit(ivc, settings);
329 auto proof = ivc.prove();
330 EXPECT_TRUE(verify_chonk(proof, ivc.get_hiding_kernel_vk_and_hash()));
335 CircuitProducer circuit_producer(NUM_APP_CIRCUITS);
336 const size_t NUM_CIRCUITS = circuit_producer.total_num_circuits;
337 Chonk ivc{ NUM_CIRCUITS };
339 size_t num_public_inputs = 0;
342 for (
size_t idx = 0; idx < NUM_CIRCUITS; ++idx) {
344 circuit_producer.create_next_circuit_and_vk(ivc, { .log2_num_gates = SMALL_LOG_2_NUM_GATES });
348 num_public_inputs = circuit.num_public_inputs();
352 EXPECT_EQ(ivc.verification_queue.size(), 2);
357 auto proof = ivc.prove();
358 EXPECT_FALSE(verify_chonk(proof, ivc.get_hiding_kernel_vk_and_hash()));
363 CircuitProducer circuit_producer(NUM_APP_CIRCUITS);
364 const size_t NUM_CIRCUITS = circuit_producer.total_num_circuits;
365 Chonk ivc{ NUM_CIRCUITS };
368 for (
size_t idx = 0; idx < NUM_CIRCUITS; ++idx) {
370 circuit_producer.create_next_circuit_and_vk(ivc, { .log2_num_gates = SMALL_LOG_2_NUM_GATES });
374 EXPECT_EQ(ivc.verification_queue.size(), 2);
376 circuit.num_public_inputs());
379 auto proof = ivc.prove();
380 EXPECT_FALSE(verify_chonk(proof, ivc.get_hiding_kernel_vk_and_hash()));
390 const TestSettings settings{ .log2_num_gates = SMALL_LOG_2_NUM_GATES };
392 auto [unused_1, vk_and_hash_1] = accumulate_and_prove_ivc(1, settings);
393 auto [unused_2, vk_and_hash_2] = accumulate_and_prove_ivc(3, settings);
396 EXPECT_EQ(*vk_and_hash_1->vk.get(), *vk_and_hash_2->vk.get());
406 const size_t NUM_APP_CIRCUITS = 1;
407 const size_t log2_num_gates_small = 5;
408 const size_t log2_num_gates_big = 18;
410 const TestSettings settings_1{ .log2_num_gates = log2_num_gates_small };
411 const TestSettings settings_2{ .log2_num_gates = log2_num_gates_big };
413 auto [unused_1, vk_and_hash_1] = accumulate_and_prove_ivc(NUM_APP_CIRCUITS, settings_1);
414 auto [unused_2, vk_and_hash_2] = accumulate_and_prove_ivc(NUM_APP_CIRCUITS, settings_2);
417 EXPECT_EQ(*vk_and_hash_1->vk.get(), *vk_and_hash_2->vk.get());
428 const size_t NUM_APP_CIRCUITS = 17;
432 EXPECT_TRUE(verified);
442 TestSettings settings{ .log2_num_gates = SMALL_LOG_2_NUM_GATES };
443 auto [proof,
vk] = accumulate_and_prove_ivc(1, settings);
446 const std::string filename =
"proof.msgpack";
447 proof.to_file_msgpack(filename);
450 EXPECT_TRUE(verify_chonk(proof_deserialized,
vk));
454 uint8_t*
buffer = proof.to_msgpack_heap_buffer();
455 auto uint8_buffer = from_buffer<std::vector<uint8_t>>(
buffer);
456 uint8_t
const* uint8_ptr = uint8_buffer.data();
459 EXPECT_TRUE(verify_chonk(proof_deserialized,
vk));
463 msgpack::sbuffer
buffer = proof.to_msgpack_buffer();
465 EXPECT_TRUE(verify_chonk(proof_deserialized,
vk));
467 std::vector<uint8_t> random_bytes(
buffer.size());
468 std::generate(random_bytes.begin(), random_bytes.end(), []() { return static_cast<uint8_t>(rand() % 256); });
#define BB_DISABLE_ASSERTS()
TEST_F(ChonkTests, TestCircuitSizes)
Test sizes of the circuits generated by MockCircuitProducer.
PrivateFunctionExecutionMockCircuitProducer CircuitProducer
static void test_hiding_kernel_io_propagation(HidingKernelIOField field_to_test)
Helper function to test HidingKernelIO field propagation consistency.
static bool verify_chonk(const ChonkProof &proof, const std::shared_ptr< MegaZKFlavor::VKAndHash > &vk_and_hash)
static void tamper_with_proof(HonkProof &proof, size_t public_inputs_offset)
Tamper with a proof.
HidingKernelIOField
Enum for specifying which HidingKernelIO field to test for propagation consistency.
Flavor::Commitment Commitment
static void test_kernel_io_tampering(KernelIOField field_to_tamper)
Helper function to test tampering with KernelIO fields.
static void SetUpTestSuite()
static std::pair< ChonkProof, std::shared_ptr< MegaZKFlavor::VKAndHash > > accumulate_and_prove_ivc(size_t num_app_circuits, TestSettings settings={}, bool check_circuit_sizes=false)
static void test_app_io_tampering()
Helper function to test tampering with AppIO pairing inputs.
KernelIOField
Enum for specifying which KernelIO field to tamper with in tests.
The IVC scheme used by the aztec client for private function execution.
HypernovaDeciderProver DeciderProver
ChonkProof prove()
Construct Chonk proof, which, if verified, fully establishes the correctness of RCG.
ProverInstance_< Flavor > ProverInstance
VerifierInstance_< Flavor > VerifierInstance
void accumulate(ClientCircuit &circuit, const std::shared_ptr< MegaVerificationKey > &precomputed_vk) override
Perform prover work for accumulation (e.g. HN folding, merge proving)
MegaCircuitBuilder ClientCircuit
Verifier for Chonk IVC proofs (both native and recursive).
Output verify(const Proof &proof)
Verify a Chonk proof.
HyperNova decider prover. Produces final opening proof for the accumulated claim.
Curve::AffineElement Commitment
NativeVerificationKey_< PrecomputedEntities< Commitment >, Codec, HashFunction, CommitmentKey > VerificationKey
The verification key is responsible for storing the commitments to the precomputed (non-witness) poly...
Base Native verification key class.
A ProverInstance is normally constructed from a finalized circuit and it contains all the information...
The VerifierInstance encapsulates all the necessary information for a Honk Verifier to verify a proof...
Native representation and serde for AppIO public inputs.
Native representation and serde for HidingKernelIO public inputs.
For test purposes only: Native representation and serde for KernelIO public inputs
uint8_t buffer[RANDOM_BUFFER_SIZE]
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
Entry point for Barretenberg command-line interface.
std::vector< fr > HonkProof
::testing::Types< BN254Settings, GrumpkinSettings > TestSettings
void tamper_with_proof(InnerProver &inner_prover, ProofType &inner_proof, TamperType type)
Test method that provides several ways to tamper with a proof. TODO(https://github....
ChonkVerifier< false > ChonkNativeVerifier
VerifierCommitmentKey< Curve > vk
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
static ChonkProof_ from_msgpack_buffer(uint8_t const *&buffer)
static ChonkProof_ from_file_msgpack(const std::string &filename)