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: eccvm sumcheck with commitments to round univariates #11206

Merged
merged 32 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
9a71a91
eccvm sumcheck butchered
iakovenkos Jan 10, 2025
1b18f05
wip wip
iakovenkos Jan 10, 2025
e00dd04
eccvm verifies
iakovenkos Jan 14, 2025
682c075
build fixed recursion failing
iakovenkos Jan 14, 2025
af6d6e6
debugging rec verifier
iakovenkos Jan 14, 2025
9323abe
recursion fix
iakovenkos Jan 14, 2025
230ce10
sumcheck output unified
iakovenkos Jan 14, 2025
f1eb3c5
remove self reduce
iakovenkos Jan 15, 2025
8cb98b0
trying to constify eccvm recursive
iakovenkos Jan 15, 2025
806ef49
Merge branch 'master' into si/fixing-eccvm-zk-sumcheck
iakovenkos Jan 16, 2025
41654f3
Merge branch 'master' into si/fixing-eccvm-zk-sumcheck
iakovenkos Jan 16, 2025
c91f533
build fix
iakovenkos Jan 16, 2025
e1d1d11
Merge branch 'si/fixing-eccvm-zk-sumcheck' of github.com:AztecProtoco…
iakovenkos Jan 16, 2025
7c73666
tests fixed
iakovenkos Jan 16, 2025
f525ef2
Merge branch 'master' into si/fixing-eccvm-zk-sumcheck
iakovenkos Jan 16, 2025
6aec0f7
commited sumcheck test added
iakovenkos Jan 17, 2025
74cd1a8
test cleaned up
iakovenkos Jan 17, 2025
f53a308
creating test for pcs
iakovenkos Jan 17, 2025
2f1f99d
Merge branch 'si/fixing-eccvm-zk-sumcheck' of github.com:AztecProtoco…
iakovenkos Jan 17, 2025
35df724
Merge branch 'master' into si/fixing-eccvm-zk-sumcheck
iakovenkos Jan 17, 2025
f4c3dc8
shplemini test + clean-up + figuring out constness
iakovenkos Jan 18, 2025
1587941
const proof size + clean up + docs
iakovenkos Jan 20, 2025
e94c031
eccvm bench correction
iakovenkos Jan 20, 2025
9e5e4e7
build fix
iakovenkos Jan 20, 2025
51b3766
Merge branch 'master' into si/fixing-eccvm-zk-sumcheck
iakovenkos Jan 20, 2025
6731c5d
more clean-up
iakovenkos Jan 20, 2025
fc108a3
Merge branch 'si/fixing-eccvm-zk-sumcheck' of github.com:AztecProtoco…
iakovenkos Jan 20, 2025
80b6bf0
Merge branch 'master' into si/fixing-eccvm-zk-sumcheck
iakovenkos Jan 20, 2025
48a1a18
eccvm recursive failure tests fixed
iakovenkos Jan 20, 2025
fdb62f1
bug fix
iakovenkos Jan 20, 2025
4a3f07b
resolving comments
iakovenkos Jan 21, 2025
98d304f
killed optional bool in sumcheck output + resolving comments
iakovenkos Jan 22, 2025
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 @@ -403,24 +403,21 @@ TYPED_TEST(ShpleminiTest, ShpleminiZKWithSumcheckOpenings)

std::shared_ptr<CK> ck = create_commitment_key<CK>(4096);

// Generate Sumcheck challenge
// Generate Sumcheck challenge, current implementation of Sumcheck Round Univariates batching in Shplemini assumes
// that the challenge is of CONST_PROOF_SIZE_LOG_N
std::vector<Fr> challenge = this->random_evaluation_point(CONST_PROOF_SIZE_LOG_N);

// Initialize the corresponding PCS inputs
std::vector<bb::Polynomial<Fr>> round_univariates = {};
std::vector<Commitment> sumcheck_commitments = {};
std::vector<std::array<Fr, 3>> sumcheck_evaluations = {};

// Generate valid sumcheck polynomials of given length
this->compute_sumcheck_opening_data(round_univariates, sumcheck_commitments, sumcheck_evaluations, challenge, ck);

auto prover_transcript = TypeParam::Transcript::prover_init_empty();

// Generate masking polynomials for Sumcheck Round Univariates
ZKSumcheckData<TypeParam> zk_sumcheck_data(this->log_n, prover_transcript, ck);
// Generate mock witness
InstanceWitnessGenerator<Curve> pcs_instance_witness(this->n, 1);

// Generate valid sumcheck polynomials of given length
pcs_instance_witness.template compute_sumcheck_opening_data<TypeParam>(
this->n, this->log_n, this->sumcheck_univariate_length, challenge, ck);

// Compute the sum of the Libra constant term and Libra univariates evaluated at Sumcheck challenges
const Fr claimed_inner_product =
SmallSubgroupIPAProver<TypeParam>::compute_claimed_inner_product(zk_sumcheck_data, challenge, this->log_n);
Expand All @@ -439,8 +436,8 @@ TYPED_TEST(ShpleminiTest, ShpleminiZKWithSumcheckOpenings)
ck,
prover_transcript,
small_subgroup_ipa_prover.get_witness_polynomials(),
round_univariates,
sumcheck_evaluations);
pcs_instance_witness.round_univariates,
pcs_instance_witness.sumcheck_evaluations);

if constexpr (std::is_same_v<TypeParam, GrumpkinSettings>) {
IPA<Curve>::compute_opening_proof(this->ck(), opening_claim, prover_transcript);
Expand Down Expand Up @@ -486,8 +483,8 @@ TYPED_TEST(ShpleminiTest, ShpleminiZKWithSumcheckOpenings)
&consistency_checked,
libra_commitments,
libra_evaluation,
sumcheck_commitments,
sumcheck_evaluations);
pcs_instance_witness.sumcheck_commitments,
pcs_instance_witness.sumcheck_evaluations);
// Verify claim using KZG or IPA
if constexpr (std::is_same_v<TypeParam, GrumpkinSettings>) {
auto result =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ template <typename Curve> struct InstanceWitnessGenerator {
std::vector<Fr> unshifted_evals;
std::vector<Fr> shifted_evals;

// Containers for mock Sumcheck data
std::vector<bb::Polynomial<Fr>> round_univariates;
std::vector<Commitment> sumcheck_commitments;
std::vector<std::array<Fr, 3>> sumcheck_evaluations;

InstanceWitnessGenerator(const size_t n,
const size_t num_polynomials,
const size_t num_shiftable,
Expand Down Expand Up @@ -78,16 +83,15 @@ template <typename Curve> struct InstanceWitnessGenerator {
}

template <typename Flavor>
void compute_sumcheck_opening_data(const size_t log_n,
void compute_sumcheck_opening_data(const size_t n,
const size_t log_n,
const size_t sumcheck_univariate_length,
std::vector<bb::Polynomial<Fr>>& round_univariates,
std::vector<Commitment>& sumcheck_commitments,
std::vector<std::array<Fr, 3>>& sumcheck_evaluations,
std::vector<Fr>& challenge,
std::shared_ptr<CommitmentKey>& ck)
{
// Generate valid sumcheck polynomials of given length
auto mock_sumcheck_polynomials = ZKSumcheckData<Flavor>(log_n, sumcheck_univariate_length);

for (size_t idx = 0; idx < log_n; idx++) {
bb::Polynomial<Fr> round_univariate = mock_sumcheck_polynomials.libra_univariates[idx];

Expand All @@ -104,8 +108,8 @@ template <typename Curve> struct InstanceWitnessGenerator {
}

// Simulate the `const proof size` logic
auto round_univariate = bb::Polynomial<Fr>(this->n);
for (size_t idx = this->log_n; idx < CONST_PROOF_SIZE_LOG_N; idx++) {
auto round_univariate = bb::Polynomial<Fr>(n);
for (size_t idx = log_n; idx < CONST_PROOF_SIZE_LOG_N; idx++) {
round_univariates.push_back(round_univariate);
sumcheck_commitments.push_back(ck->commit(round_univariate));
sumcheck_evaluations.push_back({ Fr(0), Fr(0), Fr(0) });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,5 +167,5 @@ TEST_F(ECCVMTests, CommittedSumcheck)
EXPECT_TRUE(prover_target_sum == verifier_output.round_univariate_evaluations[0][0] +
verifier_output.round_univariate_evaluations[0][1]);

EXPECT_TRUE(verifier_output.verified.value());
EXPECT_TRUE(verifier_output.verified);
}
6 changes: 3 additions & 3 deletions barretenberg/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ bool ECCVMVerifier::verify_proof(const ECCVMProof& proof)
libra_commitments[2] = transcript->template receive_from_prover<Commitment>("Libra:quotient_commitment");

// If Sumcheck did not verify, return false
if (sumcheck_output.verified.has_value() && !sumcheck_output.verified.value()) {
if (!sumcheck_output.verified) {
vinfo("eccvm sumcheck failed");
return false;
}
Expand Down Expand Up @@ -135,8 +135,8 @@ bool ECCVMVerifier::verify_proof(const ECCVMProof& proof)

const bool batched_opening_verified =
PCS::reduce_verify(key->pcs_verification_key, batch_opening_claim, ipa_transcript);
vinfo("eccvm sumcheck verified?: ", sumcheck_output.verified.value());
vinfo("eccvm sumcheck verified?: ", sumcheck_output.verified);
vinfo("batch opening verified?: ", batched_opening_verified);
return sumcheck_output.verified.value() && batched_opening_verified && consistency_checked;
return sumcheck_output.verified && batched_opening_verified && consistency_checked;
}
} // namespace bb
2 changes: 2 additions & 0 deletions barretenberg/cpp/src/barretenberg/flavor/flavor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,8 @@ concept IsRecursiveFlavor = IsAnyOf<T, UltraRecursiveFlavor_<UltraCircuitBuilder
ECCVMRecursiveFlavor_<UltraCircuitBuilder>,
AvmRecursiveFlavor_<UltraCircuitBuilder>>;

// These concepts are relevant for Sumcheck, where the logic is different for BN254 and Grumpkin Flavors
template <typename T> concept IsGrumpkinFlavor = IsAnyOf<T, ECCVMFlavor, ECCVMRecursiveFlavor_<UltraCircuitBuilder>>;
template <typename T> concept IsECCVMRecursiveFlavor = IsAnyOf<T, ECCVMRecursiveFlavor_<UltraCircuitBuilder>>;


Expand Down
32 changes: 16 additions & 16 deletions barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,16 @@ template <typename Flavor> class SumcheckProver {
std::shared_ptr<Transcript> transcript;
SumcheckProverRound<Flavor> round;

static constexpr bool IS_ECCVM = std::is_same_v<Flavor, ECCVMFlavor>;
std::vector<FF> multivariate_challenge;

std::vector<typename Flavor::Commitment> round_univariate_commitments = {};
std::vector<std::array<FF, 3>> round_evaluations = {};
std::vector<Polynomial<FF>> round_univariates = {};
std::vector<FF> eval_domain = {};
FF libra_evaluation = FF{ 0 };

RowDisablingPolynomial<FF> row_disabling_polynomial;

/**
*
* @brief Container for partially evaluated Prover Polynomials at a current challenge. Upon computing challenge \f$
Expand Down Expand Up @@ -189,7 +192,6 @@ template <typename Flavor> class SumcheckProver {

bb::GateSeparatorPolynomial<FF> gate_separators(gate_challenges, multivariate_d);

std::vector<FF> multivariate_challenge;
multivariate_challenge.reserve(multivariate_d);
// In the first round, we compute the first univariate polynomial and populate the book-keeping table of
// #partially_evaluated_polynomials, which has \f$ n/2 \f$ rows and \f$ N \f$ columns. When the Flavor has ZK,
Expand Down Expand Up @@ -267,8 +269,13 @@ template <typename Flavor> class SumcheckProver {
{
std::shared_ptr<CommitmentKey> ck = nullptr;

if constexpr (IS_ECCVM) {
if constexpr (IsGrumpkinFlavor<Flavor>) {
ck = std::make_shared<CommitmentKey>(BATCHED_RELATION_PARTIAL_LENGTH);
// Compute the vector {0, 1, \ldots, BATCHED_RELATION_PARTIAL_LENGTH-1} needed to transform the round
// univariates from Lagrange to monomial basis
for (size_t idx = 0; idx < BATCHED_RELATION_PARTIAL_LENGTH; idx++) {
eval_domain.push_back(FF(idx));
}
} else {
// Ensure that the length of Sumcheck Round Univariates does not exceed the length of Libra masking
// polynomials.
Expand All @@ -277,10 +284,8 @@ template <typename Flavor> class SumcheckProver {

bb::GateSeparatorPolynomial<FF> gate_separators(gate_challenges, multivariate_d);

std::vector<FF> multivariate_challenge;
multivariate_challenge.reserve(multivariate_d);
size_t round_idx = 0;
RowDisablingPolynomial<FF> row_disabling_polynomial;
// In the first round, we compute the first univariate polynomial and populate the book-keeping table of
// #partially_evaluated_polynomials, which has \f$ n/2 \f$ rows and \f$ N \f$ columns. When the Flavor has ZK,
// compute_univariate also takes into account the zk_sumcheck_data.
Expand All @@ -296,15 +301,10 @@ template <typename Flavor> class SumcheckProver {

PROFILE_THIS_NAME("rest of sumcheck round 1");

if constexpr (!IS_ECCVM) {
if constexpr (!IsGrumpkinFlavor<Flavor>) {
// Place the evaluations of the round univariate into transcript.
transcript->send_to_verifier("Sumcheck:univariate_0", round_univariate);
} else {
// Compute the vector {0, 1, \ldots, BATCHED_RELATION_PARTIAL_LENGTH-1} needed to transform the round
// univariates from Lagrange to monomial basis
for (size_t idx = 0; idx < BATCHED_RELATION_PARTIAL_LENGTH; idx++) {
eval_domain.push_back(FF(idx));
}

// Compute monomial coefficients of the round univariate, commit to it, populate an auxiliary structure
// needed in the PCS round
Expand Down Expand Up @@ -337,7 +337,7 @@ template <typename Flavor> class SumcheckProver {
alpha,
zk_sumcheck_data,
row_disabling_polynomial);
if constexpr (!IS_ECCVM) {
if constexpr (!IsGrumpkinFlavor<Flavor>) {
// Place evaluations of Sumcheck Round Univariate in the transcript
transcript->send_to_verifier("Sumcheck:univariate_" + std::to_string(round_idx), round_univariate);
} else {
Expand All @@ -360,7 +360,7 @@ template <typename Flavor> class SumcheckProver {
round.round_size = round.round_size >> 1;
}

if constexpr (IS_ECCVM) {
if constexpr (IsGrumpkinFlavor<Flavor>) {
round_evaluations[multivariate_d - 1][2] =
round_univariate.evaluate(multivariate_challenge[multivariate_d - 1]);
}
Expand All @@ -369,7 +369,7 @@ template <typename Flavor> class SumcheckProver {
// Zero univariates are used to pad the proof to the fixed size CONST_PROOF_SIZE_LOG_N.
auto zero_univariate = bb::Univariate<FF, Flavor::BATCHED_RELATION_PARTIAL_LENGTH>::zero();
for (size_t idx = multivariate_d; idx < CONST_PROOF_SIZE_LOG_N; idx++) {
if constexpr (!IS_ECCVM) {
if constexpr (!IsGrumpkinFlavor<Flavor>) {
transcript->send_to_verifier("Sumcheck:univariate_" + std::to_string(idx), zero_univariate);
} else {
transcript->send_to_verifier("Sumcheck:univariate_comm_" + std::to_string(idx),
Expand All @@ -396,7 +396,7 @@ template <typename Flavor> class SumcheckProver {

// The sum of the Libra constant term and the evaluations of Libra univariates at corresponding sumcheck
// challenges is included in the Sumcheck Output
if constexpr (!IS_ECCVM) {
if constexpr (!IsGrumpkinFlavor<Flavor>) {
return SumcheckOutput<Flavor>{ .challenge = multivariate_challenge,
.claimed_evaluations = multivariate_evaluations,
.claimed_libra_evaluation = libra_evaluation };
Expand Down Expand Up @@ -742,7 +742,7 @@ template <typename Flavor> class SumcheckVerifier {
SumcheckOutput<Flavor> verify(const bb::RelationParameters<FF>& relation_parameters,
Copy link
Contributor

Choose a reason for hiding this comment

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

Ok right so you've already made a separate method for verify so probably even more reason to do something similar for prove. Above I suggested a specialization rather than a separate method entirely but I think either approach works

Copy link
Contributor Author

Choose a reason for hiding this comment

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

replied above

RelationSeparator alpha,
const std::vector<FF>& gate_challenges)
requires std::is_same_v<Flavor, ECCVMFlavor> || IsECCVMRecursiveFlavor<Flavor>
requires IsGrumpkinFlavor<Flavor>
{
bool verified(false);

Expand Down
4 changes: 2 additions & 2 deletions barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ template <typename Flavor> class SumcheckTests : public ::testing::Test {
}
auto verifier_output = sumcheck_verifier.verify(relation_parameters, verifier_alpha, verifier_gate_challenges);

auto verified = verifier_output.verified.value();
auto verified = verifier_output.verified;

EXPECT_EQ(verified, true);
};
Expand Down Expand Up @@ -367,7 +367,7 @@ template <typename Flavor> class SumcheckTests : public ::testing::Test {
}
auto verifier_output = sumcheck_verifier.verify(relation_parameters, verifier_alpha, verifier_gate_challenges);

auto verified = verifier_output.verified.value();
auto verified = verifier_output.verified;

EXPECT_EQ(verified, false);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ template <typename Flavor> struct SumcheckOutput {
ClaimedEvaluations claimed_evaluations;
// Whether or not the evaluations of multilinear polynomials \f$ P_1, \ldots, P_N \f$ and final Sumcheck evaluation
// have been confirmed
std::optional<bool> verified = false; // optional b/c this struct is shared by the Prover/Verifier
bool verified = false;
Copy link
Contributor

Choose a reason for hiding this comment

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

thank you for this!

// For ZK Flavors: the sum of the Libra constant term and Libra univariates evaluated at Sumcheck challenges
FF claimed_libra_evaluation = FF{ 0 };
// For ECCVMVerifier: Commitments to round univariates
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ bool TranslatorVerifier::verify_proof(const HonkProof& proof)
auto sumcheck_output = sumcheck.verify(relation_parameters, alpha, gate_challenges);

// If Sumcheck did not verify, return false
if (sumcheck_output.verified.has_value() && !sumcheck_output.verified.value()) {
if (!sumcheck_output.verified) {
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ template <typename Flavor> bool DeciderVerifier_<Flavor>::verify()
}

// If Sumcheck did not verify, return false
if (sumcheck_output.verified.has_value() && !sumcheck_output.verified.value()) {
if (!sumcheck_output.verified) {
info("Sumcheck verification failed.");
return false;
}
Expand All @@ -81,7 +81,7 @@ template <typename Flavor> bool DeciderVerifier_<Flavor>::verify()
sumcheck_output.claimed_libra_evaluation);
const auto pairing_points = PCS::reduce_verify_batch_opening_claim(opening_claim, transcript);
bool verified = pcs_verification_key->pairing_check(pairing_points[0], pairing_points[1]);
return sumcheck_output.verified.value() && verified && consistency_checked;
return sumcheck_output.verified && verified && consistency_checked;
}

template class DeciderVerifier_<UltraFlavor>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ TEST_F(SumcheckTestsRealCircuit, Ultra)
auto verifier_output =
sumcheck_verifier.verify(decider_pk->relation_parameters, verifier_alphas, verifier_gate_challenges);

auto verified = verifier_output.verified.value();
auto verified = verifier_output.verified;

ASSERT_TRUE(verified);
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ AvmRecursiveVerifier_<Flavor>::AggregationObject AvmRecursiveVerifier_<Flavor>::
// when called over a "circuit field" types.
SumcheckOutput<Flavor> output = sumcheck.verify(relation_parameters, alpha, gate_challenges);

vinfo("verified sumcheck: ", (output.verified.has_value() && output.verified.value()));
vinfo("verified sumcheck: ", (output.verified));

// Public columns evaluation checks
std::vector<FF> mle_challenge(output.challenge.begin(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ bool AvmVerifier::verify_proof(const HonkProof& proof, const std::vector<std::ve
SumcheckOutput<Flavor> output = sumcheck.verify(relation_parameters, alpha, gate_challenges);

// If Sumcheck did not verify, return false
if (!output.verified.has_value() || !output.verified.value()) {
if (!output.verified) {
vinfo("Sumcheck verification failed");
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ bool AvmVerifier::verify_proof(const HonkProof& proof, const std::vector<std::ve
SumcheckOutput<Flavor> output = sumcheck.verify(relation_parameters, alpha, gate_challenges);

// If Sumcheck did not verify, return false
if (!output.verified.has_value() || !output.verified.value()) {
if (!output.verified) {
vinfo("Sumcheck verification failed");
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ AvmRecursiveVerifier_<Flavor>::AggregationObject AvmRecursiveVerifier_<Flavor>::
// when called over a "circuit field" types.
SumcheckOutput<Flavor> output = sumcheck.verify(relation_parameters, alpha, gate_challenges);

vinfo("verified sumcheck: ", (output.verified.has_value() && output.verified.value()));
vinfo("verified sumcheck: ", (output.verified));

// Public columns evaluation checks
std::vector<FF> mle_challenge(output.challenge.begin(),
Expand Down
2 changes: 1 addition & 1 deletion bb-pilcom/bb-pil-backend/templates/verifier.cpp.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ bool AvmVerifier::verify_proof(const HonkProof& proof, const std::vector<std::ve
SumcheckOutput<Flavor> output = sumcheck.verify(relation_parameters, alpha, gate_challenges);

// If Sumcheck did not verify, return false
if (!output.verified.has_value() || !output.verified.value()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks @iakovenkos for having adapted the AVM templates.

if (!output.verified) {
vinfo("Sumcheck verification failed");
return false;
}
Expand Down
Loading