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) {
164 kernel_io.pairing_inputs.P0() = Commitment::infinity();
165 kernel_io.pairing_inputs.P1() = Commitment::infinity();
166 EXPECT_TRUE(kernel_io.pairing_inputs.check());
170 kernel_io.output_hn_accum_hash +=
FF(1);
173 kernel_io.kernel_return_data = kernel_io.kernel_return_data + Commitment::one();
176 kernel_io.app_return_data = kernel_io.app_return_data + Commitment::one();
179 kernel_io.ecc_op_tables[0] = kernel_io.ecc_op_tables[0] + Commitment::one();
183 kernel_io.to_proof(kernel_entry.proof, num_public_inputs);
187 auto proof = ivc.prove();
188 EXPECT_FALSE(
verify_chonk(proof, ivc.get_hiding_kernel_vk_and_hash()));
205 const size_t NUM_APP_CIRCUITS = 2;
207 const size_t NUM_CIRCUITS = circuit_producer.total_num_circuits;
208 Chonk ivc{ NUM_CIRCUITS };
209 TestSettings settings{ .log2_num_gates = SMALL_LOG_2_NUM_GATES };
212 for (
size_t idx = 0; idx < NUM_CIRCUITS; ++idx) {
213 auto [circuit,
vk] = circuit_producer.create_next_circuit_and_vk(ivc, settings);
214 ivc.accumulate(circuit,
vk);
218 HidingKernelIOSerde tail_io;
219 for (
auto& it : std::ranges::reverse_view(ivc.verification_queue)) {
221 size_t num_public_inputs = it.honk_vk->num_public_inputs;
222 ASSERT_EQ(num_public_inputs, HidingKernelIOSerde::PUBLIC_INPUTS_SIZE)
223 <<
"Tail kernel should use HidingKernelIO format";
224 tail_io = HidingKernelIOSerde::from_proof(it.proof, num_public_inputs);
230 auto proof = ivc.prove();
231 auto vk_and_hash = ivc.get_hiding_kernel_vk_and_hash();
234 size_t hiding_kernel_pub_inputs = vk_and_hash->vk->num_public_inputs;
235 ASSERT_EQ(hiding_kernel_pub_inputs, HidingKernelIOSerde::PUBLIC_INPUTS_SIZE)
236 <<
"HidingKernel should use HidingKernelIO format";
237 HidingKernelIOSerde hiding_io = HidingKernelIOSerde::from_proof(proof.mega_proof, hiding_kernel_pub_inputs);
240 switch (field_to_test) {
242 EXPECT_EQ(tail_io.pairing_inputs.P0(), hiding_io.pairing_inputs.P0())
243 <<
"P0 mismatch: Tail has " << tail_io.pairing_inputs.P0() <<
" but HidingKernel has "
244 << hiding_io.pairing_inputs.P0();
245 EXPECT_EQ(tail_io.pairing_inputs.P1(), hiding_io.pairing_inputs.P1())
246 <<
"P1 mismatch: Tail has " << tail_io.pairing_inputs.P1() <<
" but HidingKernel has "
247 << hiding_io.pairing_inputs.P1();
250 EXPECT_EQ(tail_io.kernel_return_data, hiding_io.kernel_return_data)
251 <<
"kernel_return_data mismatch: Tail has " << tail_io.kernel_return_data <<
" but HidingKernel has "
252 << hiding_io.kernel_return_data;
255 for (
size_t i = 0; i < tail_io.ecc_op_tables.size(); ++i) {
256 EXPECT_EQ(tail_io.ecc_op_tables[i], hiding_io.ecc_op_tables[i])
257 <<
"M_tail[" << i <<
"] mismatch: Tail has " << tail_io.ecc_op_tables[i] <<
" but HidingKernel has "
258 << hiding_io.ecc_op_tables[i];
274 const size_t NUM_APP_CIRCUITS = 2;
278 auto [proof,
vk] = accumulate_and_prove_ivc(NUM_APP_CIRCUITS, {},
true);
279 EXPECT_TRUE(verify_chonk(proof,
vk));
285 accumulate_and_prove_ivc(NUM_APP_CIRCUITS, { .log2_num_gates = SMALL_LOG_2_NUM_GATES },
true);
286 EXPECT_TRUE(verify_chonk(proof,
vk));
298 const size_t NUM_APP_CIRCUITS = 2;
299 auto [proof,
vk] = accumulate_and_prove_ivc(NUM_APP_CIRCUITS);
301 EXPECT_TRUE(verify_chonk(proof,
vk));
315 const size_t NUM_APP_CIRCUITS = 2;
319 CircuitProducer circuit_producer(NUM_APP_CIRCUITS);
320 const size_t NUM_CIRCUITS = circuit_producer.total_num_circuits;
321 Chonk ivc{ NUM_CIRCUITS };
322 TestSettings settings{ .log2_num_gates = SMALL_LOG_2_NUM_GATES };
325 for (
size_t idx = 0; idx < NUM_CIRCUITS; ++idx) {
326 circuit_producer.construct_and_accumulate_next_circuit(ivc, settings);
328 auto proof = ivc.prove();
329 EXPECT_TRUE(verify_chonk(proof, ivc.get_hiding_kernel_vk_and_hash()));
334 CircuitProducer circuit_producer(NUM_APP_CIRCUITS);
335 const size_t NUM_CIRCUITS = circuit_producer.total_num_circuits;
336 Chonk ivc{ NUM_CIRCUITS };
338 size_t num_public_inputs = 0;
341 for (
size_t idx = 0; idx < NUM_CIRCUITS; ++idx) {
343 circuit_producer.create_next_circuit_and_vk(ivc, { .log2_num_gates = SMALL_LOG_2_NUM_GATES });
347 num_public_inputs = circuit.num_public_inputs();
351 EXPECT_EQ(ivc.verification_queue.size(), 2);
352 tamper_with_proof(ivc.verification_queue[0].proof,
356 auto proof = ivc.prove();
357 EXPECT_FALSE(verify_chonk(proof, ivc.get_hiding_kernel_vk_and_hash()));
362 CircuitProducer circuit_producer(NUM_APP_CIRCUITS);
363 const size_t NUM_CIRCUITS = circuit_producer.total_num_circuits;
364 Chonk ivc{ NUM_CIRCUITS };
367 for (
size_t idx = 0; idx < NUM_CIRCUITS; ++idx) {
369 circuit_producer.create_next_circuit_and_vk(ivc, { .log2_num_gates = SMALL_LOG_2_NUM_GATES });
373 EXPECT_EQ(ivc.verification_queue.size(), 2);
374 tamper_with_proof(ivc.verification_queue[1].proof,
375 circuit.num_public_inputs());
378 auto proof = ivc.prove();
379 EXPECT_FALSE(verify_chonk(proof, ivc.get_hiding_kernel_vk_and_hash()));
389 const TestSettings settings{ .log2_num_gates = SMALL_LOG_2_NUM_GATES };
391 auto [unused_1, vk_and_hash_1] = accumulate_and_prove_ivc(1, settings);
392 auto [unused_2, vk_and_hash_2] = accumulate_and_prove_ivc(3, settings);
395 EXPECT_EQ(*vk_and_hash_1->vk.get(), *vk_and_hash_2->vk.get());
405 const size_t NUM_APP_CIRCUITS = 1;
406 const size_t log2_num_gates_small = 5;
407 const size_t log2_num_gates_big = 18;
409 const TestSettings settings_1{ .log2_num_gates = log2_num_gates_small };
410 const TestSettings settings_2{ .log2_num_gates = log2_num_gates_big };
412 auto [unused_1, vk_and_hash_1] = accumulate_and_prove_ivc(NUM_APP_CIRCUITS, settings_1);
413 auto [unused_2, vk_and_hash_2] = accumulate_and_prove_ivc(NUM_APP_CIRCUITS, settings_2);
416 EXPECT_EQ(*vk_and_hash_1->vk.get(), *vk_and_hash_2->vk.get());
427 const size_t NUM_APP_CIRCUITS = 17;
431 EXPECT_TRUE(verified);
441 TestSettings settings{ .log2_num_gates = SMALL_LOG_2_NUM_GATES };
442 auto [proof,
vk] = accumulate_and_prove_ivc(1, settings);
445 const std::string filename =
"proof.msgpack";
446 proof.to_file_msgpack(filename);
449 EXPECT_TRUE(verify_chonk(proof_deserialized,
vk));
453 uint8_t*
buffer = proof.to_msgpack_heap_buffer();
454 auto uint8_buffer = from_buffer<std::vector<uint8_t>>(
buffer);
455 uint8_t
const* uint8_ptr = uint8_buffer.data();
458 EXPECT_TRUE(verify_chonk(proof_deserialized,
vk));
462 msgpack::sbuffer
buffer = proof.to_msgpack_buffer();
464 EXPECT_TRUE(verify_chonk(proof_deserialized,
vk));
466 std::vector<uint8_t> random_bytes(
buffer.size());
467 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 stores commitments to the precomputed (non-witness) polynomials used by the veri...
Base Native verification key class.
Contains all the information required by a Honk prover to create a proof, constructed from a finalize...
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
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)