Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Quick and dirty relation skipping #4755

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
eebe885
moved to new branch
maramihali Feb 16, 2024
30f9b9e
works
maramihali Feb 16, 2024
bbaacad
aaaaaaaaaaaaa
maramihali Feb 16, 2024
b5b77f4
bench work
maramihali Feb 16, 2024
7e09c8b
cleaning up
maramihali Feb 19, 2024
2188c57
Merge branch 'master' into mm/pg-refactor-new
maramihali Feb 19, 2024
ffaddfc
cleanup
maramihali Feb 19, 2024
ec36ede
more cleanup
maramihali Feb 20, 2024
f97dd1e
more cleanup
maramihali Feb 20, 2024
f1934c1
Merge branch 'mm/pg-refactor-new' of github.com:AztecProtocol/aztec-p…
maramihali Feb 20, 2024
5a75ea3
Merge branch 'master' into mm/pg-refactor-new
maramihali Feb 20, 2024
c587218
typos + make gcc pass
maramihali Feb 20, 2024
cb57dad
stuff
maramihali Feb 20, 2024
58b61b8
Merge branch 'master' into mm/pg-refactor-new
maramihali Feb 21, 2024
f1f7127
make sure we fold as many function circuits as expected, not one more
maramihali Feb 22, 2024
a89ebd0
Merge branch 'master' into mm/pg-refactor-new
maramihali Feb 22, 2024
0388795
additional op count timing
ludamad Feb 22, 2024
02bc325
Merge branch 'master' into mm/pg-refactor-new
maramihali Feb 22, 2024
0e78233
Merge branch 'feat/op-count-time-ivc-bench' into mm/pg-refactor-new
ludamad Feb 22, 2024
8b52cc0
Merge remote-tracking branch 'origin/mm/pg-refactor-new' into mm/pg-r…
ludamad Feb 22, 2024
f6378f3
Merge github.com:AztecProtocol/aztec-packages into mm/pg-refactor-new
maramihali Feb 22, 2024
6a339fe
Merge branch 'mm/pg-refactor-new' of github.com:AztecProtocol/aztec-p…
maramihali Feb 22, 2024
26118e6
Merge remote-tracking branch 'origin/master' into mm/pg-refactor-new
codygunton Feb 23, 2024
d48b113
Skippedy
Rumata888 Feb 26, 2024
5b7b2d5
Format
Rumata888 Feb 27, 2024
98b03b6
A lot of comments
Rumata888 Feb 27, 2024
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
44 changes: 29 additions & 15 deletions barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace {
class IvcBench : public benchmark::Fixture {
public:
using Builder = GoblinUltraCircuitBuilder;
using VerifierFoldData = GoblinMockCircuits::VerifierFoldData;

// Number of function circuits to accumulate(based on Zacs target numbers)
static constexpr size_t NUM_ITERATIONS_MEDIUM_COMPLEXITY = 6;
Expand All @@ -43,29 +44,45 @@ class IvcBench : public benchmark::Fixture {
*/
static void perform_ivc_accumulation_rounds(State& state, ClientIVC& ivc)
{
// Initialize IVC with function circuit
// Initialize IVC with a function circuit
Builder initial_function_circuit{ ivc.goblin.op_queue };
GoblinMockCircuits::construct_mock_function_circuit(initial_function_circuit);
ivc.initialize(initial_function_circuit);
auto kernel_verifier_accumulator = std::make_shared<ClientIVC::VerifierInstance>();
kernel_verifier_accumulator->verification_key = ivc.vks.first_func_vk;

// Accumulate another function circuit
Builder function_circuit{ ivc.goblin.op_queue };
GoblinMockCircuits::construct_mock_function_circuit(function_circuit);
ivc.initialize(function_circuit);
auto function_fold_proof = ivc.accumulate(function_circuit);
VerifierFoldData function_fold_output = { function_fold_proof, ivc.vks.func_vk };

// Accumulate kernel circuit (first kernel mocked as simple circuit since no folding proofs yet)
// Create and accumulate the first folding kernel which only verifies the accumulation of a function circuit
Builder kernel_circuit{ ivc.goblin.op_queue };
GoblinMockCircuits::construct_mock_function_circuit(kernel_circuit);
kernel_verifier_accumulator = GoblinMockCircuits::construct_mock_folding_kernel(
kernel_circuit, function_fold_output, {}, kernel_verifier_accumulator);
auto kernel_fold_proof = ivc.accumulate(kernel_circuit);
VerifierFoldData kernel_fold_output = { kernel_fold_proof, ivc.vks.first_kernel_vk };

auto NUM_CIRCUITS = static_cast<size_t>(state.range(0));
NUM_CIRCUITS -= 1; // Subtract one to account for the "initialization" round above
// Subtract two to account for the "initialization" round above i.e. we have already folded two function
// circuits
NUM_CIRCUITS -= 2;
for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) {

// Accumulate function circuit
Builder function_circuit{ ivc.goblin.op_queue };
GoblinMockCircuits::construct_mock_function_circuit(function_circuit);
auto function_fold_proof = ivc.accumulate(function_circuit);
function_fold_output = { function_fold_proof, ivc.vks.func_vk };

// Accumulate kernel circuit
// Create kernel circuit containing the recursive folding verification of a function circuit and a kernel
// circuit and accumulate it
Builder kernel_circuit{ ivc.goblin.op_queue };
GoblinMockCircuits::construct_mock_folding_kernel(kernel_circuit, function_fold_proof, kernel_fold_proof);
auto kernel_fold_proof = ivc.accumulate(kernel_circuit);
kernel_verifier_accumulator = GoblinMockCircuits::construct_mock_folding_kernel(
kernel_circuit, function_fold_output, kernel_fold_output, kernel_verifier_accumulator);

kernel_fold_proof = ivc.accumulate(kernel_circuit);
kernel_fold_output = { kernel_fold_proof, ivc.vks.kernel_vk };
}
}
};
Expand All @@ -77,7 +94,7 @@ class IvcBench : public benchmark::Fixture {
BENCHMARK_DEFINE_F(IvcBench, Full)(benchmark::State& state)
{
ClientIVC ivc;

ivc.precompute_folding_verification_keys();
for (auto _ : state) {
BB_REPORT_OP_COUNT_IN_BENCH(state);
// Perform a specified number of iterations of function/kernel accumulation
Expand All @@ -95,7 +112,7 @@ BENCHMARK_DEFINE_F(IvcBench, Full)(benchmark::State& state)
BENCHMARK_DEFINE_F(IvcBench, Accumulate)(benchmark::State& state)
{
ClientIVC ivc;

ivc.precompute_folding_verification_keys();
// Perform a specified number of iterations of function/kernel accumulation
for (auto _ : state) {
BB_REPORT_OP_COUNT_IN_BENCH(state);
Expand All @@ -110,7 +127,6 @@ BENCHMARK_DEFINE_F(IvcBench, Accumulate)(benchmark::State& state)
BENCHMARK_DEFINE_F(IvcBench, Decide)(benchmark::State& state)
{
ClientIVC ivc;

// Perform a specified number of iterations of function/kernel accumulation
perform_ivc_accumulation_rounds(state, ivc);

Expand All @@ -128,7 +144,6 @@ BENCHMARK_DEFINE_F(IvcBench, Decide)(benchmark::State& state)
BENCHMARK_DEFINE_F(IvcBench, ECCVM)(benchmark::State& state)
{
ClientIVC ivc;

// Perform a specified number of iterations of function/kernel accumulation
perform_ivc_accumulation_rounds(state, ivc);

Expand All @@ -146,7 +161,7 @@ BENCHMARK_DEFINE_F(IvcBench, ECCVM)(benchmark::State& state)
BENCHMARK_DEFINE_F(IvcBench, Translator)(benchmark::State& state)
{
ClientIVC ivc;

ivc.precompute_folding_verification_keys();
BB_REPORT_OP_COUNT_IN_BENCH(state);
// Perform a specified number of iterations of function/kernel accumulation
perform_ivc_accumulation_rounds(state, ivc);
Expand All @@ -160,7 +175,6 @@ BENCHMARK_DEFINE_F(IvcBench, Translator)(benchmark::State& state)

#define ARGS \
Arg(IvcBench::NUM_ITERATIONS_MEDIUM_COMPLEXITY) \
->Arg(1 << 0) \
->Arg(1 << 1) \
->Arg(1 << 2) \
->Arg(1 << 3) \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ template <typename Composer> void fold_one(State& state) noexcept
static_assert(std::same_as<Flavor, UltraFlavor>);
bb::mock_proofs::generate_basic_arithmetic_circuit(builder, log2_num_gates);
}
return composer.create_instance(builder);
return composer.create_prover_instance(builder);
};

std::shared_ptr<Instance> instance_1 = construct_instance();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ void _bench_round(::benchmark::State& state,
void (*F)(ProtoGalaxyProver_<ProverInstances_<typename Composer::Flavor, 2>>&))
{
using Flavor = typename Composer::Flavor;
using Instance = ProverInstance_<Flavor>;
using Builder = typename Flavor::CircuitBuilder;

bb::srs::init_crs_factory("../srs_db/ignition");
Expand All @@ -28,16 +27,16 @@ void _bench_round(::benchmark::State& state,
static_assert(std::same_as<Flavor, UltraFlavor>);
bb::mock_proofs::generate_basic_arithmetic_circuit(builder, log2_num_gates);
}
return composer.create_instance(builder);
return composer.create_prover_instance(builder);
};

std::shared_ptr<Instance> instance_1 = construct_instance();
std::shared_ptr<Instance> instance_2 = construct_instance();
auto prover_instance_1 = construct_instance();
auto prover_instance_2 = construct_instance();

auto folding_prover = composer.create_folding_prover({ instance_1, instance_2 });
auto folding_prover = composer.create_folding_prover({ prover_instance_1, prover_instance_2 });

// prepare the prover state
folding_prover.state.accumulator = instance_1;
folding_prover.state.accumulator = prover_instance_1;
folding_prover.state.deltas.resize(log2_num_gates);
std::fill_n(folding_prover.state.deltas.begin(), log2_num_gates, 0);
folding_prover.state.perturbator = Flavor::Polynomial::random(1 << log2_num_gates);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ inline UltraProver get_prover(UltraComposer& composer,
{
UltraComposer::CircuitBuilder builder;
test_circuit_function(builder, num_iterations);
std::shared_ptr<UltraComposer::Instance> instance = composer.create_instance(builder);
std::shared_ptr<UltraComposer::ProverInstance> instance = composer.create_prover_instance(builder);
return composer.create_prover(instance);
}

Expand All @@ -64,7 +64,7 @@ inline GoblinUltraProver get_prover(GoblinUltraComposer& composer,
{
GoblinUltraComposer::CircuitBuilder builder;
test_circuit_function(builder, num_iterations);
std::shared_ptr<GoblinUltraComposer::Instance> instance = composer.create_instance(builder);
std::shared_ptr<GoblinUltraComposer::ProverInstance> instance = composer.create_prover_instance(builder);
return composer.create_prover(instance);
}

Expand Down
83 changes: 69 additions & 14 deletions barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ void ClientIVC::initialize(ClientCircuit& circuit)
{
goblin.merge(circuit); // Construct new merge proof
Composer composer;
fold_output.accumulator = composer.create_instance(circuit);
prover_fold_output.accumulator = composer.create_prover_instance(circuit);
}

/**
Expand All @@ -32,11 +32,10 @@ ClientIVC::FoldProof ClientIVC::accumulate(ClientCircuit& circuit)
{
goblin.merge(circuit); // Add recursive merge verifier and construct new merge proof
Composer composer;
auto instance = composer.create_instance(circuit);
std::vector<std::shared_ptr<Instance>> instances{ fold_output.accumulator, instance };
auto folding_prover = composer.create_folding_prover(instances);
fold_output = folding_prover.fold_instances();
return fold_output.folding_data;
prover_instance = composer.create_prover_instance(circuit);
auto folding_prover = composer.create_folding_prover({ prover_fold_output.accumulator, prover_instance });
prover_fold_output = folding_prover.fold_instances();
return prover_fold_output.folding_data;
}

/**
Expand All @@ -46,7 +45,7 @@ ClientIVC::FoldProof ClientIVC::accumulate(ClientCircuit& circuit)
*/
ClientIVC::Proof ClientIVC::prove()
{
return { fold_output.folding_data, decider_prove(), goblin.prove() };
return { prover_fold_output.folding_data, decider_prove(), goblin.prove() };
}

/**
Expand All @@ -55,19 +54,19 @@ ClientIVC::Proof ClientIVC::prove()
* @param proof
* @return bool
*/
bool ClientIVC::verify(Proof& proof)
bool ClientIVC::verify(Proof& proof, const std::vector<VerifierAccumulator>& verifier_instances)
{
// Goblin verification (merge, eccvm, translator)
bool goblin_verified = goblin.verify(proof.goblin_proof);

// Decider verification
Composer composer;
auto folding_verifier = composer.create_folding_verifier();
bool folding_verified = folding_verifier.verify_folding_proof(proof.fold_proof);
// NOTE: Use of member accumulator here will go away with removal of vkey from ProverInstance
auto decider_verifier = composer.create_decider_verifier(fold_output.accumulator);
auto folding_verifier = composer.create_folding_verifier({ verifier_instances[0], verifier_instances[1] });
auto verifier_accumulator = folding_verifier.verify_folding_proof(proof.fold_proof);

auto decider_verifier = composer.create_decider_verifier(verifier_accumulator);
bool decision = decider_verifier.verify_proof(proof.decider_proof);
return goblin_verified && folding_verified && decision;
return goblin_verified && decision;
}

/**
Expand All @@ -78,8 +77,64 @@ bool ClientIVC::verify(Proof& proof)
HonkProof ClientIVC::decider_prove() const
{
Composer composer;
auto decider_prover = composer.create_decider_prover(fold_output.accumulator);
auto decider_prover = composer.create_decider_prover(prover_fold_output.accumulator);
return decider_prover.construct_proof();
}

/**
* @brief Precompute the array of verification keys by simulating folding. There will be 4 different verification keys:
* initial function verification key (without recursive merge verifier), subsequent function verification key (with
* recursive merge verifier), initial kernel verification key (with recursive merge verifier appended, no previous
* kernel to fold), "full" kernel verification key( two recursive folding verifiers and merge verifier).
*
*/
void ClientIVC::precompute_folding_verification_keys()
{
using VerifierInstance = VerifierInstance_<GoblinUltraFlavor>;

Composer composer;
ClientCircuit initial_function_circuit{ goblin.op_queue };
GoblinMockCircuits::construct_mock_function_circuit(initial_function_circuit);

// Initialise both the first prover and verifier accumulator from the inital function circuit
initialize(initial_function_circuit);
composer.compute_commitment_key(prover_fold_output.accumulator->instance_size);
vks.first_func_vk = composer.compute_verification_key(prover_fold_output.accumulator);
auto initial_verifier_acc = std::make_shared<VerifierInstance>();
initial_verifier_acc->verification_key = vks.first_func_vk;

// Accumulate the next function circuit
ClientCircuit function_circuit{ goblin.op_queue };
GoblinMockCircuits::construct_mock_function_circuit(function_circuit);
auto function_fold_proof = accumulate(function_circuit);

// Create its verification key (we have called accumulate so it includes the recursive merge verifier)
vks.func_vk = composer.compute_verification_key(prover_instance);

// Create the initial kernel iteration and precompute its verification key
ClientCircuit kernel_circuit{ goblin.op_queue };
auto kernel_acc = GoblinMockCircuits::construct_mock_folding_kernel(
kernel_circuit, { function_fold_proof, vks.func_vk }, {}, initial_verifier_acc);
auto kernel_fold_proof = accumulate(kernel_circuit);
vks.first_kernel_vk = composer.compute_verification_key(prover_instance);

// Create another mock function circuit to run the full kernel
function_circuit = ClientCircuit{ goblin.op_queue };
GoblinMockCircuits::construct_mock_function_circuit(function_circuit);
function_fold_proof = accumulate(function_circuit);

// Create the full kernel circuit and compute verification key
kernel_circuit = GoblinUltraCircuitBuilder{ goblin.op_queue };
kernel_acc = GoblinMockCircuits::construct_mock_folding_kernel(
kernel_circuit, { function_fold_proof, vks.func_vk }, { kernel_fold_proof, vks.first_kernel_vk }, kernel_acc);
kernel_fold_proof = accumulate(kernel_circuit);

vks.kernel_vk = composer.compute_verification_key(prover_instance);

// Clean the ivc state
goblin.op_queue = std::make_shared<Goblin::OpQueue>();
goblin.merge_proof_exists = false;
GoblinMockCircuits::perform_op_queue_interactions_for_mock_first_circuit(goblin.op_queue);
}

} // namespace bb
31 changes: 26 additions & 5 deletions barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,13 @@ class ClientIVC {

public:
using Flavor = GoblinUltraFlavor;
using VerificationKey = Flavor::VerificationKey;
using FF = Flavor::FF;
using FoldProof = std::vector<FF>;
using Accumulator = std::shared_ptr<ProverInstance_<Flavor>>;
using ProverAccumulator = std::shared_ptr<ProverInstance_<Flavor>>;
using VerifierAccumulator = std::shared_ptr<VerifierInstance_<Flavor>>;
using ProverInstance = ProverInstance_<GoblinUltraFlavor>;
using VerifierInstance = VerifierInstance_<GoblinUltraFlavor>;
using ClientCircuit = GoblinUltraCircuitBuilder; // can only be GoblinUltra

// A full proof for the IVC scheme
Expand All @@ -28,14 +32,27 @@ class ClientIVC {
Goblin::Proof goblin_proof;
};

struct PrecomputedVerificationKeys {
std::shared_ptr<VerificationKey> first_func_vk;
std::shared_ptr<VerificationKey> func_vk;
std::shared_ptr<VerificationKey> first_kernel_vk;
std::shared_ptr<VerificationKey> kernel_vk;
};

private:
using FoldingOutput = FoldingResult<Flavor>;
using Instance = ProverInstance_<GoblinUltraFlavor>;
using ProverFoldOutput = FoldingResult<GoblinUltraFlavor>;
using Composer = GoblinUltraComposer;
// Note: We need to save the last instance that was folded in order to compute its verification key, this will not
// be needed in the real IVC as they are provided as inputs

public:
Goblin goblin;
FoldingOutput fold_output;
ProverFoldOutput prover_fold_output;
ProverAccumulator prover_accumulator;
PrecomputedVerificationKeys vks;
// Note: We need to save the last instance that was folded in order to compute its verification key, this will not
// be needed in the real IVC as they are provided as inputs
std::shared_ptr<ProverInstance> prover_instance;

ClientIVC();

Expand All @@ -45,8 +62,12 @@ class ClientIVC {

Proof prove();

bool verify(Proof& proof);
bool verify(Proof& proof, const std::vector<VerifierAccumulator>& verifier_instances);

HonkProof decider_prove() const;

void decider_prove_and_verify(const VerifierAccumulator&) const;

void precompute_folding_verification_keys();
};
} // namespace bb
Loading
Loading