Skip to content

Commit

Permalink
Single allocation in CIVC
Browse files Browse the repository at this point in the history
  • Loading branch information
codygunton committed Nov 20, 2024
1 parent 603b9c2 commit 7bdd134
Show file tree
Hide file tree
Showing 17 changed files with 85 additions and 40 deletions.
16 changes: 12 additions & 4 deletions barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,16 @@ void ClientIVC::accumulate(ClientCircuit& circuit, const std::shared_ptr<Verific
proving_key = std::make_shared<DeciderProvingKey>(circuit, trace_settings);
trace_usage_tracker = ExecutionTraceUsageTracker(trace_settings);
} else {
proving_key = std::make_shared<DeciderProvingKey>(
circuit, trace_settings, fold_output.accumulator->proving_key.commitment_key);
proving_key = std::make_shared<DeciderProvingKey>(circuit, trace_settings);
}

if (!bn254_commitment_key) {
info("commitment key being initialized");
bn254_commitment_key = std::make_shared<typename MegaFlavor::CommitmentKey>(proving_key->dyadic_circuit_size);
} else {
info("commitment key already initialized");
}
proving_key->proving_key.commitment_key = bn254_commitment_key;

vinfo("getting honk vk... precomputed?: ", precomputed_vk);
// Update the accumulator trace usage based on the present circuit
Expand Down Expand Up @@ -274,11 +281,11 @@ HonkProof ClientIVC::construct_and_prove_hiding_circuit()

builder.add_pairing_point_accumulator(stdlib::recursion::init_default_agg_obj_indices<ClientCircuit>(builder));

// Construct the last merge proof for the present circuit and add to merge verification queue
// Construct the last merge proof for the present circuit and add to merge verification queuee
MergeProof merge_proof = goblin.prove_merge(builder);
merge_verification_queue.emplace_back(merge_proof);

auto decider_pk = std::make_shared<DeciderProvingKey>(builder);
auto decider_pk = std::make_shared<DeciderProvingKey>(builder, TraceSettings(), bn254_commitment_key);
honk_vk = std::make_shared<VerificationKey>(decider_pk->proving_key);
MegaProver prover(decider_pk);

Expand Down Expand Up @@ -338,6 +345,7 @@ bool ClientIVC::verify(const Proof& proof)
HonkProof ClientIVC::decider_prove() const
{
vinfo("prove decider...");
fold_output.accumulator->proving_key.commitment_key = bn254_commitment_key;
MegaDeciderProver decider_prover(fold_output.accumulator);
return decider_prover.construct_proof();
vinfo("finished decider proving.");
Expand Down
10 changes: 8 additions & 2 deletions barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,6 @@ class ClientIVC {
using ProverFoldOutput = FoldingResult<Flavor>;

public:
GoblinProver goblin;

ProverFoldOutput fold_output; // prover accumulator and fold proof

std::shared_ptr<DeciderVerificationKey> verifier_accumulator; // verifier accumulator
Expand All @@ -122,11 +120,19 @@ class ClientIVC {
// Setting auto_verify_mode = true will cause kernel completion logic to be added to kernels automatically
bool auto_verify_mode;

std::shared_ptr<typename MegaFlavor::CommitmentKey> bn254_commitment_key;

GoblinProver goblin;

bool initialized = false; // Is the IVC accumulator initialized

ClientIVC(TraceSettings trace_settings = {}, bool auto_verify_mode = false)
: trace_settings(trace_settings)
, auto_verify_mode(auto_verify_mode)
, bn254_commitment_key(trace_settings.structure.has_value()
? std::make_shared<CommitmentKey<curve::BN254>>(trace_settings.dyadic_size())
: nullptr)
, goblin(bn254_commitment_key)
{}

void instantiate_stdlib_verification_queue(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ template <class Curve> class CommitmentKey {
: pippenger_runtime_state(get_num_needed_srs_points(num_points))
, crs_factory(srs::get_crs_factory<Curve>())
, srs(crs_factory->get_prover_crs(get_num_needed_srs_points(num_points)))
{}
{
info("CommitmentKey constructor from num_points being called!");
}

// Note: This constructor is to be used only by Plonk; For Honk the srs lives in the CommitmentKey
CommitmentKey(const size_t num_points, std::shared_ptr<srs::factories::ProverCrs<Curve>> prover_crs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ WASM_EXPORT void acir_prove_and_verify_aztec_client(uint8_t const* acir_stack,
}
// TODO(#7371) dedupe this with the rest of the similar code
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1101): remove use of auto_verify_mode
ClientIVC ivc{ { E2E_FULL_TEST_STRUCTURE }, /*auto_verify_mode=*/true };
ClientIVC ivc{ { CLIENT_IVC_BENCH_STRUCTURE }, /*auto_verify_mode=*/true };

// Accumulate the entire program stack into the IVC
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1116): remove manual setting of is_kernel once databus
Expand Down
3 changes: 1 addition & 2 deletions barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,7 @@ void ECCVMProver::execute_relation_check_rounds()
gate_challenges[idx] = transcript->template get_challenge<FF>("Sumcheck:gate_challenge_" + std::to_string(idx));
}

auto commitment_key = std::make_shared<CommitmentKey>(Flavor::BATCHED_RELATION_PARTIAL_LENGTH);
zk_sumcheck_data = ZKSumcheckData<Flavor>(key->log_circuit_size, transcript, commitment_key);
zk_sumcheck_data = ZKSumcheckData<Flavor>(key->log_circuit_size, transcript, key->commitment_key);

sumcheck_output = sumcheck.prove(key->polynomials, relation_parameters, alpha, gate_challenges, zk_sumcheck_data);
}
Expand Down
10 changes: 6 additions & 4 deletions barretenberg/cpp/src/barretenberg/goblin/goblin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class GoblinProver {
*/

std::shared_ptr<OpQueue> op_queue = std::make_shared<OpQueue>();
std::shared_ptr<CommitmentKey<curve::BN254>> commitment_key;

MergeProof merge_proof;
GoblinProof goblin_proof;
Expand All @@ -70,11 +71,12 @@ class GoblinProver {
GoblinAccumulationOutput accumulator; // Used only for ACIR methods for now

public:
GoblinProver()
GoblinProver(const std::shared_ptr<CommitmentKey<curve::BN254>>& bn254_commitment_key = nullptr)
{ // Mocks the interaction of a first circuit with the op queue due to the inability to currently handle zero
// commitments (https://github.com/AztecProtocol/barretenberg/issues/871) which would otherwise appear in the
// first round of the merge protocol. To be removed once the issue has been resolved.
GoblinMockCircuits::perform_op_queue_interactions_for_mock_first_circuit(op_queue);
commitment_key = bn254_commitment_key ? bn254_commitment_key : nullptr;
GoblinMockCircuits::perform_op_queue_interactions_for_mock_first_circuit(op_queue, commitment_key);
}
/**
* @brief Construct a MegaHonk proof and a merge proof for the present circuit.
Expand Down Expand Up @@ -160,7 +162,7 @@ class GoblinProver {
merge_proof_exists = true;
}

MergeProver merge_prover{ circuit_builder.op_queue };
MergeProver merge_prover{ circuit_builder.op_queue, commitment_key };
return merge_prover.construct_proof();
};

Expand Down Expand Up @@ -209,7 +211,7 @@ class GoblinProver {

auto translator_builder =
std::make_unique<TranslatorBuilder>(translation_batching_challenge_v, evaluation_challenge_x, op_queue);
translator_prover = std::make_unique<TranslatorProver>(*translator_builder, transcript);
translator_prover = std::make_unique<TranslatorProver>(*translator_builder, transcript, commitment_key);
}

{
Expand Down
8 changes: 5 additions & 3 deletions barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ class GoblinMockCircuits {
*
* @param op_queue
*/
static void perform_op_queue_interactions_for_mock_first_circuit(std::shared_ptr<bb::ECCOpQueue>& op_queue)
static void perform_op_queue_interactions_for_mock_first_circuit(
std::shared_ptr<bb::ECCOpQueue>& op_queue, std::shared_ptr<CommitmentKey> commitment_key = nullptr)
{
PROFILE_THIS();

Expand All @@ -134,11 +135,12 @@ class GoblinMockCircuits {

// Manually compute the op queue transcript commitments (which would normally be done by the merge prover)
bb::srs::init_crs_factory("../srs_db/ignition");
auto commitment_key = CommitmentKey(op_queue->get_current_size());
auto bn254_commitment_key =
commitment_key ? commitment_key : std::make_shared<CommitmentKey>(op_queue->get_current_size());
std::array<Point, Flavor::NUM_WIRES> op_queue_commitments;
size_t idx = 0;
for (auto& entry : op_queue->get_aggregate_transcript()) {
op_queue_commitments[idx++] = commitment_key.commit({ 0, entry });
op_queue_commitments[idx++] = commitment_key->commit({ 0, entry });
}
// Store the commitment data for use by the prover of the next circuit
op_queue->set_commitment_data(op_queue_commitments);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,15 @@ template <typename T> struct MegaTraceBlockData {
};
}

static uint32_t size() { return 0; }
static uint32_t dyadic_size() { return 0; }
size_t size() const
requires std::same_as<T, uint32_t>
{
size_t result{ 0 };
for (const auto& block_size : get()) {
result += block_size;
}
return static_cast<size_t>(result);
}

bool operator==(const MegaTraceBlockData& other) const = default;
};
Expand All @@ -72,6 +79,15 @@ struct TraceSettings {
// The size of the overflow block. Specified separately because it is allowed to be determined at runtime in the
// context of VK computation
uint32_t overflow_capacity = 0;

size_t size() const { return structure->size() + static_cast<size_t>(overflow_capacity); }

size_t dyadic_size() const
{
const size_t total_size = size();
const size_t lower_dyadic = 1 << numeric::get_msb(total_size);
return total_size > lower_dyadic ? lower_dyadic << 1 : lower_dyadic;
}
};

class MegaTraceBlock : public ExecutionTraceBlock<fr, /*NUM_WIRES_ */ 4, /*NUM_SELECTORS_*/ 14> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -581,11 +581,13 @@ class MegaFlavor {
VerificationKey(ProvingKey& proving_key)
{
set_metadata(proving_key);
if (proving_key.commitment_key == nullptr) {
proving_key.commitment_key = std::make_shared<CommitmentKey>(proving_key.circuit_size);
auto& ck = proving_key.commitment_key;
if (!ck || ck->srs->get_monomial_size() < proving_key.circuit_size) {
vinfo("commitment key being constructed in VK constructor");
ck = std::make_shared<CommitmentKey>(proving_key.circuit_size);
}
for (auto [polynomial, commitment] : zip_view(proving_key.polynomials.get_precomputed(), this->get_all())) {
commitment = proving_key.commitment_key->commit(polynomial);
commitment = ck->commit(polynomial);
}
}

Expand Down
2 changes: 1 addition & 1 deletion barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "barretenberg/polynomials/polynomial_arithmetic.hpp"
#include "barretenberg/sumcheck/sumcheck_output.hpp"
#include "barretenberg/transcript/transcript.hpp"
#include "barretenberg/ultra_honk/decider_proving_key.hpp"
#include "barretenberg/ultra_honk/decider_proving_key.hpp" // WORKTODO: not needed?
#include "sumcheck_round.hpp"

namespace bb {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,18 @@

namespace bb {

TranslatorProver::TranslatorProver(CircuitBuilder& circuit_builder, const std::shared_ptr<Transcript>& transcript)
TranslatorProver::TranslatorProver(CircuitBuilder& circuit_builder,
const std::shared_ptr<Transcript>& transcript,
std::shared_ptr<CommitmentKey> commitment_key)
: dyadic_circuit_size(Flavor::compute_dyadic_circuit_size(circuit_builder))
, mini_circuit_dyadic_size(Flavor::compute_mini_circuit_dyadic_size(circuit_builder))
, transcript(transcript)
, key(std::make_shared<ProvingKey>(circuit_builder))
{
PROFILE_THIS();

// Compute total number of gates, dyadic circuit size, etc.
key = std::make_shared<ProvingKey>(circuit_builder);
key->commitment_key = commitment_key ? commitment_key : std::make_shared<CommitmentKey>(key->circuit_size);
compute_witness(circuit_builder);
compute_commitment_key(key->circuit_size);
}

/**
Expand Down Expand Up @@ -159,9 +160,8 @@ void TranslatorProver::execute_relation_check_rounds()
gate_challenges[idx] = transcript->template get_challenge<FF>("Sumcheck:gate_challenge_" + std::to_string(idx));
}

// create masking polynomials for sumcheck round univariates and auxiliary data
auto commitment_key = std::make_shared<CommitmentKey>(Flavor::BATCHED_RELATION_PARTIAL_LENGTH);
zk_sumcheck_data = ZKSumcheckData<Flavor>(key->log_circuit_size, transcript, commitment_key);
// // create masking polynomials for sumcheck round univariates and auxiliary data
zk_sumcheck_data = ZKSumcheckData<Flavor>(key->log_circuit_size, transcript, key->commitment_key);

sumcheck_output = sumcheck.prove(key->polynomials, relation_parameters, alpha, gate_challenges, zk_sumcheck_data);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ class TranslatorProver {
size_t dyadic_circuit_size = 0; // final power-of-2 circuit size
size_t mini_circuit_dyadic_size = 0; // The size of the small circuit that contains non-range constraint relations

explicit TranslatorProver(CircuitBuilder& circuit_builder, const std::shared_ptr<Transcript>& transcript);
explicit TranslatorProver(CircuitBuilder& circuit_builder,
const std::shared_ptr<Transcript>& transcript,
std::shared_ptr<CommitmentKey> commitment_key = nullptr);

void compute_witness(CircuitBuilder& circuit_builder);
void compute_commitment_key(size_t circuit_size);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ template <IsUltraFlavor Flavor> void DeciderProver_<Flavor>::execute_relation_ch
*/
template <IsUltraFlavor Flavor> void DeciderProver_<Flavor>::execute_pcs_rounds()
{
if (proving_key->proving_key.commitment_key == nullptr) {
if (!proving_key->proving_key.commitment_key) {
vinfo("Constructor vk in decider PCS rounds function");
proving_key->proving_key.commitment_key =
std::make_shared<CommitmentKey>(proving_key->proving_key.circuit_size);
}
vinfo("made commitment key");
using OpeningClaim = ProverOpeningClaim<Curve>;

OpeningClaim prover_opening_claim;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ template <IsHonkFlavor Flavor> class DeciderProvingKey_ {
std::vector<FF> gate_challenges;
// The target sum, which is typically nonzero for a ProtogalaxyProver's accmumulator
FF target_sum;

size_t final_active_wire_idx{ 0 }; // idx of last non-trivial wire value in the trace
size_t dyadic_circuit_size{ 0 }; // final power-of-2 circuit size

DeciderProvingKey_(Circuit& circuit,
TraceSettings trace_settings = {},
std::shared_ptr<typename Flavor::CommitmentKey> commitment_key = nullptr)
std::shared_ptr<CommitmentKey> commitment_key = nullptr)
: is_structured(trace_settings.structure.has_value())
{
PROFILE_THIS_NAME("DeciderProvingKey(Circuit&)");
Expand Down Expand Up @@ -79,6 +79,7 @@ template <IsHonkFlavor Flavor> class DeciderProvingKey_ {

// Complete the public inputs execution trace block from circuit.public_inputs
Trace::populate_public_inputs_block(circuit);
vinfo("populated public inputs block");
circuit.blocks.compute_offsets(is_structured);

// Find index of last non-trivial wire value in the trace
Expand All @@ -101,9 +102,11 @@ template <IsHonkFlavor Flavor> class DeciderProvingKey_ {
proving_key = ProvingKey(dyadic_circuit_size, circuit.public_inputs.size(), commitment_key);
// If not using structured trace OR if using structured trace but overflow has occurred (overflow block in
// use), allocate full size polys
vinfo("allocated polynomials object in proving key");
if ((IsMegaFlavor<Flavor> && !is_structured) || (is_structured && circuit.blocks.has_overflow)) {
// Allocate full size polynomials
proving_key.polynomials = typename Flavor::ProverPolynomials(dyadic_circuit_size);
vinfo("allocated polynomials object in proving key");
} else { // Allocate only a correct amount of memory for each polynomial
// Allocate the wires and selectors polynomials
{
Expand Down Expand Up @@ -328,7 +331,6 @@ template <IsHonkFlavor Flavor> class DeciderProvingKey_ {
private:
static constexpr size_t num_zero_rows = Flavor::has_zero_row ? 1 : 0;
static constexpr size_t NUM_WIRES = Circuit::NUM_WIRES;
size_t dyadic_circuit_size = 0; // final power-of-2 circuit size

size_t compute_dyadic_size(Circuit&);

Expand Down
7 changes: 4 additions & 3 deletions barretenberg/cpp/src/barretenberg/ultra_honk/merge_prover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ namespace bb {
*
*/
template <class Flavor>
MergeProver_<Flavor>::MergeProver_(const std::shared_ptr<ECCOpQueue>& op_queue)
MergeProver_<Flavor>::MergeProver_(const std::shared_ptr<ECCOpQueue>& op_queue,
std::shared_ptr<CommitmentKey> commitment_key)
: op_queue(op_queue)
{
// Update internal size data in the op queue that allows for extraction of e.g. previous aggregate transcript
op_queue->set_size_data();
// Get the appropriate commitment based on the updated ultra ops size
pcs_commitment_key = std::make_shared<CommitmentKey>(op_queue->get_current_size());
pcs_commitment_key =
commitment_key ? commitment_key : std::make_shared<CommitmentKey>(op_queue->get_current_size());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ template <typename Flavor> class MergeProver_ {
public:
std::shared_ptr<Transcript> transcript;

explicit MergeProver_(const std::shared_ptr<ECCOpQueue>&);
explicit MergeProver_(const std::shared_ptr<ECCOpQueue>& op_queue,
std::shared_ptr<CommitmentKey> commitment_key = nullptr);

BB_PROFILE HonkProof construct_proof();

Expand Down
2 changes: 2 additions & 0 deletions barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,10 @@ template <IsUltraFlavor Flavor> void OinkProver<Flavor>::prove()
// Generate relation separators alphas for sumcheck/combiner computation
proving_key->alphas = generate_alphas_round();

#ifndef __wasm__
// Free the commitment key
proving_key->proving_key.commitment_key = nullptr;
#endif
}

/**
Expand Down

0 comments on commit 7bdd134

Please sign in to comment.