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

refactor: share verifier rounds #4849

Merged
merged 13 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from 10 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
1 change: 1 addition & 0 deletions barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ class GoblinUltraFlavor {
/**
* @brief Derived class that defines proof structure for GoblinUltra proofs, as well as supporting functions.
* Note: Made generic for use in GoblinUltraRecursive.
* TODO(https://github.com/AztecProtocol/barretenberg/issues/877): Remove this Commitment template parameter
*/
template <typename Commitment> class Transcript_ : public NativeTranscript {
public:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,81 +1,17 @@
#include "protogalaxy_verifier.hpp"
#include "barretenberg/proof_system/library/grand_product_delta.hpp"
#include "barretenberg/ultra_honk/oink_verifier.hpp"
namespace bb {

template <class VerifierInstances>
void ProtoGalaxyVerifier_<VerifierInstances>::receive_and_finalise_instance(const std::shared_ptr<Instance>& inst,
const std::string& domain_separator)
{
// Get circuit parameters and the public inputs
inst->verification_key->circuit_size =
transcript->template receive_from_prover<uint32_t>(domain_separator + "_circuit_size");
inst->verification_key->log_circuit_size =
static_cast<size_t>(numeric::get_msb(inst->verification_key->circuit_size));
inst->verification_key->num_public_inputs =
transcript->template receive_from_prover<uint32_t>(domain_separator + "_public_input_size");
inst->verification_key->pub_inputs_offset =
transcript->template receive_from_prover<uint32_t>(domain_separator + "_pub_inputs_offset");
inst->verification_key->public_inputs.clear();
for (size_t i = 0; i < inst->verification_key->num_public_inputs; ++i) {
auto public_input_i =
transcript->template receive_from_prover<FF>(domain_separator + "_public_input_" + std::to_string(i));
inst->verification_key->public_inputs.emplace_back(public_input_i);
}

// Get commitments to first three wire polynomials
auto labels = inst->commitment_labels;
auto& witness_commitments = inst->witness_commitments;
witness_commitments.w_l = transcript->template receive_from_prover<Commitment>(domain_separator + "_" + labels.w_l);
witness_commitments.w_r = transcript->template receive_from_prover<Commitment>(domain_separator + "_" + labels.w_r);
witness_commitments.w_o = transcript->template receive_from_prover<Commitment>(domain_separator + "_" + labels.w_o);

if constexpr (IsGoblinFlavor<Flavor>) {
// Get commitments to the ECC wire polynomials and databus polynomials
witness_commitments.ecc_op_wire_1 =
transcript->template receive_from_prover<Commitment>(domain_separator + "_" + labels.ecc_op_wire_1);
witness_commitments.ecc_op_wire_2 =
transcript->template receive_from_prover<Commitment>(domain_separator + "_" + labels.ecc_op_wire_2);
witness_commitments.ecc_op_wire_3 =
transcript->template receive_from_prover<Commitment>(domain_separator + "_" + labels.ecc_op_wire_3);
witness_commitments.ecc_op_wire_4 =
transcript->template receive_from_prover<Commitment>(domain_separator + "_" + labels.ecc_op_wire_4);
witness_commitments.calldata =
transcript->template receive_from_prover<Commitment>(domain_separator + "_" + labels.calldata);
witness_commitments.calldata_read_counts =
transcript->template receive_from_prover<Commitment>(domain_separator + "_" + labels.calldata_read_counts);
}

// Get challenge for sorted list batching and wire four memory records commitment
auto eta = transcript->template get_challenge<FF>(domain_separator + "_eta");
witness_commitments.sorted_accum =
transcript->template receive_from_prover<Commitment>(domain_separator + "_" + labels.sorted_accum);
witness_commitments.w_4 = transcript->template receive_from_prover<Commitment>(domain_separator + "_" + labels.w_4);

// Get permutation challenges and commitment to permutation and lookup grand products
auto [beta, gamma] =
transcript->template get_challenges<FF>(domain_separator + "_beta", domain_separator + "_gamma");

if constexpr (IsGoblinFlavor<Flavor>) {
// If Goblin (i.e. using DataBus) receive commitments to log-deriv inverses polynomial
witness_commitments.lookup_inverses = transcript->template receive_from_prover<Commitment>(
domain_separator + "_" + commitment_labels.lookup_inverses);
}

witness_commitments.z_perm =
transcript->template receive_from_prover<Commitment>(domain_separator + "_" + labels.z_perm);
witness_commitments.z_lookup =
transcript->template receive_from_prover<Commitment>(domain_separator + "_" + labels.z_lookup);

// Compute correction terms for grand products
const FF public_input_delta = compute_public_input_delta<Flavor>(inst->verification_key->public_inputs,
beta,
gamma,
inst->verification_key->circuit_size,
inst->verification_key->pub_inputs_offset);
const FF lookup_grand_product_delta =
compute_lookup_grand_product_delta<FF>(beta, gamma, inst->verification_key->circuit_size);
inst->relation_parameters =
RelationParameters<FF>{ eta, beta, gamma, public_input_delta, lookup_grand_product_delta };
auto& key = inst->verification_key;
OinkVerifier<Flavor> oink_verifier{ key, transcript, domain_separator + '_' };
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't really like this domain_separator hack, but it works

Copy link
Contributor Author

@lucasxia01 lucasxia01 Mar 14, 2024

Choose a reason for hiding this comment

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

I had to add '_' to the domain separator so that normally we wouldn't add '_' to the manifest strings when domain_separator was empty (in the ultra_verifier case)

auto [relation_parameters, witness_commitments] = oink_verifier.verify();
inst->relation_parameters = relation_parameters;
inst->witness_commitments = witness_commitments;

// Get the relation separation challenges
for (size_t idx = 0; idx < NUM_SUBRELATIONS - 1; idx++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,8 @@ template <typename RecursiveFlavor> class ProtoGalaxyRecursiveTests : public tes
auto native_folding_manifest = native_folding_verifier.transcript->get_manifest();

for (size_t i = 0; i < recursive_folding_manifest.size(); ++i) {
EXPECT_EQ(recursive_folding_manifest[i], native_folding_manifest[i]);
EXPECT_EQ(recursive_folding_manifest[i], native_folding_manifest[i])
<< "Recursive Verifier/Verifier manifest discrepency in round " << i;
}

// Check for a failure flag in the recursive verifier circuit
Expand Down Expand Up @@ -276,7 +277,8 @@ template <typename RecursiveFlavor> class ProtoGalaxyRecursiveTests : public tes
auto native_folding_manifest = native_folding_verifier.transcript->get_manifest();

for (size_t i = 0; i < recursive_folding_manifest.size(); ++i) {
EXPECT_EQ(recursive_folding_manifest[i], native_folding_manifest[i]);
EXPECT_EQ(recursive_folding_manifest[i], native_folding_manifest[i])
<< "Recursive Verifier/Verifier manifest discrepency in round " << i;
}

DeciderProver decider_prover(folding_proof.accumulator);
Expand Down
140 changes: 140 additions & 0 deletions barretenberg/cpp/src/barretenberg/ultra_honk/oink_verifier.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#include "barretenberg/ultra_honk/oink_verifier.hpp"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this file is largely copied, just split up into different functions


namespace bb {

/**
* @brief Oink Verifier function that runs all the rounds of the verifier
* @details Returns the witness commitments and relation_parameters
* @tparam Flavor
* @return OinkOutput<Flavor>
*/
template <IsUltraFlavor Flavor> OinkOutput<Flavor> OinkVerifier<Flavor>::verify()
{
// Execute the Verifier rounds
execute_preamble_round();
execute_wire_commitments_round();
execute_sorted_list_accumulator_round();
execute_log_derivative_inverse_round();
execute_grand_product_computation_round();

return OinkOutput<Flavor>{
.relation_parameters = relation_parameters,
.commitments = witness_comms,
};
}

/**
* @brief Get circuit size, public input size, and public inputs from transcript
*
*/
template <IsUltraFlavor Flavor> void OinkVerifier<Flavor>::execute_preamble_round()
{
// TODO(Adrian): Change the initialization of the transcript to take the VK hash?
const auto circuit_size = transcript->template receive_from_prover<uint32_t>(domain_separator + "circuit_size");
const auto public_input_size =
transcript->template receive_from_prover<uint32_t>(domain_separator + "public_input_size");
const auto pub_inputs_offset =
transcript->template receive_from_prover<uint32_t>(domain_separator + "pub_inputs_offset");

ASSERT(circuit_size == key->circuit_size);
Copy link
Contributor Author

@lucasxia01 lucasxia01 Mar 14, 2024

Choose a reason for hiding this comment

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

this could also be turn into if (circuit_size != key->circuit_size) return false; instead of assert.

ASSERT(public_input_size == key->num_public_inputs);
ASSERT(pub_inputs_offset == key->pub_inputs_offset);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

probably not needed as well. This should just be overwritten by transcript pub_inputs_offset?


std::vector<FF> public_inputs;
for (size_t i = 0; i < public_input_size; ++i) {
auto public_input_i =
transcript->template receive_from_prover<FF>(domain_separator + "public_input_" + std::to_string(i));
public_inputs.emplace_back(public_input_i);
ASSERT(public_input_i == key->public_inputs[i]);
}
}

/**
* @brief Get the wire polynomials (part of the witness), with the exception of the fourth wire, which is
* only received after adding memory records. In the Goblin Flavor, we also receive the ECC OP wires and the
* DataBus columns.
*/
template <IsUltraFlavor Flavor> void OinkVerifier<Flavor>::execute_wire_commitments_round()
{
// Get commitments to first three wire polynomials
witness_comms.w_l = transcript->template receive_from_prover<Commitment>(domain_separator + comm_labels.w_l);
witness_comms.w_r = transcript->template receive_from_prover<Commitment>(domain_separator + comm_labels.w_r);
witness_comms.w_o = transcript->template receive_from_prover<Commitment>(domain_separator + comm_labels.w_o);

// If Goblin, get commitments to ECC op wire polynomials and DataBus columns
if constexpr (IsGoblinFlavor<Flavor>) {
witness_comms.ecc_op_wire_1 =
transcript->template receive_from_prover<Commitment>(domain_separator + comm_labels.ecc_op_wire_1);
witness_comms.ecc_op_wire_2 =
transcript->template receive_from_prover<Commitment>(domain_separator + comm_labels.ecc_op_wire_2);
witness_comms.ecc_op_wire_3 =
transcript->template receive_from_prover<Commitment>(domain_separator + comm_labels.ecc_op_wire_3);
witness_comms.ecc_op_wire_4 =
transcript->template receive_from_prover<Commitment>(domain_separator + comm_labels.ecc_op_wire_4);
witness_comms.calldata =
transcript->template receive_from_prover<Commitment>(domain_separator + comm_labels.calldata);
witness_comms.calldata_read_counts =
transcript->template receive_from_prover<Commitment>(domain_separator + comm_labels.calldata_read_counts);
}
}

/**
* @brief Get sorted witness-table accumulator and fourth wire commitments
*
*/
template <IsUltraFlavor Flavor> void OinkVerifier<Flavor>::execute_sorted_list_accumulator_round()
{
// Get challenge for sorted list batching and wire four memory records
FF eta = transcript->template get_challenge<FF>(domain_separator + "eta");
relation_parameters.eta = eta;

// Get commitments to sorted list accumulator and fourth wire
witness_comms.sorted_accum =
transcript->template receive_from_prover<Commitment>(domain_separator + comm_labels.sorted_accum);
witness_comms.w_4 = transcript->template receive_from_prover<Commitment>(domain_separator + comm_labels.w_4);
}

/**
* @brief Get log derivative inverse polynomial and its commitment, if GoblinFlavor
*
*/
template <IsUltraFlavor Flavor> void OinkVerifier<Flavor>::execute_log_derivative_inverse_round()
{
// Get permutation challenges
auto [beta, gamma] = transcript->template get_challenges<FF>(domain_separator + "beta", domain_separator + "gamma");
relation_parameters.beta = beta;
relation_parameters.gamma = gamma;
// If Goblin (i.e. using DataBus) receive commitments to log-deriv inverses polynomial
if constexpr (IsGoblinFlavor<Flavor>) {
witness_comms.lookup_inverses =
transcript->template receive_from_prover<Commitment>(domain_separator + comm_labels.lookup_inverses);
}
}

/**
* @brief Compute lookup grand product delta and get permutation and lookup grand product commitments
*
*/
template <IsUltraFlavor Flavor> void OinkVerifier<Flavor>::execute_grand_product_computation_round()
{
const FF public_input_delta = compute_public_input_delta<Flavor>(key->public_inputs,
relation_parameters.beta,
relation_parameters.gamma,
key->circuit_size,
key->pub_inputs_offset);
const FF lookup_grand_product_delta =
compute_lookup_grand_product_delta<FF>(relation_parameters.beta, relation_parameters.gamma, key->circuit_size);

relation_parameters.public_input_delta = public_input_delta;
relation_parameters.lookup_grand_product_delta = lookup_grand_product_delta;

// Get commitment to permutation and lookup grand products
witness_comms.z_perm = transcript->template receive_from_prover<Commitment>(domain_separator + comm_labels.z_perm);
witness_comms.z_lookup =
transcript->template receive_from_prover<Commitment>(domain_separator + comm_labels.z_lookup);
}

template class OinkVerifier<UltraFlavor>;
template class OinkVerifier<GoblinUltraFlavor>;

} // namespace bb
60 changes: 60 additions & 0 deletions barretenberg/cpp/src/barretenberg/ultra_honk/oink_verifier.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#pragma once

#include "barretenberg/flavor/flavor.hpp"
#include "barretenberg/flavor/goblin_ultra.hpp"
#include "barretenberg/flavor/ultra.hpp"
#include "barretenberg/proof_system/library/grand_product_delta.hpp"
#include "barretenberg/relations/relation_parameters.hpp"

namespace bb {

template <IsUltraFlavor Flavor> struct OinkOutput {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

output state from Oink verifier

bb::RelationParameters<typename Flavor::FF> relation_parameters;
typename Flavor::WitnessCommitments commitments;
};

/**
* @brief Verifier class for all the presumcheck rounds, which are shared between the folding verifier and ultra
* verifier.
* @details This class contains execute_preamble_round(), execute_wire_commitments_round(),
* execute_sorted_list_accumulator_round(), execute_log_derivative_inverse_round(), and
* execute_grand_product_computation_round().
*
* @tparam Flavor
*/
template <IsUltraFlavor Flavor> class OinkVerifier {
using VerificationKey = typename Flavor::VerificationKey;
using WitnessCommitments = typename Flavor::WitnessCommitments;
using Transcript = typename Flavor::Transcript;
using FF = typename Flavor::FF;
using Commitment = typename Flavor::Commitment;

public:
std::shared_ptr<Transcript> transcript;
std::shared_ptr<VerificationKey> key;
std::string domain_separator;
typename Flavor::CommitmentLabels comm_labels;
bb::RelationParameters<FF> relation_parameters;
WitnessCommitments witness_comms;

OinkVerifier(const std::shared_ptr<VerificationKey>& verifier_key,
const std::shared_ptr<Transcript>& transcript,
std::string domain_separator = "")
: transcript(transcript)
, key(verifier_key)
, domain_separator(std::move(domain_separator))
{}

OinkOutput<Flavor> verify();

void execute_preamble_round();

void execute_wire_commitments_round();

void execute_sorted_list_accumulator_round();

void execute_log_derivative_inverse_round();

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