Skip to content

Commit

Permalink
feat: add hashing to stdlib transcript (#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 #835.

---------

Co-authored-by: codygunton <[email protected]>
  • Loading branch information
2 people authored and AztecBot committed Feb 9, 2024
1 parent 46aad61 commit e8943ff
Show file tree
Hide file tree
Showing 70 changed files with 1,388 additions and 676 deletions.
8 changes: 4 additions & 4 deletions cpp/src/barretenberg/benchmark/ipa_bench/ipa.bench.cpp
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
2 changes: 1 addition & 1 deletion cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp
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 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
14 changes: 7 additions & 7 deletions cpp/src/barretenberg/commitment_schemes/ipa/ipa.test.cpp
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
6 changes: 3 additions & 3 deletions cpp/src/barretenberg/commitment_schemes/kzg/kzg.hpp
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
14 changes: 7 additions & 7 deletions cpp/src/barretenberg/commitment_schemes/kzg/kzg.test.cpp
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
4 changes: 2 additions & 2 deletions cpp/src/barretenberg/commitment_schemes/shplonk/shplonk.hpp
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 e8943ff

Please sign in to comment.