@@ -103,11 +103,16 @@ std::pair<ClientIVC::PairingPoints, ClientIVC::TableCommitments> ClientIVC::
103103
104104 // Witness commitments and public inputs corresponding to the incoming instance
105105 WitnessCommitments witness_commitments;
106+ // The pairing points produced by the verification of the decider proof
107+ PairingPoints decider_pairing_points;
106108 std::vector<StdlibFF> public_inputs;
107109
108110 // Input commitments to be passed to the merge recursive verification
109111 MergeCommitments merge_commitments;
110112 merge_commitments.T_prev_commitments = T_prev_commitments;
113+ // The decider proof exists if the tail kernel has been accumulated
114+ bool is_hiding_kernel = !decider_proof.empty ();
115+
111116 switch (verifier_inputs.type ) {
112117 case QUEUE_TYPE::PG_TAIL:
113118 case QUEUE_TYPE::PG: {
@@ -154,17 +159,45 @@ std::pair<ClientIVC::PairingPoints, ClientIVC::TableCommitments> ClientIVC::
154159 }
155160 case QUEUE_TYPE::PG_FINAL: {
156161 BB_ASSERT_EQ (stdlib_verification_queue.size (), size_t (1 ));
162+ auto stdlib_proof = verifier_inputs.proof ;
163+ auto stdlib_vk_and_hash = verifier_inputs.honk_vk_and_hash ;
157164 // Note: reinstate this.
158165 // BB_ASSERT_EQ(num_circuits_accumulated,
159166 // num_circuits - 1,
160167 // "All circuits must be accumulated before constructing the hiding circuit.");
161168 // Complete the hiding circuit construction
162- auto [pairing_points, merged_table_commitments] =
163- complete_hiding_circuit_logic (verifier_inputs.proof , verifier_inputs.honk_vk_and_hash , circuit);
164- // Return early since the hiding circuit method performs merge and public inputs handling
165- // TODO(https://github.com/AztecProtocol/barretenberg/issues/1501): we should remove the code duplication for
166- // the consistency checks at some point
167- return { pairing_points, merged_table_commitments };
169+
170+ hide_op_queue_accumulation_result (circuit);
171+
172+ // Construct stdlib accumulator, decider vkey and folding proof
173+ auto stdlib_verifier_accumulator =
174+ std::make_shared<RecursiveDeciderVerificationKey>(&circuit, recursive_verifier_native_accum);
175+
176+ // Propagate the public inputs of the tail kernel by converting them to public inputs of the hiding circuit.
177+ auto num_public_inputs = static_cast <size_t >(honk_vk->num_public_inputs );
178+ num_public_inputs -= KernelIO::PUBLIC_INPUTS_SIZE; // exclude fixed kernel_io public inputs
179+ for (size_t i = 0 ; i < num_public_inputs; i++) {
180+ stdlib_proof[i].set_public ();
181+ }
182+
183+ // Perform recursive folding verification of the last folding proof
184+ FoldingRecursiveVerifier folding_verifier{
185+ &circuit, stdlib_verifier_accumulator, { stdlib_vk_and_hash }, accumulation_recursive_transcript
186+ };
187+ auto recursive_verifier_native_accum = folding_verifier.verify_folding_proof (verifier_inputs.proof );
188+ verification_queue.clear ();
189+
190+ // // Get the completed decider verification key corresponding to the tail kernel from the folding verifier
191+ public_inputs = folding_verifier.public_inputs ;
192+
193+ witness_commitments = folding_verifier.keys_to_fold [1 ]->witness_commitments ;
194+
195+ // Perform recursive decider verification
196+ DeciderRecursiveVerifier decider{ &circuit, recursive_verifier_native_accum };
197+ BB_ASSERT_EQ (decider_proof.empty (), false , " Decider proof is empty!" );
198+
199+ decider_pairing_points = decider.verify_proof (decider_proof);
200+ break ;
168201 }
169202 default : {
170203 throw_or_abort (" Invalid queue type! Only OINK, PG, PG_TAIL and PG_FINAL are supported" );
@@ -177,19 +210,22 @@ std::pair<ClientIVC::PairingPoints, ClientIVC::TableCommitments> ClientIVC::
177210 // Reconstruct the input from the previous kernel from its public inputs
178211 KernelIO kernel_input; // pairing points, databus return data commitments
179212 kernel_input.reconstruct_from_public (public_inputs);
180-
181213 nested_pairing_points = kernel_input.pairing_inputs ;
182- // T_prev is read by the public input of the previous kernel K_{i-1} at the beginning of the recursive
183- // verification of of the folding of K_{i-1} (kernel), A_{i,1} (app), .., A_{i, n} (app). This verification
184- // happens in K_{i}
185- merge_commitments.T_prev_commitments = kernel_input.ecc_op_tables ;
186-
187214 // Perform databus consistency checks
188215 kernel_input.kernel_return_data .assert_equal (witness_commitments.calldata );
189216 kernel_input.app_return_data .assert_equal (witness_commitments.secondary_calldata );
190217
218+ // T_prev is read by the public input of the previous kernel K_{i-1} at the beginning of the recursive
219+ // verification of of the folding of K_{i-1} (kernel), A_{i,1} (app), .., A_{i, n} (app). This verification
220+ // happens in K_{i}
221+ merge_commitments.T_prev_commitments = std::move (kernel_input.ecc_op_tables );
222+
191223 // Set the kernel return data commitment to be propagated via the public inputs
192- bus_depot.set_kernel_return_data_commitment (witness_commitments.return_data );
224+
225+ if (!is_hiding_kernel) {
226+ // The hiding kernel has no return data but uses the traditional public-inputs mechanism
227+ bus_depot.set_kernel_return_data_commitment (witness_commitments.return_data );
228+ }
193229 } else {
194230 // Reconstruct the input from the previous app from its public inputs
195231 AppIO app_input; // pairing points
@@ -208,6 +244,9 @@ std::pair<ClientIVC::PairingPoints, ClientIVC::TableCommitments> ClientIVC::
208244 goblin.recursively_verify_merge (circuit, merge_commitments, accumulation_recursive_transcript);
209245
210246 pairing_points.aggregate (nested_pairing_points);
247+ if (is_hiding_kernel) {
248+ pairing_points.aggregate (decider_pairing_points);
249+ }
211250
212251 return { pairing_points, merged_table_commitments };
213252}
@@ -423,68 +462,6 @@ void ClientIVC::hide_op_queue_accumulation_result(ClientCircuit& circuit)
423462 circuit.queue_ecc_eq ();
424463}
425464
426- std::pair<ClientIVC::PairingPoints, ClientIVC::TableCommitments> ClientIVC::complete_hiding_circuit_logic (
427- const StdlibProof& stdlib_proof,
428- const std::shared_ptr<RecursiveVKAndHash>& stdlib_vk_and_hash,
429- ClientCircuit& circuit)
430- {
431- using MergeCommitments = Goblin::MergeRecursiveVerifier::InputCommitments;
432- trace_usage_tracker.print ();
433-
434- // Shared transcript between PG and Merge
435- // TODO(https://github.com/AztecProtocol/barretenberg/issues/1453): Investigate whether Decider/PG/Merge need to
436- // share a transcript
437- std::shared_ptr<RecursiveTranscript> pg_merge_transcript = std::make_shared<RecursiveTranscript>();
438-
439- hide_op_queue_accumulation_result (circuit);
440-
441- // Construct stdlib accumulator, decider vkey and folding proof
442- auto stdlib_verifier_accumulator =
443- std::make_shared<RecursiveDeciderVerificationKey>(&circuit, recursive_verifier_native_accum);
444-
445- // Propagate the public inputs of the tail kernel by converting them to public inputs of the hiding circuit.
446- auto num_public_inputs = static_cast <size_t >(honk_vk->num_public_inputs );
447- num_public_inputs -= KernelIO::PUBLIC_INPUTS_SIZE; // exclude fixed kernel_io public inputs
448- for (size_t i = 0 ; i < num_public_inputs; i++) {
449- stdlib_proof[i].set_public ();
450- }
451-
452- // Perform recursive folding verification of the last folding proof
453- FoldingRecursiveVerifier folding_verifier{
454- &circuit, stdlib_verifier_accumulator, { stdlib_vk_and_hash }, pg_merge_transcript
455- };
456- auto recursive_verifier_native_accum = folding_verifier.verify_folding_proof (stdlib_proof);
457- verification_queue.clear ();
458-
459- // Get the completed decider verification key corresponding to the tail kernel from the folding verifier
460- const std::vector<StdlibFF>& public_inputs = folding_verifier.public_inputs ;
461- WitnessCommitments& witness_commitments = folding_verifier.keys_to_fold [1 ]->witness_commitments ;
462-
463- // Reconstruct the KernelIO from the public inputs of the tail kernel and perform databus consistency checks
464- KernelIO kernel_input; // pairing points, databus return data commitments
465- kernel_input.reconstruct_from_public (public_inputs);
466- kernel_input.kernel_return_data .assert_equal (witness_commitments.calldata );
467- kernel_input.app_return_data .assert_equal (witness_commitments.secondary_calldata );
468-
469- // Extract the commitments to the subtable corresponding to the incoming circuit
470- MergeCommitments merge_commitments;
471- merge_commitments.t_commitments = witness_commitments.get_ecc_op_wires ().get_copy ();
472- merge_commitments.T_prev_commitments = std::move (
473- kernel_input.ecc_op_tables ); // Commitment to the status of the op_queue before folding the tail kernel
474- // Perform recursive verification of the last merge proof
475- auto [points_accumulator, merged_table_commitments] =
476- goblin.recursively_verify_merge (circuit, merge_commitments, pg_merge_transcript);
477-
478- points_accumulator.aggregate (kernel_input.pairing_inputs );
479-
480- // Perform recursive decider verification
481- DeciderRecursiveVerifier decider{ &circuit, recursive_verifier_native_accum };
482- BB_ASSERT_EQ (!decider_proof.empty (), true , " Decider proof is empty!" );
483- PairingPoints decider_pairing_points = decider.verify_proof (decider_proof);
484- points_accumulator.aggregate (decider_pairing_points);
485- return { points_accumulator, merged_table_commitments };
486- }
487-
488465/* *
489466 * @brief Construct the proving key of the hiding circuit, from the hiding_circuit builder in the client_ivc class
490467 */
0 commit comments