Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
3 changes: 1 addition & 2 deletions barretenberg/barretenberg.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,7 @@
},
"cmake.configureArgs": [
"--preset clang16",
"-G Ninja",
"-g"

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.

This flag was preventing my CMakeTools from building... I guess removing it didn't give you problems?

"-G Ninja"
],
"cmake.useCMakePresets": "auto",
"editor.inlayHints.enabled": "offUnlessPressed",
Expand Down
1 change: 1 addition & 0 deletions barretenberg/cpp/scripts/bb-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ IMAGE_URI=$(calculate_image_uri $REPOSITORY)
retry docker pull $IMAGE_URI

TESTS=(
client_ivc_tests
commitment_schemes_tests
crypto_aes128_tests
crypto_blake2s_tests
Expand Down
1 change: 1 addition & 0 deletions barretenberg/cpp/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ else()
endif()

add_subdirectory(barretenberg/bb)
add_subdirectory(barretenberg/client_ivc)
add_subdirectory(barretenberg/commitment_schemes)
add_subdirectory(barretenberg/common)
add_subdirectory(barretenberg/crypto)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
barretenberg_module(client_ivc goblin)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// NB: This file is here so that goblin_objects will be created
94 changes: 94 additions & 0 deletions barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#pragma once

#include "barretenberg/eccvm/eccvm_composer.hpp"
#include "barretenberg/flavor/goblin_ultra.hpp"
#include "barretenberg/goblin/goblin.hpp"
#include "barretenberg/goblin/mock_circuits.hpp"
#include "barretenberg/proof_system/circuit_builder/eccvm/eccvm_circuit_builder.hpp"
#include "barretenberg/proof_system/circuit_builder/goblin_translator_circuit_builder.hpp"
#include "barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp"
#include "barretenberg/proof_system/instance_inspector.hpp"
#include "barretenberg/stdlib/recursion/honk/verifier/merge_recursive_verifier.hpp"
#include "barretenberg/translator_vm/goblin_translator_composer.hpp"
#include "barretenberg/ultra_honk/merge_prover.hpp"
#include "barretenberg/ultra_honk/merge_verifier.hpp"
#include "barretenberg/ultra_honk/ultra_composer.hpp"

namespace bb {

class ClientIVC {

struct Proof {
Goblin::Proof goblin_proof;
HonkProof decider_proof;
};

public:
using Flavor = GoblinUltraFlavor;
using FF = Flavor::FF;
using FoldProof = std::vector<FF>;
using Accumulator = std::shared_ptr<ProverInstance_<Flavor>>;
using ClientCircuit = GoblinUltraCircuitBuilder; // can only be GoblinUltra

private:
using FoldingOutput = FoldingResult<Flavor>;
using Instance = ProverInstance_<GoblinUltraFlavor>;
using Composer = GoblinUltraComposer;

public:
Goblin goblin;
Accumulator accumulator;

ClientIVC()
{
// TODO(https://github.com/AztecProtocol/barretenberg/issues/723):
GoblinMockCircuits::perform_op_queue_interactions_for_mock_first_circuit(goblin.op_queue);
Comment thread
ledwards2225 marked this conversation as resolved.
Outdated
}

private:
public:
void initialize(ClientCircuit& circuit)
{
goblin.merge(circuit);
Composer composer;
accumulator = composer.create_instance(circuit);
}

FoldProof accumulate(ClientCircuit& circuit)
{
goblin.merge(circuit);
Composer composer;
auto instance = composer.create_instance(circuit);
std::vector<std::shared_ptr<Instance>> instances{ accumulator, instance };
auto folding_prover = composer.create_folding_prover(instances);
FoldingOutput output = folding_prover.fold_instances();
accumulator = output.accumulator;
return output.folding_data;
}

Proof prove()
{
// Construct Goblin proof (merge, eccvm, translator)
auto goblin_proof = goblin.prove();

// Construct decider proof for final accumulator
Composer composer;
auto decider_prover = composer.create_decider_prover(accumulator);
auto decider_proof = decider_prover.construct_proof();
return { goblin_proof, decider_proof };
}

bool verify(Proof& proof)
{
// Goblin verification (merge, eccvm, translator)
bool goblin_verified = goblin.verify(proof.goblin_proof);

// Decider verification
Composer composer;
// NOTE: Use of member accumulator here will go away with removal of vkey from ProverInstance
auto decider_verifier = composer.create_decider_verifier(accumulator);
bool decision = decider_verifier.verify_proof(proof.decider_proof);
return decision && goblin_verified;
}
};
} // namespace bb
120 changes: 120 additions & 0 deletions barretenberg/cpp/src/barretenberg/client_ivc/ivc_folding.test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#include "barretenberg/client_ivc/client_ivc.hpp"

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.

Will you rename this file to client_ivc.test.cpp?

#include "barretenberg/goblin/goblin.hpp"
#include "barretenberg/goblin/mock_circuits.hpp"
#include "barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp"
#include "barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp"
#include "barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.hpp"
#include "barretenberg/ultra_honk/ultra_composer.hpp"

#include <gtest/gtest.h>
using namespace bb;

class ClientIVCTests : public ::testing::Test {
protected:
static void SetUpTestSuite()
{
srs::init_crs_factory("../srs_db/ignition");
srs::init_grumpkin_crs_factory("../srs_db/grumpkin");
}

using Flavor = ClientIVC::Flavor;
using FF = typename Flavor::FF;
using Builder = ClientIVC::ClientCircuit;
using Composer = GoblinUltraComposer;
using Accumulator = ClientIVC::Accumulator;
using FoldProof = ClientIVC::FoldProof;

using GURecursiveFlavor = GoblinUltraRecursiveFlavor_<Builder>;
using RecursiveVerifierInstances = ::bb::VerifierInstances_<GURecursiveFlavor, 2>;
using FoldingRecursiveVerifier =
bb::stdlib::recursion::honk::ProtoGalaxyRecursiveVerifier_<RecursiveVerifierInstances>;

/**
* @brief Construct mock circuit with arithmetic gates and goblin ops
* @details Currently default sized to 2^16 to match kernel. (Note: op gates will bump size to next power of 2)
*
*/
static Builder create_mock_circuit(ClientIVC& ivc, size_t num_gates = 1 << 15)
{
Builder circuit{ ivc.goblin.op_queue };
GoblinMockCircuits::construct_arithmetic_circuit(circuit, num_gates);
GoblinMockCircuits::construct_goblin_ecc_op_circuit(circuit);
return circuit;
}

/**
* @brief Construct mock kernel consisting of two recursive folding verifiers
*
* @param builder
* @param fctn_fold_proof
* @param kernel_fold_proof
*/
static void construct_mock_folding_kernel(Builder& builder,
FoldProof& fctn_fold_proof,
FoldProof& kernel_fold_proof)
{
FoldingRecursiveVerifier verifier_1{ &builder };
verifier_1.verify_folding_proof(fctn_fold_proof);

FoldingRecursiveVerifier verifier_2{ &builder };
verifier_2.verify_folding_proof(kernel_fold_proof);
}

/**
* @brief Perform native fold verification and run decider prover/verifier
*
*/
static void EXPECT_FOLDING_AND_DECIDING_VERIFIED(const Accumulator& accumulator, const FoldProof& fold_proof)
{
// Verify fold proof
Composer composer;
auto folding_verifier = composer.create_folding_verifier();
bool folding_verified = folding_verifier.verify_folding_proof(fold_proof);
EXPECT_TRUE(folding_verified);

// Run decider
auto decider_prover = composer.create_decider_prover(accumulator);
auto decider_verifier = composer.create_decider_verifier(accumulator);
auto decider_proof = decider_prover.construct_proof();
bool decision = decider_verifier.verify_proof(decider_proof);
EXPECT_TRUE(decision);
}
};

/**
* @brief A full Goblin test using PG that mimicks the basic aztec client architecture
*
*/
TEST_F(ClientIVCTests, Full)
{
ClientIVC ivc;

// Initialize IVC with function circuit
Builder function_circuit = create_mock_circuit(ivc);
ivc.initialize(function_circuit);

// Accumulate kernel circuit (first kernel mocked as simple circuit since no folding proofs yet)
Builder kernel_circuit = create_mock_circuit(ivc);
FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit);
EXPECT_FOLDING_AND_DECIDING_VERIFIED(ivc.accumulator, kernel_fold_proof);

size_t NUM_CIRCUITS = 1;
for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) {
// Accumulate function circuit
Builder function_circuit = create_mock_circuit(ivc);
FoldProof function_fold_proof = ivc.accumulate(function_circuit);
EXPECT_FOLDING_AND_DECIDING_VERIFIED(ivc.accumulator, function_fold_proof);

// Accumulate kernel circuit
Builder kernel_circuit{ ivc.goblin.op_queue };
construct_mock_folding_kernel(kernel_circuit, function_fold_proof, kernel_fold_proof);
FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit);
EXPECT_FOLDING_AND_DECIDING_VERIFIED(ivc.accumulator, kernel_fold_proof);
}

// Constuct four proofs: merge, eccvm, translator, decider
auto proof = ivc.prove();

// Verify all four proofs
EXPECT_TRUE(ivc.verify(proof));
}
25 changes: 25 additions & 0 deletions barretenberg/cpp/src/barretenberg/goblin/goblin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,31 @@ class Goblin {
return { ultra_proof, instance->verification_key };
};

/** WORKTODO
* @brief Similar to "accumulate" but only does merge-related stuff, no proving
* @details When this method is used, the "prover" functionality of the IVC scheme must be performed explicitly, but
* this method has to be called first so that the recursive merge verifier can be "appended" to the circuit being
* accumulated
*
* @param circuit_builder
*/
void merge(GoblinUltraCircuitBuilder& circuit_builder)
{
// Complete the circuit logic by recursively verifying previous merge proof if it exists
if (merge_proof_exists) {
RecursiveMergeVerifier merge_verifier{ &circuit_builder };
[[maybe_unused]] auto pairing_points = merge_verifier.verify_proof(merge_proof);
}

// Construct and store the merge proof to be recursively verified on the next call to accumulate
MergeProver merge_prover{ op_queue };
merge_proof = merge_prover.construct_proof();

if (!merge_proof_exists) {
merge_proof_exists = true;
}
};

/**
* @brief Construct an ECCVM proof and the translation polynomial evaluations
*
Expand Down
88 changes: 88 additions & 0 deletions barretenberg/cpp/src/barretenberg/goblin/goblin_folding.test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include "barretenberg/goblin/goblin.hpp"
#include "barretenberg/goblin/mock_circuits.hpp"
#include "barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp"
#include "barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp"
#include "barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.hpp"
#include "barretenberg/ultra_honk/ultra_composer.hpp"

#include <gtest/gtest.h>
using namespace bb;

class GoblinFoldingTests : public ::testing::Test {
protected:
static void SetUpTestSuite()
{
srs::init_crs_factory("../srs_db/ignition");
srs::init_grumpkin_crs_factory("../srs_db/grumpkin");
}

using Curve = curve::BN254;
using FF = Curve::ScalarField;
using Builder = GoblinUltraCircuitBuilder;
using Composer = GoblinUltraComposer;
using KernelInput = Goblin::AccumulationOutput;
using Instance = ProverInstance_<GoblinUltraFlavor>;
using FoldingOutput = FoldingResult<GoblinUltraFlavor>;
using FoldProof = HonkProof;

using GURecursiveFlavor = GoblinUltraRecursiveFlavor_<Builder>;
using RecursiveVerifierInstances = ::bb::VerifierInstances_<GURecursiveFlavor, 2>;
using FoldingRecursiveVerifier =
bb::stdlib::recursion::honk::ProtoGalaxyRecursiveVerifier_<RecursiveVerifierInstances>;

// Currently default sized to 2^16 to match kernel. (Note: op gates will bump size to next power of 2)
static void create_mock_function_circuit(Builder& builder, size_t num_gates = 1 << 15)
{
GoblinMockCircuits::construct_arithmetic_circuit(builder, num_gates);
GoblinMockCircuits::construct_goblin_ecc_op_circuit(builder);
}

static FoldingOutput construct_fold_proof_and_update_accumulator(std::shared_ptr<Instance>& accumulator,
Builder& circuit_to_fold)
{
Composer composer;
auto instance = composer.create_instance(circuit_to_fold);
std::vector<std::shared_ptr<Instance>> instances{ accumulator, instance };
auto folding_prover = composer.create_folding_prover(instances);
FoldingOutput output = folding_prover.fold_instances();
return output;
}

static bool decide_and_verify(std::shared_ptr<Instance>& accumulator)
{
Composer composer;
auto decider_prover = composer.create_decider_prover(accumulator);
auto decider_verifier = composer.create_decider_verifier(accumulator);
auto decider_proof = decider_prover.construct_proof();
auto verified = decider_verifier.verify_proof(decider_proof);
return verified;
}

static void construct_mock_folding_kernel(Builder& builder,
FoldProof& fctn_fold_proof,
FoldProof& kernel_fold_proof)
{
FoldingRecursiveVerifier verifier_1{ &builder };
verifier_1.verify_folding_proof(fctn_fold_proof);

FoldingRecursiveVerifier verifier_2{ &builder };
verifier_2.verify_folding_proof(kernel_fold_proof);
}

// DEBUG only: perform native fold verification and run decider prover/verifier
static void EXEPECT_FOLDING_AND_DECIDING_VERIFIED(FoldingOutput& folding_output)
{
// Verify fold proof
Composer composer;
auto folding_verifier = composer.create_folding_verifier();
bool folding_verified = folding_verifier.verify_folding_proof(folding_output.folding_data);
EXPECT_TRUE(folding_verified);

// Run decider
auto decider_prover = composer.create_decider_prover(folding_output.accumulator);
auto decider_verifier = composer.create_decider_verifier(folding_output.accumulator);
auto decider_proof = decider_prover.construct_proof();
bool decision = decider_verifier.verify_proof(decider_proof);
EXPECT_TRUE(decision);
}
};
Loading