From 30ec33720e7374dd4ebbd4d938bdd1a04a204611 Mon Sep 17 00:00:00 2001 From: Cody Gunton Date: Mon, 8 Apr 2024 15:16:02 -0400 Subject: [PATCH] refactor: Get rid of ECCVM composer (#5562) Get rid of the ECCVM composer, following the model of https://github.com/AztecProtocol/aztec-packages/pull/5202 --------- Co-authored-by: ledwards2225 <98505400+ledwards2225@users.noreply.github.com> --- cpp/scripts/analyze_client_ivc_bench.py | 2 +- .../benchmark/goblin_bench/eccvm.bench.cpp | 10 +- .../commitment_schemes/verification_key.hpp | 8 +- cpp/src/barretenberg/eccvm/eccvm_composer.cpp | 133 ------------------ cpp/src/barretenberg/eccvm/eccvm_composer.hpp | 82 ----------- .../eccvm/eccvm_composer.test.cpp | 48 ++----- cpp/src/barretenberg/eccvm/eccvm_flavor.hpp | 39 ++++- cpp/src/barretenberg/eccvm/eccvm_prover.cpp | 47 ++++--- cpp/src/barretenberg/eccvm/eccvm_prover.hpp | 19 +-- .../eccvm/eccvm_transcript.test.cpp | 52 +++---- cpp/src/barretenberg/eccvm/eccvm_verifier.cpp | 42 +----- cpp/src/barretenberg/eccvm/eccvm_verifier.hpp | 38 ++--- cpp/src/barretenberg/flavor/flavor.hpp | 2 - cpp/src/barretenberg/goblin/goblin.hpp | 14 +- 14 files changed, 145 insertions(+), 391 deletions(-) delete mode 100644 cpp/src/barretenberg/eccvm/eccvm_composer.cpp delete mode 100644 cpp/src/barretenberg/eccvm/eccvm_composer.hpp diff --git a/cpp/scripts/analyze_client_ivc_bench.py b/cpp/scripts/analyze_client_ivc_bench.py index 7f83664a0..1c3cb5439 100644 --- a/cpp/scripts/analyze_client_ivc_bench.py +++ b/cpp/scripts/analyze_client_ivc_bench.py @@ -11,7 +11,7 @@ "ProverInstance(Circuit&)(t)", "ProtogalaxyProver::fold_instances(t)", "Decider::construct_proof(t)", - "ECCVMComposer::create_prover(t)", + "ECCVMProver(CircuitBuilder&)(t)", "ECCVMProver::construct_proof(t)", "GoblinTranslatorProver::construct_proof(t)", "Goblin::merge(t)" diff --git a/cpp/src/barretenberg/benchmark/goblin_bench/eccvm.bench.cpp b/cpp/src/barretenberg/benchmark/goblin_bench/eccvm.bench.cpp index 9a065ec69..afb8d33a4 100644 --- a/cpp/src/barretenberg/benchmark/goblin_bench/eccvm.bench.cpp +++ b/cpp/src/barretenberg/benchmark/goblin_bench/eccvm.bench.cpp @@ -1,14 +1,14 @@ #include #include "barretenberg/eccvm/eccvm_circuit_builder.hpp" -#include "barretenberg/eccvm/eccvm_composer.hpp" +#include "barretenberg/eccvm/eccvm_prover.hpp" +#include "barretenberg/eccvm/eccvm_verifier.hpp" using namespace benchmark; using namespace bb; using Flavor = ECCVMFlavor; using Builder = ECCVMCircuitBuilder; -using Composer = ECCVMComposer; namespace { @@ -49,8 +49,7 @@ void eccvm_generate_prover(State& state) noexcept size_t target_num_gates = 1 << static_cast(state.range(0)); for (auto _ : state) { Builder builder = generate_trace(target_num_gates); - Composer composer; - auto prover = composer.create_prover(builder); + ECCVMProver prover(builder); }; } @@ -60,8 +59,7 @@ void eccvm_prove(State& state) noexcept size_t target_num_gates = 1 << static_cast(state.range(0)); Builder builder = generate_trace(target_num_gates); - Composer composer; - auto prover = composer.create_prover(builder); + ECCVMProver prover(builder); for (auto _ : state) { auto proof = prover.construct_proof(); }; diff --git a/cpp/src/barretenberg/commitment_schemes/verification_key.hpp b/cpp/src/barretenberg/commitment_schemes/verification_key.hpp index d84914980..17511fe44 100644 --- a/cpp/src/barretenberg/commitment_schemes/verification_key.hpp +++ b/cpp/src/barretenberg/commitment_schemes/verification_key.hpp @@ -83,9 +83,15 @@ template <> class VerifierCommitmentKey { VerifierCommitmentKey(size_t num_points, const std::shared_ptr>& crs_factory) : pippenger_runtime_state(num_points) , srs(crs_factory->get_verifier_crs(num_points)) - {} + VerifierCommitmentKey(size_t num_points) + : pippenger_runtime_state(num_points) + { + srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); + srs = srs::get_crs_factory()->get_verifier_crs(num_points); + } + bb::scalar_multiplication::pippenger_runtime_state pippenger_runtime_state; std::shared_ptr> srs; }; diff --git a/cpp/src/barretenberg/eccvm/eccvm_composer.cpp b/cpp/src/barretenberg/eccvm/eccvm_composer.cpp deleted file mode 100644 index 91d554385..000000000 --- a/cpp/src/barretenberg/eccvm/eccvm_composer.cpp +++ /dev/null @@ -1,133 +0,0 @@ -#include "eccvm_composer.hpp" -#include "barretenberg/plonk_honk_shared/composer/composer_lib.hpp" -#include "barretenberg/plonk_honk_shared/composer/permutation_lib.hpp" - -namespace bb { - -/** - * @brief Compute witness polynomials - * - */ -template -void ECCVMComposer_::compute_witness([[maybe_unused]] CircuitConstructor& circuit_constructor) -{ - BB_OP_COUNT_TIME_NAME("ECCVMComposer::compute_witness"); - - if (computed_witness) { - return; - } - - ProverPolynomials polynomials(circuit_constructor); - - auto key_wires = proving_key->get_wires(); - auto poly_wires = polynomials.get_wires(); - - for (size_t i = 0; i < key_wires.size(); ++i) { - std::copy(poly_wires[i].begin(), poly_wires[i].end(), key_wires[i].begin()); - } - - computed_witness = true; -} - -template -ECCVMProver_ ECCVMComposer_::create_prover(CircuitConstructor& circuit_constructor, - const std::shared_ptr& transcript) -{ - BB_OP_COUNT_TIME_NAME("ECCVMComposer::create_prover"); - - compute_proving_key(circuit_constructor); - compute_witness(circuit_constructor); - compute_commitment_key(proving_key->circuit_size); - - ECCVMProver_ output_state(proving_key, commitment_key, transcript); - - return output_state; -} - -/** - * Create verifier: compute verification key, - * initialize verifier with it and an initial manifest and initialize commitment_scheme. - * - * @return The verifier. - * */ -template -ECCVMVerifier_ ECCVMComposer_::create_verifier(CircuitConstructor& circuit_constructor, - const std::shared_ptr& transcript) -{ - auto verification_key = compute_verification_key(circuit_constructor); - - ECCVMVerifier_ output_state(verification_key); - - auto pcs_verification_key = std::make_unique(verification_key->circuit_size, crs_factory_); - - output_state.pcs_verification_key = std::move(pcs_verification_key); - output_state.transcript = transcript; - - return output_state; -} - -template -std::shared_ptr ECCVMComposer_::compute_proving_key( - CircuitConstructor& circuit_constructor) -{ - BB_OP_COUNT_TIME_NAME("ECCVMComposer::create_proving_key"); - - if (proving_key) { - return proving_key; - } - - // Initialize proving_key - { - const size_t subgroup_size = circuit_constructor.get_circuit_subgroup_size(circuit_constructor.get_num_gates()); - proving_key = std::make_shared(subgroup_size, 0); - } - - // TODO(@zac-williamson): We don't enforce nonzero selectors atm. Will create problems in recursive setting. - // Fix once we have a stable base to work off of - // enforce_nonzero_polynomial_selectors(circuit_constructor, proving_key.get()); - - // First and last lagrange polynomials (in the full circuit size) - const auto [lagrange_first, lagrange_last] = - compute_first_and_last_lagrange_polynomials(proving_key->circuit_size); - proving_key->lagrange_first = lagrange_first; - proving_key->lagrange_last = lagrange_last; - { - const size_t n = proving_key->circuit_size; - typename Flavor::Polynomial lagrange_polynomial_second(n); - lagrange_polynomial_second[1] = 1; - proving_key->lagrange_second = lagrange_polynomial_second.share(); - } - - proving_key->contains_recursive_proof = false; - - return proving_key; -} - -/** - * Compute verification key consisting of selector precommitments. - * - * @return Pointer to created circuit verification key. - * */ -template -std::shared_ptr ECCVMComposer_::compute_verification_key( - CircuitConstructor& circuit_constructor) -{ - if (verification_key) { - return verification_key; - } - - if (!proving_key) { - compute_proving_key(circuit_constructor); - } - - verification_key = - std::make_shared(proving_key->circuit_size, proving_key->num_public_inputs); - - verification_key->lagrange_first = commitment_key->commit(proving_key->lagrange_first); - verification_key->lagrange_second = commitment_key->commit(proving_key->lagrange_second); - verification_key->lagrange_last = commitment_key->commit(proving_key->lagrange_last); - return verification_key; -} -template class ECCVMComposer_; - -} // namespace bb diff --git a/cpp/src/barretenberg/eccvm/eccvm_composer.hpp b/cpp/src/barretenberg/eccvm/eccvm_composer.hpp deleted file mode 100644 index 6915e2890..000000000 --- a/cpp/src/barretenberg/eccvm/eccvm_composer.hpp +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once - -#include "barretenberg/eccvm/eccvm_circuit_builder.hpp" -#include "barretenberg/eccvm/eccvm_prover.hpp" -#include "barretenberg/eccvm/eccvm_verifier.hpp" -#include "barretenberg/plonk_honk_shared/composer/composer_lib.hpp" -#include "barretenberg/srs/factories/file_crs_factory.hpp" -#include "barretenberg/srs/global_crs.hpp" - -namespace bb { -template class ECCVMComposer_ { - public: - using FF = typename Flavor::FF; - using CircuitConstructor = ECCVMCircuitBuilder; - using ProvingKey = typename Flavor::ProvingKey; - using VerificationKey = typename Flavor::VerificationKey; - using PCS = typename Flavor::PCS; - using CommitmentKey = typename Flavor::CommitmentKey; - using VerifierCommitmentKey = typename Flavor::VerifierCommitmentKey; - using ProverPolynomials = typename Flavor::ProverPolynomials; - using Transcript = typename Flavor::Transcript; - - static constexpr std::string_view NAME_STRING = "ECCVM"; - static constexpr size_t NUM_RESERVED_GATES = 0; // equal to the number of multilinear evaluations leaked - static constexpr size_t NUM_WIRES = Flavor::NUM_WIRES; - std::shared_ptr proving_key; - std::shared_ptr verification_key; - - // The crs_factory holds the path to the srs and exposes methods to extract the srs elements - std::shared_ptr> crs_factory_; - - // The commitment key is passed to the prover but also used herein to compute the verfication key commitments - std::shared_ptr commitment_key; - - std::vector recursive_proof_public_input_indices; - bool contains_recursive_proof = false; - bool computed_witness = false; - ECCVMComposer_() - requires(std::same_as) - { - crs_factory_ = bb::srs::get_grumpkin_crs_factory(); - }; - - explicit ECCVMComposer_(std::shared_ptr> crs_factory) - : crs_factory_(std::move(crs_factory)) - {} - - ECCVMComposer_(std::shared_ptr p_key, std::shared_ptr v_key) - : proving_key(std::move(p_key)) - , verification_key(std::move(v_key)) - {} - - ECCVMComposer_(ECCVMComposer_&& other) noexcept = default; - ECCVMComposer_(ECCVMComposer_ const& other) noexcept = default; - ECCVMComposer_& operator=(ECCVMComposer_&& other) noexcept = default; - ECCVMComposer_& operator=(ECCVMComposer_ const& other) noexcept = default; - ~ECCVMComposer_() = default; - - std::shared_ptr compute_proving_key(CircuitConstructor& circuit_constructor); - std::shared_ptr compute_verification_key(CircuitConstructor& circuit_constructor); - - void compute_witness(CircuitConstructor& circuit_constructor); - - ECCVMProver_ create_prover(CircuitConstructor& circuit_constructor, - const std::shared_ptr& transcript = std::make_shared()); - ECCVMVerifier_ create_verifier( - CircuitConstructor& circuit_constructor, - const std::shared_ptr& transcript = std::make_shared()); - - void add_table_column_selector_poly_to_proving_key(bb::polynomial& small, const std::string& tag); - - void compute_commitment_key(size_t circuit_size) - { - BB_OP_COUNT_TIME_NAME("ECCVMComposer::compute_commitment_key"); - commitment_key = std::make_shared(circuit_size); - }; -}; - -// TODO(#532): this pattern is weird; is this not instantiating the templates? -using ECCVMComposer = ECCVMComposer_; - -} // namespace bb diff --git a/cpp/src/barretenberg/eccvm/eccvm_composer.test.cpp b/cpp/src/barretenberg/eccvm/eccvm_composer.test.cpp index 17d3e66c7..37a6f02a8 100644 --- a/cpp/src/barretenberg/eccvm/eccvm_composer.test.cpp +++ b/cpp/src/barretenberg/eccvm/eccvm_composer.test.cpp @@ -4,7 +4,8 @@ #include #include "barretenberg/eccvm/eccvm_circuit_builder.hpp" -#include "barretenberg/eccvm/eccvm_composer.hpp" +#include "barretenberg/eccvm/eccvm_prover.hpp" +#include "barretenberg/eccvm/eccvm_verifier.hpp" #include "barretenberg/numeric/uint256/uint256.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_delta.hpp" #include "barretenberg/polynomials/polynomial.hpp" @@ -13,31 +14,20 @@ #include "barretenberg/sumcheck/sumcheck_round.hpp" using namespace bb; +using G1 = bb::g1; +using Fr = bb::fr; -template class ECCVMComposerTests : public ::testing::Test { +class ECCVMComposerTests : public ::testing::Test { protected: // TODO(640): The Standard Honk on Grumpkin test suite fails unless the SRS is initialized for every test. - void SetUp() override - { - if constexpr (std::is_same::value) { - srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); - } else { - srs::init_crs_factory("../srs_db/ignition"); - } - }; + void SetUp() override { srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); }; }; - -using FlavorTypes = ::testing::Types; -TYPED_TEST_SUITE(ECCVMComposerTests, FlavorTypes); - namespace { auto& engine = numeric::get_debug_randomness(); } -template ECCVMCircuitBuilder generate_circuit(numeric::RNG* engine = nullptr) +ECCVMCircuitBuilder generate_circuit(numeric::RNG* engine = nullptr) { std::shared_ptr op_queue = std::make_shared(); - using G1 = typename Flavor::CycleGroup; - using Fr = typename G1::Fr; auto generators = G1::derive_generators("test generators", 3); @@ -65,28 +55,21 @@ template ECCVMCircuitBuilder generate_circuit(numeric::RNG* en return builder; } -TYPED_TEST(ECCVMComposerTests, BaseCase) +TEST_F(ECCVMComposerTests, BaseCase) { - using Flavor = TypeParam; - - auto builder = generate_circuit(&engine); - - auto composer = ECCVMComposer_(); - auto prover = composer.create_prover(builder); - + ECCVMCircuitBuilder builder = generate_circuit(&engine); + ECCVMProver prover(builder); auto proof = prover.construct_proof(); - auto verifier = composer.create_verifier(builder); + ECCVMVerifier verifier(prover.key); bool verified = verifier.verify_proof(proof); ASSERT_TRUE(verified); } -TYPED_TEST(ECCVMComposerTests, EqFails) +TEST_F(ECCVMComposerTests, EqFails) { - using Flavor = TypeParam; - using G1 = typename Flavor::CycleGroup; using ECCVMOperation = eccvm::VMOperation; - auto builder = generate_circuit(&engine); + auto builder = generate_circuit(&engine); // Tamper with the eq op such that the expected value is incorect builder.op_queue->raw_ops.emplace_back(ECCVMOperation{ .add = false, .mul = false, @@ -97,11 +80,10 @@ TYPED_TEST(ECCVMComposerTests, EqFails) .z2 = 0, .mul_scalar_full = 0 }); builder.op_queue->num_transcript_rows++; - auto composer = ECCVMComposer_(); - auto prover = composer.create_prover(builder); + ECCVMProver prover(builder); auto proof = prover.construct_proof(); - auto verifier = composer.create_verifier(builder); + ECCVMVerifier verifier(prover.key); bool verified = verifier.verify_proof(proof); ASSERT_FALSE(verified); } diff --git a/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp b/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp index 7916f19c7..912d7e540 100644 --- a/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp +++ b/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp @@ -307,6 +307,21 @@ class ECCVMFlavor { using Base = ProvingKey_, WitnessEntities, CommitmentKey>; using Base::Base; + ProvingKey(const CircuitBuilder& builder) + : ProvingKey_, WitnessEntities, CommitmentKey>( + builder.get_circuit_subgroup_size(builder.get_num_gates()), 0) + { + const auto [_lagrange_first, _lagrange_last] = + compute_first_and_last_lagrange_polynomials(circuit_size); + lagrange_first = _lagrange_first; + lagrange_last = _lagrange_last; + { + Polynomial _lagrange_second(circuit_size); + _lagrange_second[1] = 1; + lagrange_second = _lagrange_second.share(); + } + } + auto get_to_be_shifted() { return ECCVMFlavor::get_to_be_shifted(*this); } // The plookup wires that store plookup read data. RefArray get_table_column_wires() { return {}; }; @@ -320,7 +335,29 @@ class ECCVMFlavor { * resolve that, and split out separate PrecomputedPolynomials/Commitments data for clarity but also for * portability of our circuits. */ - using VerificationKey = VerificationKey_, VerifierCommitmentKey>; + class VerificationKey : public VerificationKey_, VerifierCommitmentKey> { + public: + std::vector public_inputs; + + VerificationKey(const size_t circuit_size, const size_t num_public_inputs) + : VerificationKey_(circuit_size, num_public_inputs) + {} + + VerificationKey(const std::shared_ptr& proving_key) + : public_inputs(proving_key->public_inputs) + { + this->pcs_verification_key = std::make_shared(proving_key->circuit_size); + this->circuit_size = proving_key->circuit_size; + this->log_circuit_size = numeric::get_msb(this->circuit_size); + this->num_public_inputs = proving_key->num_public_inputs; + this->pub_inputs_offset = proving_key->pub_inputs_offset; + + for (auto [polynomial, commitment] : + zip_view(proving_key->get_precomputed_polynomials(), this->get_all())) { + commitment = proving_key->commitment_key->commit(polynomial); + } + } + }; /** * @brief A container for polynomials produced after the first round of sumcheck. diff --git a/cpp/src/barretenberg/eccvm/eccvm_prover.cpp b/cpp/src/barretenberg/eccvm/eccvm_prover.cpp index 6399bbff9..31832e225 100644 --- a/cpp/src/barretenberg/eccvm/eccvm_prover.cpp +++ b/cpp/src/barretenberg/eccvm/eccvm_prover.cpp @@ -13,22 +13,20 @@ namespace bb { /** - * Create ECCVMProver_ from proving key, witness and manifest. + * Create ECCVMProver from proving key, witness and manifest. * * @param input_key Proving key. * @param input_manifest Input manifest * * @tparam settings Settings class. * */ -template -ECCVMProver_::ECCVMProver_(const std::shared_ptr& input_key, - const std::shared_ptr& commitment_key, - const std::shared_ptr& transcript) +ECCVMProver::ECCVMProver(const std::shared_ptr& input_key, + const std::shared_ptr& commitment_key, + const std::shared_ptr& transcript) : transcript(transcript) , key(input_key) , commitment_key(commitment_key) -{ - // this will be initialized properly later +{ // this will be initialized properly later key->z_perm = Polynomial(key->circuit_size); for (auto [prover_poly, key_poly] : zip_view(prover_polynomials.get_unshifted(), key->get_all())) { ASSERT(flavor_get_label(prover_polynomials, prover_poly) == flavor_get_label(*key, key_poly)); @@ -40,11 +38,25 @@ ECCVMProver_::ECCVMProver_(const std::shared_ptr& transcript) +{ + BB_OP_COUNT_TIME_NAME("ECCVMProver(CircuitBuilder&)"); + // compute wire polynomials and copy into proving key + auto local_key = std::make_shared(builder); + ProverPolynomials polynomials(builder); // WORKTODO: inefficient + for (auto [prover_poly, key_poly] : zip_view(polynomials.get_wires(), local_key->get_wires())) { + ASSERT(flavor_get_label(prover_polynomials, prover_poly) == flavor_get_label(*key, key_poly)); + std::copy(prover_poly.begin(), prover_poly.end(), key_poly.begin()); + } + + *this = ECCVMProver(std::move(local_key), std::make_shared(local_key->circuit_size), transcript); +} + /** * @brief Add circuit size, public input size, and public inputs to transcript * */ -template void ECCVMProver_::execute_preamble_round() +void ECCVMProver::execute_preamble_round() { const auto circuit_size = static_cast(key->circuit_size); @@ -55,7 +67,7 @@ template void ECCVMProver_::execute_preamble_roun * @brief Compute commitments to the first three wires * */ -template void ECCVMProver_::execute_wire_commitments_round() +void ECCVMProver::execute_wire_commitments_round() { auto wire_polys = key->get_wires(); auto labels = commitment_labels.get_wires(); @@ -68,7 +80,7 @@ template void ECCVMProver_::execute_wire_commitme * @brief Compute sorted witness-table accumulator * */ -template void ECCVMProver_::execute_log_derivative_commitments_round() +void ECCVMProver::execute_log_derivative_commitments_round() { // Compute and add beta to relation parameters auto [beta, gamma] = transcript->template get_challenges("beta", "gamma"); @@ -93,7 +105,7 @@ template void ECCVMProver_::execute_log_derivativ * @brief Compute permutation and lookup grand product polynomials and commitments * */ -template void ECCVMProver_::execute_grand_product_computation_round() +void ECCVMProver::execute_grand_product_computation_round() { // Compute permutation grand product and their commitments compute_permutation_grand_products(key, prover_polynomials, relation_parameters); @@ -105,7 +117,7 @@ template void ECCVMProver_::execute_grand_product * @brief Run Sumcheck resulting in u = (u_1,...,u_d) challenges and all evaluations at u being calculated. * */ -template void ECCVMProver_::execute_relation_check_rounds() +void ECCVMProver::execute_relation_check_rounds() { using Sumcheck = SumcheckProver; @@ -123,7 +135,7 @@ template void ECCVMProver_::execute_relation_chec * @details See https://hackmd.io/dlf9xEwhTQyE3hiGbq4FsA?view for a complete description of the unrolled protocol. * * */ -template void ECCVMProver_::execute_zeromorph_rounds() +void ECCVMProver::execute_zeromorph_rounds() { ZeroMorph::prove(prover_polynomials.get_unshifted(), prover_polynomials.get_to_be_shifted(), @@ -140,7 +152,7 @@ template void ECCVMProver_::execute_zeromorph_rou * * @tparam Flavor */ -template void ECCVMProver_::execute_transcript_consistency_univariate_opening_round() +void ECCVMProver::execute_transcript_consistency_univariate_opening_round() { // Since IPA cannot currently handle polynomials for which the latter half of the coefficients are 0, we hackily // batch the constant polynomial 1 in with the 5 transcript polynomials. See issue #768 for more details. @@ -197,13 +209,13 @@ template void ECCVMProver_::execute_transcript_co translation_batching_challenge_v = transcript->template get_challenge("Translation:batching_challenge"); } -template HonkProof& ECCVMProver_::export_proof() +HonkProof& ECCVMProver::export_proof() { proof = transcript->export_proof(); return proof; } -template HonkProof& ECCVMProver_::construct_proof() +HonkProof& ECCVMProver::construct_proof() { BB_OP_COUNT_TIME_NAME("ECCVMProver::construct_proof"); @@ -223,7 +235,4 @@ template HonkProof& ECCVMProver_::construct_proof return export_proof(); } - -template class ECCVMProver_; - } // namespace bb diff --git a/cpp/src/barretenberg/eccvm/eccvm_prover.hpp b/cpp/src/barretenberg/eccvm/eccvm_prover.hpp index bf607c47e..3c5967ff2 100644 --- a/cpp/src/barretenberg/eccvm/eccvm_prover.hpp +++ b/cpp/src/barretenberg/eccvm/eccvm_prover.hpp @@ -11,24 +11,27 @@ namespace bb { // We won't compile this class with Standard, but we will like want to compile it (at least for testing) // with a flavor that uses the curve Grumpkin, or a flavor that does/does not have zk, etc. -template class ECCVMProver_ { - +class ECCVMProver { + using Flavor = ECCVMFlavor; using FF = typename Flavor::FF; using PCS = typename Flavor::PCS; - using PCSCommitmentKey = typename Flavor::CommitmentKey; + using CommitmentKey = typename Flavor::CommitmentKey; using ProvingKey = typename Flavor::ProvingKey; using Polynomial = typename Flavor::Polynomial; using ProverPolynomials = typename Flavor::ProverPolynomials; using CommitmentLabels = typename Flavor::CommitmentLabels; - using Curve = typename Flavor::Curve; using Transcript = typename Flavor::Transcript; using TranslationEvaluations = bb::TranslationEvaluations; using ZeroMorph = ZeroMorphProver_; + using CircuitBuilder = typename Flavor::CircuitBuilder; public: - explicit ECCVMProver_(const std::shared_ptr& input_key, - const std::shared_ptr& commitment_key, - const std::shared_ptr& transcript = std::make_shared()); + explicit ECCVMProver(const std::shared_ptr& input_key, + const std::shared_ptr& commitment_key, + const std::shared_ptr& transcript = std::make_shared()); + + explicit ECCVMProver(CircuitBuilder& builder, + const std::shared_ptr& transcript = std::make_shared()); BB_PROFILE void execute_preamble_round(); BB_PROFILE void execute_wire_commitments_round(); @@ -68,7 +71,7 @@ template class ECCVMProver_ { FF translation_batching_challenge_v; // to be rederived by the translator verifier SumcheckOutput sumcheck_output; - std::shared_ptr commitment_key; + std::shared_ptr commitment_key; private: HonkProof proof; diff --git a/cpp/src/barretenberg/eccvm/eccvm_transcript.test.cpp b/cpp/src/barretenberg/eccvm/eccvm_transcript.test.cpp index 1e91fa84a..f4cc50f7c 100644 --- a/cpp/src/barretenberg/eccvm/eccvm_transcript.test.cpp +++ b/cpp/src/barretenberg/eccvm/eccvm_transcript.test.cpp @@ -1,5 +1,6 @@ #include "barretenberg/ecc/curves/bn254/g1.hpp" -#include "barretenberg/eccvm/eccvm_composer.hpp" +#include "barretenberg/eccvm/eccvm_prover.hpp" +#include "barretenberg/eccvm/eccvm_verifier.hpp" #include "barretenberg/flavor/flavor.hpp" #include "barretenberg/numeric/bitop/get_msb.hpp" #include "barretenberg/polynomials/univariate.hpp" @@ -8,17 +9,11 @@ using namespace bb; -template class ECCVMTranscriptTests : public ::testing::Test { +class ECCVMTranscriptTests : public ::testing::Test { public: - void SetUp() override - { - if constexpr (std::is_same::value) { - srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); - } else { - srs::init_crs_factory("../srs_db/ignition"); - } - }; - using FF = typename Flavor::FF; + void SetUp() override { srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); }; + using FF = grumpkin::fr; + using Flavor = ECCVMFlavor; /** * @brief Construct a manifest for a ECCVM Honk proof @@ -238,23 +233,17 @@ template class ECCVMTranscriptTests : public ::testing::Test { numeric::RNG& engine = numeric::get_debug_randomness(); -using FlavorTypes = testing::Types; - -TYPED_TEST_SUITE(ECCVMTranscriptTests, FlavorTypes); /** * @brief Ensure consistency between the manifest hard coded in this testing suite and the one generated by the * standard honk prover over the course of proof construction. */ -TYPED_TEST(ECCVMTranscriptTests, ProverManifestConsistency) +TEST_F(ECCVMTranscriptTests, ProverManifestConsistency) { - using Flavor = TypeParam; - // Construct a simple circuit auto builder = this->generate_trace(&engine); // Automatically generate a transcript manifest by constructing a proof - auto composer = ECCVMComposer_(); - auto prover = composer.create_prover(builder); + ECCVMProver prover(builder); auto proof = prover.construct_proof(); // Check that the prover generated manifest agrees with the manifest hard coded in this suite @@ -272,20 +261,17 @@ TYPED_TEST(ECCVMTranscriptTests, ProverManifestConsistency) * construction and the one generated by the verifier over the course of proof verification. * */ -TYPED_TEST(ECCVMTranscriptTests, VerifierManifestConsistency) +TEST_F(ECCVMTranscriptTests, VerifierManifestConsistency) { - using Flavor = TypeParam; - // Construct a simple circuit auto builder = this->generate_trace(&engine); // Automatically generate a transcript manifest in the prover by constructing a proof - auto composer = ECCVMComposer_(); - auto prover = composer.create_prover(builder); + ECCVMProver prover(builder); auto proof = prover.construct_proof(); // Automatically generate a transcript manifest in the verifier by verifying a proof - auto verifier = composer.create_verifier(builder); + ECCVMVerifier verifier(prover.key); verifier.verify_proof(proof); // Check consistency between the manifests generated by the prover and verifier @@ -307,13 +293,12 @@ TYPED_TEST(ECCVMTranscriptTests, VerifierManifestConsistency) * @details We generate 6 challenges that are each 128 bits, and check that they are not 0. * */ -TYPED_TEST(ECCVMTranscriptTests, ChallengeGenerationTest) +TEST_F(ECCVMTranscriptTests, ChallengeGenerationTest) { - using Flavor = TypeParam; // initialized with random value sent to verifier auto transcript = Flavor::Transcript::prover_init_empty(); // test a bunch of challenges - auto challenges = transcript->template 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"; @@ -321,25 +306,22 @@ TYPED_TEST(ECCVMTranscriptTests, ChallengeGenerationTest) constexpr uint32_t random_val{ 17 }; // arbitrary transcript->send_to_verifier("random val", random_val); // test more challenges - auto [a, b, c] = transcript->template 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"; } -TYPED_TEST(ECCVMTranscriptTests, StructureTest) +TEST_F(ECCVMTranscriptTests, StructureTest) { - using Flavor = TypeParam; - // Construct a simple circuit auto builder = this->generate_trace(&engine); // Automatically generate a transcript manifest by constructing a proof - auto composer = ECCVMComposer_(); - auto prover = composer.create_prover(builder); + ECCVMProver prover(builder); auto proof = prover.construct_proof(); - auto verifier = composer.create_verifier(builder); + ECCVMVerifier verifier(prover.key); EXPECT_TRUE(verifier.verify_proof(proof)); // try deserializing and serializing with no changes and check proof is still valid diff --git a/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp b/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp index 8db713a10..aa3cb7f19 100644 --- a/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp +++ b/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp @@ -1,48 +1,18 @@ #include "./eccvm_verifier.hpp" #include "barretenberg/commitment_schemes/zeromorph/zeromorph.hpp" -#include "barretenberg/numeric/bitop/get_msb.hpp" -#include "barretenberg/transcript/transcript.hpp" +#include "barretenberg/sumcheck/sumcheck.hpp" namespace bb { -template -ECCVMVerifier_::ECCVMVerifier_(const std::shared_ptr& verifier_key) - : key(verifier_key) -{} - -template -ECCVMVerifier_::ECCVMVerifier_(ECCVMVerifier_&& other) noexcept - : key(std::move(other.key)) - , pcs_verification_key(std::move(other.pcs_verification_key)) -{} - -template ECCVMVerifier_& ECCVMVerifier_::operator=(ECCVMVerifier_&& other) noexcept -{ - key = other.key; - pcs_verification_key = (std::move(other.pcs_verification_key)); - commitments.clear(); - pcs_fr_elements.clear(); - return *this; -} /** * @brief This function verifies an ECCVM Honk proof for given program settings. - * */ -template bool ECCVMVerifier_::verify_proof(const HonkProof& proof) +bool ECCVMVerifier::verify_proof(const HonkProof& proof) { - using FF = typename Flavor::FF; - using Commitment = typename Flavor::Commitment; - using PCS = typename Flavor::PCS; using ZeroMorph = ZeroMorphVerifier_; - using VerifierCommitments = typename Flavor::VerifierCommitments; - using CommitmentLabels = typename Flavor::CommitmentLabels; - using Transcript = typename Flavor::Transcript; - using Curve = typename Flavor::Curve; RelationParameters relation_parameters; - transcript = std::make_shared(proof); - VerifierCommitments commitments{ key }; CommitmentLabels commitment_labels; @@ -171,7 +141,7 @@ template bool ECCVMVerifier_::verify_proof(const HonkP claimed_evaluations.get_unshifted(), claimed_evaluations.get_shifted(), multivariate_challenge, - pcs_verification_key, + key->pcs_verification_key, transcript); // Execute transcript consistency univariate opening round // TODO(#768): Find a better way to do this. See issue for details. @@ -212,12 +182,10 @@ template bool ECCVMVerifier_::verify_proof(const HonkP // Construct and verify batched opening claim OpeningClaim batched_univariate_claim = { { evaluation_challenge_x, batched_transcript_eval }, batched_commitment }; - univariate_opening_verified = PCS::reduce_verify(pcs_verification_key, batched_univariate_claim, transcript); + univariate_opening_verified = + PCS::reduce_verify(key->pcs_verification_key, batched_univariate_claim, transcript); } return sumcheck_verified.value() && multivariate_opening_verified && univariate_opening_verified; } - -template class ECCVMVerifier_; - } // namespace bb diff --git a/cpp/src/barretenberg/eccvm/eccvm_verifier.hpp b/cpp/src/barretenberg/eccvm/eccvm_verifier.hpp index c62d1b876..5ef29beff 100644 --- a/cpp/src/barretenberg/eccvm/eccvm_verifier.hpp +++ b/cpp/src/barretenberg/eccvm/eccvm_verifier.hpp @@ -1,44 +1,32 @@ #pragma once #include "barretenberg/eccvm/eccvm_flavor.hpp" -#include "barretenberg/honk/proof_system/types/proof.hpp" -#include "barretenberg/sumcheck/sumcheck.hpp" namespace bb { -template class ECCVMVerifier_ { +class ECCVMVerifier { + using Flavor = ECCVMFlavor; using FF = typename Flavor::FF; + using Curve = typename Flavor::Curve; using Commitment = typename Flavor::Commitment; + using CommitmentLabels = typename Flavor::CommitmentLabels; + using Transcript = typename Flavor::Transcript; + using ProvingKey = typename Flavor::ProvingKey; using VerificationKey = typename Flavor::VerificationKey; + using VerifierCommitments = typename Flavor::VerifierCommitments; using VerifierCommitmentKey = typename Flavor::VerifierCommitmentKey; - using Transcript = typename Flavor::Transcript; + using PCS = typename Flavor::PCS; public: - explicit ECCVMVerifier_(const std::shared_ptr& verifier_key = nullptr); - ECCVMVerifier_(const std::shared_ptr& key, - std::map commitments, - std::map pcs_fr_elements, - const std::shared_ptr& pcs_verification_key, - const std::shared_ptr& transcript) - : key(std::move(key)) - , commitments(std::move(commitments)) - , pcs_fr_elements(std::move(pcs_fr_elements)) - , pcs_verification_key(std::move(pcs_verification_key)) - , transcript(std::move(transcript)) - {} - ECCVMVerifier_(ECCVMVerifier_&& other) noexcept; - ECCVMVerifier_(const ECCVMVerifier_& other) = delete; - ECCVMVerifier_& operator=(const ECCVMVerifier_& other) = delete; - ECCVMVerifier_& operator=(ECCVMVerifier_&& other) noexcept; - ~ECCVMVerifier_() = default; + explicit ECCVMVerifier(const std::shared_ptr& verifier_key) + : key(verifier_key){}; + + explicit ECCVMVerifier(const std::shared_ptr& proving_key) + : ECCVMVerifier(std::make_shared(proving_key)){}; bool verify_proof(const HonkProof& proof); std::shared_ptr key; std::map commitments; std::map pcs_fr_elements; - std::shared_ptr pcs_verification_key; std::shared_ptr transcript; }; - -using ECCVMVerifierGrumpkin = ECCVMVerifier_; - } // namespace bb diff --git a/cpp/src/barretenberg/flavor/flavor.hpp b/cpp/src/barretenberg/flavor/flavor.hpp index 7f15cc14f..d2a847a0d 100644 --- a/cpp/src/barretenberg/flavor/flavor.hpp +++ b/cpp/src/barretenberg/flavor/flavor.hpp @@ -335,8 +335,6 @@ template concept IsFoldingFlavor = IsAnyOf, GoblinUltraRecursiveFlavor_>; -template concept IsECCVMFlavor = IsAnyOf; - template inline std::string flavor_get_label(Container&& container, const Element& element) { for (auto [label, data] : zip_view(container.get_labels(), container.get_all())) { diff --git a/cpp/src/barretenberg/goblin/goblin.hpp b/cpp/src/barretenberg/goblin/goblin.hpp index 71f7c9c05..f8b6adc61 100644 --- a/cpp/src/barretenberg/goblin/goblin.hpp +++ b/cpp/src/barretenberg/goblin/goblin.hpp @@ -1,7 +1,8 @@ #pragma once #include "barretenberg/eccvm/eccvm_circuit_builder.hpp" -#include "barretenberg/eccvm/eccvm_composer.hpp" +#include "barretenberg/eccvm/eccvm_prover.hpp" +#include "barretenberg/eccvm/eccvm_verifier.hpp" #include "barretenberg/goblin/mock_circuits.hpp" #include "barretenberg/plonk_honk_shared/instance_inspector.hpp" #include "barretenberg/stdlib/honk_recursion/verifier/merge_recursive_verifier.hpp" @@ -30,8 +31,7 @@ class Goblin { using OpQueue = bb::ECCOpQueue; using ECCVMFlavor = bb::ECCVMFlavor; using ECCVMBuilder = bb::ECCVMCircuitBuilder; - using ECCVMComposer = bb::ECCVMComposer; - using ECCVMProver = bb::ECCVMProver_; + using ECCVMProver = bb::ECCVMProver; using TranslatorBuilder = bb::GoblinTranslatorCircuitBuilder; using TranslatorProver = bb::GoblinTranslatorProver; using RecursiveMergeVerifier = bb::stdlib::recursion::goblin::MergeRecursiveVerifier_; @@ -84,7 +84,6 @@ class Goblin { std::unique_ptr eccvm_builder; std::unique_ptr translator_builder; std::unique_ptr translator_prover; - std::unique_ptr eccvm_composer; std::unique_ptr eccvm_prover; AccumulationOutput accumulator; // Used only for ACIR methods for now @@ -160,8 +159,7 @@ class Goblin { void prove_eccvm() { eccvm_builder = std::make_unique(op_queue); - eccvm_composer = std::make_unique(); - eccvm_prover = std::make_unique(eccvm_composer->create_prover(*eccvm_builder)); + eccvm_prover = std::make_unique(*eccvm_builder); goblin_proof.eccvm_proof = eccvm_prover->construct_proof(); goblin_proof.translation_evaluations = eccvm_prover->translation_evaluations; }; @@ -205,7 +203,7 @@ class Goblin { MergeVerifier merge_verifier; bool merge_verified = merge_verifier.verify_proof(proof.merge_proof); - auto eccvm_verifier = eccvm_composer->create_verifier(*eccvm_builder); + ECCVMVerifier eccvm_verifier(eccvm_prover->key); bool eccvm_verified = eccvm_verifier.verify_proof(proof.eccvm_proof); GoblinTranslatorVerifier translator_verifier(translator_prover->key, eccvm_verifier.transcript); @@ -292,7 +290,7 @@ class Goblin { // MergeVerifier merge_verifier; // bool merge_verified = merge_verifier.verify_proof(goblin_proof.merge_proof); - auto eccvm_verifier = eccvm_composer->create_verifier(*eccvm_builder); + ECCVMVerifier eccvm_verifier(eccvm_prover->key); bool eccvm_verified = eccvm_verifier.verify_proof(goblin_proof.eccvm_proof); GoblinTranslatorVerifier translator_verifier(translator_prover->key, eccvm_verifier.transcript);