Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,17 @@ class BoomerangGoblinRecursiveVerifierTests : public testing::Test {
using OuterDeciderProvingKey = DeciderProvingKey_<OuterFlavor>;

using Commitment = MergeVerifier::Commitment;
using TableCommitment = MergeVerifier::TableCommitments;
using RecursiveCommitment = GoblinRecursiveVerifier::MergeVerifier::Commitment;
using TableCommitments = GoblinRecursiveVerifier::MergeVerifier::TableCommitments;
using RecursiveTableCommitment = GoblinRecursiveVerifier::MergeVerifier::TableCommitments;

static void SetUpTestSuite() { bb::srs::init_file_crs_factory(bb::srs::bb_crs_path()); }

struct ProverOutput {
GoblinProof proof;
Goblin::VerificationKey verifier_input;
std::array<Commitment, MegaFlavor::NUM_WIRES> t_commitments;
TableCommitment t_commitments;
TableCommitment T_prev_commitments;
};

/**
Expand All @@ -58,17 +60,21 @@ class BoomerangGoblinRecursiveVerifierTests : public testing::Test {
GoblinMockCircuits::construct_simple_circuit(builder);
goblin_final.op_queue->merge();
// Subtable values and commitments - needed for (Recursive)MergeVerifier
std::array<Commitment, MegaFlavor::NUM_WIRES> t_commitments;
TableCommitment t_commitments;
TableCommitment T_prev_commitments;
auto t_current = goblin_final.op_queue->construct_current_ultra_ops_subtable_columns();
auto T_prev = goblin_final.op_queue->construct_previous_ultra_ops_table_columns();
CommitmentKey<curve::BN254> pcs_commitment_key(goblin_final.op_queue->get_ultra_ops_table_num_rows());
for (size_t idx = 0; idx < MegaFlavor::NUM_WIRES; idx++) {
t_commitments[idx] = pcs_commitment_key.commit(t_current[idx]);
T_prev_commitments[idx] = pcs_commitment_key.commit(T_prev[idx]);
}

// Output is a goblin proof plus ECCVM/Translator verification keys
return { goblin_final.prove(),
{ std::make_shared<ECCVMVK>(), std::make_shared<TranslatorVK>() },
t_commitments };
t_commitments,
T_prev_commitments };
}
};

Expand All @@ -78,18 +84,21 @@ class BoomerangGoblinRecursiveVerifierTests : public testing::Test {
*/
TEST_F(BoomerangGoblinRecursiveVerifierTests, graph_description_basic)
{
auto [proof, verifier_input, t_commitments] = create_goblin_prover_output();
auto [proof, verifier_input, t_commitments, T_prev_commitments] = create_goblin_prover_output();

Builder builder;

// Merge commitments
TableCommitments recursive_t_commitments;
RecursiveTableCommitment recursive_t_commitments;
RecursiveTableCommitment recursive_T_prev_commitments;
for (size_t idx = 0; idx < MegaFlavor::NUM_WIRES; idx++) {
recursive_t_commitments[idx] = RecursiveCommitment::from_witness(&builder, t_commitments[idx]);
recursive_T_prev_commitments[idx] = RecursiveCommitment::from_witness(&builder, T_prev_commitments[idx]);
}

GoblinRecursiveVerifier verifier{ &builder, verifier_input };
GoblinRecursiveVerifierOutput output = verifier.verify(proof, recursive_t_commitments);
GoblinRecursiveVerifierOutput output =
verifier.verify(proof, recursive_t_commitments, recursive_T_prev_commitments);
output.points_accumulator.set_public();
// Construct and verify a proof for the Goblin Recursive Verifier circuit
{
Expand Down
43 changes: 31 additions & 12 deletions barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,19 @@ std::pair<ClientIVC::PairingPoints, ClientIVC::TableCommitments> ClientIVC::
perform_recursive_verification_and_databus_consistency_checks(
ClientCircuit& circuit,
const StdlibVerifierInputs& verifier_inputs,
const TableCommitments& T_prev_commitments,
const std::shared_ptr<RecursiveTranscript>& accumulation_recursive_transcript)
{
// Witness commitments and public inputs corresponding to the incoming instance
WitnessCommitments witness_commitments;
std::vector<StdlibFF> public_inputs;

// Commitments to the previous status of the op_queue, to be finalized according to the recursive verification we
// are performing
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1492): Change Merge verifier API and improve the name
// of the following variable.
TableCommitments finalised_T_prev_commitments = T_prev_commitments;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finalised is quite a confusing name


switch (verifier_inputs.type) {
case QUEUE_TYPE::PG: {
// Construct stdlib verifier accumulator from the native counterpart computed on a previous round
Expand Down Expand Up @@ -138,6 +145,9 @@ std::pair<ClientIVC::PairingPoints, ClientIVC::TableCommitments> ClientIVC::
witness_commitments = std::move(verifier_accum->witness_commitments);
public_inputs = std::move(verifier.public_inputs);

// T_prev = 0 in the first recursive verification
finalised_T_prev_commitments = HidingKernelIO::empty_ecc_op_tables(circuit);

break;
}
case QUEUE_TYPE::PG_FINAL: {
Expand All @@ -152,20 +162,18 @@ std::pair<ClientIVC::PairingPoints, ClientIVC::TableCommitments> ClientIVC::
}
}

// Extract the commitments to the subtable corresponding to the incoming circuit
TableCommitments t_commitments = witness_commitments.get_ecc_op_wires().get_copy();

// Recursively verify the corresponding merge proof
auto [pairing_points, merged_table_commitments] =
goblin.recursively_verify_merge(circuit, t_commitments, accumulation_recursive_transcript);

PairingPoints nested_pairing_points; // to be extracted from public inputs of app or kernel proof just verified

if (verifier_inputs.is_kernel) {
// Reconstruct the input from the previous kernel from its public inputs
KernelIO kernel_input; // pairing points, databus return data commitments
kernel_input.reconstruct_from_public(public_inputs);

nested_pairing_points = kernel_input.pairing_inputs;
// T_prev is read by the public input of the previous kernel K_{i-1} at the beginning of the recursive
// verification of of the folding of K_{i-1} (kernel), A_{i,1} (app), .., A_{i, n} (app). This verification
// happens in K_{i}
finalised_T_prev_commitments = kernel_input.ecc_op_tables;

// Perform databus consistency checks
kernel_input.kernel_return_data.assert_equal(witness_commitments.calldata);
Expand All @@ -183,6 +191,13 @@ std::pair<ClientIVC::PairingPoints, ClientIVC::TableCommitments> ClientIVC::
bus_depot.set_app_return_data_commitment(witness_commitments.return_data);
}

// Extract the commitments to the subtable corresponding to the incoming circuit
TableCommitments t_commitments = witness_commitments.get_ecc_op_wires().get_copy();

// Recursively verify the corresponding merge proof
auto [pairing_points, merged_table_commitments] = goblin.recursively_verify_merge(
circuit, t_commitments, finalised_T_prev_commitments, accumulation_recursive_transcript);

pairing_points.aggregate(nested_pairing_points);

return { pairing_points, merged_table_commitments };
Expand Down Expand Up @@ -217,7 +232,7 @@ void ClientIVC::complete_kernel_circuit_logic(ClientCircuit& circuit)
while (!stdlib_verification_queue.empty()) {
const StdlibVerifierInputs& verifier_input = stdlib_verification_queue.front();
auto [pairing_points, merged_table_commitments] = perform_recursive_verification_and_databus_consistency_checks(
circuit, verifier_input, accumulation_recursive_transcript);
circuit, verifier_input, T_prev_commitments, accumulation_recursive_transcript);

// TODO(https://github.com/AztecProtocol/barretenberg/issues/1376): Optimize recursion aggregation - seems
// we can use `batch_mul` here to decrease the size of the `ECCOpQueue`, but must be cautious with FS security.
Expand All @@ -240,6 +255,7 @@ void ClientIVC::complete_kernel_circuit_logic(ClientCircuit& circuit)
kernel_output.pairing_inputs = points_accumulator;
kernel_output.kernel_return_data = bus_depot.get_kernel_return_data_commitment(circuit);
kernel_output.app_return_data = bus_depot.get_app_return_data_commitment(circuit);
kernel_output.ecc_op_tables = T_prev_commitments;

kernel_output.set_public();
}
Expand Down Expand Up @@ -407,8 +423,11 @@ std::pair<ClientIVC::PairingPoints, ClientIVC::TableCommitments> ClientIVC::comp
// Extract the commitments to the subtable corresponding to the incoming circuit
TableCommitments t_commitments = witness_commitments.get_ecc_op_wires().get_copy();
// Perform recursive verification of the last merge proof
auto [points_accumulator, merged_table_commitments] =
goblin.recursively_verify_merge(circuit, t_commitments, pg_merge_transcript);
auto [points_accumulator, merged_table_commitments] = goblin.recursively_verify_merge(
circuit,
t_commitments,
kernel_input.ecc_op_tables, // Commitment to the status of the op_queue before folding the tail kernel
pg_merge_transcript);

points_accumulator.aggregate(kernel_input.pairing_inputs);

Expand Down Expand Up @@ -502,8 +521,8 @@ bool ClientIVC::verify(const Proof& proof, const VerificationKey& vk)
verifier.verification_key->witness_commitments.get_ecc_op_wires().get_copy();

// Goblin verification (final merge, eccvm, translator)
auto [goblin_verified, _merged_table_commitments] =
Goblin::verify(proof.goblin_proof, t_commitments, civc_verifier_transcript);
bool goblin_verified =
Goblin::verify(proof.goblin_proof, t_commitments, T_prev_commitments, civc_verifier_transcript);
vinfo("Goblin verified: ", goblin_verified);

// TODO(https://github.com/AztecProtocol/barretenberg/issues/1396): State tracking in CIVC verifiers.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ class ClientIVC {
perform_recursive_verification_and_databus_consistency_checks(
ClientCircuit& circuit,
const StdlibVerifierInputs& verifier_inputs,
const TableCommitments& T_prev_commitments,
const std::shared_ptr<RecursiveTranscript>& accumulation_recursive_transcript);

// Complete the logic of a kernel circuit (e.g. PG/merge recursive verification, databus consistency checks)
Expand Down
2 changes: 1 addition & 1 deletion barretenberg/cpp/src/barretenberg/constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ static constexpr uint32_t NUM_LIBRA_COMMITMENTS = 3;
// extra evaluations
static constexpr uint32_t NUM_SMALL_IPA_EVALUATIONS = 4;

static constexpr uint32_t MERGE_PROOF_SIZE = 65; // used to ensure mock proofs are generated correctly
static constexpr uint32_t MERGE_PROOF_SIZE = 49; // used to ensure mock proofs are generated correctly

// There are 5 distinguished wires in ECCVM that have to be opened as univariates to establish the connection between
// ECCVM and Translator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,33 +99,49 @@ ClientIVC::VerifierInputs create_mock_verification_queue_entry(const ClientIVC::
{
using FF = ClientIVC::FF;
using MegaVerificationKey = ClientIVC::MegaVerificationKey;
using Flavor = ClientIVC::Flavor;

// Use the trace settings to determine the correct dyadic size and the public inputs offset
MegaExecutionTraceBlocks blocks;
blocks.set_fixed_block_sizes(trace_settings);
blocks.compute_offsets(/*is_structured=*/true);
size_t dyadic_size = blocks.get_structured_dyadic_size();
size_t pub_inputs_offset = blocks.pub_inputs.trace_offset();
// All circuits have pairing point public inputs; kernels have additional public inputs for two databus commitments
size_t num_public_inputs = bb::PAIRING_POINTS_SIZE;
if (is_kernel) {
num_public_inputs += bb::PROPAGATED_DATABUS_COMMITMENTS_SIZE;
}

// Construct a mock Oink or PG proof
// Construct a mock Oink or PG proof and a mock MegaHonk verification key
std::vector<FF> proof;
if (verification_type == ClientIVC::QUEUE_TYPE::OINK) {
proof = create_mock_oink_proof<ClientIVC::Flavor>(num_public_inputs);
} else if (verification_type == ClientIVC::QUEUE_TYPE::PG || verification_type == ClientIVC::QUEUE_TYPE::PG_FINAL) {
proof = create_mock_pg_proof<ClientIVC::Flavor>(num_public_inputs);
std::shared_ptr<MegaVerificationKey> verification_key;

if (is_kernel) {
Comment thread
federicobarbacovi marked this conversation as resolved.
using KernelIO = stdlib::recursion::honk::KernelIO;
switch (verification_type) {
case ClientIVC::QUEUE_TYPE::OINK:
proof = create_mock_oink_proof<Flavor, KernelIO>();
break;
case ClientIVC::QUEUE_TYPE::PG:
case ClientIVC::QUEUE_TYPE::PG_FINAL:
proof = create_mock_pg_proof<Flavor, KernelIO>();
break;
default:
throw_or_abort("Invalid verification type! Only OINK, PG and PG_FINAL are supported");
}
verification_key = create_mock_honk_vk<Flavor, KernelIO>(dyadic_size, pub_inputs_offset);
} else {
throw_or_abort("Invalid verification type! Only OINK, PG and PG_FINAL are supported");
using AppIO = stdlib::recursion::honk::AppIO;
switch (verification_type) {
case ClientIVC::QUEUE_TYPE::OINK:
proof = create_mock_oink_proof<Flavor, AppIO>();
break;
case ClientIVC::QUEUE_TYPE::PG:
case ClientIVC::QUEUE_TYPE::PG_FINAL:
proof = create_mock_pg_proof<Flavor, AppIO>();
break;
default:
throw_or_abort("Invalid verification type! Only OINK, PG and PG_FINAL are supported");
}
verification_key = create_mock_honk_vk<Flavor, AppIO>(dyadic_size, pub_inputs_offset);
}

// Construct a mock MegaHonk verification key
std::shared_ptr<MegaVerificationKey> verification_key =
create_mock_honk_vk<ClientIVC::Flavor>(dyadic_size, num_public_inputs, pub_inputs_offset);

return ClientIVC::VerifierInputs{ proof, verification_key, verification_type, is_kernel };
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -481,8 +481,6 @@ TEST_F(IvcRecursionConstraintTest, GenerateHidingKernelVKFromConstraints)
// construct a mock tail kernel
acir_format::mock_ivc_accumulation(ivc, ClientIVC::QUEUE_TYPE::PG_FINAL, /*is_kernel=*/true);
AcirProgram program = construct_mock_kernel_program(ivc->verification_queue);
// acir_format::mock_ivc_accumulation(ivc, ClientIVC::QUEUE_TYPE::PG_FINAL, /*is_kernel=*/true);
// program = construct_mock_kernel_program(ivc->verification_queue);
program.witness = {}; // remove the witness to mimick VK construction context

kernel_vk = construct_kernel_vk_from_acir_program(program, TraceSettings());
Expand Down
Loading
Loading