Skip to content

Commit

Permalink
feat: add hashing to stdlib transcript (AztecProtocol#4161)
Browse files Browse the repository at this point in the history
Combines native and stdlib transcripts by templating it with a
TranscriptParams parameter. This parameter contains the type of field
element in the proof (bb::fr for native and field_t<Builder> for stdlib)
and conversion functions for converting from the field element to/from
other types.

Adds the stdlib conversion functions, and the convert_challenge function
for native and stdlib for turning a challenge into a bn254 scalar or
grumpkin scalar.

Resolves AztecProtocol/barretenberg#835.

---------

Co-authored-by: codygunton <codygunton@gmail.com>
  • Loading branch information
lucasxia01 and codygunton authored Feb 8, 2024
1 parent c00229a commit e78b86f
Show file tree
Hide file tree
Showing 70 changed files with 1,388 additions and 676 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ std::shared_ptr<bb::srs::factories::CrsFactory<curve::Grumpkin>> crs_factory(
auto ck = std::make_shared<CommitmentKey<Curve>>(1 << MAX_POLYNOMIAL_DEGREE_LOG2, crs_factory);
auto vk = std::make_shared<VerifierCommitmentKey<Curve>>(1 << MAX_POLYNOMIAL_DEGREE_LOG2, crs_factory);

std::vector<std::shared_ptr<BaseTranscript>> prover_transcripts(MAX_POLYNOMIAL_DEGREE_LOG2 -
MIN_POLYNOMIAL_DEGREE_LOG2 + 1);
std::vector<std::shared_ptr<NativeTranscript>> prover_transcripts(MAX_POLYNOMIAL_DEGREE_LOG2 -
MIN_POLYNOMIAL_DEGREE_LOG2 + 1);
std::vector<OpeningClaim<Curve>> opening_claims(MAX_POLYNOMIAL_DEGREE_LOG2 - MIN_POLYNOMIAL_DEGREE_LOG2 + 1);

void ipa_open(State& state) noexcept
Expand All @@ -36,7 +36,7 @@ void ipa_open(State& state) noexcept
const OpeningPair<Curve> opening_pair = { x, eval };
const OpeningClaim<Curve> opening_claim{ opening_pair, ck->commit(poly) };
// initialize empty prover transcript
auto prover_transcript = std::make_shared<BaseTranscript>();
auto prover_transcript = std::make_shared<NativeTranscript>();
state.ResumeTiming();
// Compute proof
IPA<Curve>::compute_opening_proof(ck, opening_pair, poly, prover_transcript);
Expand All @@ -53,7 +53,7 @@ void ipa_verify(State& state) noexcept
auto prover_transcript = prover_transcripts[static_cast<size_t>(state.range(0)) - MIN_POLYNOMIAL_DEGREE_LOG2];
auto opening_claim = opening_claims[static_cast<size_t>(state.range(0)) - MIN_POLYNOMIAL_DEGREE_LOG2];
// initialize verifier transcript from proof data
auto verifier_transcript = std::make_shared<BaseTranscript>(prover_transcript->proof_data);
auto verifier_transcript = std::make_shared<NativeTranscript>(prover_transcript->proof_data);

state.ResumeTiming();
auto result = IPA<Curve>::verify(vk, opening_claim, verifier_transcript);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ template <typename Curve> class GeminiVerifier_ {
}

// compute vector of powers of random evaluation point r
const Fr r = transcript->get_challenge("Gemini:r");
const Fr r = transcript->template get_challenge<Fr>("Gemini:r");
std::vector<Fr> r_squares = gemini::squares_of_r(r, num_variables);

// Get evaluations a_i, i = 0,...,m-1 from transcript
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ template <class Curve> class GeminiTest : public CommitmentTest<Curve> {
std::vector<GroupElement> multilinear_commitments,
std::vector<GroupElement> multilinear_commitments_to_be_shifted)
{
auto prover_transcript = BaseTranscript::prover_init_empty();
auto prover_transcript = NativeTranscript::prover_init_empty();

const Fr rho = Fr::random_element();

Expand Down Expand Up @@ -65,7 +65,7 @@ template <class Curve> class GeminiTest : public CommitmentTest<Curve> {
prover_transcript->send_to_verifier(label, commitment);
}

const Fr r_challenge = prover_transcript->get_challenge("Gemini:r");
const Fr r_challenge = prover_transcript->get_challenge<Fr>("Gemini:r");

auto prover_output = GeminiProver::compute_fold_polynomial_evaluations(
multilinear_evaluation_point, std::move(gemini_polynomials), r_challenge);
Expand All @@ -79,7 +79,7 @@ template <class Curve> class GeminiTest : public CommitmentTest<Curve> {
// Check that the Fold polynomials have been evaluated correctly in the prover
this->verify_batch_opening_pair(prover_output.opening_pairs, prover_output.witnesses);

auto verifier_transcript = BaseTranscript::verifier_init_empty(prover_transcript);
auto verifier_transcript = NativeTranscript::verifier_init_empty(prover_transcript);

// Compute:
// - Single opening pair: {r, \hat{a}_0}
Expand Down
18 changes: 10 additions & 8 deletions barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ template <typename Curve> class IPA {
static void compute_opening_proof(const std::shared_ptr<CK>& ck,
const OpeningPair<Curve>& opening_pair,
const Polynomial& polynomial,
const std::shared_ptr<BaseTranscript>& transcript)
const std::shared_ptr<NativeTranscript>& transcript)
{
ASSERT(opening_pair.challenge != 0 && "The challenge point should not be zero");
auto poly_degree = static_cast<size_t>(polynomial.size());
transcript->send_to_verifier("IPA:poly_degree", static_cast<uint64_t>(poly_degree));
const Fr generator_challenge = transcript->get_challenge("IPA:generator_challenge");
transcript->send_to_verifier("IPA:poly_degree", static_cast<uint32_t>(poly_degree));
const Fr generator_challenge = transcript->template get_challenge<Fr>("IPA:generator_challenge");
auto aux_generator = Commitment::one() * generator_challenge;
// Checks poly_degree is greater than zero and a power of two
// In the future, we might want to consider if non-powers of two are needed
Expand Down Expand Up @@ -138,7 +138,7 @@ template <typename Curve> class IPA {
transcript->send_to_verifier("IPA:R_" + index, Commitment(R_elements[i]));

// Generate the round challenge.
const Fr round_challenge = transcript->get_challenge("IPA:round_challenge_" + index);
const Fr round_challenge = transcript->get_challenge<Fr>("IPA:round_challenge_" + index);
const Fr round_challenge_inv = round_challenge.invert();

auto G_lo = GroupElement::batch_mul_with_endomorphism(
Expand Down Expand Up @@ -183,10 +183,12 @@ template <typename Curve> class IPA {
*/
static bool verify(const std::shared_ptr<VK>& vk,
const OpeningClaim<Curve>& opening_claim,
const std::shared_ptr<BaseTranscript>& transcript)
const std::shared_ptr<NativeTranscript>& transcript)
{
auto poly_degree = static_cast<size_t>(transcript->template receive_from_prover<uint64_t>("IPA:poly_degree"));
const Fr generator_challenge = transcript->get_challenge("IPA:generator_challenge");
auto poly_degree = static_cast<uint32_t>(transcript->template receive_from_prover<typename Curve::BaseField>(
"IPA:poly_degree")); // note this is base field because this is a uint32_t, which should map to a bb::fr,
// not a grumpkin::fr, which is a BaseField element for Grumpkin
const Fr generator_challenge = transcript->template get_challenge<Fr>("IPA:generator_challenge");
auto aux_generator = Commitment::one() * generator_challenge;

auto log_poly_degree = static_cast<size_t>(numeric::get_msb(poly_degree));
Expand All @@ -204,7 +206,7 @@ template <typename Curve> class IPA {
std::string index = std::to_string(i);
auto element_L = transcript->template receive_from_prover<Commitment>("IPA:L_" + index);
auto element_R = transcript->template receive_from_prover<Commitment>("IPA:R_" + index);
round_challenges[i] = transcript->get_challenge("IPA:round_challenge_" + index);
round_challenges[i] = transcript->template get_challenge<Fr>("IPA:round_challenge_" + index);
round_challenges_inv[i] = round_challenges[i].invert();

msm_elements[2 * i] = element_L;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ TEST_F(IPATest, Open)
const OpeningClaim<Curve> opening_claim{ opening_pair, commitment };

// initialize empty prover transcript
auto prover_transcript = std::make_shared<BaseTranscript>();
auto prover_transcript = std::make_shared<NativeTranscript>();
IPA::compute_opening_proof(this->ck(), opening_pair, poly, prover_transcript);

// initialize verifier transcript from proof data
auto verifier_transcript = std::make_shared<BaseTranscript>(prover_transcript->proof_data);
auto verifier_transcript = std::make_shared<NativeTranscript>(prover_transcript->proof_data);

auto result = IPA::verify(this->vk(), opening_claim, verifier_transcript);
EXPECT_TRUE(result);
Expand Down Expand Up @@ -131,7 +131,7 @@ TEST_F(IPATest, GeminiShplonkIPAWithShift)
batched_commitment_unshifted = commitment1 * rhos[0] + commitment2 * rhos[1];
batched_commitment_to_be_shifted = commitment2 * rhos[2];

auto prover_transcript = BaseTranscript::prover_init_empty();
auto prover_transcript = NativeTranscript::prover_init_empty();

auto gemini_polynomials = GeminiProver::compute_gemini_polynomials(
mle_opening_point, std::move(batched_unshifted), std::move(batched_to_be_shifted));
Expand All @@ -142,7 +142,7 @@ TEST_F(IPATest, GeminiShplonkIPAWithShift)
prover_transcript->send_to_verifier(label, commitment);
}

const Fr r_challenge = prover_transcript->get_challenge("Gemini:r");
const Fr r_challenge = prover_transcript->template get_challenge<Fr>("Gemini:r");

const auto [gemini_opening_pairs, gemini_witnesses] = GeminiProver::compute_fold_polynomial_evaluations(
mle_opening_point, std::move(gemini_polynomials), r_challenge);
Expand All @@ -153,18 +153,18 @@ TEST_F(IPATest, GeminiShplonkIPAWithShift)
prover_transcript->send_to_verifier(label, evaluation);
}

const Fr nu_challenge = prover_transcript->get_challenge("Shplonk:nu");
const Fr nu_challenge = prover_transcript->template get_challenge<Fr>("Shplonk:nu");
auto batched_quotient_Q =
ShplonkProver::compute_batched_quotient(gemini_opening_pairs, gemini_witnesses, nu_challenge);
prover_transcript->send_to_verifier("Shplonk:Q", this->ck()->commit(batched_quotient_Q));

const Fr z_challenge = prover_transcript->get_challenge("Shplonk:z");
const Fr z_challenge = prover_transcript->template get_challenge<Fr>("Shplonk:z");
const auto [shplonk_opening_pair, shplonk_witness] = ShplonkProver::compute_partially_evaluated_batched_quotient(
gemini_opening_pairs, gemini_witnesses, std::move(batched_quotient_Q), nu_challenge, z_challenge);

IPA::compute_opening_proof(this->ck(), shplonk_opening_pair, shplonk_witness, prover_transcript);

auto verifier_transcript = BaseTranscript::verifier_init_empty(prover_transcript);
auto verifier_transcript = NativeTranscript::verifier_init_empty(prover_transcript);

auto gemini_verifier_claim = GeminiVerifier::reduce_verification(mle_opening_point,
batched_evaluation,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ template <typename Curve> class KZG {
static void compute_opening_proof(std::shared_ptr<CK> ck,
const OpeningPair<Curve>& opening_pair,
const Polynomial& polynomial,
const std::shared_ptr<BaseTranscript>& prover_trancript)
const std::shared_ptr<NativeTranscript>& prover_trancript)
{
Polynomial quotient = polynomial;
quotient[0] -= opening_pair.evaluation;
Expand All @@ -55,7 +55,7 @@ template <typename Curve> class KZG {
*/
static bool verify(const std::shared_ptr<VK>& vk,
const OpeningClaim<Curve>& claim,
const std::shared_ptr<BaseTranscript>& verifier_transcript)
const std::shared_ptr<NativeTranscript>& verifier_transcript)
{
auto quotient_commitment = verifier_transcript->template receive_from_prover<Commitment>("KZG:W");
auto lhs = claim.commitment - (GroupElement::one() * claim.opening_pair.evaluation) +
Expand All @@ -82,7 +82,7 @@ template <typename Curve> class KZG {

GroupElement P_0;
if constexpr (Curve::is_stdlib_type) {
auto builder = verifier_transcript->builder;
auto builder = quotient_commitment.get_context();
auto one = Fr(builder, 1);
std::vector<GroupElement> commitments = { claim.commitment,
quotient_commitment,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ TYPED_TEST(KZGTest, single)
auto opening_pair = OpeningPair<TypeParam>{ challenge, evaluation };
auto opening_claim = OpeningClaim<TypeParam>{ opening_pair, commitment };

auto prover_transcript = BaseTranscript::prover_init_empty();
auto prover_transcript = NativeTranscript::prover_init_empty();

KZG::compute_opening_proof(this->ck(), opening_pair, witness, prover_transcript);

auto verifier_transcript = BaseTranscript::verifier_init_empty(prover_transcript);
auto verifier_transcript = NativeTranscript::verifier_init_empty(prover_transcript);
bool verified = KZG::verify(this->vk(), opening_claim, verifier_transcript);

EXPECT_EQ(verified, true);
Expand Down Expand Up @@ -109,7 +109,7 @@ TYPED_TEST(KZGTest, GeminiShplonkKzgWithShift)
batched_commitment_unshifted = commitment1 * rhos[0] + commitment2 * rhos[1];
batched_commitment_to_be_shifted = commitment2 * rhos[2];

auto prover_transcript = BaseTranscript::prover_init_empty();
auto prover_transcript = NativeTranscript::prover_init_empty();

// Run the full prover PCS protocol:

Expand All @@ -125,7 +125,7 @@ TYPED_TEST(KZGTest, GeminiShplonkKzgWithShift)
prover_transcript->send_to_verifier(label, commitment);
}

const Fr r_challenge = prover_transcript->get_challenge("Gemini:r");
const Fr r_challenge = prover_transcript->template get_challenge<Fr>("Gemini:r");

const auto [gemini_opening_pairs, gemini_witnesses] = GeminiProver::compute_fold_polynomial_evaluations(
mle_opening_point, std::move(gemini_polynomials), r_challenge);
Expand All @@ -139,12 +139,12 @@ TYPED_TEST(KZGTest, GeminiShplonkKzgWithShift)
// Shplonk prover output:
// - opening pair: (z_challenge, 0)
// - witness: polynomial Q - Q_z
const Fr nu_challenge = prover_transcript->get_challenge("Shplonk:nu");
const Fr nu_challenge = prover_transcript->template get_challenge<Fr>("Shplonk:nu");
auto batched_quotient_Q =
ShplonkProver::compute_batched_quotient(gemini_opening_pairs, gemini_witnesses, nu_challenge);
prover_transcript->send_to_verifier("Shplonk:Q", this->ck()->commit(batched_quotient_Q));

const Fr z_challenge = prover_transcript->get_challenge("Shplonk:z");
const Fr z_challenge = prover_transcript->template get_challenge<Fr>("Shplonk:z");
const auto [shplonk_opening_pair, shplonk_witness] = ShplonkProver::compute_partially_evaluated_batched_quotient(
gemini_opening_pairs, gemini_witnesses, std::move(batched_quotient_Q), nu_challenge, z_challenge);

Expand All @@ -154,7 +154,7 @@ TYPED_TEST(KZGTest, GeminiShplonkKzgWithShift)

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

auto verifier_transcript = BaseTranscript::verifier_init_empty(prover_transcript);
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,11 @@ template <typename Curve> class ShplonkVerifier_ {

const size_t num_claims = claims.size();

const Fr nu = transcript->get_challenge("Shplonk:nu");
const Fr nu = transcript->template get_challenge<Fr>("Shplonk:nu");

auto Q_commitment = transcript->template receive_from_prover<Commitment>("Shplonk:Q");

const Fr z_challenge = transcript->get_challenge("Shplonk:z");
const Fr z_challenge = transcript->template get_challenge<Fr>("Shplonk:z");

// [G] = [Q] - ∑ⱼ ρʲ / ( r − xⱼ )⋅[fⱼ] + G₀⋅[1]
// = [Q] - [∑ⱼ ρʲ ⋅ ( fⱼ(X) − vⱼ) / ( r − xⱼ )]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ TYPED_TEST(ShplonkTest, ShplonkSimple)

const size_t n = 16;

auto prover_transcript = BaseTranscript::prover_init_empty();
auto prover_transcript = NativeTranscript::prover_init_empty();

// Generate two random (unrelated) polynomials of two different sizes, as well as their evaluations at a (single but
// different) random point and their commitments.
Expand All @@ -47,11 +47,11 @@ TYPED_TEST(ShplonkTest, ShplonkSimple)
std::vector<Polynomial> polynomials = { poly1.share(), poly2.share() };

// Execute the shplonk prover functionality
const Fr nu_challenge = prover_transcript->get_challenge("Shplonk:nu");
const Fr nu_challenge = prover_transcript->template get_challenge<Fr>("Shplonk:nu");
auto batched_quotient_Q = ShplonkProver::compute_batched_quotient(opening_pairs, polynomials, nu_challenge);
prover_transcript->send_to_verifier("Shplonk:Q", this->ck()->commit(batched_quotient_Q));

const Fr z_challenge = prover_transcript->get_challenge("Shplonk:z");
const Fr z_challenge = prover_transcript->template get_challenge<Fr>("Shplonk:z");
const auto [prover_opening_pair, shplonk_prover_witness] =
ShplonkProver::compute_partially_evaluated_batched_quotient(
opening_pairs, polynomials, std::move(batched_quotient_Q), nu_challenge, z_challenge);
Expand All @@ -64,7 +64,7 @@ TYPED_TEST(ShplonkTest, ShplonkSimple)
opening_claims.emplace_back(OpeningClaim{ opening_pairs[0], commitment1 });
opening_claims.emplace_back(OpeningClaim{ opening_pairs[1], commitment2 });

auto verifier_transcript = BaseTranscript::verifier_init_empty(prover_transcript);
auto verifier_transcript = NativeTranscript::verifier_init_empty(prover_transcript);

// Execute the shplonk verifier functionality
const auto verifier_claim = ShplonkVerifier::reduce_verification(this->vk(), opening_claims, verifier_transcript);
Expand Down
Loading

0 comments on commit e78b86f

Please sign in to comment.