diff --git a/barretenberg/cpp/src/barretenberg/benchmark/ipa_bench/ipa.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/ipa_bench/ipa.bench.cpp index af594ba44e66..4f1719c141c4 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/ipa_bench/ipa.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/ipa_bench/ipa.bench.cpp @@ -16,8 +16,8 @@ std::shared_ptr> crs_factory( auto ck = std::make_shared>(1 << MAX_POLYNOMIAL_DEGREE_LOG2, crs_factory); auto vk = std::make_shared>(1 << MAX_POLYNOMIAL_DEGREE_LOG2, crs_factory); -std::vector> prover_transcripts(MAX_POLYNOMIAL_DEGREE_LOG2 - - MIN_POLYNOMIAL_DEGREE_LOG2 + 1); +std::vector> prover_transcripts(MAX_POLYNOMIAL_DEGREE_LOG2 - + MIN_POLYNOMIAL_DEGREE_LOG2 + 1); std::vector> opening_claims(MAX_POLYNOMIAL_DEGREE_LOG2 - MIN_POLYNOMIAL_DEGREE_LOG2 + 1); void ipa_open(State& state) noexcept @@ -36,7 +36,7 @@ void ipa_open(State& state) noexcept const OpeningPair opening_pair = { x, eval }; const OpeningClaim opening_claim{ opening_pair, ck->commit(poly) }; // initialize empty prover transcript - auto prover_transcript = std::make_shared(); + auto prover_transcript = std::make_shared(); state.ResumeTiming(); // Compute proof IPA::compute_opening_proof(ck, opening_pair, poly, prover_transcript); @@ -53,7 +53,7 @@ void ipa_verify(State& state) noexcept auto prover_transcript = prover_transcripts[static_cast(state.range(0)) - MIN_POLYNOMIAL_DEGREE_LOG2]; auto opening_claim = opening_claims[static_cast(state.range(0)) - MIN_POLYNOMIAL_DEGREE_LOG2]; // initialize verifier transcript from proof data - auto verifier_transcript = std::make_shared(prover_transcript->proof_data); + auto verifier_transcript = std::make_shared(prover_transcript->proof_data); state.ResumeTiming(); auto result = IPA::verify(vk, opening_claim, verifier_transcript); diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp index 6edf56c0b4bf..94fbd5c43c70 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp @@ -149,7 +149,7 @@ template 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("Gemini:r"); std::vector r_squares = gemini::squares_of_r(r, num_variables); // Get evaluations a_i, i = 0,...,m-1 from transcript diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.test.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.test.cpp index 0574dcfa115d..7e378bba2501 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.test.cpp @@ -25,7 +25,7 @@ template class GeminiTest : public CommitmentTest { std::vector multilinear_commitments, std::vector 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(); @@ -65,7 +65,7 @@ template class GeminiTest : public CommitmentTest { 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("Gemini:r"); auto prover_output = GeminiProver::compute_fold_polynomial_evaluations( multilinear_evaluation_point, std::move(gemini_polynomials), r_challenge); @@ -79,7 +79,7 @@ template class GeminiTest : public CommitmentTest { // 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} diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp index ccac4dbdc2fe..b179a6dee7e8 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp @@ -36,12 +36,12 @@ template class IPA { static void compute_opening_proof(const std::shared_ptr& ck, const OpeningPair& opening_pair, const Polynomial& polynomial, - const std::shared_ptr& transcript) + const std::shared_ptr& transcript) { ASSERT(opening_pair.challenge != 0 && "The challenge point should not be zero"); auto poly_degree = static_cast(polynomial.size()); - transcript->send_to_verifier("IPA:poly_degree", static_cast(poly_degree)); - const Fr generator_challenge = transcript->get_challenge("IPA:generator_challenge"); + transcript->send_to_verifier("IPA:poly_degree", static_cast(poly_degree)); + const Fr generator_challenge = transcript->template get_challenge("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 @@ -138,7 +138,7 @@ template 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("IPA:round_challenge_" + index); const Fr round_challenge_inv = round_challenge.invert(); auto G_lo = GroupElement::batch_mul_with_endomorphism( @@ -183,10 +183,12 @@ template class IPA { */ static bool verify(const std::shared_ptr& vk, const OpeningClaim& opening_claim, - const std::shared_ptr& transcript) + const std::shared_ptr& transcript) { - auto poly_degree = static_cast(transcript->template receive_from_prover("IPA:poly_degree")); - const Fr generator_challenge = transcript->get_challenge("IPA:generator_challenge"); + auto poly_degree = static_cast(transcript->template receive_from_prover( + "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("IPA:generator_challenge"); auto aux_generator = Commitment::one() * generator_challenge; auto log_poly_degree = static_cast(numeric::get_msb(poly_degree)); @@ -204,7 +206,7 @@ template class IPA { std::string index = std::to_string(i); auto element_L = transcript->template receive_from_prover("IPA:L_" + index); auto element_R = transcript->template receive_from_prover("IPA:R_" + index); - round_challenges[i] = transcript->get_challenge("IPA:round_challenge_" + index); + round_challenges[i] = transcript->template get_challenge("IPA:round_challenge_" + index); round_challenges_inv[i] = round_challenges[i].invert(); msm_elements[2 * i] = element_L; diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.test.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.test.cpp index b1d61d63df40..719be120fda2 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.test.cpp @@ -72,11 +72,11 @@ TEST_F(IPATest, Open) const OpeningClaim opening_claim{ opening_pair, commitment }; // initialize empty prover transcript - auto prover_transcript = std::make_shared(); + auto prover_transcript = std::make_shared(); IPA::compute_opening_proof(this->ck(), opening_pair, poly, prover_transcript); // initialize verifier transcript from proof data - auto verifier_transcript = std::make_shared(prover_transcript->proof_data); + auto verifier_transcript = std::make_shared(prover_transcript->proof_data); auto result = IPA::verify(this->vk(), opening_claim, verifier_transcript); EXPECT_TRUE(result); @@ -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)); @@ -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("Gemini:r"); const auto [gemini_opening_pairs, gemini_witnesses] = GeminiProver::compute_fold_polynomial_evaluations( mle_opening_point, std::move(gemini_polynomials), r_challenge); @@ -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("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("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, diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.hpp index 1e4a0f1b18ec..8a3226200001 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.hpp @@ -31,7 +31,7 @@ template class KZG { static void compute_opening_proof(std::shared_ptr ck, const OpeningPair& opening_pair, const Polynomial& polynomial, - const std::shared_ptr& prover_trancript) + const std::shared_ptr& prover_trancript) { Polynomial quotient = polynomial; quotient[0] -= opening_pair.evaluation; @@ -55,7 +55,7 @@ template class KZG { */ static bool verify(const std::shared_ptr& vk, const OpeningClaim& claim, - const std::shared_ptr& verifier_transcript) + const std::shared_ptr& verifier_transcript) { auto quotient_commitment = verifier_transcript->template receive_from_prover("KZG:W"); auto lhs = claim.commitment - (GroupElement::one() * claim.opening_pair.evaluation) + @@ -82,7 +82,7 @@ template 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 commitments = { claim.commitment, quotient_commitment, diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.test.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.test.cpp index 9e45ffff90ae..4ec38c455617 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.test.cpp @@ -39,11 +39,11 @@ TYPED_TEST(KZGTest, single) auto opening_pair = OpeningPair{ challenge, evaluation }; auto opening_claim = OpeningClaim{ 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); @@ -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: @@ -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("Gemini:r"); const auto [gemini_opening_pairs, gemini_witnesses] = GeminiProver::compute_fold_polynomial_evaluations( mle_opening_point, std::move(gemini_polynomials), r_challenge); @@ -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("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("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); @@ -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 diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplonk.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplonk.hpp index a73ffa37a8f6..fb08f81d8895 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplonk.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplonk.hpp @@ -168,11 +168,11 @@ template class ShplonkVerifier_ { const size_t num_claims = claims.size(); - const Fr nu = transcript->get_challenge("Shplonk:nu"); + const Fr nu = transcript->template get_challenge("Shplonk:nu"); auto Q_commitment = transcript->template receive_from_prover("Shplonk:Q"); - const Fr z_challenge = transcript->get_challenge("Shplonk:z"); + const Fr z_challenge = transcript->template get_challenge("Shplonk:z"); // [G] = [Q] - ∑ⱼ ρʲ / ( r − xⱼ )⋅[fⱼ] + G₀⋅[1] // = [Q] - [∑ⱼ ρʲ ⋅ ( fⱼ(X) − vⱼ) / ( r − xⱼ )] diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplonk.test.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplonk.test.cpp index ee5168b22535..359766165269 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplonk.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplonk.test.cpp @@ -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. @@ -47,11 +47,11 @@ TYPED_TEST(ShplonkTest, ShplonkSimple) std::vector 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("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("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); @@ -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); diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp index ce1e8c6fdd16..8441b8dd21d9 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp @@ -322,13 +322,13 @@ template class ZeroMorphProver_ { const std::vector& g_shift_evaluations, const std::vector& multilinear_challenge, const std::shared_ptr>& commitment_key, - const std::shared_ptr& transcript, + const std::shared_ptr& transcript, const std::vector& concatenated_polynomials = {}, const std::vector& concatenated_evaluations = {}, const std::vector>& concatenation_groups = {}) { // Generate batching challenge \rho and powers 1,...,\rho^{m-1} - const FF rho = transcript->get_challenge("rho"); + const FF rho = transcript->template get_challenge("rho"); // Extract multilinear challenge u and claimed multilinear evaluations from Sumcheck output std::span u_challenge = multilinear_challenge; @@ -397,7 +397,7 @@ template class ZeroMorphProver_ { } // Get challenge y - FF y_challenge = transcript->get_challenge("ZM:y"); + FF y_challenge = transcript->template get_challenge("ZM:y"); // Compute the batched, lifted-degree quotient \hat{q} auto batched_quotient = compute_batched_lifted_degree_quotient(quotients, y_challenge, N); @@ -407,7 +407,7 @@ template class ZeroMorphProver_ { transcript->send_to_verifier("ZM:C_q", q_commitment); // Get challenges x and z - auto [x_challenge, z_challenge] = challenges_to_field_elements(transcript->get_challenges("ZM:x", "ZM:z")); + auto [x_challenge, z_challenge] = transcript->template get_challenges("ZM:x", "ZM:z"); // Compute degree check polynomial \zeta partially evaluated at x auto zeta_x = @@ -644,7 +644,7 @@ template class ZeroMorphVerifier_ { const std::vector& concatenated_evaluations = {}) { size_t log_N = multivariate_challenge.size(); - FF rho = transcript->get_challenge("rho"); + FF rho = transcript->template get_challenge("rho"); // Construct batched evaluation v = sum_{i=0}^{m-1}\rho^i*f_i(u) + sum_{i=0}^{l-1}\rho^{m+i}*h_i(u) FF batched_evaluation = FF(0); @@ -670,13 +670,13 @@ template class ZeroMorphVerifier_ { } // Challenge y - FF y_challenge = transcript->get_challenge("ZM:y"); + FF y_challenge = transcript->template get_challenge("ZM:y"); // Receive commitment C_{q} auto C_q = transcript->template receive_from_prover("ZM:C_q"); // Challenges x, z - auto [x_challenge, z_challenge] = challenges_to_field_elements(transcript->get_challenges("ZM:x", "ZM:z")); + auto [x_challenge, z_challenge] = transcript->template 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); diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.test.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.test.cpp index b963ecb05116..084e003c0a4d 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.test.cpp @@ -74,8 +74,8 @@ template class ZeroMorphTest : public CommitmentTest { g_commitments.emplace_back(f_commitments[i]); } - // Initialize an empty BaseTranscript - auto prover_transcript = BaseTranscript::prover_init_empty(); + // Initialize an empty NativeTranscript + auto prover_transcript = NativeTranscript::prover_init_empty(); // Execute Prover protocol ZeroMorphProver::prove(f_polynomials, @@ -86,7 +86,7 @@ template class ZeroMorphTest : public CommitmentTest { this->commitment_key, prover_transcript); - auto verifier_transcript = BaseTranscript::verifier_init_empty(prover_transcript); + auto verifier_transcript = NativeTranscript::verifier_init_empty(prover_transcript); // Execute Verifier protocol auto pairing_points = ZeroMorphVerifier::verify( @@ -220,8 +220,8 @@ template class ZeroMorphWithConcatenationTest : public CommitmentT concatenation_groups_commitments.emplace_back(concatenation_group_commitment); } - // Initialize an empty BaseTranscript - auto prover_transcript = BaseTranscript::prover_init_empty(); + // Initialize an empty NativeTranscript + auto prover_transcript = NativeTranscript::prover_init_empty(); // Execute Prover protocol ZeroMorphProver::prove(f_polynomials, // unshifted @@ -235,7 +235,7 @@ template class ZeroMorphWithConcatenationTest : public CommitmentT c_evaluations, to_vector_of_ref_vectors(concatenation_groups)); - auto verifier_transcript = BaseTranscript::verifier_init_empty(prover_transcript); + auto verifier_transcript = NativeTranscript::verifier_init_empty(prover_transcript); // Execute Verifier protocol auto pairing_points = ZeroMorphVerifier::verify(f_commitments, // unshifted diff --git a/barretenberg/cpp/src/barretenberg/ecc/fields/field_conversion.cpp b/barretenberg/cpp/src/barretenberg/ecc/fields/field_conversion.cpp index 3c34ad7561ab..0d09d6b57526 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/fields/field_conversion.cpp +++ b/barretenberg/cpp/src/barretenberg/ecc/fields/field_conversion.cpp @@ -1,9 +1,10 @@ #include "barretenberg/ecc/fields/field_conversion.hpp" +#include "barretenberg/plonk/proof_system/constants.hpp" namespace bb::field_conversion { -static constexpr uint64_t NUM_CONVERSION_LIMB_BITS = 68; // set to be 68 because bigfield has 68 bit limbs +static constexpr uint64_t NUM_LIMB_BITS = plonk::NUM_LIMB_BITS_IN_FIELD_SIMULATION; static constexpr uint64_t TOTAL_BITS = 254; bb::fr convert_from_bn254_frs(std::span fr_vec, bb::fr* /*unused*/) @@ -34,10 +35,9 @@ bool convert_from_bn254_frs(std::span fr_vec, bool* /*unused*/) grumpkin::fr convert_from_bn254_frs(std::span fr_vec, grumpkin::fr* /*unused*/) { // Combines the two elements into one uint256_t, and then convert that to a grumpkin::fr - ASSERT(uint256_t(fr_vec[0]) < (uint256_t(1) << (NUM_CONVERSION_LIMB_BITS * 2))); // lower 136 bits - ASSERT(uint256_t(fr_vec[1]) < - (uint256_t(1) << (TOTAL_BITS - NUM_CONVERSION_LIMB_BITS * 2))); // upper 254-136=118 bits - uint256_t value = uint256_t(fr_vec[0]) + (uint256_t(fr_vec[1]) << (NUM_CONVERSION_LIMB_BITS * 2)); + ASSERT(uint256_t(fr_vec[0]) < (uint256_t(1) << (NUM_LIMB_BITS * 2))); // lower 136 bits + ASSERT(uint256_t(fr_vec[1]) < (uint256_t(1) << (TOTAL_BITS - NUM_LIMB_BITS * 2))); // upper 254-136=118 bits + uint256_t value = uint256_t(fr_vec[0]) + (uint256_t(fr_vec[1]) << (NUM_LIMB_BITS * 2)); grumpkin::fr result(value); return result; } @@ -78,7 +78,7 @@ std::vector convert_to_bn254_frs(const grumpkin::fr& val) { // Goal is to slice up the 64 bit limbs of grumpkin::fr/uint256_t to mirror the 68 bit limbs of bigfield // We accomplish this by dividing the grumpkin::fr's value into two 68*2=136 bit pieces. - constexpr uint64_t LOWER_BITS = 2 * NUM_CONVERSION_LIMB_BITS; + constexpr uint64_t LOWER_BITS = 2 * NUM_LIMB_BITS; constexpr uint256_t LOWER_MASK = (uint256_t(1) << LOWER_BITS) - 1; auto value = uint256_t(val); ASSERT(value < (uint256_t(1) << TOTAL_BITS)); @@ -113,4 +113,19 @@ std::vector convert_to_bn254_frs(const curve::Grumpkin::AffineElement& v return fr_vec; } -} // namespace bb::field_conversion \ No newline at end of file +grumpkin::fr convert_to_grumpkin_fr(const bb::fr& f) +{ + const uint64_t NUM_BITS_IN_TWO_LIMBS = 2 * NUM_LIMB_BITS; // the number of bits in 2 bigfield limbs which is 136 + + constexpr uint256_t LIMB_MASK = + (uint256_t(1) << NUM_BITS_IN_TWO_LIMBS) - 1; // split bn254_fr into two 136 bit pieces + const uint256_t value = f; + const uint256_t low = static_cast(value & LIMB_MASK); + const uint256_t hi = static_cast(value >> NUM_BITS_IN_TWO_LIMBS); + ASSERT(static_cast(low) + (static_cast(hi) << NUM_BITS_IN_TWO_LIMBS) == value); + + std::vector fr_vec{ low, hi }; + return convert_from_bn254_frs(fr_vec); +} + +} // namespace bb::field_conversion diff --git a/barretenberg/cpp/src/barretenberg/ecc/fields/field_conversion.hpp b/barretenberg/cpp/src/barretenberg/ecc/fields/field_conversion.hpp index cf5b12d1def9..a3abc63673d9 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/fields/field_conversion.hpp +++ b/barretenberg/cpp/src/barretenberg/ecc/fields/field_conversion.hpp @@ -8,7 +8,7 @@ namespace bb::field_conversion { /** - * @brief Calculates number of bb::fr required to represent the input type + * @brief Calculates the size of a types in terms of bb::frs * @details We want to support the following types: bool, size_t, uint32_t, uint64_t, bb::fr, grumpkin::fr, * curve::BN254::AffineElement, curve::Grumpkin::AffineElement, bb::Univariate, std::array, for * FF = bb::fr/grumpkin::fr, and N is arbitrary @@ -208,4 +208,15 @@ template std::vector inline convert_to_bn254_frs(co return fr_vec; } +grumpkin::fr convert_to_grumpkin_fr(const bb::fr& f); + +template T inline convert_challenge(const bb::fr& challenge) +{ + if constexpr (std::is_same_v) { + return challenge; + } else if constexpr (std::is_same_v) { + return convert_to_grumpkin_fr(challenge); + } +} + } // namespace bb::field_conversion diff --git a/barretenberg/cpp/src/barretenberg/ecc/fields/field_conversion.test.cpp b/barretenberg/cpp/src/barretenberg/ecc/fields/field_conversion.test.cpp index 0a024f82545d..a2b6c3dd6821 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/fields/field_conversion.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ecc/fields/field_conversion.test.cpp @@ -131,4 +131,16 @@ TEST_F(FieldConversionTest, FieldConversionUnivariateGrumpkinFr) check_conversion(x1); } +/** + * @brief Convert challenge test for grumpkin::fr + * + */ +TEST_F(FieldConversionTest, ConvertChallengeGrumpkinFr) +{ + bb::fr chal(std::string("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789")); // 256 bits + auto result = bb::field_conversion::convert_challenge(chal); + auto expected = uint256_t(chal); + EXPECT_EQ(uint256_t(result), expected); +} + } // namespace bb::field_conversion_tests diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp index ec5cba49084b..58e525278e9b 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp @@ -71,7 +71,7 @@ template void ECCVMProver_::execute_wire_commitme template void ECCVMProver_::execute_log_derivative_commitments_round() { // Compute and add beta to relation parameters - auto [beta, gamma] = challenges_to_field_elements(transcript->get_challenges("beta", "gamma")); + auto [beta, gamma] = transcript->template 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; @@ -110,10 +110,10 @@ template void ECCVMProver_::execute_relation_chec using Sumcheck = SumcheckProver; auto sumcheck = Sumcheck(key->circuit_size, transcript); - FF alpha = transcript->get_challenge("Sumcheck:alpha"); + FF alpha = transcript->template get_challenge("Sumcheck:alpha"); std::vector gate_challenges(numeric::get_msb(key->circuit_size)); for (size_t idx = 0; idx < gate_challenges.size(); idx++) { - gate_challenges[idx] = transcript->get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); + gate_challenges[idx] = transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); } sumcheck_output = sumcheck.prove(prover_polynomials, relation_parameters, alpha, gate_challenges); } @@ -128,7 +128,7 @@ template void ECCVMProver_::execute_univariatizat const size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES; // Generate batching challenge ρ and powers 1,ρ,…,ρᵐ⁻¹ - FF rho = transcript->get_challenge("rho"); + FF rho = transcript->template get_challenge("rho"); std::vector rhos = gemini::powers_of_rho(rho, NUM_POLYNOMIALS); // Batch the unshifted polynomials and the to-be-shifted polynomials using ρ @@ -168,7 +168,7 @@ template void ECCVMProver_::execute_univariatizat * */ template void ECCVMProver_::execute_pcs_evaluation_round() { - const FF r_challenge = transcript->get_challenge("Gemini:r"); + const FF r_challenge = transcript->template get_challenge("Gemini:r"); gemini_output = Gemini::compute_fold_polynomial_evaluations( sumcheck_output.challenge, std::move(gemini_polynomials), r_challenge); @@ -185,7 +185,7 @@ template void ECCVMProver_::execute_pcs_evaluatio * */ template void ECCVMProver_::execute_shplonk_batched_quotient_round() { - nu_challenge = transcript->get_challenge("Shplonk:nu"); + nu_challenge = transcript->template get_challenge("Shplonk:nu"); batched_quotient_Q = Shplonk::compute_batched_quotient(gemini_output.opening_pairs, gemini_output.witnesses, nu_challenge); @@ -200,7 +200,7 @@ template void ECCVMProver_::execute_shplonk_batch * */ template void ECCVMProver_::execute_shplonk_partial_evaluation_round() { - const FF z_challenge = transcript->get_challenge("Shplonk:z"); + const FF z_challenge = transcript->template 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); @@ -232,7 +232,7 @@ template void ECCVMProver_::execute_transcript_co transcript->send_to_verifier("Translation:hack_commitment", commitment_key->commit(hack)); // Get the challenge at which we evaluate the polynomials as univariates - evaluation_challenge_x = transcript->get_challenge("Translation:evaluation_challenge_x"); + evaluation_challenge_x = transcript->template get_challenge("Translation:evaluation_challenge_x"); translation_evaluations.op = key->transcript_op.evaluate(evaluation_challenge_x); translation_evaluations.Px = key->transcript_Px.evaluate(evaluation_challenge_x); @@ -249,7 +249,7 @@ template void ECCVMProver_::execute_transcript_co transcript->send_to_verifier("Translation:hack_evaluation", hack.evaluate(evaluation_challenge_x)); // Get another challenge for batching the univariate claims - FF ipa_batching_challenge = transcript->get_challenge("Translation:ipa_batching_challenge"); + FF ipa_batching_challenge = transcript->template get_challenge("Translation:ipa_batching_challenge"); // Collect the polynomials and evaluations to be batched RefArray univariate_polynomials{ key->transcript_op, key->transcript_Px, key->transcript_Py, @@ -271,7 +271,7 @@ template void ECCVMProver_::execute_transcript_co commitment_key, { evaluation_challenge_x, batched_evaluation }, batched_univariate, transcript); // Get another challenge for batching the univariate claims - translation_batching_challenge_v = transcript->get_challenge("Translation:batching_challenge"); + translation_batching_challenge_v = transcript->template get_challenge("Translation:batching_challenge"); } template HonkProof& ECCVMProver_::export_proof() diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_transcript.test.cpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_transcript.test.cpp index 73dafdf3c682..f1ab178db34e 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_transcript.test.cpp @@ -299,7 +299,7 @@ TYPED_TEST(ECCVMTranscriptTests, ChallengeGenerationTest) // initialized with random value sent to verifier auto transcript = Flavor::Transcript::prover_init_empty(); // test a bunch of challenges - auto challenges = transcript->get_challenges("a", "b", "c", "d", "e", "f"); + auto challenges = transcript->template get_challenges("a", "b", "c", "d", "e", "f"); // check they are not 0 for (size_t i = 0; i < challenges.size(); ++i) { ASSERT_NE(challenges[i], 0) << "Challenge " << i << " is 0"; @@ -307,7 +307,7 @@ 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] = challenges_to_field_elements(transcript->get_challenges("a", "b", "c")); + auto [a, b, c] = transcript->template get_challenges("a", "b", "c"); ASSERT_NE(a, 0) << "Challenge a is 0"; ASSERT_NE(b, 0) << "Challenge b is 0"; diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp index 58cf1e656c3e..71ce6e2ae6ad 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp @@ -137,7 +137,7 @@ template bool ECCVMVerifier_::verify_proof(const HonkP 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] = challenges_to_field_elements(transcript->get_challenges("beta", "gamma")); + auto [beta, gamma] = transcript->template get_challenges("beta", "gamma"); relation_parameters.gamma = gamma; auto beta_sqr = beta * beta; @@ -155,10 +155,10 @@ template bool ECCVMVerifier_::verify_proof(const HonkP // Execute Sumcheck Verifier const size_t log_circuit_size = numeric::get_msb(circuit_size); auto sumcheck = SumcheckVerifier(log_circuit_size, transcript); - FF alpha = transcript->get_challenge("Sumcheck:alpha"); + FF alpha = transcript->template get_challenge("Sumcheck:alpha"); std::vector gate_challenges(numeric::get_msb(key->circuit_size)); for (size_t idx = 0; idx < gate_challenges.size(); idx++) { - gate_challenges[idx] = transcript->get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); + gate_challenges[idx] = transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); } auto [multivariate_challenge, purported_evaluations, sumcheck_verified] = @@ -178,7 +178,7 @@ template bool ECCVMVerifier_::verify_proof(const HonkP auto batched_commitment_to_be_shifted = GroupElement::zero(); const size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES; // Compute powers of batching challenge rho - FF rho = transcript->get_challenge("rho"); + FF rho = transcript->template get_challenge("rho"); std::vector rhos = gemini::powers_of_rho(rho, NUM_POLYNOMIALS); // Compute batched multivariate evaluation @@ -238,7 +238,7 @@ template bool ECCVMVerifier_::verify_proof(const HonkP { auto hack_commitment = receive_commitment("Translation:hack_commitment"); - FF evaluation_challenge_x = transcript->get_challenge("Translation:evaluation_challenge_x"); + FF evaluation_challenge_x = transcript->template get_challenge("Translation:evaluation_challenge_x"); // Construct arrays of commitments and evaluations to be batched const size_t NUM_UNIVARIATES = 6; @@ -256,7 +256,7 @@ template bool ECCVMVerifier_::verify_proof(const HonkP }; // Get another challenge for batching the univariate claims - FF ipa_batching_challenge = transcript->get_challenge("Translation:ipa_batching_challenge"); + FF ipa_batching_challenge = transcript->template get_challenge("Translation:ipa_batching_challenge"); // Construct batched commitment and batched evaluation auto batched_commitment = transcript_commitments[0]; diff --git a/barretenberg/cpp/src/barretenberg/flavor/ecc_vm.hpp b/barretenberg/cpp/src/barretenberg/flavor/ecc_vm.hpp index ba3c2df1abf7..ad1feee32f35 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/ecc_vm.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/ecc_vm.hpp @@ -520,7 +520,7 @@ template class ECCVMBa * @brief Derived class that defines proof structure for ECCVM proofs, as well as supporting functions. * */ - class Transcript : public BaseTranscript { + class Transcript : public NativeTranscript { public: uint32_t circuit_size; Commitment transcript_add_comm; @@ -606,7 +606,7 @@ template class ECCVMBa Commitment shplonk_q_comm; Commitment kzg_w_comm; // the rest are only for Grumpkin - uint64_t ipa_poly_degree; + uint32_t ipa_poly_degree; std::vector ipa_l_comms; std::vector ipa_r_comms; FF ipa_a_0_eval; @@ -614,200 +614,200 @@ template class ECCVMBa Transcript() = default; Transcript(const HonkProof& proof) - : BaseTranscript(proof) + : NativeTranscript(proof) {} void deserialize_full_transcript() { // take current proof and put them into the struct size_t num_frs_read = 0; - circuit_size = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); + circuit_size = NativeTranscript::template deserialize_from_buffer(NativeTranscript::proof_data, + num_frs_read); size_t log_n = numeric::get_msb(circuit_size); - transcript_add_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - transcript_mul_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - transcript_eq_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - transcript_collision_check_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - transcript_msm_transition_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - transcript_pc_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - transcript_msm_count_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - transcript_Px_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - transcript_Py_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - transcript_z1_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - transcript_z2_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - transcript_z1zero_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - transcript_z2zero_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - transcript_op_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - transcript_accumulator_x_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - transcript_accumulator_y_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - transcript_msm_x_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - transcript_msm_y_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - precompute_pc_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - precompute_point_transition_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - precompute_round_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - precompute_scalar_sum_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - precompute_s1hi_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - precompute_s1lo_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - precompute_s2hi_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - precompute_s2lo_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - precompute_s3hi_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - precompute_s3lo_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - precompute_s4hi_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - precompute_s4lo_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - precompute_skew_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - precompute_dx_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - precompute_dy_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - precompute_tx_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - precompute_ty_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_transition_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_add_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_double_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_skew_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_accumulator_x_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_accumulator_y_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_pc_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_size_of_msm_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_count_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_round_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_add1_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_add2_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_add3_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_add4_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_x1_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_y1_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_x2_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_y2_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_x3_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_y3_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_x4_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_y4_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_collision_x1_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_collision_x2_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_collision_x3_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_collision_x4_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_lambda1_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_lambda2_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_lambda3_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_lambda4_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_slice1_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_slice2_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_slice3_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - msm_slice4_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - transcript_accumulator_empty_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - transcript_reset_accumulator_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - precompute_select_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - lookup_read_counts_0_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - lookup_read_counts_1_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - lookup_inverses_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); - z_perm_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); + transcript_add_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + transcript_mul_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + transcript_eq_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + transcript_collision_check_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + transcript_msm_transition_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + transcript_pc_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + transcript_msm_count_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + transcript_Px_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + transcript_Py_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + transcript_z1_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + transcript_z2_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + transcript_z1zero_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + transcript_z2zero_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + transcript_op_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + transcript_accumulator_x_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + transcript_accumulator_y_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + transcript_msm_x_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + transcript_msm_y_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + precompute_pc_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + precompute_point_transition_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + precompute_round_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + precompute_scalar_sum_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + precompute_s1hi_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + precompute_s1lo_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + precompute_s2hi_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + precompute_s2lo_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + precompute_s3hi_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + precompute_s3lo_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + precompute_s4hi_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + precompute_s4lo_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + precompute_skew_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + precompute_dx_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + precompute_dy_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + precompute_tx_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + precompute_ty_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + msm_transition_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + msm_add_comm = NativeTranscript::template deserialize_from_buffer(NativeTranscript::proof_data, + num_frs_read); + msm_double_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + msm_skew_comm = NativeTranscript::template deserialize_from_buffer(NativeTranscript::proof_data, + num_frs_read); + msm_accumulator_x_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + msm_accumulator_y_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + msm_pc_comm = NativeTranscript::template deserialize_from_buffer(NativeTranscript::proof_data, + num_frs_read); + msm_size_of_msm_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + msm_count_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + msm_round_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + msm_add1_comm = NativeTranscript::template deserialize_from_buffer(NativeTranscript::proof_data, + num_frs_read); + msm_add2_comm = NativeTranscript::template deserialize_from_buffer(NativeTranscript::proof_data, + num_frs_read); + msm_add3_comm = NativeTranscript::template deserialize_from_buffer(NativeTranscript::proof_data, + num_frs_read); + msm_add4_comm = NativeTranscript::template deserialize_from_buffer(NativeTranscript::proof_data, + num_frs_read); + msm_x1_comm = NativeTranscript::template deserialize_from_buffer(NativeTranscript::proof_data, + num_frs_read); + msm_y1_comm = NativeTranscript::template deserialize_from_buffer(NativeTranscript::proof_data, + num_frs_read); + msm_x2_comm = NativeTranscript::template deserialize_from_buffer(NativeTranscript::proof_data, + num_frs_read); + msm_y2_comm = NativeTranscript::template deserialize_from_buffer(NativeTranscript::proof_data, + num_frs_read); + msm_x3_comm = NativeTranscript::template deserialize_from_buffer(NativeTranscript::proof_data, + num_frs_read); + msm_y3_comm = NativeTranscript::template deserialize_from_buffer(NativeTranscript::proof_data, + num_frs_read); + msm_x4_comm = NativeTranscript::template deserialize_from_buffer(NativeTranscript::proof_data, + num_frs_read); + msm_y4_comm = NativeTranscript::template deserialize_from_buffer(NativeTranscript::proof_data, + num_frs_read); + msm_collision_x1_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + msm_collision_x2_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + msm_collision_x3_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + msm_collision_x4_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + msm_lambda1_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + msm_lambda2_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + msm_lambda3_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + msm_lambda4_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + msm_slice1_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + msm_slice2_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + msm_slice3_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + msm_slice4_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + transcript_accumulator_empty_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + transcript_reset_accumulator_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + precompute_select_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + lookup_read_counts_0_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + lookup_read_counts_1_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + lookup_inverses_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); + z_perm_comm = NativeTranscript::template deserialize_from_buffer(NativeTranscript::proof_data, + num_frs_read); for (size_t i = 0; i < log_n; ++i) { - sumcheck_univariates.emplace_back( - BaseTranscript::template deserialize_from_buffer< - bb::Univariate>(BaseTranscript::proof_data, num_frs_read)); + sumcheck_univariates.emplace_back(NativeTranscript::template deserialize_from_buffer< + bb::Univariate>( + NativeTranscript::proof_data, num_frs_read)); } - sumcheck_evaluations = BaseTranscript::template deserialize_from_buffer>( - BaseTranscript::proof_data, num_frs_read); + sumcheck_evaluations = NativeTranscript::template deserialize_from_buffer>( + NativeTranscript::proof_data, num_frs_read); for (size_t i = 0; i < log_n - 1; ++i) { - gemini_univariate_comms.emplace_back(BaseTranscript::template deserialize_from_buffer( - BaseTranscript::proof_data, num_frs_read)); + gemini_univariate_comms.emplace_back(NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read)); } for (size_t i = 0; i < log_n; ++i) { gemini_a_evals.emplace_back( - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read)); + NativeTranscript::template deserialize_from_buffer(NativeTranscript::proof_data, num_frs_read)); } - shplonk_q_comm = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); + shplonk_q_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); if (std::is_same>::value) { - kzg_w_comm = BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, - num_frs_read); + kzg_w_comm = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); } else if (std::is_same>::value) { - ipa_poly_degree = BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, - num_frs_read); + ipa_poly_degree = NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read); auto log_poly_degree = static_cast(numeric::get_msb(ipa_poly_degree)); for (size_t i = 0; i < log_poly_degree; ++i) { - ipa_l_comms.emplace_back(BaseTranscript::template deserialize_from_buffer( - BaseTranscript::proof_data, num_frs_read)); - ipa_r_comms.emplace_back(BaseTranscript::template deserialize_from_buffer( - BaseTranscript::proof_data, num_frs_read)); + ipa_l_comms.emplace_back(NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read)); + ipa_r_comms.emplace_back(NativeTranscript::template deserialize_from_buffer( + NativeTranscript::proof_data, num_frs_read)); } ipa_a_0_eval = - BaseTranscript::template deserialize_from_buffer(BaseTranscript::proof_data, num_frs_read); + NativeTranscript::template deserialize_from_buffer(NativeTranscript::proof_data, num_frs_read); } else { throw_or_abort("Unsupported PCS"); } @@ -815,111 +815,117 @@ template class ECCVMBa void serialize_full_transcript() { - size_t old_proof_length = BaseTranscript::proof_data.size(); - BaseTranscript::proof_data.clear(); + size_t old_proof_length = NativeTranscript::proof_data.size(); + NativeTranscript::proof_data.clear(); size_t log_n = numeric::get_msb(circuit_size); - BaseTranscript::template serialize_to_buffer(circuit_size, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(transcript_add_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(transcript_mul_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(transcript_eq_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(transcript_collision_check_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(transcript_msm_transition_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(transcript_pc_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(transcript_msm_count_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(transcript_Px_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(transcript_Py_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(transcript_z1_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(transcript_z2_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(transcript_z1zero_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(transcript_z2zero_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(transcript_op_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(transcript_accumulator_x_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(transcript_accumulator_y_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(transcript_msm_x_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(transcript_msm_y_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(precompute_pc_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(precompute_point_transition_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(precompute_round_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(precompute_scalar_sum_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(precompute_s1hi_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(precompute_s1lo_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(precompute_s2hi_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(precompute_s2lo_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(precompute_s3hi_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(precompute_s3lo_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(precompute_s4hi_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(precompute_s4lo_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(precompute_skew_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(precompute_dx_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(precompute_dy_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(precompute_tx_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(precompute_ty_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_transition_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_add_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_double_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_skew_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_accumulator_x_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_accumulator_y_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_pc_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_size_of_msm_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_count_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_round_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_add1_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_add2_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_add3_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_add4_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_x1_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_y1_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_x2_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_y2_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_x3_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_y3_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_x4_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_y4_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_collision_x1_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_collision_x2_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_collision_x3_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_collision_x4_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_lambda1_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_lambda2_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_lambda3_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_lambda4_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_slice1_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_slice2_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_slice3_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(msm_slice4_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(transcript_accumulator_empty_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(transcript_reset_accumulator_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(precompute_select_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(lookup_read_counts_0_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(lookup_read_counts_1_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(lookup_inverses_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(z_perm_comm, BaseTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(circuit_size, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(transcript_add_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(transcript_mul_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(transcript_eq_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(transcript_collision_check_comm, + NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(transcript_msm_transition_comm, + NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(transcript_pc_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(transcript_msm_count_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(transcript_Px_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(transcript_Py_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(transcript_z1_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(transcript_z2_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(transcript_z1zero_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(transcript_z2zero_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(transcript_op_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(transcript_accumulator_x_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(transcript_accumulator_y_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(transcript_msm_x_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(transcript_msm_y_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(precompute_pc_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(precompute_point_transition_comm, + NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(precompute_round_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(precompute_scalar_sum_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(precompute_s1hi_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(precompute_s1lo_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(precompute_s2hi_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(precompute_s2lo_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(precompute_s3hi_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(precompute_s3lo_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(precompute_s4hi_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(precompute_s4lo_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(precompute_skew_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(precompute_dx_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(precompute_dy_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(precompute_tx_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(precompute_ty_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_transition_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_add_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_double_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_skew_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_accumulator_x_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_accumulator_y_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_pc_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_size_of_msm_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_count_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_round_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_add1_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_add2_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_add3_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_add4_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_x1_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_y1_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_x2_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_y2_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_x3_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_y3_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_x4_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_y4_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_collision_x1_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_collision_x2_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_collision_x3_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_collision_x4_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_lambda1_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_lambda2_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_lambda3_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_lambda4_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_slice1_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_slice2_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_slice3_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(msm_slice4_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(transcript_accumulator_empty_comm, + NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(transcript_reset_accumulator_comm, + NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(precompute_select_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(lookup_read_counts_0_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(lookup_read_counts_1_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(lookup_inverses_comm, NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(z_perm_comm, NativeTranscript::proof_data); for (size_t i = 0; i < log_n; ++i) { - BaseTranscript::template serialize_to_buffer(sumcheck_univariates[i], BaseTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(sumcheck_univariates[i], NativeTranscript::proof_data); } - BaseTranscript::template serialize_to_buffer(sumcheck_evaluations, BaseTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(sumcheck_evaluations, NativeTranscript::proof_data); for (size_t i = 0; i < log_n - 1; ++i) { - BaseTranscript::template serialize_to_buffer(gemini_univariate_comms[i], BaseTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(gemini_univariate_comms[i], + NativeTranscript::proof_data); } for (size_t i = 0; i < log_n; ++i) { - BaseTranscript::template serialize_to_buffer(gemini_a_evals[i], BaseTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(gemini_a_evals[i], NativeTranscript::proof_data); } - BaseTranscript::template serialize_to_buffer(shplonk_q_comm, BaseTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(shplonk_q_comm, NativeTranscript::proof_data); if (std::is_same>::value) { - BaseTranscript::template serialize_to_buffer(kzg_w_comm, BaseTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(kzg_w_comm, NativeTranscript::proof_data); } else if (std::is_same>::value) { - BaseTranscript::template serialize_to_buffer(ipa_poly_degree, BaseTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(ipa_poly_degree, NativeTranscript::proof_data); auto log_poly_degree = static_cast(numeric::get_msb(ipa_poly_degree)); for (size_t i = 0; i < log_poly_degree; ++i) { - BaseTranscript::template serialize_to_buffer(ipa_l_comms[i], BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(ipa_r_comms[i], BaseTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(ipa_l_comms[i], NativeTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(ipa_r_comms[i], NativeTranscript::proof_data); } - BaseTranscript::template serialize_to_buffer(ipa_a_0_eval, BaseTranscript::proof_data); + NativeTranscript::template serialize_to_buffer(ipa_a_0_eval, NativeTranscript::proof_data); } - ASSERT(BaseTranscript::proof_data.size() == old_proof_length); + ASSERT(NativeTranscript::proof_data.size() == old_proof_length); } }; }; diff --git a/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp index a249820db28f..1ee03bc93b8a 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp @@ -643,7 +643,7 @@ class AvmMiniFlavor { } }; - class Transcript : public BaseTranscript { + class Transcript : public NativeTranscript { public: uint32_t circuit_size; @@ -721,7 +721,7 @@ class AvmMiniFlavor { Transcript() = default; Transcript(const std::vector& proof) - : BaseTranscript(proof) + : NativeTranscript(proof) {} void deserialize_full_transcript() diff --git a/barretenberg/cpp/src/barretenberg/flavor/generated/Toy_flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/generated/Toy_flavor.hpp index 83f540cfd8bc..1d88605d1228 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/generated/Toy_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/generated/Toy_flavor.hpp @@ -256,7 +256,7 @@ class ToyFlavor { } }; - class Transcript : public BaseTranscript { + class Transcript : public NativeTranscript { public: uint32_t circuit_size; @@ -286,7 +286,7 @@ class ToyFlavor { Transcript() = default; Transcript(const std::vector& proof) - : BaseTranscript(proof) + : NativeTranscript(proof) {} void deserialize_full_transcript() diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_translator.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_translator.hpp index 8f0fe89209db..8ea63c7c8b17 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_translator.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_translator.hpp @@ -1136,6 +1136,6 @@ class GoblinTranslatorFlavor { } }; - using Transcript = BaseTranscript; + using Transcript = NativeTranscript; }; } // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp index 5ff14f552aa6..ed28295cd6be 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp @@ -478,7 +478,7 @@ class GoblinUltraFlavor { * @brief Derived class that defines proof structure for GoblinUltra proofs, as well as supporting functions. * Note: Made generic for use in GoblinUltraRecursive. */ - template class Transcript_ : public BaseTranscript { + template class Transcript_ : public NativeTranscript { public: uint32_t circuit_size; uint32_t public_input_size; @@ -507,7 +507,7 @@ class GoblinUltraFlavor { Transcript_() = default; Transcript_(const HonkProof& proof) - : BaseTranscript(proof) + : NativeTranscript(proof) {} void deserialize_full_transcript() diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp index 16cfefff8498..bf47f5da3c95 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp @@ -167,7 +167,7 @@ template class GoblinUltraRecursiveFlavor_ { // Reuse the VerifierCommitments from GoblinUltra using VerifierCommitments = GoblinUltraFlavor::VerifierCommitments_; // Reuse the transcript from GoblinUltra - using Transcript = bb::stdlib::recursion::honk::Transcript; + using Transcript = bb::BaseTranscript>; }; } // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/flavor/ultra.hpp b/barretenberg/cpp/src/barretenberg/flavor/ultra.hpp index ae2232f86850..d078ff3c5cd2 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/ultra.hpp @@ -458,7 +458,7 @@ class UltraFlavor { * @brief Derived class that defines proof structure for Ultra proofs, as well as supporting functions. * */ - class Transcript : public BaseTranscript { + class Transcript : public NativeTranscript { public: // Transcript objects defined as public member variables for easy access and modification uint32_t circuit_size; @@ -482,7 +482,7 @@ class UltraFlavor { // Used by verifier to initialize the transcript Transcript(const std::vector& proof) - : BaseTranscript(proof) + : NativeTranscript(proof) {} static std::shared_ptr prover_init_empty() @@ -496,7 +496,7 @@ class UltraFlavor { static std::shared_ptr verifier_init_empty(const std::shared_ptr& transcript) { auto verifier_transcript = std::make_shared(transcript->proof_data); - [[maybe_unused]] auto _ = verifier_transcript->template receive_from_prover("Init"); + [[maybe_unused]] auto _ = verifier_transcript->template receive_from_prover("Init"); return verifier_transcript; }; diff --git a/barretenberg/cpp/src/barretenberg/flavor/ultra_recursive.hpp b/barretenberg/cpp/src/barretenberg/flavor/ultra_recursive.hpp index 0c8aede2d374..e1ec3530e515 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/ultra_recursive.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/ultra_recursive.hpp @@ -17,8 +17,6 @@ #include "barretenberg/relations/permutation_relation.hpp" #include "barretenberg/relations/ultra_arithmetic_relation.hpp" #include "barretenberg/srs/factories/crs_factory.hpp" -#include "barretenberg/stdlib/recursion/honk/transcript/transcript.hpp" -#include "barretenberg/transcript/transcript.hpp" #include #include @@ -29,6 +27,7 @@ #include "barretenberg/stdlib/primitives/curves/bn254.hpp" #include "barretenberg/stdlib/primitives/field/field.hpp" +#include "barretenberg/stdlib/recursion/honk/transcript/transcript.hpp" namespace bb { @@ -419,7 +418,7 @@ template class UltraRecursiveFlavor_ { } }; - using Transcript = bb::stdlib::recursion::honk::Transcript; + using Transcript = bb::BaseTranscript>; }; } // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp index 9f108389edaf..1fde752ccecc 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp @@ -23,8 +23,7 @@ class Goblin { public: using Builder = GoblinUltraCircuitBuilder; using Fr = bb::fr; - using Transcript = bb::BaseTranscript; - + using Transcript = NativeTranscript; using GoblinUltraComposer = bb::UltraComposer_; using GoblinUltraVerifier = bb::UltraVerifier_; using OpQueue = bb::ECCOpQueue; @@ -35,8 +34,8 @@ class Goblin { using TranslatorBuilder = bb::GoblinTranslatorCircuitBuilder; using TranslatorComposer = bb::GoblinTranslatorComposer; using RecursiveMergeVerifier = bb::stdlib::recursion::goblin::MergeRecursiveVerifier_; - using MergeProver = bb::MergeProver; - using MergeVerifier = bb::MergeVerifier; + using MergeProver = bb::MergeProver_; + using MergeVerifier = bb::MergeVerifier_; /** * @brief Output of goblin::accumulate; an Ultra proof and the corresponding verification key * diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/types/proof.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/types/proof.hpp index 091d310d5c25..2c9ea4e3a3b4 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/types/proof.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/types/proof.hpp @@ -1,9 +1,12 @@ #pragma once #include "barretenberg/ecc/curves/bn254/fr.hpp" +#include "barretenberg/stdlib/primitives/field/field.hpp" #include namespace bb { using HonkProof = std::vector; -} // namespace bb \ No newline at end of file +template using StdlibProof = std::vector>; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp b/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp index 5bdf8b3faab7..a5110aefa354 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp @@ -1,5 +1,6 @@ #pragma once #include "barretenberg/ecc/curves/bn254/bn254.hpp" +#include "barretenberg/proof_system/types/circuit_type.hpp" #include #include #include @@ -30,8 +31,8 @@ namespace bb { * We should only do this if it becomes necessary or convenient. */ -// These are not magic numbers and they should not be written with global constants. These parameters are not accessible -// through clearly named static class members. +// These are not magic numbers and they should not be written with global constants. These parameters are not +// accessible through clearly named static class members. template class StandardArith { public: static constexpr size_t NUM_WIRES = 3; @@ -114,13 +115,6 @@ template class UltraArith { } } - /** - * @brief Add zeros to all selectors which are not part of the conventional Ultra arithmetization - * @details Does nothing for this class since this IS the conventional Ultra arithmetization - * - */ - void pad_additional(){}; - // Note: These are needed for Plonk only (for poly storage in a std::map). Must be in same order as above struct. inline static const std::vector selector_names = { "q_m", "q_c", "q_1", "q_2", "q_3", "q_4", "q_arith", "q_sort", @@ -196,6 +190,19 @@ template class UltraHonkArith { q_poseidon2_internal().emplace_back(0); }; + /** + * @brief Resizes all selectors which are not part of the conventional Ultra arithmetization + * @details Facilitates reuse of Ultra gate construction functions in arithmetizations which extend the conventional + * Ultra arithmetization + * @param new_size + */ + void resize_additional(size_t new_size) + { + q_busread().resize(new_size); + q_poseidon2_external().resize(new_size); + q_poseidon2_internal().resize(new_size); + }; + // Note: Unused. Needed only for consistency with Ultra arith (which is used by Plonk) inline static const std::vector selector_names = {}; }; @@ -205,4 +212,7 @@ class GoblinTranslatorArith { static constexpr size_t NUM_WIRES = 81; static constexpr size_t NUM_SELECTORS = 0; }; + +template +concept HasAdditionalSelectors = IsAnyOf>; } // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp index c2630db7b7bc..e4181fecc6bd 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp @@ -60,6 +60,7 @@ template void GoblinUltraCircuitBuilder_::add_gates_to_ensure_ this->q_busread().emplace_back(0); this->q_poseidon2_external().emplace_back(1); this->q_poseidon2_internal().emplace_back(1); + this->check_selector_length_consistency(); ++this->num_gates; @@ -82,6 +83,7 @@ template void GoblinUltraCircuitBuilder_::add_gates_to_ensure_ this->q_busread().emplace_back(0); this->q_poseidon2_external().emplace_back(0); this->q_poseidon2_internal().emplace_back(0); + this->check_selector_length_consistency(); ++this->num_gates; } @@ -255,6 +257,7 @@ void GoblinUltraCircuitBuilder_::create_calldata_lookup_gate(const databus_l this->q_aux().emplace_back(0); this->q_poseidon2_external().emplace_back(0); this->q_poseidon2_internal().emplace_back(0); + this->check_selector_length_consistency(); ++this->num_gates; } @@ -283,6 +286,7 @@ void GoblinUltraCircuitBuilder_::create_poseidon2_external_gate(const poseid this->q_busread().emplace_back(0); this->q_poseidon2_external().emplace_back(1); this->q_poseidon2_internal().emplace_back(0); + this->check_selector_length_consistency(); ++this->num_gates; } @@ -310,6 +314,7 @@ void GoblinUltraCircuitBuilder_::create_poseidon2_internal_gate(const poseid this->q_busread().emplace_back(0); this->q_poseidon2_external().emplace_back(0); this->q_poseidon2_internal().emplace_back(1); + this->check_selector_length_consistency(); ++this->num_gates; } @@ -340,6 +345,7 @@ template void GoblinUltraCircuitBuilder_::create_poseidon2_end this->q_busread().emplace_back(0); this->q_poseidon2_external().emplace_back(0); this->q_poseidon2_internal().emplace_back(0); + this->check_selector_length_consistency(); ++this->num_gates; } diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp index 28a6959b830c..21aa754edfed 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp @@ -77,7 +77,9 @@ void UltraCircuitBuilder_::add_gates_to_ensure_all_polys_are_no q_lookup_type().emplace_back(0); q_elliptic().emplace_back(1); q_aux().emplace_back(1); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); ++this->num_gates; @@ -138,7 +140,9 @@ void UltraCircuitBuilder_::create_add_gate(const add_triple_) { + selectors.pad_additional(); + } check_selector_length_consistency(); ++this->num_gates; } @@ -171,7 +175,9 @@ void UltraCircuitBuilder_::create_big_add_gate(const add_quad_< q_lookup_type().emplace_back(0); q_elliptic().emplace_back(0); q_aux().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); ++this->num_gates; } @@ -266,7 +272,9 @@ void UltraCircuitBuilder_::create_big_mul_gate(const mul_quad_< q_lookup_type().emplace_back(0); q_elliptic().emplace_back(0); q_aux().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); ++this->num_gates; } @@ -293,7 +301,9 @@ void UltraCircuitBuilder_::create_balanced_add_gate(const add_q q_lookup_type().emplace_back(0); q_elliptic().emplace_back(0); q_aux().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); ++this->num_gates; // Why 3? TODO: return to this @@ -336,7 +346,9 @@ void UltraCircuitBuilder_::create_mul_gate(const mul_triple_) { + selectors.pad_additional(); + } check_selector_length_consistency(); ++this->num_gates; } @@ -366,7 +378,9 @@ void UltraCircuitBuilder_::create_bool_gate(const uint32_t vari q_lookup_type().emplace_back(0); q_elliptic().emplace_back(0); q_aux().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); ++this->num_gates; } @@ -398,7 +412,9 @@ void UltraCircuitBuilder_::create_poly_gate(const poly_triple_< q_lookup_type().emplace_back(0); q_elliptic().emplace_back(0); q_aux().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); ++this->num_gates; } @@ -453,7 +469,9 @@ void UltraCircuitBuilder_::create_ecc_add_gate(const ecc_add_ga q_lookup_type().emplace_back(0); q_elliptic().emplace_back(1); q_aux().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); ++this->num_gates; } @@ -472,7 +490,9 @@ void UltraCircuitBuilder_::create_ecc_add_gate(const ecc_add_ga q_lookup_type().emplace_back(0); q_elliptic().emplace_back(0); q_aux().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); ++this->num_gates; } @@ -519,7 +539,9 @@ void UltraCircuitBuilder_::create_ecc_dbl_gate(const ecc_dbl_ga q_sort().emplace_back(0); q_lookup_type().emplace_back(0); q_aux().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); ++this->num_gates; } @@ -539,7 +561,9 @@ void UltraCircuitBuilder_::create_ecc_dbl_gate(const ecc_dbl_ga q_lookup_type().emplace_back(0); q_elliptic().emplace_back(0); q_aux().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); ++this->num_gates; } @@ -570,7 +594,9 @@ void UltraCircuitBuilder_::fix_witness(const uint32_t witness_i q_lookup_type().emplace_back(0); q_elliptic().emplace_back(0); q_aux().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); ++this->num_gates; } @@ -646,7 +672,9 @@ plookup::ReadData UltraCircuitBuilder_::create_gates_ q_sort().emplace_back(0); q_elliptic().emplace_back(0); q_aux().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); ++this->num_gates; } @@ -956,7 +984,9 @@ void UltraCircuitBuilder_::create_sort_constraint(const std::ve q_elliptic().emplace_back(0); q_lookup_type().emplace_back(0); q_aux().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); } // dummy gate needed because of sort widget's check of next row @@ -976,7 +1006,9 @@ void UltraCircuitBuilder_::create_sort_constraint(const std::ve q_elliptic().emplace_back(0); q_lookup_type().emplace_back(0); q_aux().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); } @@ -1011,7 +1043,9 @@ void UltraCircuitBuilder_::create_dummy_constraints(const std:: q_elliptic().emplace_back(0); q_lookup_type().emplace_back(0); q_aux().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); } } @@ -1043,7 +1077,9 @@ void UltraCircuitBuilder_::create_sort_constraint_with_edges( q_elliptic().emplace_back(0); q_lookup_type().emplace_back(0); q_aux().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); // enforce range check for middle rows for (size_t i = gate_width; i < variable_index.size() - gate_width; i += gate_width) { @@ -1064,7 +1100,9 @@ void UltraCircuitBuilder_::create_sort_constraint_with_edges( q_elliptic().emplace_back(0); q_lookup_type().emplace_back(0); q_aux().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); } // enforce range checks of last row and ending at end @@ -1085,7 +1123,9 @@ void UltraCircuitBuilder_::create_sort_constraint_with_edges( q_elliptic().emplace_back(0); q_lookup_type().emplace_back(0); q_aux().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); } @@ -1107,7 +1147,9 @@ void UltraCircuitBuilder_::create_sort_constraint_with_edges( q_elliptic().emplace_back(0); q_lookup_type().emplace_back(0); q_aux().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); } @@ -1224,7 +1266,9 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m().emplace_back(0); q_c().emplace_back(0); q_arith().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); break; } @@ -1236,7 +1280,9 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m().emplace_back(1); q_c().emplace_back(0); q_arith().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); break; } @@ -1248,7 +1294,9 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m().emplace_back(0); q_c().emplace_back(0); q_arith().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); break; } @@ -1260,7 +1308,9 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m().emplace_back(0); q_c().emplace_back(0); q_arith().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); break; } @@ -1272,7 +1322,9 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m().emplace_back(1); q_c().emplace_back(0); q_arith().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); break; } @@ -1288,7 +1340,9 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m().emplace_back(0); q_c().emplace_back(0); q_arith().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); break; } @@ -1305,7 +1359,9 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m().emplace_back(0); q_c().emplace_back(0); q_arith().emplace_back(1); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); break; } @@ -1319,7 +1375,9 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m().emplace_back(0); q_c().emplace_back(0); q_arith().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); break; } @@ -1334,7 +1392,9 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m().emplace_back(1); // validate record witness is correctly computed q_c().emplace_back(0); // read/write flag stored in q_c q_arith().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); break; } @@ -1349,7 +1409,9 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m().emplace_back(1); // validate record witness is correctly computed q_c().emplace_back(0); // read/write flag stored in q_c q_arith().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); break; } @@ -1364,7 +1426,9 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m().emplace_back(1); // validate record witness is correctly computed q_c().emplace_back(1); // read/write flag stored in q_c q_arith().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); break; } @@ -1376,7 +1440,9 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m().emplace_back(0); q_c().emplace_back(0); q_arith().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } check_selector_length_consistency(); break; } @@ -1898,7 +1964,9 @@ std::array UltraCircuitBuilder_::evaluate_non_nati q_lookup_type().emplace_back(0); q_elliptic().emplace_back(0); q_aux().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } } check_selector_length_consistency(); @@ -2021,7 +2089,9 @@ std::array UltraCircuitBuilder_::evaluate_non_nati q_lookup_type().emplace_back(0); q_elliptic().emplace_back(0); q_aux().emplace_back(0); - selectors.pad_additional(); + if constexpr (HasAdditionalSelectors) { + selectors.pad_additional(); + } } check_selector_length_consistency(); diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp index 055db48379dd..78242840d9cc 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp @@ -458,6 +458,9 @@ class UltraCircuitBuilder_ : public CircuitBuilderBaseq_elliptic().resize(num_gates); builder->q_aux().resize(num_gates); builder->q_lookup_type().resize(num_gates); + if constexpr (HasAdditionalSelectors) { + builder->selectors.resize_additional(num_gates); + } } /** * @brief Checks that the circuit state is the same as the stored circuit's one diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp index 48bbcd86e8b4..cdc30efa564f 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp @@ -55,7 +55,7 @@ void ProtoGalaxyProver_::finalise_and_send_instance(std::shared instance->witness_commitments.calldata_read_counts); } - auto eta = transcript->get_challenge(domain_separator + "_eta"); + auto eta = transcript->template get_challenge(domain_separator + "_eta"); instance->compute_sorted_accumulator_polynomials(eta); // Commit to the sorted withness-table accumulator and the finalized (i.e. with memory records) fourth wire @@ -67,7 +67,8 @@ void ProtoGalaxyProver_::finalise_and_send_instance(std::shared witness_commitments.sorted_accum); transcript->send_to_verifier(domain_separator + "_" + commitment_labels.w_4, witness_commitments.w_4); - auto [beta, gamma] = transcript->get_challenges(domain_separator + "_beta", domain_separator + "_gamma"); + auto [beta, gamma] = + transcript->template get_challenges(domain_separator + "_beta", domain_separator + "_gamma"); if constexpr (IsGoblinFlavor) { // Compute and commit to the logderivative inverse used in DataBus @@ -88,7 +89,8 @@ void ProtoGalaxyProver_::finalise_and_send_instance(std::shared transcript->send_to_verifier(domain_separator + "_" + commitment_labels.z_lookup, instance->witness_commitments.z_lookup); for (size_t idx = 0; idx < NUM_SUBRELATIONS - 1; idx++) { - instance->alphas[idx] = transcript->get_challenge(domain_separator + "_alpha_" + std::to_string(idx)); + instance->alphas[idx] = + transcript->template get_challenge(domain_separator + "_alpha_" + std::to_string(idx)); } auto vk_view = instance->verification_key->get_all(); auto labels = instance->commitment_labels.get_precomputed(); @@ -156,7 +158,7 @@ template void ProtoGalaxyProver_::prepa // efficient by avoiding the computation of the perturbator finalise_and_send_instance(instance, domain_separator); instance->target_sum = 0; - auto beta = transcript->get_challenge(domain_separator + "_initial_gate_challenge"); + auto beta = transcript->template get_challenge(domain_separator + "_initial_gate_challenge"); std::vector gate_challenges(instance->log_instance_size); gate_challenges[0] = beta; for (size_t i = 1; i < instance->log_instance_size; i++) { @@ -307,7 +309,7 @@ template FoldingResult ProtoGalaxyProver_::fold_instances() { prepare_for_folding(); - FF delta = transcript->get_challenge("delta"); + FF delta = transcript->template get_challenge("delta"); auto accumulator = get_accumulator(); auto deltas = compute_round_challenge_pows(accumulator->log_instance_size, delta); @@ -316,7 +318,7 @@ FoldingResult ProtoGalaxyProver_log_instance_size; idx++) { transcript->send_to_verifier("perturbator_" + std::to_string(idx), perturbator[idx]); } - auto perturbator_challenge = transcript->get_challenge("perturbator_challenge"); + auto perturbator_challenge = transcript->template get_challenge("perturbator_challenge"); instances.next_gate_challenges = update_gate_challenges(perturbator_challenge, accumulator->gate_challenges, deltas); combine_relation_parameters(instances); @@ -330,7 +332,7 @@ FoldingResult ProtoGalaxyProver_send_to_verifier("combiner_quotient_" + std::to_string(idx), combiner_quotient.value_at(idx)); } - FF combiner_challenge = transcript->get_challenge("combiner_quotient_challenge"); + FF combiner_challenge = transcript->template get_challenge("combiner_quotient_challenge"); FoldingResult res; auto next_accumulator = diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp index 3aeeda75779e..07b32554f348 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp @@ -104,13 +104,14 @@ void ProtoGalaxyVerifier_::receive_and_finalise_instance(cons } // Get challenge for sorted list batching and wire four memory records commitment - auto eta = transcript->get_challenge(domain_separator + "_eta"); + auto eta = transcript->template get_challenge(domain_separator + "_eta"); witness_commitments.sorted_accum = transcript->template receive_from_prover(domain_separator + "_" + labels.sorted_accum); witness_commitments.w_4 = transcript->template receive_from_prover(domain_separator + "_" + labels.w_4); // Get permutation challenges and commitment to permutation and lookup grand products - auto [beta, gamma] = transcript->get_challenges(domain_separator + "_beta", domain_separator + "_gamma"); + auto [beta, gamma] = + transcript->template get_challenges(domain_separator + "_beta", domain_separator + "_gamma"); if constexpr (IsGoblinFlavor) { // If Goblin (i.e. using DataBus) receive commitments to log-deriv inverses polynomial @@ -132,7 +133,7 @@ void ProtoGalaxyVerifier_::receive_and_finalise_instance(cons // Get the relation separation challenges for (size_t idx = 0; idx < NUM_SUBRELATIONS - 1; idx++) { - inst->alphas[idx] = transcript->get_challenge(domain_separator + "_alpha_" + std::to_string(idx)); + inst->alphas[idx] = transcript->template get_challenge(domain_separator + "_alpha_" + std::to_string(idx)); } // Get the commitments to the selector polynomials for the given instance @@ -162,7 +163,7 @@ void ProtoGalaxyVerifier_::prepare_for_folding(const std::vec // efficient by avoiding the computation of the perturbator receive_and_finalise_instance(inst, domain_separator); inst->target_sum = 0; - auto beta = transcript->get_challenge(domain_separator + "_initial_gate_challenge"); + auto beta = transcript->template get_challenge(domain_separator + "_initial_gate_challenge"); std::vector gate_challenges(inst->log_instance_size); gate_challenges[0] = beta; for (size_t i = 1; i < inst->log_instance_size; i++) { @@ -184,7 +185,7 @@ bool ProtoGalaxyVerifier_::verify_folding_proof(const std::ve { prepare_for_folding(fold_data); - auto delta = transcript->get_challenge("delta"); + auto delta = transcript->template get_challenge("delta"); auto accumulator = get_accumulator(); auto deltas = compute_round_challenge_pows(accumulator->log_instance_size, delta); @@ -198,7 +199,7 @@ bool ProtoGalaxyVerifier_::verify_folding_proof(const std::ve } auto perturbator = Polynomial(perturbator_coeffs); - FF perturbator_challenge = transcript->get_challenge("perturbator_challenge"); + FF perturbator_challenge = transcript->template get_challenge("perturbator_challenge"); auto perturbator_at_challenge = perturbator.evaluate(perturbator_challenge); // The degree of K(X) is dk - k - 1 = k(d - 1) - 1. Hence we need k(d - 1) evaluations to represent it. @@ -209,7 +210,7 @@ bool ProtoGalaxyVerifier_::verify_folding_proof(const std::ve } Univariate combiner_quotient( combiner_quotient_evals); - FF combiner_challenge = transcript->get_challenge("combiner_quotient_challenge"); + FF combiner_challenge = transcript->template get_challenge("combiner_quotient_challenge"); auto combiner_quotient_at_challenge = combiner_quotient.evaluate(combiner_challenge); auto vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_impl.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_impl.hpp index 43e8e03a3701..b365edef55df 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_impl.hpp @@ -30,6 +30,7 @@ bigfield::bigfield(Builder* parent_context, const uint256_t& value) ASSERT(value < modulus); } +// TODO(https://github.com/AztecProtocol/barretenberg/issues/850): audit the evaluate_linear_identity function template bigfield::bigfield(const field_t& low_bits_in, const field_t& high_bits_in, diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field_conversion.cpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field_conversion.cpp new file mode 100644 index 000000000000..66a72dcd48d3 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field_conversion.cpp @@ -0,0 +1,48 @@ +#include "barretenberg/stdlib/primitives/field/field_conversion.hpp" + +namespace bb::stdlib::field_conversion { + +/** + * @brief Converts a challenge to a fq + * @details We sometimes need challenges that are a bb::fq element, so we need to convert the bb::fr challenge to a + * bb::fq type. We do this by in a similar fashion to the convert_from_bn254_frs function that converts to a + * fq. In fact, we do call that function that the end, but we first have to split the fr into two + * pieces, one that is the 136 lower bits and one that is the 118 higher bits. Then, we can split these two pieces into + * their bigfield limbs through convert_from_bn254_frs, which is actually just a bigfield constructor that takes in two + * two-limb frs. + * + * TODO(https://github.com/AztecProtocol/barretenberg/issues/850): audit this function more carefully + * @tparam Builder + */ +template fq convert_to_grumpkin_fr(Builder& builder, const fr& f) +{ + constexpr uint64_t NUM_BITS_IN_TWO_LIMBS = 2 * NUM_LIMB_BITS; // 136 + constexpr uint64_t UPPER_TWO_LIMB_BITS = TOTAL_BITS - NUM_BITS_IN_TWO_LIMBS; // 118 + constexpr uint256_t shift = (uint256_t(1) << NUM_BITS_IN_TWO_LIMBS); + // split f into low_bits_in and high_bits_in + constexpr uint256_t LIMB_MASK = shift - 1; // mask for upper 128 bits + const uint256_t value = f.get_value(); + const uint256_t low_val = static_cast(value & LIMB_MASK); + const uint256_t hi_val = static_cast(value >> NUM_BITS_IN_TWO_LIMBS); + + fr low{ witness_t(&builder, low_val) }; + fr hi{ witness_t(&builder, hi_val) }; + // range constrain low to 136 bits and hi to 118 bits + builder.create_range_constraint(low.witness_index, NUM_BITS_IN_TWO_LIMBS, "create_range_constraint"); + builder.create_range_constraint(hi.witness_index, UPPER_TWO_LIMB_BITS, "create_range_constraint"); + + ASSERT(static_cast(low_val) + (static_cast(hi_val) << NUM_BITS_IN_TWO_LIMBS) == value); + // checks this decomposition low + hi * 2^64 = value with an assert_equal + auto sum = low + hi * shift; + builder.assert_equal(f.witness_index, sum.witness_index, "assert_equal"); + + std::vector> fr_vec{ low, hi }; + return convert_from_bn254_frs>(builder, fr_vec); +} + +template fq convert_to_grumpkin_fr(UltraCircuitBuilder& builder, + const fr& f); +template fq convert_to_grumpkin_fr( + GoblinUltraCircuitBuilder& builder, const fr& f); + +} // namespace bb::stdlib::field_conversion diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field_conversion.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field_conversion.hpp new file mode 100644 index 000000000000..f14b05b8cd5c --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field_conversion.hpp @@ -0,0 +1,289 @@ +#pragma once + +#include "barretenberg/plonk/proof_system/constants.hpp" +#include "barretenberg/polynomials/univariate.hpp" +#include "barretenberg/stdlib/primitives/bigfield/bigfield.hpp" +#include "barretenberg/stdlib/primitives/curves/bn254.hpp" +#include "barretenberg/stdlib/primitives/field/field.hpp" +#include "barretenberg/stdlib/primitives/group/cycle_group.hpp" + +namespace bb::stdlib::field_conversion { + +template using fr = field_t; +template using fq = bigfield; +template using bn254_element = element, fr, curve::BN254::Group>; +template using grumpkin_element = cycle_group; + +static constexpr uint64_t NUM_LIMB_BITS = plonk::NUM_LIMB_BITS_IN_FIELD_SIMULATION; +static constexpr uint64_t TOTAL_BITS = 254; + +template fq convert_to_grumpkin_fr(Builder& builder, const fr& f); + +template inline T convert_challenge(Builder& builder, const fr& challenge) +{ + if constexpr (std::is_same_v>) { + return challenge; + } else if constexpr (std::is_same_v>) { + return convert_to_grumpkin_fr(builder, challenge); + } +} + +template inline std::array, 2> convert_grumpkin_fr_to_bn254_frs(const fq& input) +{ + fr shift(static_cast(1) << NUM_LIMB_BITS); + std::array, 2> result; + result[0] = input.binary_basis_limbs[0].element + (input.binary_basis_limbs[1].element * shift); + result[1] = input.binary_basis_limbs[2].element + (input.binary_basis_limbs[3].element * shift); + return result; +} +/** + * @brief Calculates the size of a types (in their native form) in terms of frs + * @details We want to support the following types: fr, fq, + * bn254_element, bb::Univariate, std::array, for + * FF = fr or fq, and N is arbitrary + * @tparam T + * @return constexpr size_t + */ +template constexpr size_t calc_num_bn254_frs(); + +template constexpr size_t calc_num_bn254_frs(fr* /*unused*/) +{ + return 1; +} + +template constexpr size_t calc_num_bn254_frs(fq* /*unused*/) +{ + return 2; +} + +template constexpr size_t calc_num_bn254_frs(bn254_element* /*unused*/) +{ + return 2 * calc_num_bn254_frs>(); +} + +template constexpr size_t calc_num_bn254_frs(grumpkin_element* /*unused*/) +{ + return 2 * calc_num_bn254_frs>(); +} + +template constexpr size_t calc_num_bn254_frs(std::array* /*unused*/) +{ + return N * calc_num_bn254_frs(); +} + +template constexpr size_t calc_num_bn254_frs(bb::Univariate* /*unused*/) +{ + return N * calc_num_bn254_frs(); +} + +template constexpr size_t calc_num_bn254_frs() +{ + return calc_num_bn254_frs(static_cast(nullptr)); +} + +/** + * @brief Conversions from vector of fr elements to transcript types. + * @details We want to support the following types: fr, fq, + * bn254_element, bb::Univariate, std::array, for + * FF = fr or fq, and N is arbitrary + * @tparam T + * @param fr_vec + * @return T + */ +template T convert_from_bn254_frs(Builder& builder, std::span> fr_vec); + +template +inline fr convert_from_bn254_frs(const Builder& /*unused*/, + std::span> fr_vec, + fr* /*unused*/) +{ + ASSERT(fr_vec.size() == 1); + return fr_vec[0]; +} + +template +inline fq convert_from_bn254_frs(const Builder& /*unused*/, + std::span> fr_vec, + fq* /*unused*/) +{ + ASSERT(fr_vec.size() == 2); + bigfield result(fr_vec[0], fr_vec[1], 0, 0); + return result; +} + +template +inline bn254_element convert_from_bn254_frs(Builder& builder, + std::span> fr_vec, + bn254_element* /*unused*/) +{ + ASSERT(fr_vec.size() == 4); + bn254_element val; + val.x = convert_from_bn254_frs>(builder, fr_vec.subspan(0, 2)); + val.y = convert_from_bn254_frs>(builder, fr_vec.subspan(2, 2)); + return val; +} + +template +inline grumpkin_element convert_from_bn254_frs(Builder& builder, + std::span> fr_vec, + grumpkin_element* /*unused*/) +{ + ASSERT(fr_vec.size() == 2); + grumpkin_element val(convert_from_bn254_frs>(builder, fr_vec.subspan(0, 1)), + convert_from_bn254_frs>(builder, fr_vec.subspan(1, 1)), + false); + return val; +} + +template +inline std::array, N> convert_from_bn254_frs(const Builder& /*unused*/, + std::span> fr_vec, + std::array, N>* /*unused*/) +{ + std::array, N> val; + for (size_t i = 0; i < N; ++i) { + val[i] = fr_vec[i]; + } + return val; +} + +template +inline std::array, N> convert_from_bn254_frs(Builder& builder, + std::span> fr_vec, + std::array, N>* /*unused*/) +{ + std::array, N> val; + for (size_t i = 0; i < N; ++i) { + std::vector> fr_vec_tmp{ fr_vec[2 * i], + fr_vec[2 * i + 1] }; // each pair of consecutive elements is a fq + val[i] = convert_from_bn254_frs>(builder, fr_vec_tmp); + } + return val; +} + +template +inline bb::Univariate, N> convert_from_bn254_frs(const Builder& /*unused*/, + std::span> fr_vec, + bb::Univariate, N>* /*unused*/) +{ + bb::Univariate, N> val; + for (size_t i = 0; i < N; ++i) { + val.evaluations[i] = fr_vec[i]; + } + return val; +} + +template +inline bb::Univariate, N> convert_from_bn254_frs(Builder& builder, + std::span> fr_vec, + bb::Univariate, N>* /*unused*/) +{ + bb::Univariate, N> val; + for (size_t i = 0; i < N; ++i) { + std::vector> fr_vec_tmp{ fr_vec[2 * i], fr_vec[2 * i + 1] }; + val.evaluations[i] = convert_from_bn254_frs>(builder, fr_vec_tmp); + } + return val; +} + +template +inline T convert_from_bn254_frs(Builder& builder, std::span> fr_vec) +{ + return convert_from_bn254_frs(builder, fr_vec, static_cast(nullptr)); +} + +/** + * @brief Conversion from transcript values to frs + * @details We want to support the following types: bool, size_t, uint32_t, uint64_t, fr, fq, + * bn254_element, curve::Grumpkin::AffineElement, bb::Univariate, std::array, for FF = fr/fq, and N is arbitrary. + * @tparam T + * @param val + * @return std::vector> + */ +template inline std::vector> convert_to_bn254_frs(const fq& val) +{ + auto fr_arr = convert_grumpkin_fr_to_bn254_frs(val); + std::vector> fr_vec(fr_arr.begin(), fr_arr.end()); + return fr_vec; +} + +template inline std::vector> convert_to_bn254_frs(const fr& val) +{ + std::vector> fr_vec{ val }; + return fr_vec; +} + +template inline std::vector> convert_to_bn254_frs(const bn254_element& val) +{ + auto fr_vec_x = convert_to_bn254_frs(val.x); + auto fr_vec_y = convert_to_bn254_frs(val.y); + std::vector> fr_vec(fr_vec_x.begin(), fr_vec_x.end()); + fr_vec.insert(fr_vec.end(), fr_vec_y.begin(), fr_vec_y.end()); + return fr_vec; +} + +template inline std::vector> convert_to_bn254_frs(const grumpkin_element& val) +{ + auto fr_vec_x = convert_to_bn254_frs(val.x); + auto fr_vec_y = convert_to_bn254_frs(val.y); + std::vector> fr_vec(fr_vec_x.begin(), fr_vec_x.end()); + fr_vec.insert(fr_vec.end(), fr_vec_y.begin(), fr_vec_y.end()); + return fr_vec; +} + +template +inline std::vector> convert_to_bn254_frs(const std::array, N>& val) +{ + std::vector> fr_vec(val.begin(), val.end()); + return fr_vec; +} + +template +inline std::vector> convert_to_bn254_frs(const std::array, N>& val) +{ + std::vector> fr_vec; + for (size_t i = 0; i < N; ++i) { + auto tmp_vec = convert_to_bn254_frs(val[i]); + fr_vec.insert(fr_vec.end(), tmp_vec.begin(), tmp_vec.end()); + } + return fr_vec; +} + +template +inline std::vector> convert_to_bn254_frs(const bb::Univariate, N>& val) +{ + std::vector> fr_vec; + for (size_t i = 0; i < N; ++i) { + auto tmp_vec = convert_to_bn254_frs(val.evaluations[i]); + fr_vec.insert(fr_vec.end(), tmp_vec.begin(), tmp_vec.end()); + } + return fr_vec; +} + +template +inline std::vector> convert_to_bn254_frs(const bb::Univariate, N>& val) +{ + std::vector> fr_vec; + for (size_t i = 0; i < N; ++i) { + auto tmp_vec = convert_to_bn254_frs(val.evaluations[i]); + fr_vec.insert(fr_vec.end(), tmp_vec.begin(), tmp_vec.end()); + } + return fr_vec; +} + +// TODO(https://github.com/AztecProtocol/barretenberg/issues/846): solve this annoying asymmetry - AllValues vs +// std::array, N> +template +inline std::vector> convert_to_bn254_frs(const AllValues& val) +{ + auto data = val.get_all(); + std::vector> fr_vec; + for (auto& item : data) { + auto tmp_vec = convert_to_bn254_frs(item); + fr_vec.insert(fr_vec.end(), tmp_vec.begin(), tmp_vec.end()); + } + return fr_vec; +} + +} // namespace bb::stdlib::field_conversion \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field_conversion.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field_conversion.test.cpp new file mode 100644 index 000000000000..51624b50abe4 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field_conversion.test.cpp @@ -0,0 +1,229 @@ +#include "barretenberg/stdlib/primitives/field/field_conversion.hpp" +#include + +namespace bb::stdlib::field_conversion_tests { + +template using fr = field_t; +template using fq = bigfield; +template using bn254_element = element, fr, curve::BN254::Group>; +template using grumpkin_element = cycle_group; + +template class StdlibFieldConversionTests : public ::testing::Test { + public: + template void check_conversion(Builder& builder, T x) + { + size_t len = bb::stdlib::field_conversion::calc_num_bn254_frs(); + auto frs = bb::stdlib::field_conversion::convert_to_bn254_frs(x); + EXPECT_EQ(len, frs.size()); + auto y = bb::stdlib::field_conversion::convert_from_bn254_frs(builder, frs); + EXPECT_EQ(x.get_value(), y.get_value()); + } + + template void check_conversion_array(Builder& builder, T x) + { + size_t len = bb::stdlib::field_conversion::calc_num_bn254_frs(); + auto frs = bb::stdlib::field_conversion::convert_to_bn254_frs(x); + EXPECT_EQ(len, frs.size()); + auto y = bb::stdlib::field_conversion::convert_from_bn254_frs(builder, frs); + EXPECT_EQ(x.size(), y.size()); + for (size_t i = 0; i < x.size(); i++) { + EXPECT_EQ(x[i].get_value(), y[i].get_value()); + } + } + + template void check_conversion_univariate(Builder& builder, T x) + { + size_t len = bb::stdlib::field_conversion::calc_num_bn254_frs(); + auto frs = bb::stdlib::field_conversion::convert_to_bn254_frs(x); + EXPECT_EQ(len, frs.size()); + auto y = bb::stdlib::field_conversion::convert_from_bn254_frs(builder, frs); + EXPECT_EQ(x.evaluations.size(), y.evaluations.size()); + for (size_t i = 0; i < x.evaluations.size(); i++) { + EXPECT_EQ(x.evaluations[i].get_value(), y.evaluations[i].get_value()); + } + } +}; + +using BuilderTypes = testing::Types; + +TYPED_TEST_SUITE(StdlibFieldConversionTests, BuilderTypes); + +/** + * @brief Field conversion test for fr + */ +TYPED_TEST(StdlibFieldConversionTests, FieldConversionFr) +{ + using Builder = TypeParam; + Builder builder; + bb::fr x1_val(std::string("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789")); // 256 bits + fr x1(&builder, x1_val); + this->check_conversion(builder, x1); + + bb::fr x2_val(bb::fr::modulus_minus_two); // modulus - 2 + fr x2(&builder, x2_val); + this->check_conversion(builder, x2); + + bb::fr x3_val(1); + fr x3(&builder, x3_val); + this->check_conversion(builder, x3); +} + +/** + * @brief Field conversion test for fq + */ +TYPED_TEST(StdlibFieldConversionTests, FieldConversionGrumpkinFr) +{ + using Builder = TypeParam; + Builder builder; + + // Constructing bigfield objects with grumpkin::fr values + grumpkin::fr x1_val(std::string("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789")); // 256 bits + fq x1(&builder, x1_val); + this->check_conversion(builder, x1); +} + +/** + * @brief Field conversion test for bn254_element + * + */ +TYPED_TEST(StdlibFieldConversionTests, FieldConversionBN254AffineElement) +{ + using Builder = TypeParam; + Builder builder; + + // Constructing element objects with curve::BN254::AffineElement values + curve::BN254::AffineElement x1_val(1, 2); + bn254_element x1 = bn254_element::from_witness(&builder, x1_val); + this->check_conversion(builder, x1); + + curve::BN254::AffineElement x2_val(1, grumpkin::fr::modulus_minus_two); + bn254_element x2 = bn254_element::from_witness(&builder, x2_val); + this->check_conversion(builder, x2); +} + +/** + * @brief Field conversion test for grumpkin_element + * + */ +TYPED_TEST(StdlibFieldConversionTests, FieldConversionGrumpkinAffineElement) +{ + using Builder = TypeParam; + Builder builder; + + // Constructing element objects with curve::Grumpkin::AffineElement values + curve::Grumpkin::AffineElement x1_val(12, 100); + grumpkin_element x1 = grumpkin_element::from_witness(&builder, x1_val); + this->check_conversion(builder, x1); + + curve::Grumpkin::AffineElement x2_val(1, grumpkin::fr::modulus_minus_two); + grumpkin_element x2 = grumpkin_element::from_witness(&builder, x2_val); + this->check_conversion(builder, x2); +} + +/** + * @brief Field conversion test for std::array, N> + */ +TYPED_TEST(StdlibFieldConversionTests, FieldConversionArrayBn254Fr) +{ + using Builder = TypeParam; + Builder builder; + + // Constructing std::array objects with fr values + std::array, 4> x1{ + fr(&builder, 1), fr(&builder, 2), fr(&builder, 3), fr(&builder, 4) + }; + this->check_conversion_array(builder, x1); + + std::array, 7> x2{ fr(&builder, bb::fr::modulus_minus_two), + fr(&builder, bb::fr::modulus_minus_two - 123), + fr(&builder, 215215125), + fr(&builder, 102701750), + fr(&builder, 367032), + fr(&builder, 12985028), + fr(&builder, bb::fr::modulus_minus_two - 125015028) }; + this->check_conversion_array(builder, x2); +} + +/** + * @brief Field conversion test for std::array, N> + */ +TYPED_TEST(StdlibFieldConversionTests, FieldConversionArrayGrumpkinFr) +{ + using Builder = TypeParam; + Builder builder; + + // Constructing std::array objects with fq values + std::array, 4> x1{ + fq( + &builder, + static_cast(std::string("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"))), + fq( + &builder, + static_cast(std::string("2bf1eaf87f7d27e8dc4056e9af975985bccc89077a21891d6c7b6ccce0631f95"))), + fq( + &builder, + static_cast(std::string("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"))), + fq( + &builder, + static_cast(std::string("018555a8eb50cf07f64b019ebaf3af3c925c93e631f3ecd455db07bbb52bbdd3"))), + }; + this->check_conversion_array(builder, x1); +} + +/** + * @brief Field conversion test for Univariate, N> + */ +TYPED_TEST(StdlibFieldConversionTests, FieldConversionUnivariateBn254Fr) +{ + using Builder = TypeParam; + Builder builder; + + // Constructing Univariate objects with fr values + Univariate, 4> x{ + { fr(&builder, 1), fr(&builder, 2), fr(&builder, 3), fr(&builder, 4) } + }; + this->check_conversion_univariate(builder, x); +} + +/** + * @brief Field conversion test for Univariate, N> + */ +TYPED_TEST(StdlibFieldConversionTests, FieldConversionUnivariateGrumpkinFr) +{ + using Builder = TypeParam; + Builder builder; + + // Constructing std::array objects with fq values + Univariate, 4> x{ + { fq(&builder, + static_cast( + std::string("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"))), + fq(&builder, + static_cast( + std::string("2bf1eaf87f7d27e8dc4056e9af975985bccc89077a21891d6c7b6ccce0631f95"))), + fq(&builder, + static_cast( + std::string("018555a8eb50cf07f64b019ebaf3af3c925c93e631f3ecd455db07bbb52bbdd3"))), + fq(&builder, + static_cast( + std::string("2bf1eaf87f7d27e8dc4056e9af975985bccc89077a21891d6c7b6ccce0631f95"))) } + }; + this->check_conversion_univariate(builder, x); +} + +/** + * @brief Convert challenge test for fq + * + */ +TYPED_TEST(StdlibFieldConversionTests, ConvertChallengeGrumpkinFr) +{ + using Builder = TypeParam; + Builder builder; + + bb::fr chal_val(std::string("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789")); // 256 bits + auto chal = fr::from_witness(&builder, chal_val); + auto result = bb::stdlib::field_conversion::convert_challenge>(builder, chal); + auto expected = uint256_t(chal.get_value()); + EXPECT_EQ(uint256_t(result.get_value()), expected); +} +} // namespace bb::stdlib::field_conversion_tests \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.hpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.hpp index fc36ffcdded5..9fef4b874f95 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.hpp @@ -1,104 +1,57 @@ #pragma once -#include "barretenberg/ecc/curves/bn254/fq.hpp" -#include "barretenberg/ecc/curves/bn254/fr.hpp" -#include "barretenberg/ecc/curves/bn254/g1.hpp" -#include "barretenberg/honk/proof_system/types/proof.hpp" -#include "barretenberg/polynomials/univariate.hpp" - #include "barretenberg/transcript/transcript.hpp" -#include "barretenberg/stdlib/primitives/bigfield/bigfield.hpp" -#include "barretenberg/stdlib/primitives/biggroup/biggroup.hpp" -#include "barretenberg/stdlib/primitives/field/field.hpp" -#include "barretenberg/stdlib/utility/utility.hpp" - namespace bb::stdlib::recursion::honk { -template class Transcript { - public: - using field_ct = field_t; - using FF = bb::fr; - using NativeTranscript = BaseTranscript; - using StdlibTypes = utility::StdlibTypesUtility; - - static constexpr size_t HASH_OUTPUT_SIZE = NativeTranscript::HASH_OUTPUT_SIZE; - - NativeTranscript native_transcript; - Builder* builder; - - Transcript() = default; - Transcript(Builder* builder, const bb::HonkProof& proof_data) - : native_transcript(proof_data) - , builder(builder){}; - - /** - * @brief Get the underlying native transcript manifest (primarily for debugging) - * - */ - auto get_manifest() const { return native_transcript.get_manifest(); }; - - /** - * @brief Compute the challenges (more than 1) indicated by labels - * - * @tparam Strings - * @param labels Names of the challenges to be computed - * @return std::array Array of challenges - */ - template std::array get_challenges(const Strings&... labels) +template struct StdlibTranscriptParams { + using Fr = stdlib::field_t; + using Proof = std::vector; + static inline Fr hash(const std::vector& data) { - // Compute the indicated challenges from the native transcript - constexpr size_t num_challenges = sizeof...(Strings); - std::array native_challenges{}; - native_challenges = native_transcript.get_challenges(labels...); - - /* - * TODO(#1351): Do stdlib hashing here. E.g., for the current pedersen/blake setup, we could write data into a - * byte_array as it is received from prover, then compress via pedersen and apply blake3s. Not doing this now - * since it's a pain and we'll be revamping our hashing anyway. For now, simply convert the native hashes to - * stdlib types without adding any hashing constraints. - */ - std::array challenges; - for (size_t i = 0; i < num_challenges; ++i) { - challenges[i] = field_ct::from_witness(builder, native_challenges[i]); + if constexpr (std::is_same_v) { + ASSERT(!data.empty() && data[0].get_context() != nullptr); + Builder* builder = data[0].get_context(); + return stdlib::poseidon2::hash(*builder, data); + } else { + using NativeFr = bb::fr; + ASSERT(!data.empty() && data[0].get_context() != nullptr); + Builder* builder = data[0].get_context(); + + // call the native hash on the data + std::vector native_data; + native_data.reserve(data.size()); + for (const auto& fr : data) { + native_data.push_back(fr.get_value()); + } + NativeFr hash_value = crypto::Poseidon2::hash(native_data); + + Fr hash_field_ct = Fr::from_witness(builder, hash_value); + return hash_field_ct; } - - return challenges; } - - /** - * @brief Compute the single challenge indicated by the input label - * - * @param label Name of challenge - * @return field_ct Challenge - */ - field_ct get_challenge(const std::string& label) + template static inline T convert_challenge(const Fr& challenge) { - // Compute the indicated challenge from the native transcript - auto native_challenge = native_transcript.get_challenge(label); - - // TODO(1351): Stdlib hashing here... - - return field_ct::from_witness(builder, native_challenge); + Builder* builder = challenge.get_context(); + return bb::stdlib::field_conversion::convert_challenge(*builder, challenge); } - - /** - * @brief Extract a native element from the transcript and return a corresponding stdlib type - * - * @tparam T Type of the native element to be extracted - * @param label Name of the element - * @return The corresponding element of appropriate stdlib type - */ - template auto receive_from_prover(const std::string& label) + template static constexpr size_t calc_num_bn254_frs() { - // Get native type corresponding to input type - using NativeType = typename StdlibTypes::template NativeType::type; - - // Extract the native element from the native transcript - NativeType element = native_transcript.template receive_from_prover(label); - - // Return the corresponding stdlib type - return StdlibTypes::from_witness(builder, element); + return bb::stdlib::field_conversion::calc_num_bn254_frs(); + } + template static inline T convert_from_bn254_frs(std::span frs) + { + ASSERT(!frs.empty() && frs[0].get_context() != nullptr); + Builder* builder = frs[0].get_context(); + return bb::stdlib::field_conversion::convert_from_bn254_frs(*builder, frs); + } + template static inline std::vector convert_to_bn254_frs(const T& element) + { + Builder* builder = element.get_context(); + return bb::stdlib::field_conversion::convert_to_bn254_frs(*builder, element); } }; -} // namespace bb::stdlib::recursion::honk + +using UltraStdlibTranscript = BaseTranscript>; +using GoblinUltraStdlibTranscript = BaseTranscript>; +} // namespace bb::stdlib::recursion::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.test.cpp index 09c8620c6193..f34292c12523 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.test.cpp @@ -5,15 +5,16 @@ #include "barretenberg/flavor/ultra.hpp" #include "barretenberg/flavor/ultra_recursive.hpp" #include "barretenberg/polynomials/univariate.hpp" -#include "barretenberg/stdlib/recursion/honk/transcript/transcript.hpp" #include "barretenberg/transcript/transcript.hpp" namespace bb::stdlib::recursion::honk { using Builder = UltraCircuitBuilder; +using UltraFlavor = UltraFlavor; using UltraRecursiveFlavor = UltraRecursiveFlavor_; using FF = fr; -using BaseTranscript = BaseTranscript; +using NativeTranscript = NativeTranscript; +using StdlibTranscript = BaseTranscript>; /** * @brief Create some mock data; add it to the provided prover transcript in various mock rounds @@ -40,16 +41,16 @@ template auto generate_mock_proof_data(auto prover // round 0 prover_transcript.send_to_verifier("data", data); - prover_transcript.get_challenge("alpha"); + prover_transcript.template get_challenge("alpha"); // round 1 prover_transcript.send_to_verifier("scalar", scalar); prover_transcript.send_to_verifier("commitment", commitment); - prover_transcript.get_challenges("beta, gamma"); + prover_transcript.template get_challenges("beta, gamma"); // round 2 prover_transcript.send_to_verifier("univariate", univariate); - prover_transcript.get_challenges("gamma", "delta"); + prover_transcript.template get_challenges("gamma", "delta"); return prover_transcript.proof_data; } @@ -70,17 +71,17 @@ template void perform_mock_verifier_transcript_ope using Univariate = typename bb::Univariate; // round 0 - transcript.template receive_from_prover("data"); - transcript.get_challenge("alpha"); + transcript.template receive_from_prover("data"); + transcript.template get_challenge("alpha"); // round 1 transcript.template receive_from_prover("scalar"); transcript.template receive_from_prover("commitment"); - transcript.get_challenges("beta, gamma"); + transcript.template get_challenges("beta, gamma"); // round 2 transcript.template receive_from_prover("univariate"); - transcript.get_challenges("gamma", "delta"); + transcript.template get_challenges("gamma", "delta"); } /** @@ -95,18 +96,19 @@ TEST(RecursiveHonkTranscript, InterfacesMatch) constexpr size_t LENGTH = 8; // arbitrary length of Univariate to be serialized // Instantiate a Prover Transcript and use it to generate some mock proof data - BaseTranscript prover_transcript; + NativeTranscript prover_transcript; auto proof_data = generate_mock_proof_data(prover_transcript); // Instantiate a (native) Verifier Transcript with the proof data and perform some mock transcript operations - BaseTranscript native_transcript(proof_data); + NativeTranscript native_transcript(proof_data); perform_mock_verifier_transcript_operations(native_transcript); // Confirm that Prover and Verifier transcripts have generated the same manifest via the operations performed EXPECT_EQ(prover_transcript.get_manifest(), native_transcript.get_manifest()); // Instantiate a stdlib Transcript and perform the same operations - Transcript transcript{ &builder, proof_data }; + StdlibProof stdlib_proof = bb::convert_proof_to_witness(&builder, proof_data); + StdlibTranscript transcript{ stdlib_proof }; perform_mock_verifier_transcript_operations(transcript); // Confirm that the native and stdlib verifier transcripts have generated the same manifest @@ -143,27 +145,28 @@ TEST(RecursiveHonkTranscript, ReturnValuesMatch) } // Construct a mock proof via the prover transcript - BaseTranscript prover_transcript; + NativeTranscript prover_transcript; prover_transcript.send_to_verifier("scalar", scalar); prover_transcript.send_to_verifier("commitment", commitment); prover_transcript.send_to_verifier("evaluations", evaluations); - prover_transcript.get_challenges("alpha, beta"); + prover_transcript.template get_challenges("alpha, beta"); auto proof_data = prover_transcript.proof_data; // Perform the corresponding operations with the native verifier transcript - BaseTranscript native_transcript(proof_data); + NativeTranscript native_transcript(proof_data); auto native_scalar = native_transcript.template receive_from_prover("scalar"); auto native_commitment = native_transcript.template receive_from_prover("commitment"); auto native_evaluations = native_transcript.template receive_from_prover>("evaluations"); - auto [native_alpha, native_beta] = native_transcript.get_challenges("alpha", "beta"); + auto [native_alpha, native_beta] = native_transcript.template get_challenges("alpha", "beta"); // Perform the same operations with the stdlib verifier transcript - Transcript stdlib_transcript{ &builder, proof_data }; + StdlibProof stdlib_proof = bb::convert_proof_to_witness(&builder, proof_data); + StdlibTranscript stdlib_transcript{ stdlib_proof }; auto stdlib_scalar = stdlib_transcript.template receive_from_prover("scalar"); auto stdlib_commitment = stdlib_transcript.template receive_from_prover("commitment"); auto stdlib_evaluations = stdlib_transcript.template receive_from_prover>("evaluations"); - auto [stdlib_alpha, stdlib_beta] = stdlib_transcript.get_challenges("alpha", "beta"); + auto [stdlib_alpha, stdlib_beta] = stdlib_transcript.template get_challenges("alpha", "beta"); // Confirm that return values are equivalent EXPECT_EQ(native_scalar, stdlib_scalar.get_value()); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.cpp index 5c7ef744e287..0ece406ee75f 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.cpp @@ -27,11 +27,12 @@ std::array DeciderRecursiveVerifier_:: using Instance = VerifierInstance_; static constexpr size_t NUM_SUBRELATIONS = Flavor::NUM_SUBRELATIONS; - transcript = std::make_shared(builder, proof); + StdlibProof stdlib_proof = bb::convert_proof_to_witness(builder, proof); + transcript = std::make_shared(stdlib_proof); auto inst = std::make_unique(); - const auto instance_size = transcript->template receive_from_prover("instance_size"); - const auto public_input_size = transcript->template receive_from_prover("public_input_size"); + const auto instance_size = transcript->template receive_from_prover("instance_size"); + const auto public_input_size = transcript->template receive_from_prover("public_input_size"); const auto log_instance_size = static_cast(numeric::get_msb(uint32_t(instance_size.get_value()))); for (size_t i = 0; i < uint32_t(public_input_size.get_value()); ++i) { diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.hpp index 56f8ec1c46de..61f9a4814206 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.hpp @@ -4,7 +4,6 @@ #include "barretenberg/honk/proof_system/types/proof.hpp" #include "barretenberg/stdlib/recursion/honk/transcript/transcript.hpp" #include "barretenberg/sumcheck/sumcheck.hpp" - namespace bb::stdlib::recursion::honk { template class DeciderRecursiveVerifier_ { using FF = typename Flavor::FF; @@ -15,6 +14,7 @@ template class DeciderRecursiveVerifier_ { using Builder = typename Flavor::CircuitBuilder; using RelationSeparator = typename Flavor::RelationSeparator; using PairingPoints = std::array; + using Transcript = bb::BaseTranscript>; public: explicit DeciderRecursiveVerifier_(Builder* builder); @@ -24,7 +24,7 @@ template class DeciderRecursiveVerifier_ { std::map commitments; std::shared_ptr pcs_verification_key; Builder* builder; - std::shared_ptr> transcript; + std::shared_ptr transcript; }; } // namespace bb::stdlib::recursion::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/merge_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/merge_recursive_verifier.cpp index 28fbe6d92df5..49bb9aa1c238 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/merge_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/merge_recursive_verifier.cpp @@ -18,7 +18,9 @@ template std::array::Element, 2> MergeRecursiveVerifier_::verify_proof( const HonkProof& proof) { - transcript = std::make_shared(builder, proof); + // transform it into stdlib proof + StdlibProof stdlib_proof = bb::convert_proof_to_witness(builder, proof); + transcript = std::make_shared(stdlib_proof); // Receive commitments [t_i^{shift}], [T_{i-1}], and [T_i] std::array C_T_prev; @@ -30,7 +32,7 @@ std::array::Element, 2> MergeRecursiveVerifier_template receive_from_prover("T_CURRENT_" + std::to_string(idx + 1)); } - FF kappa = transcript->get_challenge("kappa"); + FF kappa = transcript->template get_challenge("kappa"); // Receive transcript poly evaluations and add corresponding univariate opening claims {(\kappa, p(\kappa), [p(X)]} std::array T_prev_evals; @@ -56,7 +58,7 @@ std::array::Element, 2> MergeRecursiveVerifier_get_challenge("alpha"); + FF alpha = transcript->template get_challenge("alpha"); // Constuct batched commitment and batched evaluation from constituents using batching challenge \alpha std::vector scalars; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/merge_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/merge_recursive_verifier.hpp index 9e5a76fbc8d1..f87803599377 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/merge_recursive_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/merge_recursive_verifier.hpp @@ -14,7 +14,7 @@ template class MergeRecursiveVerifier_ { using KZG = ::bb::KZG; using OpeningClaim = ::bb::OpeningClaim; using PairingPoints = std::array; - using Transcript = honk::Transcript; + using Transcript = bb::BaseTranscript>; CircuitBuilder* builder; std::shared_ptr transcript; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/merge_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/merge_verifier.test.cpp index af5b40ecfc33..8e6595a1b981 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/merge_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/merge_verifier.test.cpp @@ -29,6 +29,8 @@ class RecursiveMergeVerifierTest : public testing::Test { using Commitment = InnerFlavor::Commitment; using FF = InnerFlavor::FF; using VerifierCommitmentKey = bb::VerifierCommitmentKey; + using MergeProver = MergeProver_; + using MergeVerifier = MergeVerifier_; public: static void SetUpTestSuite() { bb::srs::init_crs_factory("../srs_db/ignition"); } diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp index 482f078add8c..047cfa4037e6 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp @@ -8,9 +8,9 @@ void ProtoGalaxyRecursiveVerifier_::receive_accumulator(const const std::string& domain_separator) { // Get circuit parameters - const auto instance_size = transcript->template receive_from_prover(domain_separator + "_instance_size"); + const auto instance_size = transcript->template receive_from_prover(domain_separator + "_instance_size"); const auto public_input_size = - transcript->template receive_from_prover(domain_separator + "_public_input_size"); + transcript->template receive_from_prover(domain_separator + "_public_input_size"); inst->instance_size = uint32_t(instance_size.get_value()); inst->log_instance_size = uint32_t(numeric::get_msb(inst->instance_size)); inst->public_input_size = uint32_t(public_input_size.get_value()); @@ -69,9 +69,9 @@ void ProtoGalaxyRecursiveVerifier_::receive_and_finalise_inst const std::shared_ptr& inst, const std::string& domain_separator) { // Get circuit parameters and the public inputs - const auto instance_size = transcript->template receive_from_prover(domain_separator + "_instance_size"); + const auto instance_size = transcript->template receive_from_prover(domain_separator + "_instance_size"); const auto public_input_size = - transcript->template receive_from_prover(domain_separator + "_public_input_size"); + transcript->template receive_from_prover(domain_separator + "_public_input_size"); inst->instance_size = uint32_t(instance_size.get_value()); inst->log_instance_size = static_cast(numeric::get_msb(inst->instance_size)); inst->public_input_size = uint32_t(public_input_size.get_value()); @@ -83,7 +83,7 @@ void ProtoGalaxyRecursiveVerifier_::receive_and_finalise_inst } const auto pub_inputs_offset = - transcript->template receive_from_prover(domain_separator + "_pub_inputs_offset"); + transcript->template receive_from_prover(domain_separator + "_pub_inputs_offset"); inst->pub_inputs_offset = uint32_t(pub_inputs_offset.get_value()); @@ -110,13 +110,14 @@ void ProtoGalaxyRecursiveVerifier_::receive_and_finalise_inst } // Get challenge for sorted list batching and wire four memory records commitment - auto eta = transcript->get_challenge(domain_separator + "_eta"); + auto eta = transcript->template get_challenge(domain_separator + "_eta"); witness_commitments.sorted_accum = transcript->template receive_from_prover(domain_separator + "_" + labels.sorted_accum); witness_commitments.w_4 = transcript->template receive_from_prover(domain_separator + "_" + labels.w_4); // Get permutation challenges and commitment to permutation and lookup grand products - auto [beta, gamma] = transcript->get_challenges(domain_separator + "_beta", domain_separator + "_gamma"); + auto [beta, gamma] = + transcript->template get_challenges(domain_separator + "_beta", domain_separator + "_gamma"); // If Goblin (i.e. using DataBus) receive commitments to log-deriv inverses polynomial if constexpr (IsGoblinFlavor) { @@ -138,7 +139,7 @@ void ProtoGalaxyRecursiveVerifier_::receive_and_finalise_inst // Get the relation separation challenges for (size_t idx = 0; idx < NUM_SUBRELATIONS - 1; idx++) { - inst->alphas[idx] = transcript->get_challenge(domain_separator + "_alpha_" + std::to_string(idx)); + inst->alphas[idx] = transcript->template get_challenge(domain_separator + "_alpha_" + std::to_string(idx)); } // Get the commitments to the selector polynomials for the given instance @@ -157,7 +158,7 @@ template void ProtoGalaxyRecursiveVerifier_template receive_from_prover(domain_separator + "is_accumulator"); + const auto is_accumulator = transcript->template receive_from_prover(domain_separator + "is_accumulator"); inst->is_accumulator = static_cast(is_accumulator.get_value()); if (inst->is_accumulator) { receive_accumulator(inst, domain_separator); @@ -167,7 +168,7 @@ template void ProtoGalaxyRecursiveVerifier_target_sum = 0; - auto beta = transcript->get_challenge(domain_separator + "_initial_gate_challenge"); + auto beta = transcript->template get_challenge(domain_separator + "_initial_gate_challenge"); std::vector gate_challenges(inst->log_instance_size); gate_challenges[0] = beta; for (size_t i = 1; i < inst->log_instance_size; i++) { @@ -190,10 +191,11 @@ void ProtoGalaxyRecursiveVerifier_::verify_folding_proof(cons using Transcript = typename Flavor::Transcript; using ScalarNative = typename Flavor::Curve::ScalarFieldNative; - transcript = std::make_shared(builder, proof); + StdlibProof stdlib_proof = bb::convert_proof_to_witness(builder, proof); + transcript = std::make_shared(stdlib_proof); prepare_for_folding(); - auto delta = transcript->get_challenge("delta"); + auto delta = transcript->template get_challenge("delta"); auto accumulator = get_accumulator(); auto deltas = compute_round_challenge_pows(accumulator->log_instance_size, delta); @@ -208,7 +210,7 @@ void ProtoGalaxyRecursiveVerifier_::verify_folding_proof(cons auto zero = FF::from_witness(builder, ScalarNative(0)); zero.assert_equal(accumulator->target_sum - perturbator_coeffs[0], "F(0) != e"); - FF perturbator_challenge = transcript->get_challenge("perturbator_challenge"); + FF perturbator_challenge = transcript->template get_challenge("perturbator_challenge"); auto perturbator_at_challenge = evaluate_perturbator(perturbator_coeffs, perturbator_challenge); // The degree of K(X) is dk - k - 1 = k(d - 1) - 1. Hence we need k(d - 1) evaluations to represent it. @@ -219,7 +221,7 @@ void ProtoGalaxyRecursiveVerifier_::verify_folding_proof(cons } Univariate combiner_quotient( combiner_quotient_evals); - FF combiner_challenge = transcript->get_challenge("combiner_quotient_challenge"); + FF combiner_challenge = transcript->template get_challenge("combiner_quotient_challenge"); auto combiner_quotient_at_challenge = combiner_quotient.evaluate(combiner_challenge); // fine recursive i think auto vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.hpp index 15fc8dabae3d..9bcc8a9c2382 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.hpp @@ -21,6 +21,7 @@ template class ProtoGalaxyRecursiveVerifier_ { using Builder = typename Flavor::CircuitBuilder; using RelationSeparator = typename Flavor::RelationSeparator; using PairingPoints = std::array; + using Transcript = bb::BaseTranscript>; static constexpr size_t NUM_SUBRELATIONS = Flavor::NUM_SUBRELATIONS; @@ -29,7 +30,7 @@ template class ProtoGalaxyRecursiveVerifier_ { CommitmentLabels commitment_labels; Builder* builder; - std::shared_ptr> transcript; + std::shared_ptr transcript; explicit ProtoGalaxyRecursiveVerifier_(Builder* builder) : instances(VerifierInstances()) diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp index b6e6b4edfed0..47d4be24aca4 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp @@ -30,14 +30,15 @@ std::array UltraRecursiveVerifier_::ve RelationParams relation_parameters; - transcript = std::make_shared(builder, proof); + StdlibProof stdlib_proof = bb::convert_proof_to_witness(builder, proof); + transcript = std::make_shared(stdlib_proof); VerifierCommitments commitments{ key }; CommitmentLabels commitment_labels; - const auto circuit_size = transcript->template receive_from_prover("circuit_size"); - const auto public_input_size = transcript->template receive_from_prover("public_input_size"); - const auto pub_inputs_offset = transcript->template receive_from_prover("pub_inputs_offset"); + const auto circuit_size = transcript->template receive_from_prover("circuit_size"); + const auto public_input_size = transcript->template receive_from_prover("public_input_size"); + const auto pub_inputs_offset = transcript->template receive_from_prover("pub_inputs_offset"); // For debugging purposes only ASSERT(static_cast(circuit_size.get_value()) == key->circuit_size); @@ -45,8 +46,7 @@ std::array UltraRecursiveVerifier_::ve std::vector public_inputs; for (size_t i = 0; i < key->num_public_inputs; ++i) { - auto public_input_i = transcript->template receive_from_prover("public_input_" + std::to_string(i)); - public_inputs.emplace_back(public_input_i); + public_inputs.emplace_back(transcript->template receive_from_prover("public_input_" + std::to_string(i))); } // Get commitments to first three wire polynomials @@ -70,7 +70,7 @@ std::array UltraRecursiveVerifier_::ve } // Get challenge for sorted list batching and wire four memory records - auto eta = transcript->get_challenge("eta"); + auto eta = transcript->template get_challenge("eta"); relation_parameters.eta = eta; // Get commitments to sorted list accumulator and fourth wire @@ -78,7 +78,7 @@ std::array UltraRecursiveVerifier_::ve commitments.w_4 = transcript->template receive_from_prover(commitment_labels.w_4); // Get permutation challenges - auto [beta, gamma] = transcript->get_challenges("beta", "gamma"); + auto [beta, gamma] = transcript->template get_challenges("beta", "gamma"); // If Goblin (i.e. using DataBus) receive commitments to log-deriv inverses polynomial if constexpr (IsGoblinFlavor) { @@ -105,12 +105,12 @@ std::array UltraRecursiveVerifier_::ve auto sumcheck = Sumcheck(log_circuit_size, transcript); RelationSeparator alpha; for (size_t idx = 0; idx < alpha.size(); idx++) { - alpha[idx] = transcript->get_challenge("Sumcheck:alpha_" + std::to_string(idx)); + alpha[idx] = transcript->template get_challenge("Sumcheck:alpha_" + std::to_string(idx)); } auto gate_challenges = std::vector(log_circuit_size); for (size_t idx = 0; idx < log_circuit_size; idx++) { - gate_challenges[idx] = transcript->get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); + gate_challenges[idx] = transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); } auto [multivariate_challenge, claimed_evaluations, sumcheck_verified] = sumcheck.verify(relation_parameters, alpha, gate_challenges); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.hpp index 5288b699452d..08ab6159e902 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.hpp @@ -17,6 +17,7 @@ template class UltraRecursiveVerifier_ { using Builder = typename Flavor::CircuitBuilder; using RelationSeparator = typename Flavor::RelationSeparator; using PairingPoints = std::array; + using Transcript = bb::BaseTranscript>; explicit UltraRecursiveVerifier_(Builder* builder, const std::shared_ptr& native_verifier_key); @@ -29,7 +30,7 @@ template class UltraRecursiveVerifier_ { std::map commitments; std::shared_ptr pcs_verification_key; Builder* builder; - std::shared_ptr> transcript; + std::shared_ptr transcript; }; // Instance declarations for Ultra and Goblin-Ultra verifier circuits with both conventional Ultra and Goblin-Ultra diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp index e3829102c87e..09e2f41de681 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp @@ -98,7 +98,7 @@ template class SumcheckProver { // This populates partially_evaluated_polynomials. auto round_univariate = round.compute_univariate(full_polynomials, relation_parameters, pow_univariate, alpha); transcript->send_to_verifier("Sumcheck:univariate_0", round_univariate); - FF round_challenge = transcript->get_challenge("Sumcheck:u_0"); + FF round_challenge = transcript->template get_challenge("Sumcheck:u_0"); multivariate_challenge.emplace_back(round_challenge); partially_evaluate(full_polynomials, multivariate_n, round_challenge); pow_univariate.partially_evaluate(round_challenge); @@ -110,7 +110,7 @@ template class SumcheckProver { round_univariate = round.compute_univariate(partially_evaluated_polynomials, relation_parameters, pow_univariate, alpha); transcript->send_to_verifier("Sumcheck:univariate_" + std::to_string(round_idx), round_univariate); - FF round_challenge = transcript->get_challenge("Sumcheck:u_" + std::to_string(round_idx)); + FF round_challenge = transcript->template get_challenge("Sumcheck:u_" + std::to_string(round_idx)); multivariate_challenge.emplace_back(round_challenge); partially_evaluate(partially_evaluated_polynomials, round.round_size, round_challenge); pow_univariate.partially_evaluate(round_challenge); @@ -228,7 +228,7 @@ template class SumcheckVerifier { bool checked = round.check_sum(round_univariate); verified = verified && checked; - FF round_challenge = transcript->get_challenge("Sumcheck:u_" + std::to_string(round_idx)); + FF round_challenge = transcript->template get_challenge("Sumcheck:u_" + std::to_string(round_idx)); multivariate_challenge.emplace_back(round_challenge); round.compute_next_target_sum(round_univariate, round_challenge); diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp index ccb952dc19f0..842152c3a146 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp @@ -69,12 +69,12 @@ TEST_F(SumcheckTests, PolynomialNormalization) auto sumcheck = SumcheckProver(multivariate_n, transcript); RelationSeparator alpha; for (size_t idx = 0; idx < alpha.size(); idx++) { - alpha[idx] = transcript->get_challenge("Sumcheck:alpha_" + std::to_string(idx)); + alpha[idx] = transcript->template get_challenge("Sumcheck:alpha_" + std::to_string(idx)); } std::vector gate_challenges(multivariate_d); for (size_t idx = 0; idx < multivariate_d; idx++) { - gate_challenges[idx] = transcript->get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); + gate_challenges[idx] = transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); } auto output = sumcheck.prove(full_polynomials, {}, alpha, gate_challenges); @@ -141,12 +141,12 @@ TEST_F(SumcheckTests, Prover) RelationSeparator alpha; for (size_t idx = 0; idx < alpha.size(); idx++) { - alpha[idx] = transcript->get_challenge("Sumcheck:alpha_" + std::to_string(idx)); + alpha[idx] = transcript->template get_challenge("Sumcheck:alpha_" + std::to_string(idx)); } std::vector gate_challenges(multivariate_d); for (size_t idx = 0; idx < gate_challenges.size(); idx++) { - gate_challenges[idx] = transcript->get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); + gate_challenges[idx] = transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); } auto output = sumcheck.prove(full_polynomials, {}, alpha, gate_challenges); FF u_0 = output.challenge[0]; @@ -224,12 +224,12 @@ TEST_F(SumcheckTests, ProverAndVerifierSimple) RelationSeparator prover_alpha; for (size_t idx = 0; idx < prover_alpha.size(); idx++) { - prover_alpha[idx] = prover_transcript->get_challenge("Sumcheck:alpha_" + std::to_string(idx)); + prover_alpha[idx] = prover_transcript->template get_challenge("Sumcheck:alpha_" + std::to_string(idx)); } std::vector prover_gate_challenges(multivariate_d); for (size_t idx = 0; idx < multivariate_d; idx++) { prover_gate_challenges[idx] = - prover_transcript->get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); + prover_transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); } auto output = sumcheck_prover.prove(full_polynomials, {}, prover_alpha, prover_gate_challenges); @@ -238,12 +238,13 @@ TEST_F(SumcheckTests, ProverAndVerifierSimple) auto sumcheck_verifier = SumcheckVerifier(multivariate_d, verifier_transcript); RelationSeparator verifier_alpha; for (size_t idx = 0; idx < verifier_alpha.size(); idx++) { - verifier_alpha[idx] = verifier_transcript->get_challenge("Sumcheck:alpha_" + std::to_string(idx)); + verifier_alpha[idx] = + verifier_transcript->template get_challenge("Sumcheck:alpha_" + std::to_string(idx)); } std::vector verifier_gate_challenges(multivariate_d); for (size_t idx = 0; idx < multivariate_d; idx++) { verifier_gate_challenges[idx] = - verifier_transcript->get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); + verifier_transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); } auto verifier_output = sumcheck_verifier.verify(relation_parameters, verifier_alpha, verifier_gate_challenges); diff --git a/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp b/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp index 5b39412ac110..655641144b31 100644 --- a/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp +++ b/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp @@ -6,6 +6,9 @@ #include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp" #include "barretenberg/ecc/fields/field_conversion.hpp" #include "barretenberg/honk/proof_system/types/proof.hpp" +#include "barretenberg/stdlib/hash/poseidon2/poseidon2.hpp" +#include "barretenberg/stdlib/primitives/field/field.hpp" +#include "barretenberg/stdlib/primitives/field/field_conversion.hpp" // #define LOG_CHALLENGES // #define LOG_INTERACTIONS @@ -58,15 +61,39 @@ class TranscriptManifest { bool operator==(const TranscriptManifest& other) const = default; }; +struct NativeTranscriptParams { + using Fr = bb::fr; + using Proof = HonkProof; + static inline Fr hash(const std::vector& data) + { + return crypto::Poseidon2::hash(data); + } + template static inline T convert_challenge(const Fr& challenge) + { + return bb::field_conversion::convert_challenge(challenge); + } + template static constexpr size_t calc_num_bn254_frs() + { + return bb::field_conversion::calc_num_bn254_frs(); + } + template static inline T convert_from_bn254_frs(std::span frs) + { + return bb::field_conversion::convert_from_bn254_frs(frs); + } + template static inline std::vector convert_to_bn254_frs(const T& element) + { + return bb::field_conversion::convert_to_bn254_frs(element); + } +}; + /** * @brief Common transcript class for both parties. Stores the data for the current round, as well as the * manifest. */ -class BaseTranscript { +template class BaseTranscript { public: - using Fr = bb::fr; - using Poseidon2Params = crypto::Poseidon2Bn254ScalarFieldParams; - using Proof = HonkProof; + using Fr = typename TranscriptParams::Fr; + using Proof = typename TranscriptParams::Proof; BaseTranscript() = default; @@ -78,6 +105,7 @@ class BaseTranscript { explicit BaseTranscript(const Proof& proof_data) : proof_data(proof_data.begin(), proof_data.end()) {} + static constexpr size_t HASH_OUTPUT_SIZE = 32; std::ptrdiff_t proof_start = 0; @@ -132,7 +160,7 @@ class BaseTranscript { // Hash the full buffer with poseidon2, which is believed to be a collision resistant hash function and a random // oracle, removing the need to pre-hash to compress and then hash with a random oracle, as we previously did // with Pedersen and Blake3s. - Fr base_hash = crypto::Poseidon2::hash(full_buffer); + Fr base_hash = TranscriptParams::hash(full_buffer); Fr new_challenge = base_hash; // update previous challenge buffer for next time we call this function @@ -167,7 +195,7 @@ class BaseTranscript { */ template void serialize_to_buffer(const T& element, Proof& proof_data) { - auto element_frs = bb::field_conversion::convert_to_bn254_frs(element); + auto element_frs = TranscriptParams::template convert_to_bn254_frs(element); proof_data.insert(proof_data.end(), element_frs.begin(), element_frs.end()); } /** @@ -181,13 +209,13 @@ class BaseTranscript { */ template T deserialize_from_buffer(const Proof& proof_data, size_t& offset) const { - constexpr size_t element_fr_size = bb::field_conversion::calc_num_bn254_frs(); + constexpr size_t element_fr_size = TranscriptParams::template calc_num_bn254_frs(); ASSERT(offset + element_fr_size <= proof_data.size()); auto element_frs = std::span{ proof_data }.subspan(offset, element_fr_size); offset += element_fr_size; - auto element = bb::field_conversion::convert_from_bn254_frs(element_frs); + auto element = TranscriptParams::template convert_from_bn254_frs(element_frs); return element; } @@ -225,7 +253,8 @@ class BaseTranscript { * @param labels human-readable names for the challenges for the manifest * @return std::array challenges for this round. */ - template std::array get_challenges(const Strings&... labels) + template + std::array get_challenges(const Strings&... labels) { constexpr size_t num_challenges = sizeof...(Strings); @@ -235,7 +264,7 @@ class BaseTranscript { // Compute the new challenge buffer from which we derive the challenges. // Create challenges from Frs. - std::array challenges{}; + std::array challenges{}; // Generate the challenges by iteratively hashing over the previous challenge. for (size_t i = 0; i < num_challenges; i++) { @@ -247,10 +276,10 @@ class BaseTranscript { // copy half of the hash to lower 128 bits of challenge Note: because of how read() from buffers to fields works (in field_declarations.hpp), we use the later half of the buffer // std::copy_n(next_challenge_buffer.begin(), - HASH_OUTPUT_SIZE / 2, - field_element_buffer.begin() + HASH_OUTPUT_SIZE / 2); + // HASH_OUTPUT_SIZE / 2, + // field_element_buffer.begin() + HASH_OUTPUT_SIZE / 2); */ - challenges[i] = static_cast(get_next_challenge_buffer()); + challenges[i] = TranscriptParams::template convert_challenge(get_next_challenge_buffer()); } // Prepare for next round. @@ -278,7 +307,7 @@ class BaseTranscript { // TODO(Adrian): Consider restricting serialization (via concepts) to types T for which sizeof(T) reliably // returns the size of T in frs. (E.g. this is true for std::array but not for std::vector). // convert element to field elements - auto element_frs = bb::field_conversion::convert_to_bn254_frs(element); + auto element_frs = TranscriptParams::convert_to_bn254_frs(element); proof_data.insert(proof_data.end(), element_frs.begin(), element_frs.end()); #ifdef LOG_INTERACTIONS @@ -297,7 +326,7 @@ class BaseTranscript { */ template T receive_from_prover(const std::string& label) { - constexpr size_t element_size = bb::field_conversion::calc_num_bn254_frs(); + const size_t element_size = TranscriptParams::template calc_num_bn254_frs(); ASSERT(num_frs_read + element_size <= proof_data.size()); auto element_frs = std::span{ proof_data }.subspan(num_frs_read, element_size); @@ -305,7 +334,7 @@ class BaseTranscript { BaseTranscript::consume_prover_element_frs(label, element_frs); - auto element = bb::field_conversion::convert_from_bn254_frs(element_frs); + auto element = TranscriptParams::template convert_from_bn254_frs(element_frs); #ifdef LOG_INTERACTIONS if constexpr (Loggable) { @@ -339,13 +368,13 @@ class BaseTranscript { static std::shared_ptr verifier_init_empty(const std::shared_ptr& transcript) { auto verifier_transcript = std::make_shared(transcript->proof_data); - [[maybe_unused]] auto _ = verifier_transcript->template receive_from_prover("Init"); + [[maybe_unused]] auto _ = verifier_transcript->template receive_from_prover("Init"); return verifier_transcript; }; - uint256_t get_challenge(const std::string& label) + template ChallengeType get_challenge(const std::string& label) { - uint256_t result = get_challenges(label)[0]; + ChallengeType result = get_challenges(label)[0]; #if defined LOG_CHALLENGES || defined LOG_INTERACTIONS info("challenge: ", label, ": ", result); #endif @@ -357,15 +386,16 @@ class BaseTranscript { void print() { manifest.print(); } }; -/** - * @brief Convert an array of uint256_t's to an array of field elements - * @details The syntax `std::array [a, b] = transcript.get_challenges("a", "b")` is unfortunately not allowed - * (structured bindings must be defined with auto return type), so we need a workaround. - */ -template std::array challenges_to_field_elements(std::array&& arr) +template +static bb::StdlibProof convert_proof_to_witness(Builder* builder, const HonkProof& proof) { - std::array result; - std::move(arr.begin(), arr.end(), result.begin()); + bb::StdlibProof result; + for (const auto& element : proof) { + result.push_back(bb::stdlib::witness_t(builder, element)); + } return result; } + +using NativeTranscript = BaseTranscript; + } // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/transcript/transcript.test.cpp b/barretenberg/cpp/src/barretenberg/transcript/transcript.test.cpp index 2d70ad4a24f3..2301e92cadb2 100644 --- a/barretenberg/cpp/src/barretenberg/transcript/transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/transcript/transcript.test.cpp @@ -1,18 +1,18 @@ -#include "barretenberg/transcript/transcript.hpp" +#include "barretenberg/stdlib/recursion/honk/transcript/transcript.hpp" #include using namespace bb; -using FF = fr; -using Fr = fr; -using Fq = fq; -using Transcript = BaseTranscript; +using FF = bb::fr; +using Fr = bb::fr; +using Fq = bb::fq; +using Transcript = NativeTranscript; /** * @brief Test sending, receiving, and exporting proofs * */ -TEST(BaseTranscript, TwoProversTwoFields) +TEST(NativeTranscript, TwoProversTwoFields) { const auto EXPECT_STATE = [](const Transcript& transcript, size_t start, size_t written, size_t read) { EXPECT_EQ(transcript.proof_start, static_cast(start)); diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.hpp index 9117a03a4053..5e033178cba5 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.hpp @@ -19,7 +19,7 @@ class GoblinTranslatorComposer { using CommitmentKey = typename Flavor::CommitmentKey; using VerifierCommitmentKey = typename Flavor::VerifierCommitmentKey; using Polynomial = typename Flavor::Polynomial; - using Transcript = BaseTranscript; + using Transcript = NativeTranscript; static constexpr std::string_view NAME_STRING = "GoblinTranslator"; static constexpr size_t NUM_WIRES = CircuitBuilder::NUM_WIRES; diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.test.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.test.cpp index 05850f7366ae..0bd890ccd34a 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.test.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.test.cpp @@ -63,7 +63,7 @@ TEST_F(GoblinTranslatorComposerTests, Basic) auto prover_transcript = std::make_shared(); prover_transcript->send_to_verifier("init", Fq::random_element()); prover_transcript->export_proof(); - Fq translation_batching_challenge = prover_transcript->get_challenge("Translation:batching_challenge"); + Fq translation_batching_challenge = prover_transcript->template get_challenge("Translation:batching_challenge"); Fq translation_evaluation_challenge = Fq::random_element(); auto circuit_builder = CircuitBuilder(translation_batching_challenge, translation_evaluation_challenge, op_queue); EXPECT_TRUE(circuit_builder.check_circuit()); diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.cpp index e6b1e89a9630..11a557a1b98f 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.cpp @@ -88,7 +88,7 @@ void GoblinTranslatorProver::execute_wire_and_sorted_constraints_commitments_rou void GoblinTranslatorProver::execute_grand_product_computation_round() { // Compute and store parameters required by relations in Sumcheck - FF gamma = transcript->get_challenge("gamma"); + FF gamma = transcript->template get_challenge("gamma"); const size_t NUM_LIMB_BITS = Flavor::NUM_LIMB_BITS; relation_parameters.beta = 0; relation_parameters.gamma = gamma; @@ -140,10 +140,10 @@ void GoblinTranslatorProver::execute_relation_check_rounds() using Sumcheck = SumcheckProver; auto sumcheck = Sumcheck(key->circuit_size, transcript); - FF alpha = transcript->get_challenge("Sumcheck:alpha"); + FF alpha = transcript->template get_challenge("Sumcheck:alpha"); std::vector gate_challenges(numeric::get_msb(key->circuit_size)); for (size_t idx = 0; idx < gate_challenges.size(); idx++) { - gate_challenges[idx] = transcript->get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); + gate_challenges[idx] = transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); } sumcheck_output = sumcheck.prove(prover_polynomials, relation_parameters, alpha, gate_challenges); } diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.cpp index 6165e4f99d9d..2eb78673a02f 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.cpp @@ -64,7 +64,7 @@ void GoblinTranslatorVerifier::put_translation_data_in_relation_parameters(const */ bool GoblinTranslatorVerifier::verify_proof(const HonkProof& proof) { - batching_challenge_v = transcript->get_challenge("Translation:batching_challenge"); + batching_challenge_v = transcript->template get_challenge("Translation:batching_challenge"); transcript->load_proof(proof); Flavor::VerifierCommitments commitments{ key }; @@ -229,7 +229,7 @@ bool GoblinTranslatorVerifier::verify_proof(const HonkProof& proof) commitments.ordered_range_constraints_4 = receive_commitment(commitment_labels.ordered_range_constraints_4); // Get permutation challenges - FF gamma = transcript->get_challenge("gamma"); + FF gamma = transcript->template get_challenge("gamma"); relation_parameters.beta = 0; relation_parameters.gamma = gamma; @@ -242,10 +242,10 @@ bool GoblinTranslatorVerifier::verify_proof(const HonkProof& proof) // Execute Sumcheck Verifier const size_t log_circuit_size = numeric::get_msb(circuit_size); auto sumcheck = SumcheckVerifier(log_circuit_size, transcript); - FF alpha = transcript->get_challenge("Sumcheck:alpha"); + FF alpha = transcript->template get_challenge("Sumcheck:alpha"); std::vector gate_challenges(numeric::get_msb(key->circuit_size)); for (size_t idx = 0; idx < gate_challenges.size(); idx++) { - gate_challenges[idx] = transcript->get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); + gate_challenges[idx] = transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); } auto [multivariate_challenge, claimed_evaluations, sumcheck_verified] = diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_composer.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_composer.test.cpp index 6c948a15e2f7..7252076bab7f 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_composer.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_composer.test.cpp @@ -23,6 +23,8 @@ class GoblinUltraHonkComposerTests : public ::testing::Test { using FF = Curve::ScalarField; using Point = Curve::AffineElement; using CommitmentKey = bb::CommitmentKey; + using MergeProver = MergeProver_; + using MergeVerifier = MergeVerifier_; /** * @brief Generate a simple test circuit with some ECC op gates and conventional arithmetic gates diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_transcript.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_transcript.test.cpp index a557b138dae4..5e97fd5bfaf8 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_transcript.test.cpp @@ -201,7 +201,7 @@ TEST_F(GoblinUltraTranscriptTests, ChallengeGenerationTest) // initialized with random value sent to verifier auto transcript = Flavor::Transcript::prover_init_empty(); // test a bunch of challenges - auto challenges = transcript->get_challenges("a", "b", "c", "d", "e", "f"); + auto challenges = transcript->template get_challenges("a", "b", "c", "d", "e", "f"); // check they are not 0 for (size_t i = 0; i < challenges.size(); ++i) { ASSERT_NE(challenges[i], 0) << "Challenge " << i << " is 0"; @@ -209,7 +209,7 @@ TEST_F(GoblinUltraTranscriptTests, ChallengeGenerationTest) constexpr uint32_t random_val{ 17 }; // arbitrary transcript->send_to_verifier("random val", random_val); // test more challenges - auto [a, b, c] = challenges_to_field_elements(transcript->get_challenges("a", "b", "c")); + auto [a, b, c] = transcript->template get_challenges("a", "b", "c"); ASSERT_NE(a, 0) << "Challenge a is 0"; ASSERT_NE(b, 0) << "Challenge b is 0"; ASSERT_NE(c, 0) << "Challenge c is 0"; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_prover.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_prover.cpp index 8d39901d419a..721830fadd23 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_prover.cpp @@ -8,7 +8,8 @@ namespace bb { * per-circuit contribution t_i^{shift} * */ -MergeProver::MergeProver(const std::shared_ptr& op_queue) +template +MergeProver_::MergeProver_(const std::shared_ptr& op_queue) : op_queue(op_queue) , pcs_commitment_key(std::make_shared(op_queue->ultra_ops[0].size())) { @@ -29,7 +30,7 @@ MergeProver::MergeProver(const std::shared_ptr& op_queue) * * @return honk::proof */ -HonkProof MergeProver::construct_proof() +template HonkProof MergeProver_::construct_proof() { transcript = std::make_shared(); @@ -69,7 +70,7 @@ HonkProof MergeProver::construct_proof() // Compute evaluations T_i(\kappa), T_{i-1}(\kappa), t_i^{shift}(\kappa), add to transcript. For each polynomial // we add a univariate opening claim {p(X), (\kappa, p(\kappa))} to the set of claims to be checked via batched KZG. - FF kappa = transcript->get_challenge("kappa"); + FF kappa = transcript->template get_challenge("kappa"); // Add univariate opening claims for each polynomial. std::vector opening_claims; @@ -94,7 +95,7 @@ HonkProof MergeProver::construct_proof() opening_claims.emplace_back(OpeningClaim{ polynomial, { kappa, evaluation } }); } - FF alpha = transcript->get_challenge("alpha"); + FF alpha = transcript->template get_challenge("alpha"); // Construct batched polynomial to opened via KZG auto batched_polynomial = Polynomial(N); @@ -117,4 +118,7 @@ HonkProof MergeProver::construct_proof() return transcript->proof_data; } +template class MergeProver_; +template class MergeProver_; + } // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_prover.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_prover.hpp index 2b616022458c..c4002403382c 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_prover.hpp @@ -13,20 +13,21 @@ namespace bb { * @brief Prover class for the Goblin ECC op queue transcript merge protocol * */ -class MergeProver { - using Curve = curve::BN254; - using FF = Curve::ScalarField; - using Polynomial = polynomial; - using CommitmentKey = bb::CommitmentKey; - using Commitment = Curve::AffineElement; - using PCS = bb::KZG; - using OpeningClaim = typename bb::ProverOpeningClaim; - using Transcript = BaseTranscript; +template class MergeProver_ { + using FF = typename Flavor::FF; + using Polynomial = typename Flavor::Polynomial; + using CommitmentKey = typename Flavor::CommitmentKey; + using Commitment = typename Flavor::Commitment; + using PCS = typename Flavor::PCS; + using Curve = typename Flavor::Curve; + using OpeningClaim = ProverOpeningClaim; + using OpeningPair = bb::OpeningPair; + using Transcript = NativeTranscript; public: std::shared_ptr transcript; - explicit MergeProver(const std::shared_ptr&); + explicit MergeProver_(const std::shared_ptr&); BB_PROFILE HonkProof construct_proof(); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.cpp index f8eb261b195d..e0ade5f34be0 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.cpp @@ -2,8 +2,10 @@ namespace bb { -MergeVerifier::MergeVerifier() - : pcs_verification_key(std::make_unique(0, bb::srs::get_crs_factory())){}; +template +MergeVerifier_::MergeVerifier_() + : transcript(std::make_shared()) + , pcs_verification_key(std::make_unique(0, bb::srs::get_crs_factory())){}; /** * @brief Verify proper construction of the aggregate Goblin ECC op queue polynomials T_i^(j), j = 1,2,3,4. @@ -13,34 +15,35 @@ MergeVerifier::MergeVerifier() * M_{i-1}), where the shift magnitude M_{i-1} is the length of T_{i-1}. This protocol verfies that the aggregate op * queue has been constructed correctly via a simple Schwartz-Zippel check. Evaluations are checked via batched KZG. * + * @tparam Flavor * @return HonkProof& */ -bool MergeVerifier::verify_proof(const HonkProof& proof) +template bool MergeVerifier_::verify_proof(const HonkProof& proof) { transcript = std::make_shared(proof); // Receive commitments [t_i^{shift}], [T_{i-1}], and [T_i] - std::array C_T_prev; - std::array C_t_shift; - std::array C_T_current; - for (size_t idx = 0; idx < NUM_WIRES; ++idx) { + std::array C_T_prev; + std::array C_t_shift; + std::array C_T_current; + for (size_t idx = 0; idx < Flavor::NUM_WIRES; ++idx) { C_T_prev[idx] = transcript->template receive_from_prover("T_PREV_" + std::to_string(idx + 1)); C_t_shift[idx] = transcript->template receive_from_prover("t_SHIFT_" + std::to_string(idx + 1)); C_T_current[idx] = transcript->template receive_from_prover("T_CURRENT_" + std::to_string(idx + 1)); } - FF kappa = transcript->get_challenge("kappa"); + FF kappa = transcript->template get_challenge("kappa"); // Receive transcript poly evaluations and add corresponding univariate opening claims {(\kappa, p(\kappa), [p(X)]} - std::array T_prev_evals; - std::array t_shift_evals; - std::array T_current_evals; + std::array T_prev_evals; + std::array t_shift_evals; + std::array T_current_evals; std::vector opening_claims; - for (size_t idx = 0; idx < NUM_WIRES; ++idx) { + for (size_t idx = 0; idx < Flavor::NUM_WIRES; ++idx) { T_prev_evals[idx] = transcript->template receive_from_prover("T_prev_eval_" + std::to_string(idx + 1)); opening_claims.emplace_back(OpeningClaim{ { kappa, T_prev_evals[idx] }, C_T_prev[idx] }); } - for (size_t idx = 0; idx < NUM_WIRES; ++idx) { + for (size_t idx = 0; idx < Flavor::NUM_WIRES; ++idx) { t_shift_evals[idx] = transcript->template receive_from_prover("t_shift_eval_" + std::to_string(idx + 1)); opening_claims.emplace_back(OpeningClaim{ { kappa, t_shift_evals[idx] }, C_t_shift[idx] }); } @@ -56,7 +59,7 @@ bool MergeVerifier::verify_proof(const HonkProof& proof) identity_checked = identity_checked && (T_current_evals[idx] == T_prev_evals[idx] + t_shift_evals[idx]); } - FF alpha = transcript->get_challenge("alpha"); + FF alpha = transcript->template get_challenge("alpha"); // Construct batched commitment and evaluation from constituents auto batched_commitment = opening_claims[0].commitment; @@ -76,4 +79,7 @@ bool MergeVerifier::verify_proof(const HonkProof& proof) return identity_checked && verified; } +template class MergeVerifier_; +template class MergeVerifier_; + } // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.hpp index efd95773b6f4..38749c1347f6 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.hpp @@ -14,19 +14,19 @@ namespace bb { * @brief Verifier class for the Goblin ECC op queue transcript merge protocol * */ -class MergeVerifier { - using Curve = curve::BN254; +template class MergeVerifier_ { + using Curve = typename Flavor::Curve; using FF = typename Curve::ScalarField; using Commitment = typename Curve::AffineElement; using PCS = bb::KZG; using OpeningClaim = bb::OpeningClaim; using VerifierCommitmentKey = bb::VerifierCommitmentKey; - using Transcript = BaseTranscript; + using Transcript = NativeTranscript; public: std::shared_ptr transcript; - explicit MergeVerifier(); + explicit MergeVerifier_(); bool verify_proof(const HonkProof& proof); private: diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/sumcheck.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/sumcheck.test.cpp index 2f736f2ed823..1ec8602c4fb4 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/sumcheck.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/sumcheck.test.cpp @@ -166,7 +166,7 @@ TEST_F(SumcheckTestsRealCircuit, Ultra) RelationSeparator prover_alphas; for (size_t idx = 0; idx < prover_alphas.size(); idx++) { - prover_alphas[idx] = prover_transcript->get_challenge("Sumcheck:alpha_" + std::to_string(idx)); + prover_alphas[idx] = prover_transcript->template get_challenge("Sumcheck:alpha_" + std::to_string(idx)); } instance->alphas = prover_alphas; @@ -174,7 +174,7 @@ TEST_F(SumcheckTestsRealCircuit, Ultra) std::vector prover_gate_challenges(log_circuit_size); for (size_t idx = 0; idx < log_circuit_size; idx++) { prover_gate_challenges[idx] = - prover_transcript->get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); + prover_transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); } instance->gate_challenges = prover_gate_challenges; auto prover_output = sumcheck_prover.prove(instance); @@ -184,13 +184,13 @@ TEST_F(SumcheckTestsRealCircuit, Ultra) auto sumcheck_verifier = SumcheckVerifier(log_circuit_size, verifier_transcript); RelationSeparator verifier_alphas; for (size_t idx = 0; idx < verifier_alphas.size(); idx++) { - verifier_alphas[idx] = verifier_transcript->get_challenge("Sumcheck:alpha_" + std::to_string(idx)); + verifier_alphas[idx] = verifier_transcript->template get_challenge("Sumcheck:alpha_" + std::to_string(idx)); } std::vector verifier_gate_challenges(log_circuit_size); for (size_t idx = 0; idx < log_circuit_size; idx++) { verifier_gate_challenges[idx] = - verifier_transcript->get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); + verifier_transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); } auto verifier_output = sumcheck_verifier.verify(instance->relation_parameters, verifier_alphas, verifier_gate_challenges); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp index 16118067408b..27acb7dd4327 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp @@ -91,7 +91,7 @@ template void UltraProver_::execute_wire_commitme */ template void UltraProver_::execute_sorted_list_accumulator_round() { - FF eta = transcript->get_challenge("eta"); + FF eta = transcript->template get_challenge("eta"); instance->compute_sorted_accumulator_polynomials(eta); @@ -112,7 +112,7 @@ template void UltraProver_::execute_sorted_list_a template void UltraProver_::execute_log_derivative_inverse_round() { // Compute and store challenges beta and gamma - auto [beta, gamma] = challenges_to_field_elements(transcript->get_challenges("beta", "gamma")); + auto [beta, gamma] = transcript->template get_challenges("beta", "gamma"); relation_parameters.beta = beta; relation_parameters.gamma = gamma; @@ -151,12 +151,12 @@ template void UltraProver_::execute_relation_chec auto sumcheck = Sumcheck(circuit_size, transcript); RelationSeparator alphas; for (size_t idx = 0; idx < alphas.size(); idx++) { - alphas[idx] = transcript->get_challenge("Sumcheck:alpha_" + std::to_string(idx)); + alphas[idx] = transcript->template get_challenge("Sumcheck:alpha_" + std::to_string(idx)); } instance->alphas = alphas; std::vector gate_challenges(numeric::get_msb(circuit_size)); for (size_t idx = 0; idx < gate_challenges.size(); idx++) { - gate_challenges[idx] = transcript->get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); + gate_challenges[idx] = transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); } instance->gate_challenges = gate_challenges; sumcheck_output = sumcheck.prove(instance); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_transcript.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_transcript.test.cpp index 609b455e22f8..fd6ccf7c1483 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_transcript.test.cpp @@ -187,7 +187,7 @@ TEST_F(UltraTranscriptTests, ChallengeGenerationTest) // initialized with random value sent to verifier auto transcript = Flavor::Transcript::prover_init_empty(); // test a bunch of challenges - auto challenges = transcript->get_challenges("a", "b", "c", "d", "e", "f"); + auto challenges = transcript->template get_challenges("a", "b", "c", "d", "e", "f"); // check they are not 0 for (size_t i = 0; i < challenges.size(); ++i) { ASSERT_NE(challenges[i], 0) << "Challenge " << i << " is 0"; @@ -195,7 +195,7 @@ TEST_F(UltraTranscriptTests, ChallengeGenerationTest) constexpr uint32_t random_val{ 17 }; // arbitrary transcript->send_to_verifier("random val", random_val); // test more challenges - auto [a, b, c] = challenges_to_field_elements(transcript->get_challenges("a", "b", "c")); + auto [a, b, c] = transcript->template get_challenges("a", "b", "c"); ASSERT_NE(a, 0) << "Challenge a is 0"; ASSERT_NE(b, 0) << "Challenge b is 0"; ASSERT_NE(c, 0) << "Challenge c is 0"; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp index 4ab7b6addf37..084e711ee715 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp @@ -97,7 +97,7 @@ template bool UltraVerifier_::verify_proof(const HonkP } // Get challenge for sorted list batching and wire four memory records - FF eta = transcript->get_challenge("eta"); + FF eta = transcript->template get_challenge("eta"); relation_parameters.eta = eta; // Get commitments to sorted list accumulator and fourth wire @@ -105,7 +105,7 @@ template bool UltraVerifier_::verify_proof(const HonkP commitments.w_4 = transcript->template receive_from_prover(commitment_labels.w_4); // Get permutation challenges - auto [beta, gamma] = challenges_to_field_elements(transcript->get_challenges("beta", "gamma")); + auto [beta, gamma] = transcript->template get_challenges("beta", "gamma"); // If Goblin (i.e. using DataBus) receive commitments to log-deriv inverses polynomial if constexpr (IsGoblinFlavor) { @@ -131,12 +131,12 @@ template bool UltraVerifier_::verify_proof(const HonkP auto sumcheck = SumcheckVerifier(log_circuit_size, transcript); RelationSeparator alphas; for (size_t idx = 0; idx < alphas.size(); idx++) { - alphas[idx] = transcript->get_challenge("Sumcheck:alpha_" + std::to_string(idx)); + alphas[idx] = transcript->template get_challenge("Sumcheck:alpha_" + std::to_string(idx)); } auto gate_challenges = std::vector(log_circuit_size); for (size_t idx = 0; idx < log_circuit_size; idx++) { - gate_challenges[idx] = transcript->get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); + gate_challenges[idx] = transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); } auto [multivariate_challenge, claimed_evaluations, sumcheck_verified] = sumcheck.verify(relation_parameters, alphas, gate_challenges); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_prover.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_prover.cpp index d79339a530bd..9e79beae75f8 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_prover.cpp @@ -73,12 +73,11 @@ void AvmMiniProver::execute_relation_check_rounds() using Sumcheck = SumcheckProver; auto sumcheck = Sumcheck(key->circuit_size, transcript); - - FF alpha = transcript->get_challenge("Sumcheck:alpha"); + FF alpha = transcript->template get_challenge("Sumcheck:alpha"); std::vector gate_challenges(numeric::get_msb(key->circuit_size)); for (size_t idx = 0; idx < gate_challenges.size(); idx++) { - gate_challenges[idx] = transcript->get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); + gate_challenges[idx] = transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); } sumcheck_output = sumcheck.prove(prover_polynomials, relation_parameters, alpha, gate_challenges); } diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_verifier.cpp index 8d093e0fee3b..e73881458ce2 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_verifier.cpp @@ -164,12 +164,10 @@ bool AvmMiniVerifier::verify_proof(const HonkProof& proof) // Execute Sumcheck Verifier const size_t log_circuit_size = numeric::get_msb(circuit_size); auto sumcheck = SumcheckVerifier(log_circuit_size, transcript); - - FF alpha = transcript->get_challenge("Sumcheck:alpha"); - + FF alpha = transcript->template get_challenge("Sumcheck:alpha"); auto gate_challenges = std::vector(log_circuit_size); for (size_t idx = 0; idx < log_circuit_size; idx++) { - gate_challenges[idx] = transcript->get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); + gate_challenges[idx] = transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); } auto [multivariate_challenge, claimed_evaluations, sumcheck_verified] = diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/Toy_prover.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/Toy_prover.cpp index dd76091689d3..525726c645a6 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/Toy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/Toy_prover.cpp @@ -70,10 +70,10 @@ void ToyProver::execute_relation_check_rounds() { using Sumcheck = SumcheckProver; auto sumcheck = Sumcheck(key->circuit_size, transcript); - FF alpha = transcript->get_challenge("Sumcheck:alpha"); + FF alpha = transcript->template get_challenge("Sumcheck:alpha"); std::vector gate_challenges(numeric::get_msb(key->circuit_size)); for (size_t idx = 0; idx < gate_challenges.size(); idx++) { - gate_challenges[idx] = transcript->get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); + gate_challenges[idx] = transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); } sumcheck_output = sumcheck.prove(prover_polynomials, relation_parameters, alpha, gate_challenges); } diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/Toy_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/Toy_verifier.cpp index b430c530234a..327822cfdd9d 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/Toy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/Toy_verifier.cpp @@ -82,10 +82,10 @@ bool ToyVerifier::verify_proof(const HonkProof& proof) // Execute Sumcheck Verifier const size_t log_circuit_size = numeric::get_msb(circuit_size); auto sumcheck = SumcheckVerifier(log_circuit_size, transcript); - FF alpha = transcript->get_challenge("Sumcheck:alpha"); + FF alpha = transcript->template get_challenge("Sumcheck:alpha"); auto gate_challenges = std::vector(log_circuit_size); for (size_t idx = 0; idx < log_circuit_size; idx++) { - gate_challenges[idx] = transcript->get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); + gate_challenges[idx] = transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); } auto [multivariate_challenge, claimed_evaluations, sumcheck_verified] = sumcheck.verify(relation_parameters, alpha, gate_challenges);