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
ead1afc
small refactor of translation evals logic in eccvm
iakovenkos Feb 17, 2025
d9d9a1f
+ ECCVMTranslation Class; extended functionality in SmallSubgroupIPA
iakovenkos Feb 18, 2025
5504006
test added
iakovenkos Feb 18, 2025
acc8a51
test passes
iakovenkos Feb 18, 2025
4d4349e
cleaning up
iakovenkos Feb 18, 2025
3aa169b
small subgroup ipa test clean-up
iakovenkos Feb 19, 2025
6628ec7
propagate translation challenges from eccvm verifier to translator ve…
iakovenkos Feb 19, 2025
a51d492
slightly more sound
iakovenkos Feb 20, 2025
bfaab51
IndependentVKHash test added to Goblin
iakovenkos Feb 20, 2025
b4eaa6b
Merge branch 'master' into si/fix-translation-evaluations
iakovenkos Feb 20, 2025
b21a2b2
fix build
iakovenkos Feb 20, 2025
bcc3284
translation labels no longer constexpr to fix build
iakovenkos Feb 20, 2025
ae74a81
Merge branch 'master' into si/fix-translation-evaluations
iakovenkos Feb 20, 2025
8af3dbf
first steps: extending the eccvm prover
iakovenkos Feb 20, 2025
7d8e932
renamed constants + docs
iakovenkos Feb 24, 2025
a18fc20
Merge branch 'master' into si/fix-translation-evaluations
iakovenkos Feb 24, 2025
98f29b0
fix build
iakovenkos Feb 24, 2025
9eec4c3
Merge branch 'si/fix-translation-evaluations' of github.com:AztecProt…
iakovenkos Feb 24, 2025
7d2a2ee
Merge branch 'si/fix-translation-evaluations' into si/fix-translation…
iakovenkos Feb 24, 2025
bfe9f09
integration + clean-up
iakovenkos Feb 24, 2025
896cd45
wip: recursive verifiers
iakovenkos Feb 24, 2025
8731224
Merge branch 'master' into si/fix-translation-evaluations-pt2
iakovenkos Feb 28, 2025
e08c1fe
build fixed
iakovenkos Feb 28, 2025
790a71d
fix tests
iakovenkos Mar 3, 2025
c9b6d5f
cleaning up
iakovenkos Mar 3, 2025
44ea7b1
ECCVMProver docs explaining the SmallSubgroupIPA usage + shift the ma…
iakovenkos Mar 3, 2025
e1704c7
more consistency in consts
iakovenkos Mar 3, 2025
f449343
more clean-up
iakovenkos Mar 3, 2025
2b498f0
polishing
iakovenkos Mar 4, 2025
77fc71d
Merge branch 'master' into si/fix-translation-evaluations-pt2
iakovenkos Mar 4, 2025
e5aab7d
fix tests
iakovenkos Mar 4, 2025
8bad944
Merge branch 'master' into si/fix-translation-evaluations-pt2
iakovenkos Mar 4, 2025
5285563
Merge branch 'master' into si/fix-translation-evaluations-pt2
iakovenkos Mar 4, 2025
3112079
cleanup after review
iakovenkos Mar 6, 2025
80f3630
Merge branch 'si/fix-translation-evaluations-pt2' of github.com:Aztec…
iakovenkos Mar 6, 2025
233b355
Merge branch 'master' into si/fix-translation-evaluations-pt2
iakovenkos Mar 6, 2025
06efe1f
Merge branch 'master' into si/fix-translation-evaluations-pt2
iakovenkos Mar 6, 2025
471a9ad
fix build
iakovenkos Mar 6, 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 @@ -605,8 +605,8 @@ template <typename Curve> class ShpleminiVerifier_ {
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]
// compute the scalars to be multiplied against the commitments [libra_concatenated], [grand_sum], [grand_sum],
// and [libra_quotient]
for (size_t idx = 0; idx < NUM_SMALL_IPA_EVALUATIONS; idx++) {
Fr scaling_factor = denominators[idx] * shplonk_challenge_power;
batching_scalars[idx] = -scaling_factor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,22 +85,26 @@ template <typename Flavor>
SmallSubgroupIPAProver<Flavor>::SmallSubgroupIPAProver(TranslationData<typename Flavor::Transcript>& translation_data,
const FF evaluation_challenge_x,
const FF batching_challenge_v,
const FF claimed_inner_product,
const std::shared_ptr<typename Flavor::Transcript>& transcript,
std::shared_ptr<typename Flavor::CommitmentKey>& commitment_key)
: SmallSubgroupIPAProver(transcript, commitment_key)

{
// TranslationData is Grumpkin-specific
if constexpr (IsAnyOf<Flavor, ECCVMFlavor, GrumpkinSettings>) {
this->claimed_inner_product = claimed_inner_product;
label_prefix = "Translation:";
interpolation_domain = translation_data.interpolation_domain;
concatenated_polynomial = translation_data.masked_concatenated_polynomial;
concatenated_lagrange_form = translation_data.concatenated_polynomial_lagrange;

// Construct the challenge polynomial in Lagrange basis, compute its monomial coefficients
compute_eccvm_challenge_polynomial(evaluation_challenge_x, batching_challenge_v);

// The prover computes the inner product of the challenge polynomial and the concatenation of
// the masking terms. This value is used to "denoise" the masked batched evaluation of
// `translation_polynomials` contained in `translation_data`.
claimed_inner_product = compute_claimed_translation_inner_product(translation_data);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

realized that the claimed sum could be computed here, makes ECCVMProver integration slightly cleaner

transcript->send_to_verifier(label_prefix + "masking_term_eval", claimed_inner_product);
}
}

Expand Down Expand Up @@ -396,17 +400,10 @@ typename Flavor::Curve::ScalarField SmallSubgroupIPAProver<Flavor>::compute_clai
*/
template <typename Flavor>
typename Flavor::Curve::ScalarField SmallSubgroupIPAProver<Flavor>::compute_claimed_translation_inner_product(
TranslationData<typename Flavor::Transcript>& translation_data,
const FF& evaluation_challenge_x,
const FF& batching_challenge_v)
TranslationData<typename Flavor::Transcript>& translation_data)
{
FF claimed_inner_product{ 0 };
if constexpr (IsAnyOf<Flavor, ECCVMFlavor, GrumpkinSettings>) {
const std::vector<FF> coeffs_lagrange_basis =
compute_eccvm_challenge_coeffs<typename Flavor::Curve>(evaluation_challenge_x, batching_challenge_v);

Polynomial<FF> challenge_polynomial_lagrange(coeffs_lagrange_basis);

for (size_t idx = 0; idx < SUBGROUP_SIZE; idx++) {
claimed_inner_product +=
translation_data.concatenated_polynomial_lagrange.at(idx) * challenge_polynomial_lagrange.at(idx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "barretenberg/polynomials/univariate.hpp"
#include "barretenberg/stdlib/primitives/curves/grumpkin.hpp"
#include "barretenberg/sumcheck/zk_sumcheck_data.hpp"
#include "small_subgroup_ipa_utils.hpp"

#include <array>
#include <vector>
Expand Down Expand Up @@ -87,9 +88,6 @@ template <typename Flavor> class SmallSubgroupIPAProver {
// Fixed generator of H
static constexpr FF subgroup_generator = Curve::subgroup_generator;

// The SmallSubgroupIPA claim
FF claimed_inner_product;

// Interpolation domain {1, g, \ldots, g^{SUBGROUP_SIZE - 1}} used by ECCVM
std::array<FF, SUBGROUP_SIZE> interpolation_domain;
// We use IFFT over BN254 scalar field
Expand Down Expand Up @@ -123,6 +121,9 @@ template <typename Flavor> class SmallSubgroupIPAProver {
std::shared_ptr<typename Flavor::CommitmentKey> commitment_key;

public:
// The SmallSubgroupIPA claim
FF claimed_inner_product{ 0 };

// Default constructor to initialize all polynomials, transcript, and commitment key.
SmallSubgroupIPAProver(const std::shared_ptr<typename Flavor::Transcript>& transcript,
std::shared_ptr<typename Flavor::CommitmentKey>& commitment_key);
Expand All @@ -138,7 +139,6 @@ template <typename Flavor> class SmallSubgroupIPAProver {
SmallSubgroupIPAProver(TranslationData<typename Flavor::Transcript>& translation_data,
const FF evaluation_challenge_x,
const FF batching_challenge_v,
const FF claimed_inner_product,
const std::shared_ptr<typename Flavor::Transcript>& transcript,
std::shared_ptr<typename Flavor::CommitmentKey>& commitment_key);

Expand All @@ -161,9 +161,7 @@ template <typename Flavor> class SmallSubgroupIPAProver {
const std::vector<FF>& multivariate_challenge,
const size_t& log_circuit_size);

static FF compute_claimed_translation_inner_product(TranslationData<typename Flavor::Transcript>& translation_data,
const FF& evaluation_challenge_x,
const FF& batching_challenge_v);
FF compute_claimed_translation_inner_product(TranslationData<typename Flavor::Transcript>& translation_data);

Polynomial<FF> static compute_monomial_coefficients(std::span<FF> lagrange_coeffs,
const std::array<FF, SUBGROUP_SIZE>& interpolation_domain,
Expand All @@ -178,6 +176,16 @@ template <typename Flavor> class SmallSubgroupIPAProver {
// Getters for test purposes
const Polynomial<FF>& get_batched_polynomial() const { return grand_sum_identity_polynomial; }
const Polynomial<FF>& get_challenge_polynomial() const { return challenge_polynomial; }

std::array<FF, NUM_SMALL_IPA_EVALUATIONS> evaluation_points(const FF& small_ipa_evaluation_challenge)
{
return compute_evaluation_points(small_ipa_evaluation_challenge, Curve::subgroup_generator);
}

std::array<std::string, NUM_SMALL_IPA_EVALUATIONS> evaluation_labels()
{
return get_evaluation_labels(label_prefix);
};
};

/*!
Expand Down Expand Up @@ -390,6 +398,14 @@ template <typename Curve> class SmallSubgroupIPAVerifier {
result.begin(), result.end(), result.begin(), [&](FF& denominator) { return denominator * numerator; });
return result;
}
static std::array<FF, NUM_SMALL_IPA_EVALUATIONS> evaluation_points(const FF& small_ipa_evaluation_challenge)
{
return compute_evaluation_points<FF>(small_ipa_evaluation_challenge, Curve::subgroup_generator);
}
static std::array<std::string, NUM_SMALL_IPA_EVALUATIONS> evaluation_labels(const std::string& label_prefix)
{
return get_evaluation_labels(label_prefix);
};
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ template <typename Flavor> class SmallSubgroupIPATest : public ::testing::Test {

// A helper to evaluate the four IPA witness polynomials at x, x*g, x, x
std::array<FF, NUM_SMALL_IPA_EVALUATIONS> evaluate_small_ipa_witnesses(
const std::array<Polynomial<FF>, 4>& witness_polynomials)
const std::array<Polynomial<FF>, NUM_SMALL_IPA_EVALUATIONS>& witness_polynomials)
{
// Hard-coded pattern of evaluation: (x, x*g, x, x)
return { witness_polynomials[0].evaluate(evaluation_challenge),
Expand Down Expand Up @@ -289,25 +289,19 @@ TYPED_TEST(SmallSubgroupIPATest, TranslationMaskingTermConsistency)
const FF evaluation_challenge_x = FF::random_element();
const FF batching_challenge_v = FF::random_element();

const FF claimed_inner_product = Prover::compute_claimed_translation_inner_product(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

no need to compute the claimed inner product separately since it's done inside the constructor

translation_data, evaluation_challenge_x, batching_challenge_v);

Prover small_subgroup_ipa_prover(translation_data,
evaluation_challenge_x,
batching_challenge_v,
claimed_inner_product,
prover_transcript,
ck);
Prover small_subgroup_ipa_prover(
translation_data, evaluation_challenge_x, batching_challenge_v, prover_transcript, ck);
small_subgroup_ipa_prover.prove();

const std::array<FF, NUM_SMALL_IPA_EVALUATIONS> small_ipa_evaluations =
this->evaluate_small_ipa_witnesses(small_subgroup_ipa_prover.get_witness_polynomials());

bool consistency_checked = Verifier::check_eccvm_evaluations_consistency(small_ipa_evaluations,
this->evaluation_challenge,
evaluation_challenge_x,
batching_challenge_v,
claimed_inner_product);
bool consistency_checked =
Verifier::check_eccvm_evaluations_consistency(small_ipa_evaluations,
this->evaluation_challenge,
evaluation_challenge_x,
batching_challenge_v,
small_subgroup_ipa_prover.claimed_inner_product);

EXPECT_TRUE(consistency_checked);
}
Expand Down Expand Up @@ -348,24 +342,19 @@ TYPED_TEST(SmallSubgroupIPATest, TranslationMaskingTermConsistencyFailure)
const FF evaluation_challenge_x = FF::random_element();
const FF batching_challenge_v = FF::random_element();

const FF claimed_inner_product = FF::random_element();

Prover small_subgroup_ipa_prover(translation_data,
evaluation_challenge_x,
batching_challenge_v,
claimed_inner_product,
prover_transcript,
ck);
Prover small_subgroup_ipa_prover(
translation_data, evaluation_challenge_x, batching_challenge_v, prover_transcript, ck);
small_subgroup_ipa_prover.prove();

const std::array<FF, NUM_SMALL_IPA_EVALUATIONS> small_ipa_evaluations =
this->evaluate_small_ipa_witnesses(small_subgroup_ipa_prover.get_witness_polynomials());

bool consistency_checked = Verifier::check_eccvm_evaluations_consistency(small_ipa_evaluations,
this->evaluation_challenge,
evaluation_challenge_x,
batching_challenge_v,
claimed_inner_product);
bool consistency_checked =
Verifier::check_eccvm_evaluations_consistency(small_ipa_evaluations,
this->evaluation_challenge,
evaluation_challenge_x,
batching_challenge_v,
/*tampered claimed inner product = */ FF::random_element());

EXPECT_TRUE(!consistency_checked);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#pragma once
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It makes sense to isolate other methods shared by prover and verifier, decided to not pollute this PR with such changes


#include "barretenberg/common/ref_array.hpp"
#include "barretenberg/constants.hpp"

#include <array>
#include <string>

namespace bb {

/**
* @brief Shared by Prover and Verifier. `label_prefix` is either `Libra:` or `Translation:`.
*/
inline std::array<std::string, NUM_SMALL_IPA_EVALUATIONS> get_evaluation_labels(const std::string& label_prefix)
{
return { label_prefix + "concatenation_eval",
label_prefix + "grand_sum_shift_eval",
label_prefix + "grand_sum_eval",
label_prefix + "quotient_eval" };
};

/**
* @brief The verification of Grand Sum Identity requires the evaluations G(r), A(g * r), A(r), Q(r). Shared by Prover
* and Verifier.
*/
template <typename FF>
inline std::array<FF, NUM_SMALL_IPA_EVALUATIONS> compute_evaluation_points(const FF& small_ipa_evaluation_challenge,
const FF& subgroup_generator)
{
return { small_ipa_evaluation_challenge,
small_ipa_evaluation_challenge * subgroup_generator,
small_ipa_evaluation_challenge,
small_ipa_evaluation_challenge };
}

/**
* @brief Contains commitments to polynomials [G], [A], and [Q]. See \ref SmallSubgroupIPAProver docs.
*/
template <typename Commitment> struct SmallSubgroupIPACommitments {
Commitment concatenated, grand_sum, quotient;
// The grand sum commitment is returned twice since we are opening the corresponding polynomial at 2 points.
RefArray<Commitment, NUM_SMALL_IPA_EVALUATIONS> get_all()
{
return { concatenated, grand_sum, grand_sum, quotient }; // {[G], [A], [A], [Q]}
};
};
} // namespace bb
37 changes: 37 additions & 0 deletions barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ class ECCVMFlavor {
// define the containers for storing the contributions from each relation in Sumcheck
using SumcheckTupleOfTuplesOfUnivariates = decltype(create_sumcheck_tuple_of_tuples_of_univariates<Relations>());

// The sub-protocol `compute_translation_opening_claims` outputs an opening claim for the batched univariate
// evaluation of `op`, `Px`, `Py`, `z1`, and `z2`, and an array of opening claims for the evaluations of the
// SmallSubgroupIPA witness polynomials.
static constexpr size_t NUM_TRANSLATION_OPENING_CLAIMS = NUM_SMALL_IPA_EVALUATIONS + 1;
using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values<Relations>());

// TODO(https://github.com/AztecProtocol/barretenberg/issues/989): refine access specifiers in flavors, this is
Expand Down Expand Up @@ -1013,11 +1017,19 @@ class ECCVMFlavor {
std::vector<Commitment> gemini_fold_comms;
std::vector<FF> gemini_fold_evals;
Commitment shplonk_q_comm;
Commitment translation_concatenated_masking_term_commitment;
FF translation_masking_term_eval;
FF translation_eval_op;
FF translation_eval_px;
FF translation_eval_py;
FF translation_eval_z1;
FF translation_eval_z2;
Commitment translation_grand_sum_commitment;
Commitment translation_quotient_commitment;
FF translation_concatenation_eval;
FF translation_grand_sum_shift_eval;
FF translation_grand_sum_eval;
FF translation_quotient_eval;
Commitment shplonk_q2_comm;

Transcript() = default;
Expand Down Expand Up @@ -1242,6 +1254,8 @@ class ECCVMFlavor {
libra_quotient_eval = deserialize_from_buffer<FF>(proof_data, num_frs_read);
shplonk_q_comm = deserialize_from_buffer<Commitment>(proof_data, num_frs_read);

translation_concatenated_masking_term_commitment =
NativeTranscript::template deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
translation_eval_op =
NativeTranscript::template deserialize_from_buffer<FF>(NativeTranscript::proof_data, num_frs_read);
translation_eval_px =
Expand All @@ -1253,6 +1267,20 @@ class ECCVMFlavor {
translation_eval_z2 =
NativeTranscript::template deserialize_from_buffer<FF>(NativeTranscript::proof_data, num_frs_read);

translation_masking_term_eval =
NativeTranscript::template deserialize_from_buffer<FF>(proof_data, num_frs_read);
translation_grand_sum_commitment =
NativeTranscript::template deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
translation_quotient_commitment =
NativeTranscript::template deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
translation_concatenation_eval =
NativeTranscript::template deserialize_from_buffer<FF>(proof_data, num_frs_read);
translation_grand_sum_shift_eval =
NativeTranscript::template deserialize_from_buffer<FF>(proof_data, num_frs_read);
translation_grand_sum_eval =
NativeTranscript::template deserialize_from_buffer<FF>(proof_data, num_frs_read);
translation_quotient_eval =
NativeTranscript::template deserialize_from_buffer<FF>(proof_data, num_frs_read);
shplonk_q2_comm = NativeTranscript::template deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
}

Expand Down Expand Up @@ -1393,12 +1421,21 @@ class ECCVMFlavor {
NativeTranscript::template serialize_to_buffer(libra_quotient_eval, proof_data);
NativeTranscript::template serialize_to_buffer(shplonk_q_comm, proof_data);

NativeTranscript::template serialize_to_buffer(translation_concatenated_masking_term_commitment,
proof_data);
NativeTranscript::template serialize_to_buffer(translation_eval_op, NativeTranscript::proof_data);
NativeTranscript::template serialize_to_buffer(translation_eval_px, NativeTranscript::proof_data);
NativeTranscript::template serialize_to_buffer(translation_eval_py, NativeTranscript::proof_data);
NativeTranscript::template serialize_to_buffer(translation_eval_z1, NativeTranscript::proof_data);
NativeTranscript::template serialize_to_buffer(translation_eval_z2, NativeTranscript::proof_data);

NativeTranscript::template serialize_to_buffer(translation_masking_term_eval, proof_data);
NativeTranscript::template serialize_to_buffer(translation_grand_sum_commitment, proof_data);
NativeTranscript::template serialize_to_buffer(translation_quotient_commitment, proof_data);
NativeTranscript::template serialize_to_buffer(translation_concatenation_eval, proof_data);
NativeTranscript::template serialize_to_buffer(translation_grand_sum_shift_eval, proof_data);
NativeTranscript::template serialize_to_buffer(translation_grand_sum_eval, proof_data);
NativeTranscript::template serialize_to_buffer(translation_quotient_eval, proof_data);
NativeTranscript::template serialize_to_buffer(shplonk_q2_comm, NativeTranscript::proof_data);

ASSERT(NativeTranscript::proof_data.size() == old_proof_length);
Expand Down
Loading