Skip to content

Commit

Permalink
more cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
maramihali committed Feb 20, 2024
1 parent ffaddfc commit f97dd1e
Show file tree
Hide file tree
Showing 14 changed files with 89 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,26 @@ 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_verifeir_accumulator = std::make_shared<ClientIVC::VerifierInstance>();
kernel_verifeir_accumulator->verification_key = ivc.vks[0];
kernel_verifeir_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);
auto function_fold_proof = ivc.accumulate(function_circuit);
FoldOutput function_fold_output = { function_fold_proof, ivc.vks[1] };
FoldOutput function_fold_output = { function_fold_proof, ivc.vks.func_vk };

// Create and accumulate the first folding kernel which only verifies the accumulation of a function circuit
Builder kernel_circuit{ ivc.goblin.op_queue };
kernel_verifeir_accumulator = GoblinMockCircuits::construct_mock_folding_kernel(
kernel_circuit, function_fold_output, {}, kernel_verifeir_accumulator);
auto kernel_fold_proof = ivc.accumulate(kernel_circuit);
FoldOutput kernel_fold_output = { kernel_fold_proof, ivc.vks[2] };
FoldOutput kernel_fold_output = { kernel_fold_proof, ivc.vks.first_kernel_vk };

auto NUM_CIRCUITS = static_cast<size_t>(state.range(0));
// Subtract one to account for the "initialization" round above
NUM_CIRCUITS -= 1;
Expand All @@ -69,15 +72,16 @@ class IvcBench : public benchmark::Fixture {
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[1] };
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 };
kernel_verifeir_accumulator = GoblinMockCircuits::construct_mock_folding_kernel(
kernel_circuit, function_fold_output, kernel_fold_output, kernel_verifeir_accumulator);

kernel_fold_proof = ivc.accumulate(kernel_circuit);
kernel_fold_output = { kernel_fold_proof, ivc.vks[3] };
kernel_fold_output = { kernel_fold_proof, ivc.vks.kernel_vk };
}
}
};
Expand Down
20 changes: 11 additions & 9 deletions barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ ClientIVC::Proof ClientIVC::prove()
* @param proof
* @return bool
*/
bool ClientIVC::verify(Proof& proof, const std::vector<ClientIVC::VerifierAccumulator>& verifier_instances)
bool ClientIVC::verify(Proof& proof, const std::vector<VerifierAccumulator>& verifier_instances)
{
// Goblin verification (merge, eccvm, translator)
bool goblin_verified = goblin.verify(proof.goblin_proof);
Expand Down Expand Up @@ -90,31 +90,33 @@ HonkProof ClientIVC::decider_prove() const
*/
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[0] = composer.compute_verification_key(prover_fold_output.accumulator);
vks.first_func_vk = composer.compute_verification_key(prover_fold_output.accumulator);
auto verifier_acc = std::make_shared<VerifierInstance>();
verifier_acc->verification_key = vks[0];
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[1] = composer.compute_verification_key(prover_instance);
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 new_acc = GoblinMockCircuits::construct_mock_folding_kernel(
kernel_circuit, { function_fold_proof, vks[1] }, {}, verifier_acc);
kernel_circuit, { function_fold_proof, vks.func_vk }, {}, verifier_acc);
auto kernel_fold_proof = accumulate(kernel_circuit);
vks[2] = composer.compute_verification_key(prover_instance);
vks.first_kernel_vk = composer.compute_verification_key(prover_instance);

// Create another mock function circuit to run the full kernel
ClientCircuit circuit_4{ goblin.op_queue };
Expand All @@ -124,12 +126,12 @@ void ClientIVC::precompute_folding_verification_keys()
// Create the fullk ernel circuit and compute verification key
ClientCircuit new_kernel_circuit = GoblinUltraCircuitBuilder{ goblin.op_queue };
auto new_new_acc = GoblinMockCircuits::construct_mock_folding_kernel(
new_kernel_circuit, { function_fold_proof, vks[1] }, { kernel_fold_proof, vks[2] }, new_acc);
new_kernel_circuit, { function_fold_proof, vks.func_vk }, { kernel_fold_proof, vks.first_kernel_vk }, new_acc);
kernel_fold_proof = accumulate(new_kernel_circuit);

vks[3] = composer.compute_verification_key(prover_instance);
vks.kernel_vk = composer.compute_verification_key(prover_instance);
auto kernel_inst = std::make_shared<VerifierInstance>();
kernel_inst->verification_key = vks[3];
kernel_inst->verification_key = vks.kernel_vk;

// Clean the ivc state
goblin.op_queue = std::make_shared<Goblin::OpQueue>();
Expand Down
13 changes: 9 additions & 4 deletions barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ class ClientIVC {
using FoldProof = std::vector<FF>;
using ProverAccumulator = std::shared_ptr<ProverInstance_<Flavor>>;
using VerifierAccumulator = std::shared_ptr<VerifierInstance_<Flavor>>;
using VerifierInstance = VerifierInstance_<GoblinUltraFlavor>;
using ProverInstance = ProverInstance_<GoblinUltraFlavor>;
using VerifierInstance = VerifierInstance_<GoblinUltraFlavor>;
using ClientCircuit = GoblinUltraCircuitBuilder; // can only be GoblinUltra

// A full proof for the IVC scheme
Expand All @@ -32,6 +32,13 @@ 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 ProverFoldOutput = FoldingResult<GoblinUltraFlavor>;
using Composer = GoblinUltraComposer;
Expand All @@ -40,13 +47,11 @@ class ClientIVC {
Goblin goblin;
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;

std::array<std::shared_ptr<VerificationKey>, 4> vks;

ClientIVC();

void initialize(ClientCircuit& circuit);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ TEST_F(MockKernelTest, PinFoldingKernelSizes)
GoblinMockCircuits::construct_mock_function_circuit(circuit_1);
ivc.initialize(circuit_1);
auto verifier_acc = std::make_shared<ClientIVC::VerifierInstance>();
verifier_acc->verification_key = ivc.vks[0];
verifier_acc->verification_key = ivc.vks.first_func_vk;

GoblinUltraCircuitBuilder circuit_2{ ivc.goblin.op_queue };
GoblinMockCircuits::construct_mock_function_circuit(circuit_2);
Expand All @@ -36,7 +36,7 @@ TEST_F(MockKernelTest, PinFoldingKernelSizes)
// Construct kernel circuit
GoblinUltraCircuitBuilder kernel_circuit{ ivc.goblin.op_queue };
auto new_acc = GoblinMockCircuits::construct_mock_folding_kernel(
kernel_circuit, { fold_proof_1, ivc.vks[1] }, {}, verifier_acc);
kernel_circuit, { fold_proof_1, ivc.vks.func_vk }, {}, verifier_acc);

auto fold_proof_3 = ivc.accumulate(kernel_circuit);
EXPECT_EQ(ivc.prover_instance->log_instance_size, 17);
Expand All @@ -47,7 +47,7 @@ TEST_F(MockKernelTest, PinFoldingKernelSizes)

GoblinUltraCircuitBuilder new_kernel_circuit = GoblinUltraCircuitBuilder{ ivc.goblin.op_queue };
new_acc = GoblinMockCircuits::construct_mock_folding_kernel(
new_kernel_circuit, { fold_proof_3, ivc.vks[2] }, { fold_proof_4, ivc.vks[1] }, new_acc);
new_kernel_circuit, { fold_proof_3, ivc.vks.first_kernel_vk }, { fold_proof_4, ivc.vks.func_vk }, new_acc);
GoblinUltraComposer composer;
auto instance = composer.create_prover_instance(new_kernel_circuit);
EXPECT_EQ(instance->proving_key->log_circuit_size, 17);
Expand Down
6 changes: 5 additions & 1 deletion barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ class GoblinMockCircuits {
using VerificationKey = Flavor::VerificationKey;
static constexpr size_t NUM_OP_QUEUE_COLUMNS = Flavor::NUM_WIRES;

/**
* @brief
*
*/
struct FoldOutput {
std::vector<FF> fold_proof;
std::shared_ptr<VerificationKey> inst_vk;
Expand Down Expand Up @@ -242,7 +246,7 @@ class GoblinMockCircuits {
stdlib::generate_ecdsa_verification_test_circuit(builder, NUM_ECDSA_VERIFICATIONS);
stdlib::generate_sha256_test_circuit(builder, NUM_SHA_HASHES);

// Init
// Initial kernel iteration does not have a previous kernel to fold
if (kernel.fold_proof.empty()) {
FoldingRecursiveVerifier verifier_1{ &builder, prev_kernel_accum, { func.inst_vk } };
auto fctn_verifier_accum = verifier_1.verify_folding_proof(func.fold_proof);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ template <class ProverInstances> void ProtoGalaxyProver_<ProverInstances>::pertu
FF delta = transcript->template get_challenge<FF>("delta");
state.deltas = compute_round_challenge_pows(state.accumulator->log_instance_size, delta);
state.perturbator = compute_perturbator(state.accumulator, state.deltas);

// Prover doesn't send the constant coefficient of F because this is supposed to be equal to the target sum of the
// accumulator which the folding verifier has from the previous iteration.
for (size_t idx = 1; idx <= state.accumulator->log_instance_size; idx++) {
transcript->send_to_verifier("perturbator_" + std::to_string(idx), state.perturbator[idx]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ template <class ProverInstances_> class ProtoGalaxyProver_ {

ProverInstances instances;
std::shared_ptr<Transcript> transcript = std::make_shared<Transcript>();
ProtogalaxyProofConstructionState<ProverInstances> state;
std::shared_ptr<CommitmentKey> commitment_key;
ProtogalaxyProofConstructionState<ProverInstances> state;

ProtoGalaxyProver_() = default;
ProtoGalaxyProver_(const std::vector<std::shared_ptr<Instance>>& insts,
Expand Down Expand Up @@ -457,9 +457,31 @@ template <class ProverInstances_> class ProtoGalaxyProver_ {
FF& challenge,
const FF& compressed_perturbator);

/**
* @brief Finalise the prover instances that will be folded: complete computation of all the witness polynomials and
* compute commitments. Send commitments to the verifier and retrieve challenges.
*
*/
void preparation_round();

/**
* @brief Compute perturbator (F polynomial in paper). Send all but the constant coefficient to verifier.
*
*/
void perturbator_round();

/**
* @brief Compute combiner (G polynomial in the paper) and then its quotient (K polynomial), whose coefficient will
* be sent to the verifier.
*
*/
void combiner_quotient_round();

/**
* @brief Compute the next prover accumulator (ω* in the paper), encapsulated in a ProverInstance with folding
* parameters set.
*
*/
void accumulator_update_round();
};
} // namespace bb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@ std::array<typename Flavor::GroupElement, 2> DeciderRecursiveVerifier_<Flavor>::
return pairing_points;
}

// template class DeciderRecursiveVerifier_<bb::UltraRecursiveFlavor_<GoblinUltraCircuitBuilder>>;
template class DeciderRecursiveVerifier_<bb::UltraRecursiveFlavor_<UltraCircuitBuilder>>;
template class DeciderRecursiveVerifier_<bb::GoblinUltraRecursiveFlavor_<GoblinUltraCircuitBuilder>>;
} // namespace bb::stdlib::recursion::honk
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,8 @@ std::shared_ptr<typename VerifierInstances::Instance> ProtoGalaxyRecursiveVerifi
return next_accumulator;
}

// template class ProtoGalaxyRecursiveVerifier_<VerifierInstances_<UltraRecursiveFlavor_<GoblinUltraCircuitBuilder>,
// 2>>;
template class ProtoGalaxyRecursiveVerifier_<
RecursiveVerifierInstances_<UltraRecursiveFlavor_<UltraCircuitBuilder>, 2>>;
template class ProtoGalaxyRecursiveVerifier_<
RecursiveVerifierInstances_<GoblinUltraRecursiveFlavor_<GoblinUltraCircuitBuilder>, 2>>;
} // namespace bb::stdlib::recursion::honk
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ template <typename RecursiveFlavor> class ProtoGalaxyRecursiveTests : public tes
static void test_new_evaluate()
{
Builder builder;
using fr_ct = bn254<Builder>::ScalarField;
using fr = bn254<Builder>::ScalarFieldNative;
using fr_ct = typename bn254<Builder>::ScalarField;
using fr = typename bn254<Builder>::ScalarFieldNative;

std::vector<fr> coeffs;
std::vector<fr_ct> coeffs_ct;
Expand Down Expand Up @@ -349,7 +349,8 @@ template <typename RecursiveFlavor> class ProtoGalaxyRecursiveTests : public tes
};
};

using FlavorTypes = testing::Types<GoblinUltraRecursiveFlavor_<GoblinUltraCircuitBuilder>>;
using FlavorTypes =
testing::Types<GoblinUltraRecursiveFlavor_<GoblinUltraCircuitBuilder>, UltraRecursiveFlavor_<UltraCircuitBuilder>>;
TYPED_TEST_SUITE(ProtoGalaxyRecursiveTests, FlavorTypes);

TYPED_TEST(ProtoGalaxyRecursiveTests, InnerCircuit)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ template <IsRecursiveFlavor Flavor_, size_t NUM_> struct RecursiveVerifierInstan
typename ArrayType::iterator begin() { return _data.begin(); };
typename ArrayType::iterator end() { return _data.end(); };
Builder* builder;
// RecursiveVerifierInstances_() = default;

RecursiveVerifierInstances_(Builder* builder,
std::shared_ptr<NativeInstance> accumulator,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
#include "barretenberg/sumcheck/instance/verifier_instance.hpp"

namespace bb::stdlib::recursion::honk {

/**
* @brief The stdlib counterpart of VerifierInstance, used in recursive folding verification.
*/
template <IsRecursiveFlavor Flavor> class RecursiveVerifierInstance_ {
public:
using FF = typename Flavor::FF;
Expand Down Expand Up @@ -92,6 +96,13 @@ template <IsRecursiveFlavor Flavor> class RecursiveVerifierInstance_ {
FF::from_witness(builder, instance->relation_parameters.lookup_grand_product_delta);
}

/**
* @brief Return the underlying native VerifierInstance.
*
* @details In the context of client IVC, we will have several iterations of recursive folding verification. The
* RecursiveVerifierInstance is tied to the builder in whose context it was created so in order to preserve the
* accumulator values between several iterations we need to retrieve the native VerifierInstance values.
*/
VerifierInstance get_value()
{
VerifierInstance inst;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ namespace bb {
* required by an Ultra Goblin Honk prover to create a proof. A ProverInstance is also the result of running the
* Protogalaxy prover, in which case it becomes a relaxed counterpart with the folding parameters (target sum and gate
* challenges set to non-zero values).
*
* @details This is the equivalent of ω in the paper.
*/

template <class Flavor> class ProverInstance_ {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

namespace bb {
/**
* @brief
* @brief The VerifierInstance encapsulates all the necessary information for a Goblin Ultra Honk Verifier to verify a
* proof (sumcheck + Zeromorph). In the context of folding, this is returned by the Protogalaxy verifier with non-zero
* target sum and gate challenges.
*
* @tparam Flavor
* @details This is ϕ in the paper.
*/
template <class Flavor> class VerifierInstance_ {
public:
Expand Down

0 comments on commit f97dd1e

Please sign in to comment.