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 @@ -24,7 +24,7 @@ class BoomerangGoblinRecursiveVerifierTests : public testing::Test {

using Commitment = MergeVerifier::Commitment;
using RecursiveCommitment = GoblinRecursiveVerifier::MergeVerifier::Commitment;
using MergeCommitments = GoblinRecursiveVerifier::MergeVerifier::WitnessCommitments;
using TableCommitments = GoblinRecursiveVerifier::MergeVerifier::TableCommitments;

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

Expand Down Expand Up @@ -83,15 +83,13 @@ TEST_F(BoomerangGoblinRecursiveVerifierTests, graph_description_basic)
Builder builder;

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

GoblinRecursiveVerifier verifier{ &builder, verifier_input };
GoblinRecursiveVerifierOutput output =
verifier.verify(proof, recursive_merge_commitments, recursive_merge_commitments.T_commitments);
GoblinRecursiveVerifierOutput output = verifier.verify(proof, recursive_t_commitments);
output.points_accumulator.set_public();
// Construct and verify a proof for the Goblin Recursive Verifier circuit
{
Expand Down
54 changes: 27 additions & 27 deletions barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,15 @@ void ClientIVC::instantiate_stdlib_verification_queue(
* @param merge_commitments Container for the commitments for the Merge recursive verification to be performed
* @param accumulation_recursive_transcript Transcript shared across recursive verification of the folding of
* K_{i-1} (kernel), A_{i,1} (app), .., A_{i, n} (app)
*
* @return Pair of PairingPoints for final verification and commitments to the merged tables as read from the proof by
* the Merge verifier
*/
ClientIVC::PairingPoints ClientIVC::perform_recursive_verification_and_databus_consistency_checks(
ClientCircuit& circuit,
const StdlibVerifierInputs& verifier_inputs,
MergeCommitments& merge_commitments,
const std::shared_ptr<RecursiveTranscript>& accumulation_recursive_transcript)
std::pair<ClientIVC::PairingPoints, ClientIVC::TableCommitments> ClientIVC::
perform_recursive_verification_and_databus_consistency_checks(
ClientCircuit& circuit,
const StdlibVerifierInputs& verifier_inputs,
const std::shared_ptr<RecursiveTranscript>& accumulation_recursive_transcript)
{
// Witness commitments and public inputs corresponding to the incoming instance
WitnessCommitments witness_commitments;
Expand Down Expand Up @@ -138,22 +141,22 @@ ClientIVC::PairingPoints ClientIVC::perform_recursive_verification_and_databus_c
}
case QUEUE_TYPE::PG_FINAL: {
// Constuct the hiding circuit
PairingPoints pairing_points =
auto [pairing_points, merged_table_commitments] =
complete_hiding_circuit_logic(verifier_inputs.proof, verifier_inputs.honk_vk_and_hash, circuit);
// Return early since the hiding circuit method performs merge and public inputs handling (fix this!)
return pairing_points;
return { pairing_points, merged_table_commitments };
}
default: {
throw_or_abort("Invalid queue type! Only OINK, PG and PG_FINAL are supported");
}
}

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

// Recursively verify the corresponding merge proof
PairingPoints pairing_points = goblin.recursively_verify_merge(
circuit, merge_commitments, merge_commitments.T_commitments, accumulation_recursive_transcript);
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

Expand Down Expand Up @@ -181,7 +184,7 @@ ClientIVC::PairingPoints ClientIVC::perform_recursive_verification_and_databus_c

pairing_points.aggregate(nested_pairing_points);

return pairing_points;
return { pairing_points, merged_table_commitments };
}

/**
Expand All @@ -199,9 +202,6 @@ void ClientIVC::complete_kernel_circuit_logic(ClientCircuit& circuit)
// .., A_{i, n} (app)
auto accumulation_recursive_transcript = std::make_shared<RecursiveTranscript>();

// Merge commitments to be used in the recursive verifications
MergeCommitments merge_commitments;

// Instantiate stdlib verifier inputs from their native counterparts
if (stdlib_verification_queue.empty()) {
instantiate_stdlib_verification_queue(circuit);
Expand All @@ -212,8 +212,8 @@ void ClientIVC::complete_kernel_circuit_logic(ClientCircuit& circuit)
PairingPoints points_accumulator;
while (!stdlib_verification_queue.empty()) {
const StdlibVerifierInputs& verifier_input = stdlib_verification_queue.front();
PairingPoints pairing_points = perform_recursive_verification_and_databus_consistency_checks(
circuit, verifier_input, merge_commitments, accumulation_recursive_transcript);
auto [pairing_points, merged_table_commitments] = perform_recursive_verification_and_databus_consistency_checks(
circuit, verifier_input, 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 Down Expand Up @@ -353,7 +353,7 @@ void ClientIVC::hide_op_queue_accumulation_result(ClientCircuit& circuit)
circuit.queue_ecc_eq();
}

ClientIVC::PairingPoints ClientIVC::complete_hiding_circuit_logic(
std::pair<ClientIVC::PairingPoints, ClientIVC::TableCommitments> ClientIVC::complete_hiding_circuit_logic(
const StdlibProof& stdlib_proof,
const std::shared_ptr<RecursiveVKAndHash>& stdlib_vk_and_hash,
ClientCircuit& circuit)
Expand Down Expand Up @@ -398,11 +398,10 @@ ClientIVC::PairingPoints ClientIVC::complete_hiding_circuit_logic(
kernel_input.app_return_data.assert_equal(witness_commitments.secondary_calldata);

// Extract the commitments to the subtable corresponding to the incoming circuit
MergeCommitments merge_commitments;
merge_commitments.set_t_commitments(witness_commitments.get_ecc_op_wires());
TableCommitments t_commitments = witness_commitments.get_ecc_op_wires().get_copy();
// Perform recursive verification of the last merge proof
PairingPoints points_accumulator = goblin.recursively_verify_merge(
circuit, merge_commitments, merge_commitments.T_commitments, pg_merge_transcript);
auto [points_accumulator, merged_table_commitments] =
goblin.recursively_verify_merge(circuit, t_commitments, pg_merge_transcript);

points_accumulator.aggregate(kernel_input.pairing_inputs);

Expand All @@ -411,7 +410,7 @@ ClientIVC::PairingPoints ClientIVC::complete_hiding_circuit_logic(
BB_ASSERT_EQ(!decider_proof.empty(), true, "Decider proof is empty!");
PairingPoints decider_pairing_points = decider.verify_proof(decider_proof);
points_accumulator.aggregate(decider_pairing_points);
return points_accumulator;
return { points_accumulator, merged_table_commitments };
}

/**
Expand All @@ -434,7 +433,8 @@ std::shared_ptr<ClientIVC::DeciderZKProvingKey> ClientIVC::construct_hiding_circ
std::make_shared<RecursiveVerificationKey>(&builder, verification_queue[0].honk_vk),
ClientIVC::RecursiveFlavor::FF::from_witness(&builder, verification_queue[0].honk_vk->hash()));

PairingPoints pairing_points = complete_hiding_circuit_logic(stdlib_proof, stdlib_vk_and_hash, builder);
auto [pairing_points, merged_table_commitments] =
complete_hiding_circuit_logic(stdlib_proof, stdlib_vk_and_hash, builder);
fold_output.accumulator = nullptr;

HidingKernelIO hiding_output{ pairing_points };
Expand Down Expand Up @@ -491,12 +491,12 @@ bool ClientIVC::verify(const Proof& proof, const VerificationKey& vk)
vinfo("Mega verified: ", mega_verified);

// Extract the commitments to the subtable corresponding to the incoming circuit
MergeVerifier::WitnessCommitments merge_commitments;
merge_commitments.set_t_commitments(verifier.verification_key->witness_commitments.get_ecc_op_wires());
MergeVerifier::TableCommitments t_commitments =
verifier.verification_key->witness_commitments.get_ecc_op_wires().get_copy();

// Goblin verification (final merge, eccvm, translator)
bool goblin_verified = Goblin::verify(
proof.goblin_proof, merge_commitments, merge_commitments.T_commitments, civc_verifier_transcript);
auto [goblin_verified, _merged_table_commitments] =

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Curious why the _ prefix here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Because in contrast to the other variables that I have set up with this same, this is a variable that is not going to be used, and I wanted to highlight that (but I can't use _ because it's used above. This is going to change in a following PR when the _ above will be used, so its name will change)

Goblin::verify(proof.goblin_proof, t_commitments, civc_verifier_transcript);
vinfo("Goblin verified: ", goblin_verified);

// TODO(https://github.com/AztecProtocol/barretenberg/issues/1396): State tracking in CIVC verifiers.
Expand Down
7 changes: 3 additions & 4 deletions barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class ClientIVC {
using WitnessCommitments = RecursiveFlavor::WitnessCommitments;

// Merge commitments
using MergeCommitments = stdlib::recursion::goblin::MergeRecursiveVerifier_<ClientCircuit>::WitnessCommitments;
using TableCommitments = std::array<RecursiveFlavor::Commitment, ClientCircuit::NUM_WIRES>;

/**
* @brief A full proof for the IVC scheme containing a Mega proof showing correctness of the hiding circuit (which
Expand Down Expand Up @@ -199,18 +199,17 @@ class ClientIVC {
void instantiate_stdlib_verification_queue(ClientCircuit& circuit,
const std::vector<std::shared_ptr<RecursiveVKAndHash>>& input_keys = {});

[[nodiscard("Pairing points should be accumulated")]] PairingPoints
[[nodiscard("Pairing points should be accumulated")]] std::pair<PairingPoints, TableCommitments>
perform_recursive_verification_and_databus_consistency_checks(
ClientCircuit& circuit,
const StdlibVerifierInputs& verifier_inputs,
MergeCommitments& merge_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)
void complete_kernel_circuit_logic(ClientCircuit& circuit);

// Complete the logic of the hiding circuit, which includes PG, decider and merge recursive verification
ClientIVC::PairingPoints complete_hiding_circuit_logic(
std::pair<PairingPoints, TableCommitments> complete_hiding_circuit_logic(
const StdlibProof& stdlib_proof,
const std::shared_ptr<RecursiveVKAndHash>& stdlib_vk_and_hash,
ClientCircuit& circuit);
Expand Down
15 changes: 15 additions & 0 deletions barretenberg/cpp/src/barretenberg/common/ref_array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,21 @@ template <typename T, std::size_t N> class RefArray {
#endif
}

/**
* @brief Get a copy of the underlying data. Use carefully, as it allocates new data for the data pointed to by the
* elements in the RefArray
*
*/
std::array<T, N> get_copy()
{
std::array<T, N> data;
for (size_t idx = 0; idx < N; idx++) {
data[idx] = *storage[idx];
}

return data;
}

/**
* @brief Nested iterator class for RefArray, based on indexing into the pointer array.
* Provides semantics similar to what would be expected if std::array<T&, N> was possible.
Expand Down
26 changes: 12 additions & 14 deletions barretenberg/cpp/src/barretenberg/goblin/goblin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,9 @@ GoblinProof Goblin::prove()
return goblin_proof;
}

Goblin::PairingPoints Goblin::recursively_verify_merge(
std::pair<Goblin::PairingPoints, Goblin::RecursiveTableCommitments> Goblin::recursively_verify_merge(
MegaBuilder& builder,
const RecursiveSubtableCommitments& subtable_commitments,
std::array<RecursiveCommitment, MegaFlavor::NUM_WIRES>& merged_table_commitment,
const RecursiveTableCommitments& t_commitments,
const std::shared_ptr<RecursiveTranscript>& transcript)
{
ASSERT(!merge_verification_queue.empty());
Expand All @@ -86,21 +85,19 @@ Goblin::PairingPoints Goblin::recursively_verify_merge(
const stdlib::Proof<MegaBuilder> stdlib_merge_proof(builder, merge_proof);

MergeRecursiveVerifier merge_verifier{ &builder, MergeSettings::PREPEND, transcript };
PairingPoints pairing_points =
merge_verifier.verify_proof(stdlib_merge_proof, subtable_commitments, merged_table_commitment);
auto [pairing_points, merged_table_commitments] = merge_verifier.verify_proof(stdlib_merge_proof, t_commitments);

merge_verification_queue.pop_front(); // remove the processed proof from the queue

return pairing_points;
return { pairing_points, merged_table_commitments };
}

bool Goblin::verify(const GoblinProof& proof,
const SubtableCommitments& subtable_commitments,
std::array<Commitment, MegaFlavor::NUM_WIRES>& merged_table_commitment,
const std::shared_ptr<Transcript>& transcript)
std::pair<bool, Goblin::TableCommitments> Goblin::verify(const GoblinProof& proof,
const TableCommitments& t_commitments,
const std::shared_ptr<Transcript>& transcript)
{
MergeVerifier merge_verifier(MergeSettings::PREPEND, transcript);
bool merge_verified = merge_verifier.verify_proof(proof.merge_proof, subtable_commitments, merged_table_commitment);
auto [merge_verified, merged_table_commitments] = merge_verifier.verify_proof(proof.merge_proof, t_commitments);

ECCVMVerifier eccvm_verifier(transcript);
bool eccvm_verified = eccvm_verifier.verify_proof(proof.eccvm_proof);
Expand All @@ -116,16 +113,17 @@ bool Goblin::verify(const GoblinProof& proof,
// Verify the consistency between the commitments to polynomials representing the op queue received by translator
// and final merge verifier
bool op_queue_consistency_verified =
translator_verifier.verify_consistency_with_final_merge(merged_table_commitment);
translator_verifier.verify_consistency_with_final_merge(merged_table_commitments);

vinfo("merge verified?: ", merge_verified);
vinfo("eccvm verified?: ", eccvm_verified);
vinfo("accumulator construction_verified?: ", accumulator_construction_verified);
vinfo("translation verified?: ", translation_verified);
vinfo("consistency verified?: ", op_queue_consistency_verified);

return merge_verified && eccvm_verified && accumulator_construction_verified && translation_verified &&
op_queue_consistency_verified;
return { merge_verified && eccvm_verified && accumulator_construction_verified && translation_verified &&
op_queue_consistency_verified,
merged_table_commitments };
}

} // namespace bb
23 changes: 10 additions & 13 deletions barretenberg/cpp/src/barretenberg/goblin/goblin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ class Goblin {
using TranslatorVerificationKey = TranslatorFlavor::VerificationKey;
using MergeRecursiveVerifier = stdlib::recursion::goblin::MergeRecursiveVerifier_<MegaBuilder>;
using PairingPoints = MergeRecursiveVerifier::PairingPoints;
using SubtableCommitments = MergeVerifier::SubtableWitnessCommitments;
using RecursiveSubtableCommitments = MergeRecursiveVerifier::SubtableWitnessCommitments;
using TableCommitments = MergeVerifier::TableCommitments;
using RecursiveTableCommitments = MergeRecursiveVerifier::TableCommitments;
using RecursiveCommitment = MergeRecursiveVerifier::Commitment;
using RecursiveTranscript = bb::BaseTranscript<bb::stdlib::recursion::honk::StdlibTranscriptParams<MegaBuilder>>;

Expand Down Expand Up @@ -96,14 +96,12 @@ class Goblin {
* @param builder The circuit in which the recursive verification will be performed.
* @param subtable_commitments The subtable commitments data, containing the commitments to t_j read from the
* transcript by the PG verifier with which the Merge verifier shares a transcript
* @param merged_table_commitment The commitment to the merged table as read from the proof
* @param transcript The transcript to be passed to the MergeRecursiveVerifier.
* @return PairingPoints
* @return Pair of PairingPoints and commitments to the merged tables as read from the proof by the Merge verifier
*/
PairingPoints recursively_verify_merge(
std::pair<PairingPoints, RecursiveTableCommitments> recursively_verify_merge(
MegaBuilder& builder,
const RecursiveSubtableCommitments& subtable_commitments,
std::array<RecursiveCommitment, MegaFlavor::NUM_WIRES>& merged_table_commitment,
const RecursiveTableCommitments& t_commitments,
const std::shared_ptr<RecursiveTranscript>& transcript);

/**
Expand All @@ -115,13 +113,12 @@ class Goblin {
* @param merged_table_commitment The commitment to the merged table as read from the proof
* @param transcript
*
* @return true
* @return false
* @return Pair of verification result and commitments to the merged tables as read from the proof by the Merge
* verifier
*/
static bool verify(const GoblinProof& proof,
const SubtableCommitments& subtable_commitments,
std::array<Commitment, MegaFlavor::NUM_WIRES>& merged_table_commitment,
const std::shared_ptr<Transcript>& transcript);
static std::pair<bool, TableCommitments> verify(const GoblinProof& proof,
const TableCommitments& t_commitments,
const std::shared_ptr<Transcript>& transcript);
};

} // namespace bb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace bb::stdlib::recursion::honk {
*/
ClientIVCRecursiveVerifier::Output ClientIVCRecursiveVerifier::verify(const StdlibProof& proof)
{
using MergeCommitments = ClientIVCRecursiveVerifier::GoblinVerifier::MergeVerifier::WitnessCommitments;
using TableCommitments = GoblinVerifier::MergeVerifier::TableCommitments;
std::shared_ptr<Transcript> civc_rec_verifier_transcript(std::make_shared<Transcript>());
// Construct stdlib Mega verification key
auto stdlib_mega_vk_and_hash = std::make_shared<RecursiveVKAndHash>(*builder, ivc_verification_key.mega);
Expand All @@ -27,11 +27,9 @@ ClientIVCRecursiveVerifier::Output ClientIVCRecursiveVerifier::verify(const Stdl

// Perform Goblin recursive verification
GoblinVerificationKey goblin_verification_key{};
MergeCommitments merge_commitments;
merge_commitments.set_t_commitments(verifier.key->witness_commitments.get_ecc_op_wires());
TableCommitments t_commitments = verifier.key->witness_commitments.get_ecc_op_wires().get_copy();
GoblinVerifier goblin_verifier{ builder.get(), goblin_verification_key, civc_rec_verifier_transcript };
GoblinRecursiveVerifierOutput output =
goblin_verifier.verify(proof.goblin_proof, merge_commitments, merge_commitments.T_commitments);
GoblinRecursiveVerifierOutput output = goblin_verifier.verify(proof.goblin_proof, t_commitments);
output.points_accumulator.aggregate(mega_output.points_accumulator);
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1396): State tracking in CIVC verifiers
return { output };
Expand Down
Loading
Loading