1111#include " barretenberg/serialize/msgpack_impl.hpp"
1212#include " barretenberg/special_public_inputs/special_public_inputs.hpp"
1313#include " barretenberg/ultra_honk/oink_prover.hpp"
14+ #include " barretenberg/ultra_honk/oink_verifier.hpp"
1415
1516namespace bb {
1617
@@ -112,7 +113,8 @@ std::pair<ClientIVC::PairingPoints, ClientIVC::TableCommitments> ClientIVC::
112113 case QUEUE_TYPE::PG_TAIL:
113114 case QUEUE_TYPE::PG: {
114115 // Construct stdlib verifier accumulator from the native counterpart computed on a previous round
115- auto stdlib_verifier_accum = std::make_shared<RecursiveDeciderVerificationKey>(&circuit, verifier_accumulator);
116+ auto stdlib_verifier_accum =
117+ std::make_shared<RecursiveDeciderVerificationKey>(&circuit, recursive_verifier_native_accum);
116118
117119 // Perform folding recursive verification to update the verifier accumulator
118120 FoldingRecursiveVerifier verifier{
@@ -121,7 +123,7 @@ std::pair<ClientIVC::PairingPoints, ClientIVC::TableCommitments> ClientIVC::
121123 auto verifier_accum = verifier.verify_folding_proof (verifier_inputs.proof );
122124
123125 // Extract native verifier accumulator from the stdlib accum for use on the next round
124- verifier_accumulator = std::make_shared<DeciderVerificationKey>(verifier_accum->get_value ());
126+ recursive_verifier_native_accum = std::make_shared<DeciderVerificationKey>(verifier_accum->get_value ());
125127
126128 witness_commitments = std::move (verifier.keys_to_fold [1 ]->witness_commitments );
127129 public_inputs = std::move (verifier.public_inputs );
@@ -140,9 +142,9 @@ std::pair<ClientIVC::PairingPoints, ClientIVC::TableCommitments> ClientIVC::
140142 verifier_accum->is_accumulator = true ; // indicate to PG that it should not run oink
141143
142144 // Extract native verifier accumulator from the stdlib accum for use on the next round
143- verifier_accumulator = std::make_shared<DeciderVerificationKey>(verifier_accum->get_value ());
145+ recursive_verifier_native_accum = std::make_shared<DeciderVerificationKey>(verifier_accum->get_value ());
144146 // Initialize the gate challenges to zero for use in first round of folding
145- verifier_accumulator ->gate_challenges = std::vector<FF>(CONST_PG_LOG_N, 0 );
147+ recursive_verifier_native_accum ->gate_challenges = std::vector<FF>(CONST_PG_LOG_N, 0 );
146148
147149 witness_commitments = std::move (verifier_accum->witness_commitments );
148150 public_inputs = std::move (verifier.public_inputs );
@@ -321,7 +323,7 @@ void ClientIVC::accumulate(ClientCircuit& circuit, const std::shared_ptr<MegaVer
321323 // Transcript to be shared across folding of K_{i} (kernel) (the current kernel), A_{i+1,1} (app), .., A_{i+1,
322324 // n} (app)
323325 if (is_kernel) {
324- accumulation_transcript = std::make_shared<Transcript>();
326+ prover_accumulation_transcript = std::make_shared<Transcript>();
325327 }
326328
327329 VerifierInputs queue_entry{ .honk_vk = honk_vk,
@@ -330,7 +332,9 @@ void ClientIVC::accumulate(ClientCircuit& circuit, const std::shared_ptr<MegaVer
330332 if (num_circuits_accumulated == 0 ) { // First circuit in the IVC
331333 BB_ASSERT_EQ (queue_entry.is_kernel , false , " First circuit accumulated is always be an app" );
332334 // For first circuit in the IVC, use oink to complete the decider proving key and generate an oink proof
333- MegaOinkProver oink_prover{ proving_key, honk_vk, accumulation_transcript };
335+ auto oink_verifier_transcript =
336+ Transcript::convert_prover_transcript_to_verifier_transcript (prover_accumulation_transcript);
337+ MegaOinkProver oink_prover{ proving_key, honk_vk, prover_accumulation_transcript };
334338 vinfo (" computing oink proof..." );
335339 oink_prover.prove ();
336340 HonkProof oink_proof = oink_prover.export_proof ();
@@ -341,17 +345,31 @@ void ClientIVC::accumulate(ClientCircuit& circuit, const std::shared_ptr<MegaVer
341345
342346 fold_output.accumulator = proving_key; // initialize the prover accum with the completed key
343347
348+ auto decider_vk = std::make_shared<DeciderVerificationKey>(honk_vk);
349+ oink_verifier_transcript->load_proof (oink_proof);
350+ OinkVerifier<Flavor> oink_verifier{ decider_vk, oink_verifier_transcript };
351+ oink_verifier.verify ();
352+ native_verifier_accum = decider_vk;
353+ native_verifier_accum->is_accumulator = true ;
354+ native_verifier_accum->gate_challenges = std::vector<FF>(CONST_PG_LOG_N, 0 );
355+
344356 queue_entry.type = QUEUE_TYPE::OINK;
345357 queue_entry.proof = oink_proof;
346358 } else { // Otherwise, fold the new key into the accumulator
347359 vinfo (" computing folding proof" );
348360 auto vk = std::make_shared<DeciderVerificationKey_<Flavor>>(honk_vk);
361+ // make a copy of the prover_accumulation_transcript for the verifier to use
362+ auto verifier_accumulation_transcript =
363+ Transcript::convert_prover_transcript_to_verifier_transcript (prover_accumulation_transcript);
364+
349365 FoldingProver folding_prover ({ fold_output.accumulator , proving_key },
350- { verifier_accumulator , vk },
351- accumulation_transcript ,
366+ { native_verifier_accum , vk },
367+ prover_accumulation_transcript ,
352368 trace_usage_tracker);
353369 fold_output = folding_prover.prove ();
354370 vinfo (" constructed folding proof" );
371+ FoldingVerifier folding_verifier ({ native_verifier_accum, vk }, verifier_accumulation_transcript);
372+ native_verifier_accum = folding_verifier.verify_folding_proof (fold_output.proof );
355373
356374 if (num_circuits_accumulated == num_circuits - 1 ) {
357375 // we are folding in the "Tail" kernel, so the verification_queue entry should have type PG_FINAL
@@ -369,7 +387,7 @@ void ClientIVC::accumulate(ClientCircuit& circuit, const std::shared_ptr<MegaVer
369387 verification_queue.push_back (queue_entry);
370388
371389 // Construct merge proof for the present circuit
372- goblin.prove_merge (accumulation_transcript );
390+ goblin.prove_merge (prover_accumulation_transcript );
373391
374392 num_circuits_accumulated++;
375393}
@@ -414,7 +432,7 @@ std::pair<ClientIVC::PairingPoints, ClientIVC::TableCommitments> ClientIVC::comp
414432
415433 // Construct stdlib accumulator, decider vkey and folding proof
416434 auto stdlib_verifier_accumulator =
417- std::make_shared<RecursiveDeciderVerificationKey>(&circuit, verifier_accumulator );
435+ std::make_shared<RecursiveDeciderVerificationKey>(&circuit, recursive_verifier_native_accum );
418436
419437 // Propagate the public inputs of the tail kernel by converting them to public inputs of the hiding circuit.
420438 auto num_public_inputs = static_cast <size_t >(honk_vk->num_public_inputs );
@@ -427,7 +445,7 @@ std::pair<ClientIVC::PairingPoints, ClientIVC::TableCommitments> ClientIVC::comp
427445 FoldingRecursiveVerifier folding_verifier{
428446 &circuit, stdlib_verifier_accumulator, { stdlib_vk_and_hash }, pg_merge_transcript
429447 };
430- auto recursive_verifier_accumulator = folding_verifier.verify_folding_proof (stdlib_proof);
448+ auto recursive_verifier_native_accum = folding_verifier.verify_folding_proof (stdlib_proof);
431449 verification_queue.clear ();
432450
433451 // Get the completed decider verification key corresponding to the tail kernel from the folding verifier
@@ -452,7 +470,7 @@ std::pair<ClientIVC::PairingPoints, ClientIVC::TableCommitments> ClientIVC::comp
452470 points_accumulator.aggregate (kernel_input.pairing_inputs );
453471
454472 // Perform recursive decider verification
455- DeciderRecursiveVerifier decider{ &circuit, recursive_verifier_accumulator };
473+ DeciderRecursiveVerifier decider{ &circuit, recursive_verifier_native_accum };
456474 BB_ASSERT_EQ (!decider_proof.empty (), true , " Decider proof is empty!" );
457475 PairingPoints decider_pairing_points = decider.verify_proof (decider_proof);
458476 points_accumulator.aggregate (decider_pairing_points);
0 commit comments