Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
cee04ed
first steps
iakovenkos Dec 4, 2024
b859440
wip: computing the batched big sum claim poly
iakovenkos Dec 5, 2024
ff70d41
wip wip assessing approaches
iakovenkos Dec 9, 2024
109ac5f
enhanced zk sumcheck data struct with prover's methods, fixed subgrou…
iakovenkos Dec 11, 2024
e986228
verifies, important pieces missing
iakovenkos Dec 11, 2024
77c386a
consistency check added
iakovenkos Dec 12, 2024
0e9a384
reduced the number of gates
iakovenkos Dec 13, 2024
d0f2dde
big sum masked
iakovenkos Dec 13, 2024
31505cf
masked constant term + clean-up
iakovenkos Dec 13, 2024
2986222
eccvm working
iakovenkos Dec 13, 2024
4577e05
cleaning up and simplifying
iakovenkos Dec 14, 2024
d35feb5
clean up + adding scalar field subgroup generators to curves
iakovenkos Dec 16, 2024
c9d43c6
separated zk sumcheck data from small subgroup ipa
iakovenkos Dec 16, 2024
559626c
isolated small subgroup ipa verifier methods
iakovenkos Dec 17, 2024
48ca947
more clean-up
iakovenkos Dec 17, 2024
29f6de7
mega with zk transcript test fixed
iakovenkos Dec 17, 2024
c37a3fc
eccvm and translator transcript tests + template on curve instead of …
iakovenkos Dec 18, 2024
000347e
Merge branch 'master' into si/fixing-libra-commitments-and-openings
iakovenkos Dec 18, 2024
537f268
bb native tests fix
iakovenkos Dec 18, 2024
ad60e4a
gcc build fix + clean-up + bn254 flavors subgroup size increase
iakovenkos Dec 18, 2024
e11702b
come back to 87
iakovenkos Dec 18, 2024
cfd31c1
Merge branch 'master' into si/fixing-libra-commitments-and-openings
iakovenkos Dec 18, 2024
63a855b
adding tests
iakovenkos Dec 18, 2024
be153e6
added ifft for bn254 - no need to commit to sumcheck univariates
iakovenkos Dec 19, 2024
20e8b53
docs + gcc
iakovenkos Dec 19, 2024
59d485f
Merge branch 'si/fixing-libra-commitments-and-openings' of github.com…
iakovenkos Dec 19, 2024
ee6f31d
Merge branch 'master' into si/fixing-libra-commitments-and-openings
iakovenkos Dec 19, 2024
2208253
minor clean-up
iakovenkos Dec 20, 2024
398f7de
small fix
iakovenkos Dec 20, 2024
6ab449b
resolved comments
iakovenkos Jan 2, 2025
c7ea181
sumcheck clean-up
iakovenkos Jan 2, 2025
6e03b63
Merge branch 'master' into si/fixing-libra-commitments-and-openings
iakovenkos Jan 3, 2025
90b7cde
removed noise in docs
iakovenkos Jan 3, 2025
ce8e47d
fix tests
iakovenkos Jan 3, 2025
b13eb0b
Merge branch 'master' into si/fixing-libra-commitments-and-openings
iakovenkos Jan 3, 2025
3c84180
review addressed
iakovenkos Jan 7, 2025
7231860
Merge branch 'master' into si/fixing-libra-commitments-and-openings
iakovenkos Jan 7, 2025
40792a0
Merge branch 'si/fixing-libra-commitments-and-openings' of github.com…
iakovenkos Jan 7, 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 @@ -309,6 +309,7 @@ TYPED_TEST(KZGTest, ShpleminiKzgWithShiftAndConcatenation)

// Gemini verifier output:
// - claim: d+1 commitments to Fold_{r}^(0), Fold_{-r}^(0), Fold^(l), d+1 evaluations a_0_pos, a_l, l = 0:d-1
bool consistency_checked = true;
const auto batch_opening_claim =
ShpleminiVerifier::compute_batch_opening_claim(n,
RefVector(unshifted_commitments),
Expand All @@ -318,7 +319,9 @@ TYPED_TEST(KZGTest, ShpleminiKzgWithShiftAndConcatenation)
mle_opening_point,
this->vk()->get_g1_identity(),
verifier_transcript,
{},
/* repeated commitments= */ {},
/* has zk = */ {},
&consistency_checked,
/* libra commitments = */ {},
/* libra evaluations = */ {},
to_vector_of_ref_vectors(concatenation_groups_commitments),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
#include "barretenberg/commitment_schemes/commitment_key.hpp"
#include "barretenberg/commitment_schemes/gemini/gemini_impl.hpp"
#include "barretenberg/commitment_schemes/shplonk/shplonk.hpp"
#include "barretenberg/commitment_schemes/small_subgroup_ipa/small_subgroup_ipa.hpp"
#include "barretenberg/commitment_schemes/verification_key.hpp"
#include "barretenberg/flavor/repeated_commitments_data.hpp"
#include "barretenberg/sumcheck/zk_sumcheck_data.hpp"
#include "barretenberg/transcript/transcript.hpp"

namespace bb {
Expand All @@ -28,13 +30,12 @@ template <typename Curve> class ShpleminiProver_ {
std::span<FF> multilinear_challenge,
const std::shared_ptr<CommitmentKey<Curve>>& commitment_key,
const std::shared_ptr<Transcript>& transcript,
const std::vector<bb::Univariate<FF, LENGTH>>& libra_univariates = {},
const std::vector<FF>& libra_evaluations = {},
const std::array<Polynomial, NUM_LIBRA_EVALUATIONS>& libra_polynomials = {},
RefSpan<Polynomial> concatenated_polynomials = {},
const std::vector<RefVector<Polynomial>>& groups_to_be_concatenated = {})
{
// While Shplemini is not templated on Flavor, we derive ZK flag this way
const bool has_zk = !libra_evaluations.empty();
const bool has_zk = (libra_polynomials[0].size() > 0);
std::vector<OpeningClaim> opening_claims = GeminiProver::prove(circuit_size,
f_polynomials,
g_polynomials,
Expand All @@ -46,15 +47,25 @@ template <typename Curve> class ShpleminiProver_ {
has_zk);
// Create opening claims for Libra masking univariates
std::vector<OpeningClaim> libra_opening_claims;
size_t idx = 0;
for (auto [libra_univariate, libra_evaluation] : zip_view(libra_univariates, libra_evaluations)) {
OpeningClaim new_claim;
new_claim.polynomial = Polynomial(libra_univariate);
new_claim.opening_pair.challenge = multilinear_challenge[idx];
new_claim.opening_pair.evaluation = libra_evaluation;
libra_opening_claims.push_back(new_claim);
idx++;
OpeningClaim new_claim;

if (has_zk) {
static constexpr FF subgroup_generator = Curve::subgroup_generator;
const auto gemini_r = opening_claims[0].opening_pair.challenge;

std::array<std::string, NUM_LIBRA_EVALUATIONS> libra_eval_labels = {
"Libra:concatenation_eval", "Libra:shifted_big_sum_eval", "Libra:big_sum_eval", "Libra:quotient_eval"
};
const std::array<FF, 4> evaluation_points = { gemini_r, gemini_r * subgroup_generator, gemini_r, gemini_r };
for (size_t idx = 0; idx < 4; idx++) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here we batch the prover's opening claims from SmallSubgroupIPA

new_claim.polynomial = std::move(libra_polynomials[idx]);
new_claim.opening_pair.challenge = evaluation_points[idx];
new_claim.opening_pair.evaluation = new_claim.polynomial.evaluate(evaluation_points[idx]);
transcript->send_to_verifier(libra_eval_labels[idx], new_claim.opening_pair.evaluation);
libra_opening_claims.push_back(new_claim);
}
}

const OpeningClaim batched_claim =
ShplonkProver::prove(commitment_key, opening_claims, transcript, libra_opening_claims);
return batched_claim;
Expand Down Expand Up @@ -134,13 +145,15 @@ template <typename Curve> class ShpleminiVerifier_ {
const Commitment& g1_identity,
const std::shared_ptr<Transcript>& transcript,
const RepeatedCommitmentsData& repeated_commitments = {},
RefSpan<Commitment> libra_univariate_commitments = {},
const std::vector<Fr>& libra_univariate_evaluations = {},
const bool has_zk = false,
bool* consistency_checked = nullptr, // TODO(https://github.com/AztecProtocol/barretenberg/issues/1191).
// Shplemini Refactoring: Remove bool pointer
const std::array<Commitment, NUM_LIBRA_COMMITMENTS>& libra_commitments = {},
const Fr& libra_univariate_evaluation = Fr{ 0 },
const std::vector<RefVector<Commitment>>& concatenation_group_commitments = {},
RefSpan<Fr> concatenated_evaluations = {})

{

// Extract log_circuit_size
size_t log_circuit_size{ 0 };
if constexpr (Curve::is_stdlib_type) {
Expand All @@ -152,7 +165,6 @@ template <typename Curve> class ShpleminiVerifier_ {
Fr batched_evaluation = Fr{ 0 };

// While Shplemini is not templated on Flavor, we derive ZK flag this way
const bool has_zk = !libra_univariate_evaluations.empty();
Commitment hiding_polynomial_commitment;
if (has_zk) {
hiding_polynomial_commitment =
Expand All @@ -176,6 +188,14 @@ template <typename Curve> class ShpleminiVerifier_ {
const std::vector<Fr> gemini_eval_challenge_powers =
gemini::powers_of_evaluation_challenge(gemini_evaluation_challenge, CONST_PROOF_SIZE_LOG_N);

std::array<Fr, NUM_LIBRA_EVALUATIONS> libra_evaluations;
if (has_zk) {
libra_evaluations[0] = transcript->template receive_from_prover<Fr>("Libra:concatenation_eval");
libra_evaluations[1] = transcript->template receive_from_prover<Fr>("Libra:shifted_big_sum_eval");
libra_evaluations[2] = transcript->template receive_from_prover<Fr>("Libra:big_sum_eval");
libra_evaluations[3] = transcript->template receive_from_prover<Fr>("Libra:quotient_eval");
}

// Process Shplonk transcript data:
// - Get Shplonk batching challenge
const Fr shplonk_batching_challenge = transcript->template get_challenge<Fr>("Shplonk:nu");
Expand Down Expand Up @@ -297,11 +317,14 @@ template <typename Curve> class ShpleminiVerifier_ {
if (has_zk) {
add_zk_data(commitments,
scalars,
libra_univariate_commitments,
libra_univariate_evaluations,
multivariate_challenge,
libra_commitments,
libra_evaluations,
gemini_evaluation_challenge,
shplonk_batching_challenge,
shplonk_evaluation_challenge);

*consistency_checked = SmallSubgroupIPAVerifier<Curve>::check_evaluations_consistency(
libra_evaluations, gemini_evaluation_challenge, multivariate_challenge, libra_univariate_evaluation);
}

return { commitments, scalars, shplonk_evaluation_challenge };
Expand Down Expand Up @@ -588,17 +611,17 @@ template <typename Curve> class ShpleminiVerifier_ {
*
* @param commitments
* @param scalars
* @param libra_univariate_commitments
* @param libra_commitments
* @param libra_univariate_evaluations
* @param multivariate_challenge
* @param shplonk_batching_challenge
* @param shplonk_evaluation_challenge
*/
static void add_zk_data(std::vector<Commitment>& commitments,
std::vector<Fr>& scalars,
RefSpan<Commitment> libra_univariate_commitments,
const std::vector<Fr>& libra_univariate_evaluations,
const std::vector<Fr>& multivariate_challenge,
const std::array<Commitment, NUM_LIBRA_COMMITMENTS>& libra_commitments,
const std::array<Fr, NUM_LIBRA_EVALUATIONS>& libra_evaluations,
const Fr& gemini_evaluation_challenge,
const Fr& shplonk_batching_challenge,
const Fr& shplonk_evaluation_challenge)

Expand All @@ -611,32 +634,35 @@ template <typename Curve> class ShpleminiVerifier_ {

// need to keep track of the contribution to the constant term
Fr& constant_term = scalars.back();
// compute shplonk denominators and batch invert them
std::vector<Fr> denominators;
size_t num_libra_univariates = libra_univariate_commitments.size();

// compute Shplonk denominators and invert them
for (size_t idx = 0; idx < num_libra_univariates; idx++) {
if constexpr (Curve::is_stdlib_type) {
denominators.push_back(Fr(1) / (shplonk_evaluation_challenge - multivariate_challenge[idx]));
} else {
denominators.push_back(shplonk_evaluation_challenge - multivariate_challenge[idx]);
}
};
if constexpr (!Curve::is_stdlib_type) {
Fr::batch_invert(denominators);
}
// add Libra commitments to the vector of commitments; compute corresponding scalars and the correction to
// the constant term
for (const auto [libra_univariate_commitment, denominator, libra_univariate_evaluation] :
zip_view(libra_univariate_commitments, denominators, libra_univariate_evaluations)) {
commitments.push_back(std::move(libra_univariate_commitment));
Fr scaling_factor = denominator * shplonk_challenge_power;
scalars.push_back((-scaling_factor));
for (size_t idx = 0; idx < libra_commitments.size(); idx++) {
commitments.push_back(libra_commitments[idx]);
}

std::array<Fr, NUM_LIBRA_EVALUATIONS> denominators;
std::array<Fr, NUM_LIBRA_EVALUATIONS> batching_scalars;
// compute Shplonk denominators and invert them
denominators[0] = Fr(1) / (shplonk_evaluation_challenge - gemini_evaluation_challenge);
denominators[1] =
Fr(1) / (shplonk_evaluation_challenge - Fr(Curve::subgroup_generator) * gemini_evaluation_challenge);
denominators[2] = denominators[0];
denominators[3] = denominators[0];

// compute the scalars to be multiplied against the commitments [libra_concatenated], [big_sum], [big_sum], and
// [libra_quotient]
for (size_t idx = 0; idx < libra_evaluations.size(); idx++) {
Fr scaling_factor = denominators[idx] * shplonk_challenge_power;
batching_scalars[idx] = -scaling_factor;
shplonk_challenge_power *= shplonk_batching_challenge;
// update the constant term of the Shplonk batched claim
constant_term += scaling_factor * libra_univariate_evaluation;
constant_term += scaling_factor * libra_evaluations[idx];
}

// to save a scalar mul, add the sum of the batching scalars corresponding to the big sum evaluations
scalars.push_back(batching_scalars[0]);
scalars.push_back(batching_scalars[1] + batching_scalars[2]);
scalars.push_back(batching_scalars[3]);
}
};
} // namespace bb
Original file line number Diff line number Diff line change
Expand Up @@ -223,118 +223,4 @@ TYPED_TEST(ShpleminiTest, CorrectnessOfGeminiClaimBatching)
EXPECT_EQ(shplemini_result, expected_result);
}

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 test got stale

/**
* @brief Libra masking univariates are used in sumcheck to prevent the leakage of witness data through the evaluations
* of round univariates. Here we test the opening of log_n Libra masking univariates batched with the opening of several
* prover polynomials and their shifts.
*
*/
TYPED_TEST(ShpleminiTest, ShpleminiWithMaskingLibraUnivariates)
{
using ShpleminiProver = ShpleminiProver_<TypeParam>;
using ShpleminiVerifier = ShpleminiVerifier_<TypeParam>;
using KZG = KZG<TypeParam>;
using IPA = IPA<TypeParam>;
using Fr = typename TypeParam::ScalarField;
using Commitment = typename TypeParam::AffineElement;
using Polynomial = typename bb::Polynomial<Fr>;

const size_t n = 16;
const size_t log_n = 4;
// In practice, the length of Libra univariates is equal to FLAVOR::BATCHED_RELATION_PARTIAL_LENGTH
const size_t LIBRA_UNIVARIATE_LENGTH = 12;

std::array<Fr, LIBRA_UNIVARIATE_LENGTH> interpolation_domain;
for (size_t idx = 0; idx < LIBRA_UNIVARIATE_LENGTH; idx++) {
interpolation_domain[idx] = Fr(idx);
}
// Generate multilinear polynomials, their commitments (genuine and mocked) and evaluations (genuine) at a
// random point.
auto mle_opening_point = this->random_evaluation_point(log_n); // sometimes denoted 'u'
auto poly1 = Polynomial::random(n);
auto poly2 = Polynomial::random(n, 1);
auto poly3 = Polynomial::random(n, 1);
auto poly4 = Polynomial::random(n);

std::vector<bb::Univariate<Fr, LIBRA_UNIVARIATE_LENGTH>> libra_univariates;
std::vector<Commitment> libra_commitments;
std::vector<Fr> libra_evaluations;
for (size_t idx = 0; idx < log_n; idx++) {
// generate random polynomial
Polynomial libra_polynomial = Polynomial::random(LIBRA_UNIVARIATE_LENGTH);
// create a univariate with the same coefficients (to store an array instead of a vector)
bb::Univariate<Fr, LIBRA_UNIVARIATE_LENGTH> libra_univariate;
for (size_t i = 0; i < LIBRA_UNIVARIATE_LENGTH; i++) {
libra_univariate.value_at(i) = libra_polynomial[i];
}
libra_univariates.push_back(libra_univariate);

// commit to libra polynomial and populate the vector of libra commitments
Commitment libra_commitment = this->commit(libra_polynomial);
libra_commitments.push_back(libra_commitment);

// evaluate current libra univariate at the corresponding challenge and store the value in libra evaluations
libra_evaluations.push_back(libra_polynomial.evaluate(mle_opening_point[idx]));
}

Commitment commitment1 = this->commit(poly1);
Commitment commitment2 = this->commit(poly2);
Commitment commitment3 = this->commit(poly3);
Commitment commitment4 = this->commit(poly4);
std::vector<Commitment> unshifted_commitments = { commitment1, commitment2, commitment3, commitment4 };
std::vector<Commitment> shifted_commitments = { commitment2, commitment3 };
auto eval1 = poly1.evaluate_mle(mle_opening_point);
auto eval2 = poly2.evaluate_mle(mle_opening_point);
auto eval3 = poly3.evaluate_mle(mle_opening_point);
auto eval4 = poly4.evaluate_mle(mle_opening_point);
auto eval2_shift = poly2.evaluate_mle(mle_opening_point, true);
auto eval3_shift = poly3.evaluate_mle(mle_opening_point, true);

// Collect multilinear evaluations for input to prover
// std::vector<Fr> multilinear_evaluations = { eval1, eval2, eval3, eval4, eval2_shift, eval3_shift };

auto prover_transcript = NativeTranscript::prover_init_empty();

// Run the full prover PCS protocol:
auto opening_claim = ShpleminiProver::prove(Fr{ n },
RefArray{ poly1, poly2, poly3, poly4 },
RefArray{ poly2, poly3 },
mle_opening_point,
this->ck(),
prover_transcript,
libra_univariates,
libra_evaluations);
if constexpr (std::is_same_v<TypeParam, curve::Grumpkin>) {
IPA::compute_opening_proof(this->ck(), opening_claim, prover_transcript);
} else {
KZG::compute_opening_proof(this->ck(), opening_claim, prover_transcript);
}

// Run the full verifier PCS protocol with genuine opening claims (genuine commitment, genuine evaluation)

auto verifier_transcript = NativeTranscript::verifier_init_empty(prover_transcript);

// Gemini verifier output:
// - claim: d+1 commitments to Fold_{r}^(0), Fold_{-r}^(0), Fold^(l), d+1 evaluations a_0_pos, a_l, l = 0:d-1
auto batch_opening_claim = ShpleminiVerifier::compute_batch_opening_claim(n,
RefVector(unshifted_commitments),
RefVector(shifted_commitments),
RefArray{ eval1, eval2, eval3, eval4 },
RefArray{ eval2_shift, eval3_shift },
mle_opening_point,
this->vk()->get_g1_identity(),
verifier_transcript,
{},
RefVector(libra_commitments),
libra_evaluations);

if constexpr (std::is_same_v<TypeParam, curve::Grumpkin>) {
auto result = IPA::reduce_verify_batch_opening_claim(batch_opening_claim, this->vk(), verifier_transcript);
EXPECT_EQ(result, true);
} else {
const auto pairing_points = KZG::reduce_verify_batch_opening_claim(batch_opening_claim, verifier_transcript);
// Final pairing check: e([Q] - [Q_z] + z[W], [1]_2) = e([W], [x]_2)
EXPECT_EQ(this->vk()->pairing_check(pairing_points[0], pairing_points[1]), true);
}
}
} // namespace bb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ template <typename Curve> class ShplonkProver_ {
{
// Find n, the maximum size of all polynomials fⱼ(X)
size_t max_poly_size{ 0 };

if (!libra_opening_claims.empty()) {
// Max size of the polynomials in Libra opening claims is Curve::SUBGROUP_SIZE*2 + 2; we round it up to the
// next power of 2
const size_t log_subgroup_size = static_cast<size_t>(numeric::get_msb(Curve::SUBGROUP_SIZE));
max_poly_size = 1 << (log_subgroup_size + 1);
};
for (const auto& claim : opening_claims) {
max_poly_size = std::max(max_poly_size, claim.polynomial.size());
}
Expand Down
Loading