Skip to content

Commit

Permalink
Split shplonk in prep for work queue (AztecProtocol/barretenberg#321)
Browse files Browse the repository at this point in the history
  • Loading branch information
ledwards2225 authored Apr 7, 2023
1 parent a9a029e commit 578f53d
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 34 deletions.
15 changes: 10 additions & 5 deletions barretenberg/cpp/src/barretenberg/honk/pcs/kzg/kzg.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,24 +126,29 @@ TYPED_TEST(BilinearAccumulationTest, GeminiShplonkKzgWithShift)

const Fr r_challenge = prover_transcript.get_challenge("Gemini:r");

auto gemini_prover_output =
const auto [gemini_opening_pairs, gemini_witnesses] =
Gemini::compute_fold_polynomial_evaluations(mle_opening_point, std::move(fold_polynomials), r_challenge);

for (size_t l = 0; l < log_n; ++l) {
std::string label = "Gemini:a_" + std::to_string(l);
const auto& evaluation = gemini_prover_output.opening_pairs[l + 1].evaluation;
const auto& evaluation = gemini_opening_pairs[l + 1].evaluation;
prover_transcript.send_to_verifier(label, evaluation);
}

// Shplonk prover output:
// - opening pair: (z_challenge, 0)
// - witness: polynomial Q - Q_z
auto shplonk_prover_output = Shplonk::reduce_prove(
this->ck(), gemini_prover_output.opening_pairs, gemini_prover_output.witnesses, prover_transcript);
const Fr nu_challenge = prover_transcript.get_challenge("Shplonk:nu");
auto batched_quotient_Q = Shplonk::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 auto [shplonk_opening_pair, shplonk_witness] = Shplonk::compute_partially_evaluated_batched_quotient(
gemini_opening_pairs, gemini_witnesses, std::move(batched_quotient_Q), nu_challenge, z_challenge);

// KZG prover:
// - Adds commitment [W] to transcript
KZG::reduce_prove(this->ck(), shplonk_prover_output.opening_pair, shplonk_prover_output.witness, prover_transcript);
KZG::reduce_prove(this->ck(), shplonk_opening_pair, shplonk_witness, prover_transcript);

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,13 @@ TYPED_TEST(ShplonkTest, ShplonkSimple)
std::vector<Polynomial> polynomials = { poly1, poly2 };

// Execute the shplonk prover functionality
const auto [prover_opening_pair, shplonk_prover_witness] =
Shplonk::reduce_prove(this->ck(), opening_pairs, polynomials, prover_transcript);
const Fr nu_challenge = prover_transcript.get_challenge("Shplonk:nu");
auto batched_quotient_Q = Shplonk::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 auto [prover_opening_pair, shplonk_prover_witness] = Shplonk::compute_partially_evaluated_batched_quotient(
opening_pairs, polynomials, std::move(batched_quotient_Q), nu_challenge, z_challenge);

// An intermediate check to confirm the opening of the shplonk prover witness Q
this->verify_opening_pair(prover_opening_pair, shplonk_prover_witness);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,17 @@ template <typename Params> class SingleBatchOpeningScheme {

public:
/**
* @brief Batches several single-point 'OpeningClaim' into a single 'OpeningClaim' suitable for
* a univariate polynomial opening scheme.
* @brief Compute batched quotient polynomial Q(X) = ∑ⱼ ρʲ ⋅ ( fⱼ(X) − vⱼ) / ( X − xⱼ )
*
* @param ck CommitmentKey
* @param opening_pairs list of opening pairs (xⱼ, vⱼ) for a witness polynomial fⱼ(X), s.t. fⱼ(xⱼ) = vⱼ.
* @param witness_polynomials list of polynomials fⱼ(X).
* @param transcript
* @return Output{OpeningClaim, WitnessPolynomial, Proof}
* @param nu
* @return Polynomial Q(X)
*/
static ProverOutput<Params> reduce_prove(std::shared_ptr<CK> ck,
std::span<const OpeningPair<Params>> opening_pairs,
std::span<const Polynomial> witness_polynomials,
ProverTranscript<Fr>& transcript)
static Polynomial compute_batched_quotient(std::span<const OpeningPair<Params>> opening_pairs,
std::span<const Polynomial> witness_polynomials,
const Fr& nu)
{
Fr nu = transcript.get_challenge("Shplonk:nu");

const size_t num_opening_pairs = opening_pairs.size();

// Find n, the maximum size of all polynomials fⱼ(X)
size_t max_poly_size{ 0 };
for (const auto& poly : witness_polynomials) {
Expand All @@ -50,7 +43,7 @@ template <typename Params> class SingleBatchOpeningScheme {
Polynomial tmp(max_poly_size);

Fr current_nu = Fr::one();
for (size_t j = 0; j < num_opening_pairs; ++j) {
for (size_t j = 0; j < opening_pairs.size(); ++j) {
// (Cⱼ, xⱼ, vⱼ)
const auto& [challenge, evaluation] = opening_pairs[j];

Expand All @@ -63,12 +56,28 @@ template <typename Params> class SingleBatchOpeningScheme {
current_nu *= nu;
}

// commit to Q(X) and add [Q] to the transcript
auto Q_commitment = ck->commit(Q);
transcript.send_to_verifier("Shplonk:Q", Q_commitment);
// Return batched quotient polynomial Q(X)
return Q;
};

// generate random evaluation challenge zeta_challenge
const Fr z_challenge = transcript.get_challenge("Shplonk:z");
/**
* @brief Compute partially evaluated batched quotient polynomial difference Q(X) - Q_z(X)
*
* @param opening_pairs list of opening pairs (xⱼ, vⱼ) for a witness polynomial fⱼ(X), s.t. fⱼ(xⱼ) = vⱼ.
* @param witness_polynomials list of polynomials fⱼ(X).
* @param batched_quotient_Q Q(X) = ∑ⱼ ρʲ ⋅ ( fⱼ(X) − vⱼ) / ( X − xⱼ )
* @param nu_challenge
* @param z_challenge
* @return Output{OpeningPair, Polynomial}
*/
static ProverOutput<Params> compute_partially_evaluated_batched_quotient(
std::span<const OpeningPair<Params>> opening_pairs,
std::span<const Polynomial> witness_polynomials,
Polynomial&& batched_quotient_Q,
const Fr& nu_challenge,
const Fr& z_challenge)
{
const size_t num_opening_pairs = opening_pairs.size();

// {ẑⱼ(r)}ⱼ , where ẑⱼ(r) = 1/zⱼ(r) = 1/(r - xⱼ)
std::vector<Fr> inverse_vanishing_evals;
Expand All @@ -80,10 +89,11 @@ template <typename Params> class SingleBatchOpeningScheme {

// G(X) = Q(X) - Q_z(X) = Q(X) - ∑ⱼ ρʲ ⋅ ( fⱼ(X) − vⱼ) / ( r − xⱼ ),
// s.t. G(r) = 0
Polynomial& G = Q;
Polynomial G(std::move(batched_quotient_Q)); // G(X) = Q(X)

// G₀ = ∑ⱼ ρʲ ⋅ vⱼ / ( r − xⱼ )
current_nu = Fr::one();
Fr current_nu = Fr::one();
Polynomial tmp(G.size());
for (size_t j = 0; j < num_opening_pairs; ++j) {
// (Cⱼ, xⱼ, vⱼ)
const auto& [challenge, evaluation] = opening_pairs[j];
Expand All @@ -96,7 +106,7 @@ template <typename Params> class SingleBatchOpeningScheme {
// G -= ρʲ ⋅ ( fⱼ(X) − vⱼ) / ( r − xⱼ )
G.add_scaled(tmp, -scaling_factor);

current_nu *= nu;
current_nu *= nu_challenge;
}

// Return opening pair (z, 0) and polynomial G(X) = Q(X) - Q_z(X)
Expand Down
24 changes: 20 additions & 4 deletions barretenberg/cpp/src/barretenberg/honk/proof_system/prover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,13 +239,28 @@ template <typename settings> void Prover<settings>::execute_pcs_evaluation_round
/**
* - Do Fiat-Shamir to get "nu" challenge.
* - Compute commitment [Q]_1
* */
template <typename settings> void Prover<settings>::execute_shplonk_batched_quotient_round()
{
nu_challenge = transcript.get_challenge("Shplonk:nu");

batched_quotient_Q =
Shplonk::compute_batched_quotient(gemini_output.opening_pairs, gemini_output.witnesses, nu_challenge);

// commit to Q(X) and add [Q] to the transcript
auto Q_commitment = commitment_key->commit(batched_quotient_Q);
transcript.send_to_verifier("Shplonk:Q", Q_commitment);
}

/**
* - Do Fiat-Shamir to get "z" challenge.
* - Compute polynomial Q(X) - Q_z(X)
* */
template <typename settings> void Prover<settings>::execute_shplonk_round()
template <typename settings> void Prover<settings>::execute_shplonk_partial_evaluation_round()
{
shplonk_output =
Shplonk::reduce_prove(commitment_key, gemini_output.opening_pairs, gemini_output.witnesses, transcript);
const Fr z_challenge = transcript.get_challenge("Shplonk:z");
shplonk_output = Shplonk::compute_partially_evaluated_batched_quotient(
gemini_output.opening_pairs, gemini_output.witnesses, std::move(batched_quotient_Q), nu_challenge, z_challenge);
}

/**
Expand Down Expand Up @@ -302,7 +317,8 @@ template <typename settings> plonk::proof& Prover<settings>::construct_proof()

// Fiat-Shamir: nu
// Compute Shplonk batched quotient commitment
execute_shplonk_round();
execute_shplonk_batched_quotient_round();
execute_shplonk_partial_evaluation_round();
// queue.process_queue(); // NOTE: Don't remove; we may reinstate the queue

// Fiat-Shamir: z
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ template <typename settings> class Prover {
void execute_relation_check_rounds();
void execute_univariatization_round();
void execute_pcs_evaluation_round();
void execute_shplonk_round();
void execute_shplonk_batched_quotient_round();
void execute_shplonk_partial_evaluation_round();
void execute_kzg_round();

void compute_wire_commitments();
Expand Down Expand Up @@ -71,6 +72,9 @@ template <typename settings> class Prover {
// Container for d + 1 Fold polynomials produced by Gemini
std::vector<Polynomial> fold_polynomials;

Polynomial batched_quotient_Q;
Fr nu_challenge;

// Honk only needs a small portion of the functionality but may be fine to use existing work_queue
// NOTE: this is not currently in use, but it may well be used in the future.
// TODO(Adrian): Uncomment when we need this again.
Expand Down

0 comments on commit 578f53d

Please sign in to comment.