From 462be34feba8ad5005b4930e22cbda7af8d3e694 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Tue, 15 Aug 2023 18:12:18 +0000 Subject: [PATCH] building and running through Shplonk --- .../barretenberg/ecc/curves/bn254/bn254.hpp | 2 ++ .../ecc/curves/grumpkin/grumpkin.hpp | 2 ++ .../barretenberg/honk/pcs/gemini/gemini.hpp | 12 ++++++-- .../barretenberg/honk/pcs/shplonk/shplonk.hpp | 29 ++++++++++++------- .../stdlib/primitives/curves/bn254.hpp | 1 + .../verifier/ultra_recursive_verifier.cpp | 27 +++++++++++++---- 6 files changed, 54 insertions(+), 19 deletions(-) diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/ecc/curves/bn254/bn254.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/ecc/curves/bn254/bn254.hpp index 84688be1a62f..e5df58ce3505 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/ecc/curves/bn254/bn254.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/ecc/curves/bn254/bn254.hpp @@ -17,5 +17,7 @@ class BN254 { using G2AffineElement = typename barretenberg::g2::affine_element; using G2BaseField = typename barretenberg::fq2; using TargetField = barretenberg::fq12; + + static constexpr bool is_stdlib_type = false; }; } // namespace curve \ No newline at end of file diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/ecc/curves/grumpkin/grumpkin.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/ecc/curves/grumpkin/grumpkin.hpp index fc799acce556..881af2620dc2 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/ecc/curves/grumpkin/grumpkin.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/ecc/curves/grumpkin/grumpkin.hpp @@ -42,5 +42,7 @@ class Grumpkin { using Group = typename grumpkin::g1; using Element = typename Group::element; using AffineElement = typename Group::affine_element; + + static constexpr bool is_stdlib_type = false; }; } // namespace curve \ No newline at end of file diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/pcs/gemini/gemini.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/pcs/gemini/gemini.hpp index 0a84028a676d..e30d8fa840e5 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/pcs/gemini/gemini.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/pcs/gemini/gemini.hpp @@ -236,12 +236,18 @@ template class GeminiVerifier_ { // C₀ᵣ₋ = [F] - r⁻¹⋅[G] GroupElement C0_r_neg = batched_f; Fr r_inv = r.invert(); - // WORKTODO: reinstate some kind of !batched_g.is_point_at_infinity() check for stdlib? - // if (!batched_g.is_point_at_infinity()) { + + // WORKTODO: reinstate some kind of !batched_g.is_point_at_infinity() check for stdlib? This is mostly relevant for Gemini unit tests since in practice batched_g will not be zero + bool batched_g_is_point_at_infinity = false; + if constexpr (!Curve::is_stdlib_type) { + batched_g_is_point_at_infinity = batched_g.is_point_at_infinity(); + } + if (!batched_g_is_point_at_infinity) { batched_g = batched_g * r_inv; C0_r_pos += batched_g; C0_r_neg -= batched_g; - // } + } + return { C0_r_pos, C0_r_neg }; } diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/pcs/shplonk/shplonk.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/pcs/shplonk/shplonk.hpp index 12bcc5ad1dfc..37bb0c98b627 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/pcs/shplonk/shplonk.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/honk/pcs/shplonk/shplonk.hpp @@ -163,7 +163,7 @@ template class ShplonkVerifier_ { */ static OpeningClaim reduce_verification(std::shared_ptr vk, std::span> claims, - VerifierTranscript& transcript) + auto& transcript) { const size_t num_claims = claims.size(); @@ -179,21 +179,25 @@ template class ShplonkVerifier_ { // = [Q] - ∑ⱼ (1/zⱼ(r))[Bⱼ] + G₀ [1] // G₀ = ∑ⱼ ρʲ ⋅ vⱼ / ( r − xⱼ ) - Fr G_commitment_constant{ Fr::zero() }; + auto G_commitment_constant = Fr(0); // [G] = [Q] - ∑ⱼ ρʲ / ( r − xⱼ )⋅[fⱼ] + G₀⋅[1] // = [Q] - [∑ⱼ ρʲ ⋅ ( fⱼ(X) − vⱼ) / ( r − xⱼ )] GroupElement G_commitment = Q_commitment; - // {ẑⱼ(r)}ⱼ , where ẑⱼ(r) = 1/zⱼ(r) = 1/(r - xⱼ) - std::vector inverse_vanishing_evals; - inverse_vanishing_evals.reserve(num_claims); + // Compute {ẑⱼ(r)}ⱼ , where ẑⱼ(r) = 1/zⱼ(r) = 1/(r - xⱼ) + // WORKTODO: doing innefficient inversion for now since batch inversion is not implemented for field_t + std::vector vanishing_evals; + vanishing_evals.reserve(num_claims); for (const auto& claim : claims) { - inverse_vanishing_evals.emplace_back(z_challenge - claim.opening_pair.challenge); + vanishing_evals.emplace_back(z_challenge - claim.opening_pair.challenge); + } + std::vector inverse_vanishing_evals; + for (const auto& val : vanishing_evals) { + inverse_vanishing_evals.emplace_back(val.invert()); } - Fr::batch_invert(inverse_vanishing_evals); - Fr current_nu{ Fr::one() }; + auto current_nu = Fr(1); for (size_t j = 0; j < num_claims; ++j) { // (Cⱼ, xⱼ, vⱼ) const auto& [opening_pair, commitment] = claims[j]; @@ -210,10 +214,15 @@ template class ShplonkVerifier_ { // [G] += G₀⋅[1] = [G] + (∑ⱼ ρʲ ⋅ vⱼ / ( r − xⱼ ))⋅[1] // GroupElement sort_of_one{ x, y }; - G_commitment += vk->srs->get_first_g1() * G_commitment_constant; + if constexpr (Curve::is_stdlib_type) { + auto ctx = nu.get_context(); + G_commitment += GroupElement::one(ctx) * G_commitment_constant; + } else { + G_commitment += vk->srs->get_first_g1() * G_commitment_constant; + } // Return opening pair (z, 0) and commitment [G] - return { { z_challenge, Fr::zero() }, G_commitment }; + return { { z_challenge, Fr(0) }, G_commitment }; }; }; } // namespace proof_system::honk::pcs::shplonk diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/primitives/curves/bn254.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/primitives/curves/bn254.hpp index 2f2f7dcdce13..28d720b9b2eb 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/primitives/curves/bn254.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/primitives/curves/bn254.hpp @@ -9,6 +9,7 @@ namespace stdlib { template struct bn254 { static constexpr proof_system::CurveType type = proof_system::CurveType::BN254; + static constexpr bool is_stdlib_type = true; // Corresponding native types (used exclusively for testing) using ScalarFieldNative = curve::BN254::ScalarField; diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp index 644c2614baf3..72c564ea3f9b 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp @@ -44,7 +44,7 @@ template bool UltraRecursiveVerifier_::verify_proof(co using Commitment = typename Flavor::Commitment; using Curve = typename Flavor::Curve; using Gemini = ::proof_system::honk::pcs::gemini::GeminiVerifier_; - // using Shplonk = pcs::shplonk::ShplonkVerifier_; + using Shplonk = ::proof_system::honk::pcs::shplonk::ShplonkVerifier_; // using PCS = typename Flavor::PCS; using VerifierCommitments = typename Flavor::VerifierCommitments; using CommitmentLabels = typename Flavor::CommitmentLabels; @@ -66,6 +66,8 @@ template bool UltraRecursiveVerifier_::verify_proof(co auto public_input_size_native = static_cast(public_input_size.get_value()); auto pub_inputs_offset_native = static_cast(pub_inputs_offset.get_value()); + info("1. num gates = 0", builder->get_num_gates()); + if (circuit_size_native != key->circuit_size) { return false; } @@ -107,11 +109,15 @@ template bool UltraRecursiveVerifier_::verify_proof(co // Get permutation challenges auto [beta, gamma] = transcript.get_challenges("beta", "gamma"); + info("2. num gates = 0", builder->get_num_gates()); + const FF public_input_delta = proof_system::honk::compute_public_input_delta( public_inputs, beta, gamma, circuit_size, pub_inputs_offset_native); const FF lookup_grand_product_delta = proof_system::honk::compute_lookup_grand_product_delta(beta, gamma, circuit_size); + info("3. num gates = 0", builder->get_num_gates()); + relation_parameters.beta = beta; relation_parameters.gamma = gamma; relation_parameters.public_input_delta = public_input_delta; @@ -126,6 +132,8 @@ template bool UltraRecursiveVerifier_::verify_proof(co std::optional sumcheck_output = sumcheck.verify(relation_parameters, transcript); + info("4. num gates = 0", builder->get_num_gates()); + // // Note(luke): Temporary. Done only to complete manifest through sumcheck. Delete once we proceed to Gemini. // [[maybe_unused]] FF rho = transcript.get_challenge("rho"); @@ -149,6 +157,8 @@ template bool UltraRecursiveVerifier_::verify_proof(co ++evaluation_idx; } + info("5. num gates = 0", builder->get_num_gates()); + // Construct vectors of scalars for batched unshifted and to-be-shifted commitments const size_t NUM_UNSHIFTED = commitments.get_unshifted().size(); const size_t NUM_TO_BE_SHIFTED = commitments.get_to_be_shifted().size(); @@ -167,8 +177,10 @@ template bool UltraRecursiveVerifier_::verify_proof(co // Batch the commitments to the unshifted and to-be-shifted polynomials using powers of rho auto batched_commitment_unshifted = GroupElement::batch_mul(commitments.get_unshifted(), scalars_unshifted); + info("6. num gates = 0", builder->get_num_gates()); auto batched_commitment_to_be_shifted = GroupElement::batch_mul(commitments.get_to_be_shifted(), scalars_to_be_shifted); + info("7. num gates = 0", builder->get_num_gates()); // Produce a Gemini claim consisting of: // - d+1 commitments [Fold_{r}^(0)], [Fold_{-r}^(0)], and [Fold^(l)], l = 1:d-1 @@ -179,15 +191,18 @@ template bool UltraRecursiveVerifier_::verify_proof(co batched_commitment_to_be_shifted, transcript); - // Note(luke): Temporary. Done only to complete manifest through Gemini. Delete once we proceed to Shplonk. - [[maybe_unused]] FF nu = transcript.get_challenge("Shplonk:nu"); + info("8. num gates = 0", builder->get_num_gates()); + // // Note(luke): Temporary. Done only to complete manifest through Gemini. Delete once we proceed to Shplonk. + // [[maybe_unused]] FF nu = transcript.get_challenge("Shplonk:nu"); + + // Produce a Shplonk claim: commitment [Q] - [Q_z], evaluation zero (at random challenge z) + auto shplonk_claim = Shplonk::reduce_verification(pcs_verification_key, gemini_claim, transcript); + (void)shplonk_claim; + info("9. num gates = 0", builder->get_num_gates()); // DEBUG! return true; - // // Produce a Shplonk claim: commitment [Q] - [Q_z], evaluation zero (at random challenge z) - // auto shplonk_claim = Shplonk::reduce_verification(pcs_verification_key, gemini_claim, transcript); - // // // Verify the Shplonk claim with KZG or IPA // return PCS::verify(pcs_verification_key, shplonk_claim, transcript); }