Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
maramihali committed Sep 11, 2023
1 parent 8a7c7da commit 8e480cb
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ template <UltraFlavor Flavor> void Instance_<Flavor>::construct_ecc_op_wire_poly
{
std::array<polynomial, Flavor::NUM_WIRES> op_wire_polynomials;
for (auto& poly : op_wire_polynomials) {
poly = polynomial(dyadic_circuit_size);
poly = static_cast<polynomial>(dyadic_circuit_size);
}

// The ECC op wires are constructed to contain the op data on the appropriate range and to vanish everywhere else.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,25 @@
#include "barretenberg/honk/flavor/goblin_ultra.hpp"
#include "barretenberg/honk/flavor/ultra.hpp"
#include "barretenberg/honk/flavor/ultra_grumpkin.hpp"
#include "barretenberg/honk/proof_system/folding_result.hpp"
#include "barretenberg/proof_system/composer/composer_lib.hpp"
#include "barretenberg/proof_system/flavor/flavor.hpp"
#include "barretenberg/proof_system/relations/relation_parameters.hpp"
#include "barretenberg/srs/factories/file_crs_factory.hpp"

#include <cstddef>
#include <memory>
#include <utility>
#include <vector>
namespace proof_system::honk {
// Need verifier instance as well
// An Instance is created from a Circuit and we ini tialise all the data structure that rely on information from a
// circuit Then a Prover and a Verifier is created from an Instance or several instances and each manages their own
// polynomials
// The responsability of a Prover is to commit, add to transcript while the Instance manages its polynomials
// TODO: we might wanna have a specialisaition of the Instance class for the Accumulator
/**
* @brief An Instance is normally constructed from a finalised circuit and it's role is to compute all the polynomials
* involved in creating a proof and, if requested, the verification key.
* In case of folded Instance, this will be created from the FoldingResult, the aggregated work from the folding prover
* and verifier. More specifically, a folded instance will be constructed from the complete set of folded polynomials
* and folded public inputs and its FoldingParams are expected to be non-zero
*
*/

template <UltraFlavor Flavor> class Instance_ {
public:
using Circuit = typename Flavor::CircuitBuilder;
Expand All @@ -39,9 +42,8 @@ template <UltraFlavor Flavor> class Instance_ {

ProverPolynomials prover_polynomials;

// After instances have been folded, the pub_inputs_offset will become irrelevant as it's used for computing the 4th
// wire polynomial and a folded instance does not care about wires anymore.
// Furthermore, folding limits us to having the same number of public inputs.
// The number of public inputs has to be the same for all instances because they are
// folded element by element.
std::vector<FF> public_inputs;
size_t pub_inputs_offset;

Expand All @@ -68,11 +70,11 @@ template <UltraFlavor Flavor> class Instance_ {
compute_witness(circuit);
}

Instance_(ProverPolynomials polys, std::vector<FF> public_inputs, std::shared_ptr<VerificationKey> vk)
: verification_key(std::move(vk))
, prover_polynomials(polys)
, public_inputs(public_inputs)
{}
Instance_(FoldingResult<Flavor> result)
: verification_key(std::move(result.verification_key))
, prover_polynomials(result.folded_prover_polynomials)
, public_inputs(result.folded_public_inputs)
, folding_params(result.params){};

Instance_(Instance_&& other) noexcept = default;
Instance_(Instance_ const& other) noexcept = default;
Expand Down
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,24 @@ template <UltraFlavor Flavor> struct VerifierFoldingResult {
using FF = typename Flavor::FF;
using VerificationKey = typename Flavor::VerificationKey;
using FoldingParameters = typename Flavor::FoldingParameters;
// TODO: what happens to the public input offsets
std::vector<FF> folded_public_inputs;
VerificationKey verification_key;
VerificationKey folded_verification_key;
FoldingParameters parameters;
};

/**
* @brief The aggregated result from the prover and verifier after a round of folding, used to create a new Instance.
*
* @tparam Flavor
*/
template <UltraFlavor Flavor> struct FoldingResult {
using FF = typename Flavor::FF;
using ProverPolynomials = typename Flavor::ProverPolynomials;
using VerificationKey = typename Flavor::VerificationKey;
using FoldingParameters = typename Flavor::FoldingParameters;
ProverPolynomials folded_prover_polynomials;
std::vector<FF> folded_public_inputs;
std::shared_ptr<VerificationKey> verification_key;
FoldingParameters params;
};
} // namespace proof_system::honk
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ ProtoGalaxyProver_<Flavor>::ProtoGalaxyProver_(std::vector<std::shared_ptr<Insta
: instances(insts)
{}

// Prior to folding we need to:
// - add all public inputs to the transcript, labelled by their corresponding instance index
// - finalise computation of all the instance's polynomials
// - add the relation parameters involved in computing the instances polynomials to the transcript
/**
* @brief Prior to folding we need to add all the public inputs to the transcript, labelled by their corresponding
* instance index, compute all the instance's polynomials and record the relation parameters involved in computing these
* polynomials in the transcript.
*
*/
template <UltraFlavor Flavor> void ProtoGalaxyProver_<Flavor>::prepare_for_folding()
{
for (const auto& instance : instances) {
Expand All @@ -21,21 +23,30 @@ template <UltraFlavor Flavor> void ProtoGalaxyProver_<Flavor>::prepare_for_foldi

transcript.send_to_verifier(instance_index + "_circuit_size", circuit_size);
transcript.send_to_verifier(instance_index + "_public_input_size", num_public_inputs);
// transcript.send_to_verifier(instance_index + "_pub_inputs_offset",
// static_cast<uint32_t>(instance.pub_inputs_offset));
transcript.send_to_verifier(instance_index + "_pub_inputs_offset",
static_cast<uint32_t>(instance->pub_inputs_offset));

for (size_t i = 0; i < instance->proving_key->num_public_inputs; ++i) {
auto public_input_i = instance->public_inputs[i];
transcript.send_to_verifier(instance_index + "_public_input_" + std::to_string(i), public_input_i);
}

auto eta = transcript.get_challenge(instance_index + "_eta");
auto [eta, beta, gamma] =
transcript.get_challenges(instance_index + "_eta", instance_index + "_beta", instance_index + "_gamma");
instance->compute_sorted_accumulator_polynomials(eta);
auto [beta, gamma] = transcript.get_challenges(instance_index + "_beta", instance_index + "_gamma");
instance->compute_grand_product_polynomials(beta, gamma);
}
}

// TODO(#689): implement this function
template <UltraFlavor Flavor> ProverFoldingResult<Flavor> ProtoGalaxyProver_<Flavor>::fold_instances()
{
prepare_for_folding();
ProverFoldingResult<Flavor> res;
res.folding_data = transcript.proof_data;
return res;
}

template class ProtoGalaxyProver_<honk::flavor::Ultra>;
template class ProtoGalaxyProver_<honk::flavor::UltraGrumpkin>;
template class ProtoGalaxyProver_<honk::flavor::GoblinUltra>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,19 @@ VerifierFoldingResult<Flavor> ProtoGalaxyVerifier_<Flavor>::fold_public_paramete

for (size_t i = 0; i < inst.public_input_size; ++i) {
auto public_input_i =
transcript.template receive_from_prover<FF>(idx + "public_input_" + std::to_string(i));
transcript.template receive_from_prover<FF>(idx + "_public_input_" + std::to_string(i));
inst.public_inputs.emplace_back(public_input_i);
}
auto eta = transcript.get_challenge(idx + "_eta");
auto [beta, gamma] = transcript.get_challenges(idx + "_beta", idx + "_gamma");
auto [eta, beta, gamma] = transcript.get_challenges(idx + "_eta", idx + "_beta", idx + "_gamma");
const FF public_input_delta = compute_public_input_delta<Flavor>(
inst.public_inputs, beta, gamma, inst.circuit_size, inst.pub_inputs_offset);
const FF lookup_grand_product_delta = compute_lookup_grand_product_delta<FF>(beta, gamma, inst.circuit_size);
inst.relation_parameters =
RelationParameters<FF>{ eta, beta, gamma, public_input_delta, lookup_grand_product_delta };
verifier_instances.emplace_back(inst);
}

// TODO(#722): implement the Protogalaxy verifier logic
VerifierFoldingResult<Flavor> res;
return res;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ template <UltraFlavor Flavor> class UltraProver_ {
void execute_wire_commitments_round();
void execute_sorted_list_accumulator_round();
void execute_grand_product_computation_round();
void execute_commitment_finalisation_round();
void execute_relation_check_rounds();
void execute_univariatization_round();
void execute_pcs_evaluation_round();
Expand Down Expand Up @@ -60,7 +59,6 @@ template <UltraFlavor Flavor> class UltraProver_ {

Instance& instance;

// this should be ProverOutput
sumcheck::SumcheckOutput<Flavor> sumcheck_output;
pcs::gemini::ProverOutput<Curve> gemini_output;
pcs::shplonk::ProverOutput<Curve> shplonk_output;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ template <typename Flavor> UltraVerifier_<Flavor>& UltraVerifier_<Flavor>::opera
}

/**
* @brief This function verifies an Ultra Honk proof for given program settings.
* @brief This function verifies an Ultra Honk proof for a given Flavor.
*
*/
template <typename Flavor> bool UltraVerifier_<Flavor>::verify_proof(const plonk::proof& proof)
Expand Down Expand Up @@ -68,8 +68,6 @@ template <typename Flavor> bool UltraVerifier_<Flavor>::verify_proof(const plonk
public_inputs.emplace_back(public_input_i);
}

// up to here in the folding verifier as well

// Get commitments to first three wire polynomials
commitments.w_l = transcript.template receive_from_prover<Commitment>(commitment_labels.w_l);
commitments.w_r = transcript.template receive_from_prover<Commitment>(commitment_labels.w_r);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,19 +130,16 @@ template <typename FF> class BaseTranscript {

public:
/**
* @brief After all the prover messages have been sent, finalize the round by hashing all the data, create the field
* elements and reset the state in preparation for the next round.
* @brief After all the prover messages have been sent, finalize the round by hashing all the data and then create
* the number of requested challenges which will be increasing powers of the first challenge. Finally, reset the
* state in preparation for the next round.
*
* @param labels human-readable names for the challenges for the manifest
* @return std::array<FF, num_challenges> challenges for this round.
*/
template <typename... Strings> std::array<FF, sizeof...(Strings)> get_challenges(const Strings&... labels)
{
constexpr size_t num_challenges = sizeof...(Strings);
constexpr size_t bytes_per_challenge = HASH_OUTPUT_SIZE / num_challenges;

// Ensure we have enough entropy from the hash function to construct each challenge.
static_assert(bytes_per_challenge >= MIN_BYTES_PER_CHALLENGE, "requested too many challenges in this round");

// Add challenge labels for current round to the manifest
manifest.add_challenge(round_number, labels...);
Expand All @@ -152,17 +149,16 @@ template <typename FF> class BaseTranscript {

// Create challenges from bytes.
std::array<FF, num_challenges> challenges{};
for (size_t i = 0; i < num_challenges; ++i) {
// Initialize the buffer for the i-th challenge with 0s.
std::array<uint8_t, sizeof(FF)> field_element_buffer{};
// Copy the i-th chunk of size `bytes_per_challenge` to the start of `field_element_buffer`
// The last bytes will be 0,
std::copy_n(next_challenge_buffer.begin() + i * bytes_per_challenge,
bytes_per_challenge,
field_element_buffer.begin());

// Create a FF element from a slice of bytes of next_challenge_buffer.
challenges[i] = from_buffer<FF>(field_element_buffer);

std::array<uint8_t, sizeof(FF)> field_element_buffer{};
std::copy_n(next_challenge_buffer.begin(), HASH_OUTPUT_SIZE, field_element_buffer.begin());

challenges[0] = from_buffer<FF>(field_element_buffer);

// TODO(#583): rework the transcript to have a better structure and be able to produce a variable amount of
// challenges that are not powers of each other
for (size_t i = 1; i < num_challenges; i++) {
challenges[i] = challenges[i - 1] * challenges[0];
}

// Prepare for next round.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,25 @@
using namespace proof_system::honk;

template <typename Flavor> class TranscriptTests : public testing::Test {
public:
protected:
// TODO(640): The Standard Honk on Grumpkin test suite fails unless the SRS is initialised for every test.
virtual void SetUp()
{
if constexpr (IsGrumpkinFlavor<Flavor>) {
barretenberg::srs::init_grumpkin_crs_factory("../srs_db/grumpkin");
} else {
barretenberg::srs::init_crs_factory("../srs_db/ignition");
}
};

using FF = typename Flavor::FF;
static void SetUpTestSuite() { barretenberg::srs::init_crs_factory("../srs_db/ignition"); }

/**
* @brief Construct a manifest for a standard Honk proof
*
* @details This is where we define the "Manifest" for a Standard Honk proof. The tests in this suite are intented
* to warn the developer if the Prover/Verifier has deviated from this manifest, however, the Transcript class is
* not otherwise contrained to follow the manifest.
* @details This is where we define the "Manifest" for a Standard Honk proof. The tests in this suite are
* intented to warn the developer if the Prover/Verifier has deviated from this manifest, however, the
* Transcript class is not otherwise contrained to follow the manifest.
*
* @note Entries in the manifest consist of a name string and a size (bytes), NOT actual data.
*
Expand Down Expand Up @@ -282,17 +291,16 @@ TYPED_TEST(TranscriptTests, VerifierMistake)
* construction and the one generated by the verifier over the course of proof verification.
*
*/
// TODO(Mara): This is not a typed test and we should have a construct_ultra_honk_manifest as well.
TYPED_TEST(TranscriptTests, UltraVerifierManifestConsistency)
TEST(TranscriptTests, UltraVerifierManifestConsistency)
{
barretenberg::srs::init_crs_factory("../srs_db/ignition");

// Construct a simple circuit of size n = 8 (i.e. the minimum circuit size)
auto circuit_constructor = proof_system::UltraCircuitBuilder();

// fr a = 2;
// circuit_constructor.add_variable(a);
// circuit_constructor.add_public_variable(a);

circuit_constructor.add_gates_to_ensure_all_polys_are_non_zero();
fr a = 2;
circuit_constructor.add_variable(a);
circuit_constructor.add_public_variable(a);

// Automatically generate a transcript manifest in the prover by constructing a proof
auto composer = UltraComposer();
Expand All @@ -317,3 +325,48 @@ TYPED_TEST(TranscriptTests, UltraVerifierManifestConsistency)
<< "Prover/Verifier manifest discrepency in round " << round;
}
}

TEST(TranscriptTests, FoldingManifestTest)
{
barretenberg::srs::init_crs_factory("../srs_db/ignition");

auto builder_one = proof_system::UltraCircuitBuilder();
fr a = 2;
fr b = 3;
builder_one.add_variable(a);
builder_one.add_public_variable(a);
builder_one.add_public_variable(b);

auto builder_two = proof_system::UltraCircuitBuilder();
a = 3;
b = 4;
builder_two.add_variable(a);
builder_two.add_variable(b);
builder_two.add_public_variable(a);
builder_two.add_public_variable(b);

auto composer = UltraComposer();
auto instance_one = composer.create_instance(builder_one);
auto instance_two = composer.create_instance(builder_two);

std::vector<std::shared_ptr<Instance>> insts;
insts.emplace_back(std::make_shared<Instance>(instance_one));
insts.emplace_back(std::make_shared<Instance>(instance_two));
auto prover = composer.create_folding_prover(insts);
auto verifier = composer.create_folding_verifier(insts);

auto prover_res = prover.fold_instances();
verifier.fold_public_parameters(prover_res.folding_data);

prover.transcript.print();
verifier.transcript.print();

// Check consistency between the manifests generated by the prover and verifier
auto prover_manifest = prover.transcript.get_manifest();
auto verifier_manifest = verifier.transcript.get_manifest();

for (size_t round = 0; round < prover_manifest.size(); ++round) {
ASSERT_EQ(prover_manifest[round], verifier_manifest[round])
<< "Prover/Verifier manifest discrepency in round " << round;
}
}

0 comments on commit 8e480cb

Please sign in to comment.