Skip to content

Commit

Permalink
refactor: Field-agnostic and reusable transcript (#3433)
Browse files Browse the repository at this point in the history
In preparation for proper generation of Goblin challenges, this PR makes
the transcript field agnostic. The transcript is now a class and not a
template, and challenges are `uint256_t`s. It is the developer's
responsibility to construct field elements from these.

Additionally, internal state is added to the transcript so that it can
be passed along from prover to prover and from verifier to cerifier.
After one prover has finished with it, they export the newly added proof
data. The next prover adds additional data and is able to export its
newly added proof data, and so on. This is illustrated in a test, which
also add data from two different fields (each having 254-bit modulus).
On the verification side, the verifier transcript can be initialized
with the first proof, and then later can have the second proof loaded
into its data buffer. **Ultimately, what this enables is for the second
interactions challenge's to depend on the first interaction's proof.**

There are also small additional changes, including a fix to a test that
was written incorrectly and copied and pasted into several different
files.
  • Loading branch information
codygunton committed Nov 30, 2023
1 parent 00835c6 commit d78775a
Show file tree
Hide file tree
Showing 47 changed files with 618 additions and 562 deletions.
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<Fr>::prover_init_empty();
auto prover_transcript = BaseTranscript::prover_init_empty();

const Fr rho = Fr::random_element();

Expand Down Expand Up @@ -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<Fr>::verifier_init_empty(prover_transcript);
auto verifier_transcript = BaseTranscript::verifier_init_empty(prover_transcript);

// Compute:
// - Single opening pair: {r, \hat{a}_0}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ template <typename Curve> class IPA {
static void compute_opening_proof(std::shared_ptr<CK> ck,
const OpeningPair<Curve>& opening_pair,
const Polynomial& polynomial,
BaseTranscript<Fr>& transcript)
BaseTranscript& transcript)
{
ASSERT(opening_pair.challenge != 0 && "The challenge point should not be zero");
auto poly_degree = static_cast<size_t>(polynomial.size());
Expand Down Expand Up @@ -134,7 +134,7 @@ template <typename Curve> class IPA {
*
* @return true/false depending on if the proof verifies
*/
static bool verify(std::shared_ptr<VK> vk, const OpeningClaim<Curve>& opening_claim, BaseTranscript<Fr>& transcript)
static bool verify(std::shared_ptr<VK> vk, const OpeningClaim<Curve>& opening_claim, BaseTranscript& transcript)
{
auto poly_degree = static_cast<size_t>(transcript.template receive_from_prover<uint64_t>("IPA:poly_degree"));
Fr generator_challenge = transcript.get_challenge("IPA:generator_challenge");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ TEST_F(IPATest, Open)
const OpeningClaim<Curve> opening_claim{ opening_pair, commitment };

// initialize empty prover transcript
BaseTranscript<Fr> prover_transcript;
BaseTranscript prover_transcript;
IPA::compute_opening_proof(this->ck(), opening_pair, poly, prover_transcript);

// initialize verifier transcript from proof data
BaseTranscript<Fr> verifier_transcript{ prover_transcript.proof_data };
BaseTranscript verifier_transcript{ prover_transcript.proof_data };

auto result = IPA::verify(this->vk(), opening_claim, verifier_transcript);
EXPECT_TRUE(result);
Expand Down Expand Up @@ -129,7 +129,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<Fr>::prover_init_empty();
auto prover_transcript = BaseTranscript::prover_init_empty();

auto gemini_polynomials = GeminiProver::compute_gemini_polynomials(
mle_opening_point, std::move(batched_unshifted), std::move(batched_to_be_shifted));
Expand Down Expand Up @@ -162,7 +162,7 @@ TEST_F(IPATest, GeminiShplonkIPAWithShift)

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

auto verifier_transcript = BaseTranscript<Fr>::verifier_init_empty(prover_transcript);
auto verifier_transcript = BaseTranscript::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,
BaseTranscript<Fr>& prover_trancript)
BaseTranscript& prover_trancript)
{
Polynomial quotient(polynomial);
quotient[0] -= opening_pair.evaluation;
Expand All @@ -53,9 +53,7 @@ template <typename Curve> class KZG {
* - P₀ = C − v⋅[1]₁ + r⋅[x]₁
* - P₁ = [Q(x)]₁
*/
static bool verify(std::shared_ptr<VK> vk,
const OpeningClaim<Curve>& claim,
BaseTranscript<Fr>& verifier_transcript)
static bool verify(std::shared_ptr<VK> vk, const OpeningClaim<Curve>& claim, BaseTranscript& 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 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<Fr>::prover_init_empty();
auto prover_transcript = BaseTranscript::prover_init_empty();

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

auto verifier_transcript = BaseTranscript<Fr>::verifier_init_empty(prover_transcript);
auto verifier_transcript = BaseTranscript::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<Fr>::prover_init_empty();
auto prover_transcript = BaseTranscript::prover_init_empty();

// Run the full prover PCS protocol:

Expand Down Expand Up @@ -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<Fr>::verifier_init_empty(prover_transcript);
auto verifier_transcript = BaseTranscript::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 @@ -28,7 +28,7 @@ TYPED_TEST(ShplonkTest, ShplonkSimple)

const size_t n = 16;

auto prover_transcript = BaseTranscript<Fr>::prover_init_empty();
auto prover_transcript = BaseTranscript::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 Down Expand Up @@ -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<Fr>::verifier_init_empty(prover_transcript);
auto verifier_transcript = BaseTranscript::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
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include "barretenberg/common/ref_vector.hpp"
#include "barretenberg/common/zip_view.hpp"
#include "barretenberg/polynomials/polynomial.hpp"
#include "barretenberg/transcript/transcript.hpp"

namespace proof_system::honk::pcs::zeromorph {

/**
Expand Down Expand Up @@ -396,7 +398,7 @@ template <typename Curve> class ZeroMorphProver_ {
}

// Get challenge y
auto y_challenge = transcript.get_challenge("ZM:y");
FF y_challenge = transcript.get_challenge("ZM:y");

// Compute the batched, lifted-degree quotient \hat{q}
auto batched_quotient = compute_batched_lifted_degree_quotient(quotients, y_challenge, N);
Expand All @@ -406,7 +408,7 @@ template <typename Curve> class ZeroMorphProver_ {
transcript.send_to_verifier("ZM:C_q", q_commitment);

// Get challenges x and z
auto [x_challenge, z_challenge] = transcript.get_challenges("ZM:x", "ZM:z");
auto [x_challenge, z_challenge] = challenges_to_field_elements<FF>(transcript.get_challenges("ZM:x", "ZM:z"));

// Compute degree check polynomial \zeta partially evaluated at x
auto zeta_x =
Expand Down Expand Up @@ -669,13 +671,13 @@ template <typename Curve> class ZeroMorphVerifier_ {
}

// Challenge y
auto y_challenge = transcript.get_challenge("ZM:y");
FF y_challenge = transcript.get_challenge("ZM:y");

// Receive commitment C_{q}
auto C_q = transcript.template receive_from_prover<Commitment>("ZM:C_q");

// Challenges x, z
auto [x_challenge, z_challenge] = transcript.get_challenges("ZM:x", "ZM:z");
auto [x_challenge, z_challenge] = challenges_to_field_elements<FF>(transcript.get_challenges("ZM:x", "ZM:z"));

// Compute commitment C_{\zeta_x}
auto C_zeta_x = compute_C_zeta_x(C_q, C_q_k, y_challenge, x_challenge);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ template <class Curve> class ZeroMorphTest : public CommitmentTest<Curve> {
}

// Initialize an empty BaseTranscript
auto prover_transcript = BaseTranscript<Fr>::prover_init_empty();
auto prover_transcript = BaseTranscript::prover_init_empty();

// Execute Prover protocol
ZeroMorphProver::prove(f_polynomials,
Expand All @@ -88,7 +88,7 @@ template <class Curve> class ZeroMorphTest : public CommitmentTest<Curve> {
this->commitment_key,
prover_transcript);

auto verifier_transcript = BaseTranscript<Fr>::verifier_init_empty(prover_transcript);
auto verifier_transcript = BaseTranscript::verifier_init_empty(prover_transcript);

// Execute Verifier protocol
auto pairing_points = ZeroMorphVerifier::verify(
Expand Down Expand Up @@ -223,7 +223,7 @@ template <class Curve> class ZeroMorphWithConcatenationTest : public CommitmentT
}

// Initialize an empty BaseTranscript
auto prover_transcript = BaseTranscript<Fr>::prover_init_empty();
auto prover_transcript = BaseTranscript::prover_init_empty();

std::vector<std::span<Fr>> concatenated_polynomials_views;
for (auto& poly : concatenated_polynomials) {
Expand All @@ -248,7 +248,7 @@ template <class Curve> class ZeroMorphWithConcatenationTest : public CommitmentT
c_evaluations,
to_vector_of_ref_vectors(concatenation_groups_views));

auto verifier_transcript = BaseTranscript<Fr>::verifier_init_empty(prover_transcript);
auto verifier_transcript = BaseTranscript::verifier_init_empty(prover_transcript);

// Execute Verifier protocol
auto pairing_points = ZeroMorphVerifier::verify(f_commitments, // unshifted
Expand Down
5 changes: 3 additions & 2 deletions barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ template <ECCVMFlavor Flavor> void ECCVMProver_<Flavor>::execute_wire_commitment
template <ECCVMFlavor Flavor> void ECCVMProver_<Flavor>::execute_log_derivative_commitments_round()
{
// Compute and add beta to relation parameters
auto [beta, gamma] = transcript.get_challenges("beta", "gamma");
auto [beta, gamma] = challenges_to_field_elements<FF>(transcript.get_challenges("beta", "gamma"));

// TODO(#583)(@zac-williamson): fix Transcript to be able to generate more than 2 challenges per round! oof.
auto beta_sqr = beta * beta;
relation_parameters.gamma = gamma;
Expand Down Expand Up @@ -206,7 +207,7 @@ template <ECCVMFlavor Flavor> void ECCVMProver_<Flavor>::execute_relation_check_
using Sumcheck = sumcheck::SumcheckProver<Flavor>;

auto sumcheck = Sumcheck(key->circuit_size, transcript);
auto alpha = transcript.get_challenge("alpha");
FF alpha = transcript.get_challenge("alpha");
sumcheck_output = sumcheck.prove(prover_polynomials, relation_parameters, alpha);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,10 +304,11 @@ TYPED_TEST(ECCVMTranscriptTests, ChallengeGenerationTest)
constexpr uint32_t random_val{ 17 }; // arbitrary
transcript.send_to_verifier("random val", random_val);
// test more challenges
auto [a, b, c] = transcript.get_challenges("a", "b", "c");
auto [a, b, c] = challenges_to_field_elements<typename Flavor::FF>(transcript.get_challenges("a", "b", "c"));

ASSERT_NE(a, 0) << "Challenge a is 0";
ASSERT_NE(b, 0) << "Challenge a is 0";
ASSERT_NE(b, 0) << "Challenge a is 0";
ASSERT_NE(b, 0) << "Challenge b is 0";
ASSERT_NE(c, 0) << "Challenge c is 0";
}

TYPED_TEST(ECCVMTranscriptTests, StructureTest)
Expand All @@ -333,7 +334,7 @@ TYPED_TEST(ECCVMTranscriptTests, StructureTest)
EXPECT_TRUE(verifier.verify_proof(prover.export_proof())); // we have changed nothing so proof is still valid

typename Flavor::Commitment one_group_val = Flavor::Commitment::one();
typename Flavor::FF rand_val = Flavor::FF::random_element();
auto rand_val = Flavor::FF::random_element();
prover.transcript.transcript_Px_comm = one_group_val * rand_val; // choose random object to modify
EXPECT_TRUE(verifier.verify_proof(
prover.export_proof())); // we have not serialized it back to the proof so it should still be fine
Expand Down
5 changes: 3 additions & 2 deletions barretenberg/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ template <typename Flavor> bool ECCVMVerifier_<Flavor>::verify_proof(const plonk
commitments.lookup_read_counts_1 = receive_commitment(commitment_labels.lookup_read_counts_1);

// Get challenge for sorted list batching and wire four memory records
auto [beta, gamma] = transcript.get_challenges("beta", "gamma");
auto [beta, gamma] = challenges_to_field_elements<FF>(transcript.get_challenges("beta", "gamma"));

relation_parameters.gamma = gamma;
auto beta_sqr = beta * beta;
relation_parameters.beta = beta;
Expand All @@ -158,7 +159,7 @@ template <typename Flavor> bool ECCVMVerifier_<Flavor>::verify_proof(const plonk

// Execute Sumcheck Verifier
auto sumcheck = SumcheckVerifier<Flavor>(circuit_size);
auto alpha = transcript.get_challenge("alpha");
FF alpha = transcript.get_challenge("alpha");
auto [multivariate_challenge, purported_evaluations, sumcheck_verified] =
sumcheck.verify(relation_parameters, alpha, transcript);

Expand Down
Loading

0 comments on commit d78775a

Please sign in to comment.