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: split up eccvm proof into two proofs #9914

Merged
merged 6 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ void eccvm_prove(State& state) noexcept
Builder builder = generate_trace(target_num_gates);
ECCVMProver prover(builder);
for (auto _ : state) {
auto proof = prover.construct_proof();
ECCVMProof proof = prover.construct_proof();
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ template <typename Curve_> class IPA {

size_t poly_length = polynomial.size();

// TODO(https://github.com/AztecProtocol/barretenberg/issues/1150): Hash more things here.
// Step 1.
// Send polynomial degree + 1 = d to the verifier
transcript->send_to_verifier("IPA:poly_degree_plus_1", static_cast<uint32_t>(poly_length));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ TEST_F(ECCVMTests, BaseCase)
{
ECCVMCircuitBuilder builder = generate_circuit(&engine);
ECCVMProver prover(builder);
HonkProof proof = prover.construct_proof();
ECCVMProof proof = prover.construct_proof();
ECCVMVerifier verifier(prover.key);
bool verified = verifier.verify_proof(proof);

Expand All @@ -79,7 +79,7 @@ TEST_F(ECCVMTests, EqFails)
builder.op_queue->num_transcript_rows++;
ECCVMProver prover(builder);

auto proof = prover.construct_proof();
ECCVMProof proof = prover.construct_proof();
ECCVMVerifier verifier(prover.key);
bool verified = verifier.verify_proof(proof);
ASSERT_FALSE(verified);
Expand Down
65 changes: 46 additions & 19 deletions barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -951,11 +951,6 @@ class ECCVMFlavor {
FF translation_eval_z1;
FF translation_eval_z2;
Commitment shplonk_q2_comm;
uint32_t ipa_poly_degree;
std::vector<Commitment> ipa_l_comms;
std::vector<Commitment> ipa_r_comms;
Commitment ipa_G_0_eval;
FF ipa_a_0_eval;

Transcript() = default;

Expand Down Expand Up @@ -1188,20 +1183,6 @@ class ECCVMFlavor {
NativeTranscript::template deserialize_from_buffer<FF>(NativeTranscript::proof_data, num_frs_read);

shplonk_q2_comm = NativeTranscript::template deserialize_from_buffer<Commitment>(proof_data, num_frs_read);

ipa_poly_degree = NativeTranscript::template deserialize_from_buffer<uint32_t>(NativeTranscript::proof_data,
num_frs_read);

for (size_t i = 0; i < CONST_ECCVM_LOG_N; ++i) {
ipa_l_comms.emplace_back(NativeTranscript::template deserialize_from_buffer<Commitment>(
NativeTranscript::proof_data, num_frs_read));
ipa_r_comms.emplace_back(NativeTranscript::template deserialize_from_buffer<Commitment>(
NativeTranscript::proof_data, num_frs_read));
}
ipa_G_0_eval = NativeTranscript::template deserialize_from_buffer<Commitment>(NativeTranscript::proof_data,
num_frs_read);
ipa_a_0_eval =
NativeTranscript::template deserialize_from_buffer<FF>(NativeTranscript::proof_data, num_frs_read);
}

void serialize_full_transcript()
Expand Down Expand Up @@ -1344,6 +1325,52 @@ class ECCVMFlavor {

NativeTranscript::template serialize_to_buffer(shplonk_q2_comm, NativeTranscript::proof_data);

ASSERT(NativeTranscript::proof_data.size() == old_proof_length);
}
};

/**
* @brief Derived class that defines proof structure for ECCVM IPA proof, as well as supporting functions.
*
*/
class IPATranscript : public NativeTranscript {
public:
uint32_t ipa_poly_degree;
std::vector<Commitment> ipa_l_comms;
std::vector<Commitment> ipa_r_comms;
Commitment ipa_G_0_eval;
FF ipa_a_0_eval;

IPATranscript() = default;

IPATranscript(const HonkProof& proof)
: NativeTranscript(proof)
{}

void deserialize_full_transcript()
{
// take current proof and put them into the struct
size_t num_frs_read = 0;
ipa_poly_degree = NativeTranscript::template deserialize_from_buffer<uint32_t>(NativeTranscript::proof_data,
num_frs_read);

for (size_t i = 0; i < CONST_ECCVM_LOG_N; ++i) {
ipa_l_comms.emplace_back(NativeTranscript::template deserialize_from_buffer<Commitment>(
NativeTranscript::proof_data, num_frs_read));
ipa_r_comms.emplace_back(NativeTranscript::template deserialize_from_buffer<Commitment>(
NativeTranscript::proof_data, num_frs_read));
}
ipa_G_0_eval = NativeTranscript::template deserialize_from_buffer<Commitment>(NativeTranscript::proof_data,
num_frs_read);
ipa_a_0_eval =
NativeTranscript::template deserialize_from_buffer<FF>(NativeTranscript::proof_data, num_frs_read);
}

void serialize_full_transcript()
{
size_t old_proof_length = NativeTranscript::proof_data.size();
NativeTranscript::proof_data.clear();

NativeTranscript::template serialize_to_buffer(ipa_poly_degree, NativeTranscript::proof_data);
for (size_t i = 0; i < CONST_ECCVM_LOG_N; ++i) {
NativeTranscript::template serialize_to_buffer(ipa_l_comms[i], NativeTranscript::proof_data);
Expand Down
14 changes: 8 additions & 6 deletions barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@

namespace bb {

ECCVMProver::ECCVMProver(CircuitBuilder& builder, const std::shared_ptr<Transcript>& transcript)
ECCVMProver::ECCVMProver(CircuitBuilder& builder,
const std::shared_ptr<Transcript>& transcript,
const std::shared_ptr<Transcript>& ipa_transcript)
: transcript(transcript)
, ipa_transcript(ipa_transcript)
{
PROFILE_THIS_NAME("ECCVMProver(CircuitBuilder&)");

Expand Down Expand Up @@ -183,21 +186,20 @@ void ECCVMProver::execute_pcs_rounds()
const OpeningClaim batch_opening_claim = Shplonk::prove(key->commitment_key, opening_claims, transcript);

// Compute the opening proof for the batched opening claim with the univariate PCS
PCS::compute_opening_proof(key->commitment_key, batch_opening_claim, transcript);
PCS::compute_opening_proof(key->commitment_key, batch_opening_claim, ipa_transcript);

// Produce another challenge passed as input to the translator verifier
translation_batching_challenge_v = transcript->template get_challenge<FF>("Translation:batching_challenge");

vinfo("computed opening proof");
}

HonkProof ECCVMProver::export_proof()
ECCVMProof ECCVMProver::export_proof()
{
proof = transcript->export_proof();
return proof;
return { transcript->export_proof(), ipa_transcript->export_proof() };
}

HonkProof ECCVMProver::construct_proof()
ECCVMProof ECCVMProver::construct_proof()
{
PROFILE_THIS_NAME("ECCVMProver::construct_proof");

Expand Down
11 changes: 5 additions & 6 deletions barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ class ECCVMProver {
using CircuitBuilder = typename Flavor::CircuitBuilder;

explicit ECCVMProver(CircuitBuilder& builder,
const std::shared_ptr<Transcript>& transcript = std::make_shared<Transcript>());
const std::shared_ptr<Transcript>& transcript = std::make_shared<Transcript>(),
const std::shared_ptr<Transcript>& ipa_transcript = std::make_shared<Transcript>());

BB_PROFILE void execute_preamble_round();
BB_PROFILE void execute_wire_commitments_round();
Expand All @@ -37,10 +38,11 @@ class ECCVMProver {
BB_PROFILE void execute_pcs_rounds();
BB_PROFILE void execute_transcript_consistency_univariate_opening_round();

HonkProof export_proof();
HonkProof construct_proof();
ECCVMProof export_proof();
ECCVMProof construct_proof();

std::shared_ptr<Transcript> transcript;
std::shared_ptr<Transcript> ipa_transcript;

TranslationEvaluations translation_evaluations;

Expand All @@ -62,9 +64,6 @@ class ECCVMProver {
FF translation_batching_challenge_v; // to be rederived by the translator verifier

SumcheckOutput<Flavor> sumcheck_output;

private:
HonkProof proof;
};

} // namespace bb
42 changes: 33 additions & 9 deletions barretenberg/cpp/src/barretenberg/eccvm/eccvm_transcript.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,19 @@ class ECCVMTranscriptTests : public ::testing::Test {
manifest_expected.add_challenge(round, "Shplonk:z");

round++;
manifest_expected.add_challenge(round, "Translation:batching_challenge");

return manifest_expected;
}

TranscriptManifest construct_eccvm_ipa_manifest()
{
TranscriptManifest manifest_expected;
// Size of types is number of bb::frs needed to represent the type
size_t frs_per_Fr = bb::field_conversion::calc_num_bn254_frs<FF>();
size_t frs_per_G = bb::field_conversion::calc_num_bn254_frs<typename Flavor::Commitment>();
size_t frs_per_uint32 = bb::field_conversion::calc_num_bn254_frs<uint32_t>();
size_t round = 0;
manifest_expected.add_entry(round, "IPA:poly_degree_plus_1", frs_per_uint32);
manifest_expected.add_challenge(round, "IPA:generator_challenge");

Expand All @@ -220,8 +233,6 @@ class ECCVMTranscriptTests : public ::testing::Test {
round++;
manifest_expected.add_entry(round, "IPA:G_0", frs_per_G);
manifest_expected.add_entry(round, "IPA:a_0", frs_per_Fr);
manifest_expected.add_challenge(round, "Translation:batching_challenge");

return manifest_expected;
}

Expand Down Expand Up @@ -271,7 +282,7 @@ TEST_F(ECCVMTranscriptTests, ProverManifestConsistency)

// Automatically generate a transcript manifest by constructing a proof
ECCVMProver prover(builder);
auto proof = prover.construct_proof();
ECCVMProof proof = prover.construct_proof();

// Check that the prover generated manifest agrees with the manifest hard coded in this suite
auto manifest_expected = this->construct_eccvm_honk_manifest(prover.key->circuit_size);
Expand All @@ -281,6 +292,15 @@ TEST_F(ECCVMTranscriptTests, ProverManifestConsistency)
for (size_t round = 0; round < manifest_expected.size(); ++round) {
ASSERT_EQ(prover_manifest[round], manifest_expected[round]) << "Prover manifest discrepency in round " << round;
}

auto ipa_manifest_expected = this->construct_eccvm_ipa_manifest();
auto prover_ipa_manifest = prover.ipa_transcript->get_manifest();

// Note: a manifest can be printed using manifest.print()
for (size_t round = 0; round < ipa_manifest_expected.size(); ++round) {
ASSERT_EQ(prover_ipa_manifest[round], ipa_manifest_expected[round])
<< "IPA prover manifest discrepency in round " << round;
}
}

/**
Expand All @@ -295,7 +315,7 @@ TEST_F(ECCVMTranscriptTests, VerifierManifestConsistency)

// Automatically generate a transcript manifest in the prover by constructing a proof
ECCVMProver prover(builder);
auto proof = prover.construct_proof();
ECCVMProof proof = prover.construct_proof();

// Automatically generate a transcript manifest in the verifier by verifying a proof
ECCVMVerifier verifier(prover.key);
Expand Down Expand Up @@ -347,24 +367,28 @@ TEST_F(ECCVMTranscriptTests, StructureTest)

// Automatically generate a transcript manifest by constructing a proof
ECCVMProver prover(builder);
auto proof = prover.construct_proof();
ECCVMProof proof = prover.construct_proof();
ECCVMVerifier verifier(prover.key);
EXPECT_TRUE(verifier.verify_proof(proof));

// try deserializing and serializing with no changes and check proof is still valid
prover.transcript->deserialize_full_transcript();
prover.transcript->serialize_full_transcript();
EXPECT_TRUE(
verifier.verify_proof(prover.transcript->proof_data)); // we have changed nothing so proof is still valid
EXPECT_TRUE(verifier.verify_proof(
{ prover.transcript->proof_data,
prover.ipa_transcript->proof_data })); // we have changed nothing so proof is still valid

typename Flavor::Commitment one_group_val = Flavor::Commitment::one();
auto rand_val = Flavor::FF::random_element();
prover.transcript->transcript_Px_comm = one_group_val * rand_val; // choose random object to modify
EXPECT_TRUE(verifier.verify_proof(
prover.transcript->proof_data)); // we have not serialized it back to the proof so it should still be fine
{ prover.transcript->proof_data, prover.ipa_transcript->proof_data })); // we have not serialized it back to the
// proof so it should still be fine

prover.transcript->serialize_full_transcript();
EXPECT_FALSE(verifier.verify_proof(prover.transcript->proof_data)); // the proof is now wrong after serializing it
EXPECT_FALSE(
verifier.verify_proof({ prover.transcript->proof_data,
prover.ipa_transcript->proof_data })); // the proof is now wrong after serializing it

prover.transcript->deserialize_full_transcript();
EXPECT_EQ(static_cast<typename Flavor::Commitment>(prover.transcript->transcript_Px_comm),
Expand Down
7 changes: 4 additions & 3 deletions barretenberg/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@ namespace bb {
/**
* @brief This function verifies an ECCVM Honk proof for given program settings.
*/
bool ECCVMVerifier::verify_proof(const HonkProof& proof)
bool ECCVMVerifier::verify_proof(const ECCVMProof& proof)
{
using Curve = typename Flavor::Curve;
using Shplemini = ShpleminiVerifier_<Curve>;
using Shplonk = ShplonkVerifier_<Curve>;
using OpeningClaim = OpeningClaim<Curve>;

RelationParameters<FF> relation_parameters;
transcript = std::make_shared<Transcript>(proof);
transcript = std::make_shared<Transcript>(proof.pre_ipa_proof);
ipa_transcript = std::make_shared<Transcript>(proof.ipa_proof);
VerifierCommitments commitments{ key };
CommitmentLabels commitment_labels;

Expand Down Expand Up @@ -127,7 +128,7 @@ bool ECCVMVerifier::verify_proof(const HonkProof& proof)
Shplonk::reduce_verification(key->pcs_verification_key->get_g1_identity(), opening_claims, transcript);

const bool batched_opening_verified =
PCS::reduce_verify(key->pcs_verification_key, batch_opening_claim, transcript);
PCS::reduce_verify(key->pcs_verification_key, batch_opening_claim, ipa_transcript);
vinfo("eccvm sumcheck verified?: ", sumcheck_verified.value());
vinfo("batch opening verified?: ", batched_opening_verified);
return sumcheck_verified.value() && batched_opening_verified;
Expand Down
3 changes: 2 additions & 1 deletion barretenberg/cpp/src/barretenberg/eccvm/eccvm_verifier.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ class ECCVMVerifier {
explicit ECCVMVerifier(const std::shared_ptr<ECCVMVerifier::ProvingKey>& proving_key)
: ECCVMVerifier(std::make_shared<ECCVMFlavor::VerificationKey>(proving_key)){};

bool verify_proof(const HonkProof& proof);
bool verify_proof(const ECCVMProof& proof);

std::shared_ptr<VerificationKey> key;
std::map<std::string, Commitment> commitments;
std::shared_ptr<Transcript> transcript;
std::shared_ptr<Transcript> ipa_transcript;
};
} // namespace bb
5 changes: 3 additions & 2 deletions barretenberg/cpp/src/barretenberg/goblin/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ struct GoblinProof {
using FF = MegaFlavor::FF;

HonkProof merge_proof;
HonkProof eccvm_proof;
ECCVMProof eccvm_proof;
HonkProof translator_proof;
ECCVMProver::TranslationEvaluations translation_evaluations;

size_t size() const
{
return merge_proof.size() + eccvm_proof.size() + translator_proof.size() + TranslationEvaluations::size();
return merge_proof.size() + eccvm_proof.pre_ipa_proof.size() + eccvm_proof.ipa_proof.size() +
translator_proof.size() + TranslationEvaluations::size();
};

MSGPACK_FIELDS(merge_proof, eccvm_proof, translator_proof, translation_evaluations);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ static constexpr size_t HONK_PROOF_PUBLIC_INPUT_OFFSET = 3;
static constexpr size_t PUBLIC_INPUTS_SIZE_INDEX = 1;

using HonkProof = std::vector<bb::fr>; // this can be fr?
struct ECCVMProof {
HonkProof pre_ipa_proof;
HonkProof ipa_proof;

MSGPACK_FIELDS(pre_ipa_proof, ipa_proof);
};

template <typename Builder> using StdlibProof = std::vector<bb::stdlib::field_t<Builder>>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ ECCVMRecursiveVerifier_<Flavor>::ECCVMRecursiveVerifier_(
/**
* @brief This function verifies an ECCVM Honk proof for given program settings up to sumcheck.
*/
template <typename Flavor> void ECCVMRecursiveVerifier_<Flavor>::verify_proof(const HonkProof& proof)
template <typename Flavor> void ECCVMRecursiveVerifier_<Flavor>::verify_proof(const ECCVMProof& proof)
{
using Curve = typename Flavor::Curve;
using Shplemini = ShpleminiVerifier_<Curve>;
Expand All @@ -25,8 +25,10 @@ template <typename Flavor> void ECCVMRecursiveVerifier_<Flavor>::verify_proof(co

RelationParameters<FF> relation_parameters;

StdlibProof<Builder> stdlib_proof = bb::convert_proof_to_witness(builder, proof);
StdlibProof<Builder> stdlib_proof = bb::convert_proof_to_witness(builder, proof.pre_ipa_proof);
StdlibProof<Builder> stdlib_ipa_proof = bb::convert_proof_to_witness(builder, proof.ipa_proof);
transcript = std::make_shared<Transcript>(stdlib_proof);
ipa_transcript = std::make_shared<Transcript>(stdlib_ipa_proof);

VerifierCommitments commitments{ key };
CommitmentLabels commitment_labels;
Expand Down Expand Up @@ -140,7 +142,7 @@ template <typename Flavor> void ECCVMRecursiveVerifier_<Flavor>::verify_proof(co

// TODO(https://github.com/AztecProtocol/barretenberg/issues/1142): Handle this return value correctly.
const typename PCS::VerifierAccumulator batched_opening_accumulator =
PCS::reduce_verify(batch_opening_claim, transcript);
PCS::reduce_verify(batch_opening_claim, ipa_transcript);
ASSERT(sumcheck_verified);
}

Expand Down
Loading
Loading