From 1fe63b2cf5b83fef576bb99294700743929d5ec7 Mon Sep 17 00:00:00 2001 From: ludamad Date: Thu, 4 Jan 2024 15:10:26 -0500 Subject: [PATCH] feat: goblin and eccvm bench (#3606) Benchmark ECCVM and Goblin. --------- Co-authored-by: ludamad Co-authored-by: codygunton Co-authored-by: ledwards2225 --- barretenberg/cpp/CMakePresets.json | 5 + .../benchmark/honk_bench/CMakeLists.txt | 4 + .../benchmark/honk_bench/eccvm.bench.cpp | 73 ++++++++++ .../benchmark/honk_bench/goblin.bench.cpp | 137 ++++++++++++++++++ .../dsl/acir_proofs/acir_composer.cpp | 3 +- .../src/barretenberg/eccvm/eccvm_prover.hpp | 22 +-- .../cpp/src/barretenberg/flavor/flavor.hpp | 8 +- .../flavor/goblin_ultra_recursive.hpp | 14 +- .../goblin/full_goblin_recursion.test.cpp | 44 +----- .../cpp/src/barretenberg/goblin/goblin.hpp | 32 ++-- .../src/barretenberg/goblin/mock_circuits.hpp | 31 +++- barretenberg/cpp/src/barretenberg/srs/io.hpp | 3 +- .../honk/verifier/goblin_verifier.test.cpp | 4 +- .../honk/verifier/merge_verifier.test.cpp | 2 +- .../verifier/ultra_recursive_verifier.cpp | 4 +- .../verifier/ultra_recursive_verifier.hpp | 7 +- .../goblin_translator_prover.hpp | 10 +- .../barretenberg/ultra_honk/merge_prover.hpp | 2 +- .../ultra_honk/ultra_verifier.hpp | 1 + 19 files changed, 309 insertions(+), 97 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/benchmark/honk_bench/eccvm.bench.cpp create mode 100644 barretenberg/cpp/src/barretenberg/benchmark/honk_bench/goblin.bench.cpp diff --git a/barretenberg/cpp/CMakePresets.json b/barretenberg/cpp/CMakePresets.json index b87e10709b6..c458e9eee87 100644 --- a/barretenberg/cpp/CMakePresets.json +++ b/barretenberg/cpp/CMakePresets.json @@ -369,6 +369,11 @@ "jobs": 0, "targets": ["barretenberg.wasm"] }, + { + "name": "xray", + "configurePreset": "xray", + "inherits": "default" + }, { "name": "xray-verbose", "configurePreset": "xray-verbose", diff --git a/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/CMakeLists.txt index 1de8756be42..8984bc7b0ff 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/CMakeLists.txt +++ b/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/CMakeLists.txt @@ -1,6 +1,8 @@ # Each source represents a separate benchmark suite set(BENCHMARK_SOURCES standard_plonk.bench.cpp + goblin.bench.cpp + eccvm.bench.cpp ultra_honk.bench.cpp ultra_honk_rounds.bench.cpp ultra_plonk.bench.cpp @@ -10,9 +12,11 @@ set(BENCHMARK_SOURCES # Required libraries for benchmark suites set(LINKED_LIBRARIES ultra_honk + eccvm stdlib_sha256 stdlib_keccak stdlib_merkle_tree + stdlib_recursion benchmark::benchmark ) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/eccvm.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/eccvm.bench.cpp new file mode 100644 index 00000000000..d27bd0d06b4 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/eccvm.bench.cpp @@ -0,0 +1,73 @@ +#include + +#include "barretenberg/benchmark/honk_bench/benchmark_utilities.hpp" +#include "barretenberg/eccvm/eccvm_composer.hpp" +#include "barretenberg/proof_system/circuit_builder/eccvm/eccvm_circuit_builder.hpp" + +using namespace benchmark; +using namespace proof_system; + +using Flavor = honk::flavor::ECCVM; +using Builder = ECCVMCircuitBuilder; +using Composer = honk::ECCVMComposer; + +namespace { + +Builder generate_trace(size_t target_num_gates) +{ + Builder builder; + using G1 = typename Flavor::CycleGroup; + using Fr = typename G1::Fr; + + auto generators = G1::derive_generators("test generators", 2); + + typename G1::element a = generators[0]; + typename G1::element b = generators[1]; + Fr x = Fr::random_element(); + Fr y = Fr::random_element(); + + typename G1::element expected_1 = (a * x) + a + a + (b * y) + (b * x) + (b * x); + + // Each loop adds 163 gates. Note: builder.get_num_gates() is very expensive here (bug?) and it's actually painful + // to use a `while` loop + size_t num_iterations = target_num_gates / 163; + for (size_t _ = 0; _ < num_iterations; _++) { + builder.add_accumulate(a); + builder.mul_accumulate(a, x); + builder.mul_accumulate(b, x); + builder.mul_accumulate(b, y); + builder.add_accumulate(a); + builder.mul_accumulate(b, x); + builder.eq_and_reset(expected_1); + } + return builder; +} + +void eccvm_generate_prover(State& state) noexcept +{ + barretenberg::srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); + + 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); + }; +} + +void eccvm_prove(State& state) noexcept +{ + barretenberg::srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); + + 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); + for (auto _ : state) { + auto proof = prover.construct_proof(); + }; +} + +BENCHMARK(eccvm_generate_prover)->Unit(kMillisecond)->DenseRange(10, 20); +BENCHMARK(eccvm_prove)->Unit(kMillisecond)->DenseRange(10, 20); +} // namespace \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/goblin.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/goblin.bench.cpp new file mode 100644 index 00000000000..366f2ab6a24 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/goblin.bench.cpp @@ -0,0 +1,137 @@ + +#include + +#include "barretenberg/benchmark/honk_bench/benchmark_utilities.hpp" +#include "barretenberg/goblin/goblin.hpp" +#include "barretenberg/goblin/mock_circuits.hpp" +#include "barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp" +#include "barretenberg/ultra_honk/ultra_composer.hpp" + +using namespace benchmark; +using namespace barretenberg; +using namespace proof_system; + +namespace { +void goblin_full(State& state) noexcept +{ + barretenberg::srs::init_crs_factory("../srs_db/ignition"); + barretenberg::srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); + + Goblin goblin; + + // Construct an initial circuit; its proof will be recursively verified by the first kernel + GoblinUltraCircuitBuilder initial_circuit{ goblin.op_queue }; + GoblinMockCircuits::construct_simple_initial_circuit(initial_circuit); + Goblin::AccumulationOutput kernel_input = goblin.accumulate(initial_circuit); + + Goblin::Proof proof; + for (auto _ : state) { + // Construct a series of simple Goblin circuits; generate and verify their proofs + size_t NUM_CIRCUITS = 1 << static_cast(state.range(0)); + for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { + // Construct a circuit with logic resembling that of the "kernel circuit" + GoblinUltraCircuitBuilder circuit_builder{ goblin.op_queue }; + GoblinMockCircuits::construct_mock_kernel_circuit(circuit_builder, kernel_input); + + // Construct proof of the current kernel circuit to be recursively verified by the next one + kernel_input = goblin.accumulate(circuit_builder); + } + + proof = goblin.prove(); + // Verify the final ultra proof + } + honk::GoblinUltraVerifier ultra_verifier{ kernel_input.verification_key }; + ultra_verifier.verify_proof(kernel_input.proof); + // Verify the goblin proof (eccvm, translator, merge) + goblin.verify(proof); +} + +void goblin_accumulate(State& state) noexcept +{ + barretenberg::srs::init_crs_factory("../srs_db/ignition"); + barretenberg::srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); + + Goblin goblin; + + // Construct an initial circuit; its proof will be recursively verified by the first kernel + GoblinUltraCircuitBuilder initial_circuit{ goblin.op_queue }; + GoblinMockCircuits::construct_simple_initial_circuit(initial_circuit); + Goblin::AccumulationOutput kernel_input = goblin.accumulate(initial_circuit); + + // Construct a series of simple Goblin circuits; generate and verify their proofs + size_t NUM_CIRCUITS = 1 << static_cast(state.range(0)); + for (auto _ : state) { + for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { + // Construct a circuit with logic resembling that of the "kernel circuit" + GoblinUltraCircuitBuilder circuit_builder{ goblin.op_queue }; + GoblinMockCircuits::construct_mock_kernel_circuit(circuit_builder, kernel_input); + + // Construct proof of the current kernel circuit to be recursively verified by the next one + kernel_input = goblin.accumulate(circuit_builder); + } + } +} + +void goblin_eccvm_prove(State& state) noexcept +{ + barretenberg::srs::init_crs_factory("../srs_db/ignition"); + barretenberg::srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); + + Goblin goblin; + + // Construct an initial circuit; its proof will be recursively verified by the first kernel + GoblinUltraCircuitBuilder initial_circuit{ goblin.op_queue }; + GoblinMockCircuits::construct_simple_initial_circuit(initial_circuit); + Goblin::AccumulationOutput kernel_input = goblin.accumulate(initial_circuit); + + // Construct a series of simple Goblin circuits; generate and verify their proofs + size_t NUM_CIRCUITS = 1 << static_cast(state.range(0)); + for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { + // Construct a circuit with logic resembling that of the "kernel circuit" + GoblinUltraCircuitBuilder circuit_builder{ goblin.op_queue }; + GoblinMockCircuits::construct_mock_kernel_circuit(circuit_builder, kernel_input); + + // Construct proof of the current kernel circuit to be recursively verified by the next one + kernel_input = goblin.accumulate(circuit_builder); + } + + for (auto _ : state) { + goblin.prove_eccvm(); + } +} + +void goblin_translator_prove(State& state) noexcept +{ + barretenberg::srs::init_crs_factory("../srs_db/ignition"); + barretenberg::srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); + + Goblin goblin; + + // Construct an initial circuit; its proof will be recursively verified by the first kernel + GoblinUltraCircuitBuilder initial_circuit{ goblin.op_queue }; + GoblinMockCircuits::construct_simple_initial_circuit(initial_circuit); + Goblin::AccumulationOutput kernel_input = goblin.accumulate(initial_circuit); + + // Construct a series of simple Goblin circuits; generate and verify their proofs + size_t NUM_CIRCUITS = 1 << static_cast(state.range(0)); + for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { + // Construct a circuit with logic resembling that of the "kernel circuit" + GoblinUltraCircuitBuilder circuit_builder{ goblin.op_queue }; + GoblinMockCircuits::construct_mock_kernel_circuit(circuit_builder, kernel_input); + + // Construct proof of the current kernel circuit to be recursively verified by the next one + kernel_input = goblin.accumulate(circuit_builder); + } + + goblin.prove_eccvm(); + for (auto _ : state) { + goblin.prove_translator(); + } +} + +} // namespace + +BENCHMARK(goblin_full)->Unit(kMillisecond)->DenseRange(0, 7); +BENCHMARK(goblin_accumulate)->Unit(kMillisecond)->DenseRange(0, 7); +BENCHMARK(goblin_eccvm_prove)->Unit(kMillisecond)->DenseRange(0, 7); +BENCHMARK(goblin_translator_prove)->Unit(kMillisecond)->DenseRange(0, 7); \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp index f8098dc4c44..f23cb2a77a8 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp @@ -4,6 +4,7 @@ #include "barretenberg/dsl/acir_format/acir_format.hpp" #include "barretenberg/dsl/acir_format/recursion_constraint.hpp" #include "barretenberg/dsl/types.hpp" +#include "barretenberg/goblin/mock_circuits.hpp" #include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp" #include "barretenberg/plonk/proof_system/proving_key/serialize.hpp" #include "barretenberg/plonk/proof_system/verification_key/sol_gen.hpp" @@ -101,7 +102,7 @@ void AcirComposer::create_goblin_circuit(acir_format::acir_format& constraint_sy // TODO(https://github.com/AztecProtocol/barretenberg/issues/817): Add some arbitrary op gates to ensure the // associated polynomials are non-zero and to give ECCVM and Translator some ECC ops to process. - GoblinTestingUtils::construct_goblin_ecc_op_circuit(goblin_builder_); + GoblinMockCircuits::construct_goblin_ecc_op_circuit(goblin_builder_); } std::vector AcirComposer::create_goblin_proof() diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.hpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.hpp index af6f4ec457f..cc278c72daa 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.hpp @@ -30,17 +30,17 @@ template class ECCVMProver_ { const std::shared_ptr& commitment_key, const std::shared_ptr& transcript = std::make_shared()); - void execute_preamble_round(); - void execute_wire_commitments_round(); - void execute_log_derivative_commitments_round(); - void execute_grand_product_computation_round(); - void execute_relation_check_rounds(); - void execute_univariatization_round(); - void execute_pcs_evaluation_round(); - void execute_shplonk_batched_quotient_round(); - void execute_shplonk_partial_evaluation_round(); - void execute_final_pcs_round(); - void execute_transcript_consistency_univariate_opening_round(); + BBERG_PROFILE void execute_preamble_round(); + BBERG_PROFILE void execute_wire_commitments_round(); + BBERG_PROFILE void execute_log_derivative_commitments_round(); + BBERG_PROFILE void execute_grand_product_computation_round(); + BBERG_PROFILE void execute_relation_check_rounds(); + BBERG_PROFILE void execute_univariatization_round(); + BBERG_PROFILE void execute_pcs_evaluation_round(); + BBERG_PROFILE void execute_shplonk_batched_quotient_round(); + BBERG_PROFILE void execute_shplonk_partial_evaluation_round(); + BBERG_PROFILE void execute_final_pcs_round(); + BBERG_PROFILE void execute_transcript_consistency_univariate_opening_round(); plonk::proof& export_proof(); plonk::proof& construct_proof(); diff --git a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp index 959580c53c9..187f8fcec63 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp @@ -263,7 +263,7 @@ class Ultra; class ECCVM; class GoblinUltra; template class UltraRecursive_; -template class GoblinUltraRecursive_; +class GoblinUltraRecursive; } // namespace proof_system::honk::flavor // Forward declare plonk flavors @@ -293,14 +293,12 @@ concept IsUltraFlavor = IsAnyOf concept IsGoblinFlavor = IsAnyOf, - honk::flavor::GoblinUltraRecursive_>; + honk::flavor::GoblinUltraRecursive>; template concept IsRecursiveFlavor = IsAnyOf, honk::flavor::UltraRecursive_, - honk::flavor::GoblinUltraRecursive_, - honk::flavor::GoblinUltraRecursive_>; + honk::flavor::GoblinUltraRecursive>; template concept IsGrumpkinFlavor = IsAnyOf; diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp index fb6e0751361..f1c6f9aaa90 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp @@ -38,14 +38,14 @@ namespace proof_system::honk::flavor { * * @tparam BuilderType Determines the arithmetization of the verifier circuit defined based on this flavor. */ -template class GoblinUltraRecursive_ { +class GoblinUltraRecursive { public: - using CircuitBuilder = BuilderType; // Determines arithmetization of circuit instantiated with this flavor + using CircuitBuilder = GoblinUltraCircuitBuilder; using Curve = plonk::stdlib::bn254; - using GroupElement = typename Curve::Element; - using Commitment = typename Curve::Element; - using CommitmentHandle = typename Curve::Element; - using FF = typename Curve::ScalarField; + using GroupElement = Curve::Element; + using FF = Curve::ScalarField; + using Commitment = Curve::Element; + using CommitmentHandle = Curve::Element; using NativeVerificationKey = flavor::GoblinUltra::VerificationKey; // Note(luke): Eventually this may not be needed at all @@ -78,7 +78,6 @@ template class GoblinUltraRecursive_ { using SumcheckTupleOfTuplesOfUnivariates = decltype(create_sumcheck_tuple_of_tuples_of_univariates()); using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values()); - public: /** * @brief A field element for each entity of the flavor. These entities represent the prover polynomials evaluated * at one point. @@ -87,7 +86,6 @@ template class GoblinUltraRecursive_ { public: using Base = GoblinUltra::AllEntities; using Base::Base; - AllValues(std::array _data_in) { this->_data = _data_in; } }; /** * @brief The verification key is responsible for storing the the commitments to the precomputed (non-witnessk) diff --git a/barretenberg/cpp/src/barretenberg/goblin/full_goblin_recursion.test.cpp b/barretenberg/cpp/src/barretenberg/goblin/full_goblin_recursion.test.cpp index 2adc5049600..cf5cb15c4f6 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/full_goblin_recursion.test.cpp +++ b/barretenberg/cpp/src/barretenberg/goblin/full_goblin_recursion.test.cpp @@ -25,45 +25,10 @@ class GoblinRecursionTests : public ::testing::Test { using Curve = curve::BN254; using FF = Curve::ScalarField; using GoblinUltraBuilder = proof_system::GoblinUltraCircuitBuilder; - using ECCVMFlavor = flavor::ECCVM; - using ECCVMBuilder = proof_system::ECCVMCircuitBuilder; - using ECCVMComposer = ECCVMComposer_; - using TranslatorFlavor = flavor::GoblinTranslator; - using TranslatorBuilder = proof_system::GoblinTranslatorCircuitBuilder; - using TranslatorComposer = GoblinTranslatorComposer; - using TranslatorConsistencyData = barretenberg::TranslationEvaluations; - using RecursiveFlavor = flavor::GoblinUltraRecursive_; - using RecursiveVerifier = proof_system::plonk::stdlib::recursion::honk::UltraRecursiveVerifier_; - using Goblin = barretenberg::Goblin; using KernelInput = Goblin::AccumulationOutput; - using UltraVerifier = UltraVerifier_; - - /** - * @brief Construct a mock kernel circuit - * @details This circuit contains (1) some basic/arbitrary arithmetic gates, (2) a genuine recursive verification of - * the proof provided as input. It does not contain any other real kernel logic. - * - * @param builder - * @param kernel_input A proof to be recursively verified and the corresponding native verification key - */ - static void construct_mock_kernel_circuit(GoblinUltraBuilder& builder, KernelInput& kernel_input) - { - // Generic operations e.g. state updates (just arith gates for now) - GoblinTestingUtils::construct_arithmetic_circuit(builder); - - // Execute recursive aggregation of previous kernel proof - RecursiveVerifier verifier{ &builder, kernel_input.verification_key }; - // TODO(https://github.com/AztecProtocol/barretenberg/issues/801): Aggregation - auto pairing_points = verifier.verify_proof(kernel_input.proof); // previous kernel proof - // TODO(https://github.com/AztecProtocol/barretenberg/issues/803): Mock app circuit. In the absence of a mocked - // app circuit proof, we simply perform another recursive verification for the previous kernel proof to - // approximate the work done for the app proof. - pairing_points = verifier.verify_proof(kernel_input.proof); - } }; -/** - * @brief A full Goblin test that mimicks the basic aztec client architecture +/** * @brief A full Goblin test that mimicks the basic aztec client architecture * */ TEST_F(GoblinRecursionTests, Pseudo) @@ -72,8 +37,7 @@ TEST_F(GoblinRecursionTests, Pseudo) // Construct an initial circuit; its proof will be recursively verified by the first kernel GoblinUltraBuilder initial_circuit{ goblin.op_queue }; - GoblinTestingUtils::construct_simple_initial_circuit(initial_circuit); - + GoblinMockCircuits::construct_simple_initial_circuit(initial_circuit); KernelInput kernel_input = goblin.accumulate(initial_circuit); // Construct a series of simple Goblin circuits; generate and verify their proofs @@ -81,7 +45,7 @@ TEST_F(GoblinRecursionTests, Pseudo) for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { // Construct a circuit with logic resembling that of the "kernel circuit" GoblinUltraBuilder circuit_builder{ goblin.op_queue }; - construct_mock_kernel_circuit(circuit_builder, kernel_input); + GoblinMockCircuits::construct_mock_kernel_circuit(circuit_builder, kernel_input); // Construct proof of the current kernel circuit to be recursively verified by the next one kernel_input = goblin.accumulate(circuit_builder); @@ -89,7 +53,7 @@ TEST_F(GoblinRecursionTests, Pseudo) Goblin::Proof proof = goblin.prove(); // Verify the final ultra proof - UltraVerifier ultra_verifier{ kernel_input.verification_key }; + GoblinUltraVerifier ultra_verifier{ kernel_input.verification_key }; bool ultra_verified = ultra_verifier.verify_proof(kernel_input.proof); // Verify the goblin proof (eccvm, translator, merge) bool verified = goblin.verify(proof); diff --git a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp index 0586364faf7..164b29e0600 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp @@ -1,7 +1,6 @@ #pragma once #include "barretenberg/eccvm/eccvm_composer.hpp" -#include "barretenberg/goblin/mock_circuits.hpp" #include "barretenberg/proof_system/circuit_builder/eccvm/eccvm_circuit_builder.hpp" #include "barretenberg/proof_system/circuit_builder/goblin_translator_circuit_builder.hpp" #include "barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp" @@ -63,6 +62,7 @@ class Goblin { using ECCVMFlavor = proof_system::honk::flavor::ECCVM; using ECCVMBuilder = proof_system::ECCVMCircuitBuilder; using ECCVMComposer = proof_system::honk::ECCVMComposer; + using ECCVMProver = proof_system::honk::ECCVMProver_; using TranslatorBuilder = proof_system::GoblinTranslatorCircuitBuilder; using TranslatorComposer = proof_system::honk::GoblinTranslatorComposer; using RecursiveMergeVerifier = @@ -72,6 +72,7 @@ class Goblin { std::shared_ptr op_queue = std::make_shared(); HonkProof merge_proof; + Proof goblin_proof; // on the first call to accumulate there is no merge proof to verify bool merge_proof_exists{ false }; @@ -81,6 +82,7 @@ class Goblin { std::unique_ptr eccvm_builder; std::unique_ptr translator_builder; std::unique_ptr eccvm_composer; + std::unique_ptr eccvm_prover; std::unique_ptr translator_composer; AccumulationOutput accumulator; // ACIRHACK @@ -117,25 +119,31 @@ class Goblin { return { ultra_proof, instance->verification_key }; }; - Proof prove() + void prove_eccvm() { - Proof proof; - - proof.merge_proof = std::move(merge_proof); + goblin_proof.merge_proof = std::move(merge_proof); eccvm_builder = std::make_unique(op_queue); eccvm_composer = std::make_unique(); - auto eccvm_prover = eccvm_composer->create_prover(*eccvm_builder); - proof.eccvm_proof = eccvm_prover.construct_proof(); - proof.translation_evaluations = eccvm_prover.translation_evaluations; + eccvm_prover = std::make_unique(eccvm_composer->create_prover(*eccvm_builder)); + goblin_proof.eccvm_proof = eccvm_prover->construct_proof(); + goblin_proof.translation_evaluations = eccvm_prover->translation_evaluations; + }; + void prove_translator() + { translator_builder = std::make_unique( - eccvm_prover.translation_batching_challenge_v, eccvm_prover.evaluation_challenge_x, op_queue); + eccvm_prover->translation_batching_challenge_v, eccvm_prover->evaluation_challenge_x, op_queue); translator_composer = std::make_unique(); - auto translator_prover = translator_composer->create_prover(*translator_builder, eccvm_prover.transcript); - proof.translator_proof = translator_prover.construct_proof(); + auto translator_prover = translator_composer->create_prover(*translator_builder, eccvm_prover->transcript); + goblin_proof.translator_proof = translator_prover.construct_proof(); + }; - return proof; + Proof prove() + { + prove_eccvm(); + prove_translator(); + return goblin_proof; }; bool verify(const Proof& proof) diff --git a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp index 545897eb09c..7bc3f7f3e6d 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp @@ -2,11 +2,13 @@ #include "barretenberg/commitment_schemes/commitment_key.hpp" #include "barretenberg/flavor/goblin_ultra.hpp" +#include "barretenberg/goblin/goblin.hpp" #include "barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp" #include "barretenberg/srs/global_crs.hpp" +#include "barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.hpp" namespace barretenberg { -class GoblinTestingUtils { +class GoblinMockCircuits { public: using Curve = curve::BN254; using FF = Curve::ScalarField; @@ -16,12 +18,15 @@ class GoblinTestingUtils { using OpQueue = proof_system::ECCOpQueue; using GoblinUltraBuilder = proof_system::GoblinUltraCircuitBuilder; using Flavor = proof_system::honk::flavor::GoblinUltra; + using RecursiveFlavor = proof_system::honk::flavor::GoblinUltraRecursive; + using RecursiveVerifier = proof_system::plonk::stdlib::recursion::honk::GoblinRecursiveVerifier; + using KernelInput = Goblin::AccumulationOutput; static constexpr size_t NUM_OP_QUEUE_COLUMNS = Flavor::NUM_WIRES; - static void construct_arithmetic_circuit(GoblinUltraBuilder& builder) + static void construct_arithmetic_circuit(GoblinUltraBuilder& builder, size_t num_gates = 1) { // Add some arithmetic gates that utilize public inputs - for (size_t i = 0; i < 10; ++i) { + for (size_t i = 0; i < num_gates; ++i) { FF a = FF::random_element(); FF b = FF::random_element(); FF c = FF::random_element(); @@ -100,5 +105,25 @@ class GoblinTestingUtils { construct_arithmetic_circuit(builder); } + + /** + * @brief Construct a mock kernel circuit + * @details This circuit contains (1) some basic/arbitrary arithmetic gates, (2) a genuine recursive verification of + * the proof provided as input. It does not contain any other real kernel logic. + * + * @param builder + * @param kernel_input A proof to be recursively verified and the corresponding native verification key + */ + static void construct_mock_kernel_circuit(GoblinUltraBuilder& builder, KernelInput& kernel_input) + { + // Generic operations e.g. state updates (just arith gates for now) + GoblinMockCircuits::construct_arithmetic_circuit(builder, /*num_gates=*/1 << 4); + + // Execute recursive aggregation of previous kernel proof + RecursiveVerifier verifier{ &builder, kernel_input.verification_key }; + // TODO(https://github.com/AztecProtocol/barretenberg/issues/801): Aggregation + auto pairing_points = verifier.verify_proof(kernel_input.proof); // app function proof + pairing_points = verifier.verify_proof(kernel_input.proof); // previous kernel proof + } }; } // namespace barretenberg \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/srs/io.hpp b/barretenberg/cpp/src/barretenberg/srs/io.hpp index 99f97e88775..7dff29f349e 100644 --- a/barretenberg/cpp/src/barretenberg/srs/io.hpp +++ b/barretenberg/cpp/src/barretenberg/srs/io.hpp @@ -316,7 +316,8 @@ template class IO { degree, ". Is your srs large enough? Either run bootstrap.sh to download the transcript.dat " "files to `srs_db/ignition/`, or you might need to download extra transcript.dat files " - "by editing `srs_db/download_ignition.sh` (but be careful, as this suggests you've " + "by editing `srs_db/download_ignition.sh` or in the case of grumpkin points, use " + " `grumpkin_srs_gen` (but be careful, as this suggests you've " "just changed a circuit to exceed a new 'power of two' boundary).")); } } diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/goblin_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/goblin_verifier.test.cpp index 22e82dc4824..ef0c98e5aea 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/goblin_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/goblin_verifier.test.cpp @@ -33,7 +33,7 @@ template class GoblinRecursiveVerifierTest : public testi using InnerFF = InnerFlavor::FF; // Types for recursive verifier circuit - using RecursiveFlavor = ::proof_system::honk::flavor::GoblinUltraRecursive_; + using RecursiveFlavor = ::proof_system::honk::flavor::GoblinUltraRecursive; using RecursiveVerifier = UltraRecursiveVerifier_; using OuterBuilder = BuilderType; using VerificationKey = typename RecursiveVerifier::VerificationKey; @@ -255,7 +255,7 @@ template class GoblinRecursiveVerifierTest : public testi }; // Run the recursive verifier tests with conventional Ultra builder and Goblin builder -using BuilderTypes = testing::Types; +using BuilderTypes = testing::Types; TYPED_TEST_SUITE(GoblinRecursiveVerifierTest, BuilderTypes); 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 39b981c4b6a..765759e1722 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 @@ -45,7 +45,7 @@ class RecursiveMergeVerifierTest : public testing::Test { auto op_queue = std::make_shared(); InnerBuilder sample_circuit{ op_queue }; - GoblinTestingUtils::construct_simple_initial_circuit(sample_circuit); + GoblinMockCircuits::construct_simple_initial_circuit(sample_circuit); // Generate a proof over the inner circuit InnerComposer inner_composer; 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 6c303d15e25..8088fbe7792 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 @@ -120,7 +120,5 @@ std::array UltraRecursiveVerifier_::ve template class UltraRecursiveVerifier_>; template class UltraRecursiveVerifier_>; -template class UltraRecursiveVerifier_>; -template class UltraRecursiveVerifier_>; - +template class UltraRecursiveVerifier_; } // namespace proof_system::plonk::stdlib::recursion::honk 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 62803746d5d..8fb6ed47c7f 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 @@ -41,9 +41,8 @@ template class UltraRecursiveVerifier_ { // Instance declarations for Ultra and Goblin-Ultra verifier circuits with both conventional Ultra and Goblin-Ultra // arithmetization. extern template class UltraRecursiveVerifier_>; +using UltraRecursiveVerifier = UltraRecursiveVerifier_; extern template class UltraRecursiveVerifier_>; -extern template class UltraRecursiveVerifier_>; -extern template class UltraRecursiveVerifier_< - proof_system::honk::flavor::GoblinUltraRecursive_>; - +extern template class UltraRecursiveVerifier_; +using GoblinRecursiveVerifier = UltraRecursiveVerifier_; } // namespace proof_system::plonk::stdlib::recursion::honk diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.hpp index 99bf48c490d..4aa8299272b 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.hpp @@ -30,11 +30,11 @@ class GoblinTranslatorProver { const std::shared_ptr& commitment_key, const std::shared_ptr& transcript = std::make_shared()); - void execute_preamble_round(); - void execute_wire_and_sorted_constraints_commitments_round(); - void execute_grand_product_computation_round(); - void execute_relation_check_rounds(); - void execute_zeromorph_rounds(); + BBERG_PROFILE void execute_preamble_round(); + BBERG_PROFILE void execute_wire_and_sorted_constraints_commitments_round(); + BBERG_PROFILE void execute_grand_product_computation_round(); + BBERG_PROFILE void execute_relation_check_rounds(); + BBERG_PROFILE void execute_zeromorph_rounds(); plonk::proof& export_proof(); plonk::proof& construct_proof(); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_prover.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_prover.hpp index 77318490bba..c0f823d88b7 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_prover.hpp @@ -33,7 +33,7 @@ template class MergeProver_ { explicit MergeProver_(const std::shared_ptr&, const std::shared_ptr&, const std::shared_ptr& transcript = std::make_shared()); - plonk::proof& construct_proof(); + BBERG_PROFILE plonk::proof& construct_proof(); private: plonk::proof proof; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.hpp index d5dc0dab1c4..a805b4fc645 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.hpp @@ -16,6 +16,7 @@ template class UltraVerifier_ { public: explicit UltraVerifier_(const std::shared_ptr& transcript, const std::shared_ptr& verifier_key = nullptr); + explicit UltraVerifier_(const std::shared_ptr& verifier_key); UltraVerifier_(UltraVerifier_&& other);