diff --git a/barretenberg/cpp/src/barretenberg/bb/main.cpp b/barretenberg/cpp/src/barretenberg/bb/main.cpp index 12884597ab3..df9fdcb9193 100644 --- a/barretenberg/cpp/src/barretenberg/bb/main.cpp +++ b/barretenberg/cpp/src/barretenberg/bb/main.cpp @@ -1148,7 +1148,7 @@ template bool verify_honk(const std::string& proof_path, // TODO(https://github.com/AztecProtocol/barretenberg/issues/1154): Remove this and pass in the IPA proof to the // verifier. std::shared_ptr> ipa_verification_key = nullptr; - if constexpr (HasIPAAccumulatorFlavor) { + if constexpr (HasIPAAccumulator) { init_grumpkin_crs(1 << 16); vk->contains_ipa_claim = false; ipa_verification_key = std::make_shared>(1 << CONST_ECCVM_LOG_N); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/honk_recursion_constraint.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/honk_recursion_constraint.cpp index fb46b29e8f0..45da4234f6f 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/honk_recursion_constraint.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/honk_recursion_constraint.cpp @@ -6,12 +6,14 @@ #include "barretenberg/stdlib/primitives/bigfield/constants.hpp" #include "barretenberg/stdlib/primitives/curves/bn254.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp" +#include "barretenberg/stdlib_circuit_builders/ultra_rollup_recursive_flavor.hpp" #include "proof_surgeon.hpp" #include "recursion_constraint.hpp" namespace acir_format { using namespace bb; +using namespace bb::stdlib::recursion::honk; using field_ct = stdlib::field_t; using bn254 = stdlib::bn254; using aggregation_state_ct = bb::stdlib::recursion::aggregation_state; @@ -208,11 +210,11 @@ PairingPointAccumulatorIndices create_honk_recursion_constraints( RecursiveVerifier verifier(&builder, vkey); aggregation_state_ct input_agg_obj = bb::stdlib::recursion::convert_witness_indices_to_agg_obj( builder, input_aggregation_object_indices); - aggregation_state_ct output_agg_object = verifier.verify_proof(proof_fields, input_agg_obj); + UltraRecursiveVerifierOutput output = verifier.verify_proof(proof_fields, input_agg_obj); // TODO(https://github.com/AztecProtocol/barretenberg/issues/996): investigate whether assert_equal on public inputs // is important, like what the plonk recursion constraint does. - return output_agg_object.get_witness_indices(); + return output.agg_obj.get_witness_indices(); } } // namespace acir_format diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ivc_recursion_constraint.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ivc_recursion_constraint.cpp index ee700237966..7543b933f9e 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ivc_recursion_constraint.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ivc_recursion_constraint.cpp @@ -6,6 +6,7 @@ #include "barretenberg/stdlib/primitives/bigfield/constants.hpp" #include "barretenberg/stdlib/primitives/curves/bn254.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp" +#include "barretenberg/stdlib_circuit_builders/ultra_rollup_recursive_flavor.hpp" #include "proof_surgeon.hpp" #include "recursion_constraint.hpp" diff --git a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp index b170033f7b2..b9230e4675a 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp @@ -331,6 +331,7 @@ class MegaZKFlavor; class TranslatorFlavor; class AvmFlavor; template class UltraRecursiveFlavor_; +template class UltraRollupRecursiveFlavor_; template class MegaRecursiveFlavor_; template class MegaZKRecursiveFlavor_; template class TranslatorRecursiveFlavor_; @@ -367,30 +368,31 @@ template concept IsMegaFlavor = IsAnyOf, MegaRecursiveFlavor_, -MegaRecursiveFlavor_, -MegaZKRecursiveFlavor_, -MegaZKRecursiveFlavor_>; + MegaRecursiveFlavor_, + MegaZKRecursiveFlavor_, + MegaZKRecursiveFlavor_>; template concept HasDataBus = IsMegaFlavor; template -concept HasIPAAccumulatorFlavor = IsAnyOf; +concept HasIPAAccumulator = IsAnyOf>; template concept IsRecursiveFlavor = IsAnyOf, UltraRecursiveFlavor_, UltraRecursiveFlavor_, + UltraRollupRecursiveFlavor_, MegaRecursiveFlavor_, MegaRecursiveFlavor_, -MegaRecursiveFlavor_, -MegaZKRecursiveFlavor_, -MegaZKRecursiveFlavor_, -TranslatorRecursiveFlavor_, -TranslatorRecursiveFlavor_, -TranslatorRecursiveFlavor_, -ECCVMRecursiveFlavor_, -AvmRecursiveFlavor_>; + MegaRecursiveFlavor_, + MegaZKRecursiveFlavor_, + MegaZKRecursiveFlavor_, + TranslatorRecursiveFlavor_, + TranslatorRecursiveFlavor_, + TranslatorRecursiveFlavor_, + ECCVMRecursiveFlavor_, + AvmRecursiveFlavor_>; template concept IsECCVMRecursiveFlavor = IsAnyOf>; @@ -406,11 +408,12 @@ template concept IsFoldingFlavor = IsAnyOf, UltraRecursiveFlavor_, UltraRecursiveFlavor_, + UltraRollupRecursiveFlavor_, MegaRecursiveFlavor_, MegaRecursiveFlavor_, -MegaRecursiveFlavor_, -MegaZKRecursiveFlavor_, -MegaZKRecursiveFlavor_>; + MegaRecursiveFlavor_, + MegaZKRecursiveFlavor_, + MegaZKRecursiveFlavor_>; template concept FlavorHasZK = T::HasZK; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/client_ivc_verifier/client_ivc_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/stdlib/client_ivc_verifier/client_ivc_recursive_verifier.hpp index 4381b1f5faf..db36f16230a 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/client_ivc_verifier/client_ivc_recursive_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/client_ivc_verifier/client_ivc_recursive_verifier.hpp @@ -10,7 +10,6 @@ class ClientIVCRecursiveVerifier { using RecursiveDeciderVerificationKeys = RecursiveDeciderVerificationKeys_; using RecursiveDeciderVerificationKey = RecursiveDeciderVerificationKeys::DeciderVK; using RecursiveVerificationKey = RecursiveDeciderVerificationKeys::VerificationKey; - using DeciderVerifier = DeciderRecursiveVerifier_; using FoldingVerifier = ProtogalaxyRecursiveVerifier_; using MegaVerifier = UltraRecursiveVerifier_; using GoblinVerifier = GoblinRecursiveVerifier; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/client_ivc_verifier/client_ivc_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/client_ivc_verifier/client_ivc_recursive_verifier.test.cpp index 3c4cc8a4a2c..3ce5a457400 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/client_ivc_verifier/client_ivc_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/client_ivc_verifier/client_ivc_recursive_verifier.test.cpp @@ -15,8 +15,8 @@ class ClientIVCRecursionTests : public testing::Test { using ECCVMVK = GoblinVerifier::ECCVMVerificationKey; using TranslatorVK = GoblinVerifier::TranslatorVerificationKey; using Proof = ClientIVC::Proof; - using Flavor = UltraRecursiveFlavor_; - using NativeFlavor = UltraRollupFlavor; + using Flavor = UltraRollupRecursiveFlavor_; + using NativeFlavor = Flavor::NativeFlavor; using UltraRecursiveVerifier = UltraRecursiveVerifier_; static void SetUpTestSuite() @@ -125,7 +125,7 @@ TEST_F(ClientIVCRecursionTests, ClientTubeBase) // EXPECT_TRUE(CircuitChecker::check(*tube_builder)); // Construct and verify a proof for the ClientIVC Recursive Verifier circuit - auto proving_key = std::make_shared>(*tube_builder); + auto proving_key = std::make_shared>(*tube_builder); UltraProver_ tube_prover{ proving_key }; auto native_tube_proof = tube_prover.construct_proof(); @@ -135,18 +135,26 @@ TEST_F(ClientIVCRecursionTests, ClientTubeBase) UltraVerifier_ native_verifier(native_vk_with_ipa, ipa_verification_key); EXPECT_TRUE(native_verifier.verify_proof(native_tube_proof, tube_prover.proving_key->proving_key.ipa_proof)); - // Construct a base rollup circuit that recursively verifies the tube proof. + // Construct a base rollup circuit that recursively verifies the tube proof and forwards the IPA proof. Builder base_builder; - auto native_vk = std::make_shared(proving_key->proving_key); + auto native_vk = std::make_shared(proving_key->proving_key); auto vk = std::make_shared(&base_builder, native_vk); auto tube_proof = bb::convert_native_proof_to_stdlib(&base_builder, native_tube_proof); UltraRecursiveVerifier base_verifier{ &base_builder, vk }; - base_verifier.verify_proof(tube_proof, - stdlib::recursion::init_default_aggregation_state(base_builder)); + UltraRecursiveVerifierOutput output = base_verifier.verify_proof( + tube_proof, stdlib::recursion::init_default_aggregation_state(base_builder)); info("UH Recursive Verifier: num prefinalized gates = ", base_builder.num_gates); - + base_builder.add_pairing_point_accumulator(output.agg_obj.get_witness_indices()); + base_builder.add_ipa_claim(output.ipa_opening_claim.get_witness_indices()); + base_builder.ipa_proof = tube_prover.proving_key->proving_key.ipa_proof; EXPECT_EQ(base_builder.failed(), false) << base_builder.err(); EXPECT_TRUE(CircuitChecker::check(base_builder)); + + // Natively verify the IPA proof for the base rollup circuit + auto base_proving_key = std::make_shared>(base_builder); + auto ipa_transcript = std::make_shared(base_proving_key->proving_key.ipa_proof); + IPA::reduce_verify( + ipa_verification_key, output.ipa_opening_claim.get_native_opening_claim(), ipa_transcript); } } // namespace bb::stdlib::recursion::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/decider_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/decider_recursive_verifier.hpp index 409159fd764..2b2c8d053f0 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/decider_recursive_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/decider_recursive_verifier.hpp @@ -4,6 +4,7 @@ #include "barretenberg/stdlib/transcript/transcript.hpp" #include "barretenberg/stdlib_circuit_builders/mega_recursive_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp" +#include "barretenberg/stdlib_circuit_builders/ultra_rollup_recursive_flavor.hpp" #include "barretenberg/sumcheck/sumcheck.hpp" namespace bb::stdlib::recursion::honk { diff --git a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/oink_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/oink_recursive_verifier.cpp index 6e09db90b52..d9974b8f056 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/oink_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/oink_recursive_verifier.cpp @@ -5,6 +5,7 @@ #include "barretenberg/stdlib_circuit_builders/mega_recursive_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/mega_zk_recursive_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp" +#include "barretenberg/stdlib_circuit_builders/ultra_rollup_recursive_flavor.hpp" #include namespace bb::stdlib::recursion::honk { @@ -136,4 +137,5 @@ template class OinkRecursiveVerifier_>; template class OinkRecursiveVerifier_>; template class OinkRecursiveVerifier_>; +template class OinkRecursiveVerifier_>; } // namespace bb::stdlib::recursion::honk diff --git a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.cpp index 2bd074dfd97..2cd6e8050d6 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.cpp @@ -24,8 +24,8 @@ UltraRecursiveVerifier_::UltraRecursiveVerifier_(Builder* builder, const * @return Output aggregation object */ template -UltraRecursiveVerifier_::AggregationObject UltraRecursiveVerifier_::verify_proof( - const HonkProof& proof, AggregationObject agg_obj) +UltraRecursiveVerifier_::Output UltraRecursiveVerifier_::verify_proof(const HonkProof& proof, + AggregationObject agg_obj) { StdlibProof stdlib_proof = bb::convert_native_proof_to_stdlib(builder, proof); return verify_proof(stdlib_proof, agg_obj); @@ -36,8 +36,8 @@ UltraRecursiveVerifier_::AggregationObject UltraRecursiveVerifier_ -UltraRecursiveVerifier_::AggregationObject UltraRecursiveVerifier_::verify_proof( - const StdlibProof& proof, AggregationObject agg_obj) +UltraRecursiveVerifier_::Output UltraRecursiveVerifier_::verify_proof(const StdlibProof& proof, + AggregationObject agg_obj) { using Sumcheck = ::bb::SumcheckVerifier; using PCS = typename Flavor::PCS; @@ -127,7 +127,39 @@ UltraRecursiveVerifier_::AggregationObject UltraRecursiveVerifier_ipa_claim_public_input_indices and runs the native IPA verifier. + if constexpr (HasIPAAccumulator) { + const auto recover_fq_from_public_inputs = [](std::array& limbs) { + for (size_t k = 0; k < Curve::BaseField::NUM_LIMBS; k++) { + limbs[k].create_range_constraint(Curve::BaseField::NUM_LIMB_BITS, "limb_" + std::to_string(k)); + } + return Curve::BaseField::unsafe_construct_from_limbs(limbs[0], limbs[1], limbs[2], limbs[3], false); + }; + + if (verification_key->verification_key->contains_ipa_claim) { + OpeningClaim> ipa_claim; + std::array bigfield_limbs; + for (size_t k = 0; k < 4; k++) { + bigfield_limbs[k] = + verification_key + ->public_inputs[verification_key->verification_key->ipa_claim_public_input_indices[k]]; + } + ipa_claim.opening_pair.challenge = recover_fq_from_public_inputs(bigfield_limbs); + ipa_claim.opening_pair.evaluation = 0; + ipa_claim.commitment = { + verification_key->public_inputs[verification_key->verification_key->ipa_claim_public_input_indices[4]], + verification_key->public_inputs[verification_key->verification_key->ipa_claim_public_input_indices[5]], + false // WORKTODO: make this a witness? + }; + output.ipa_opening_claim = std::move(ipa_claim); + } + } + + return output; } template class UltraRecursiveVerifier_>; @@ -138,4 +170,5 @@ template class UltraRecursiveVerifier_>; template class UltraRecursiveVerifier_>; template class UltraRecursiveVerifier_>; +template class UltraRecursiveVerifier_>; } // namespace bb::stdlib::recursion::honk diff --git a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.hpp index a72692241f8..7a8006e6431 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.hpp @@ -6,9 +6,17 @@ #include "barretenberg/stdlib_circuit_builders/mega_recursive_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/mega_zk_recursive_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp" +#include "barretenberg/stdlib_circuit_builders/ultra_rollup_recursive_flavor.hpp" #include "barretenberg/sumcheck/sumcheck.hpp" namespace bb::stdlib::recursion::honk { + +template struct UltraRecursiveVerifierOutput { + using AggregationObject = aggregation_state; + using Builder = typename Flavor::CircuitBuilder; + AggregationObject agg_obj; + OpeningClaim> ipa_opening_claim; +}; template class UltraRecursiveVerifier_ { public: using FF = typename Flavor::FF; @@ -23,13 +31,14 @@ template class UltraRecursiveVerifier_ { using AggregationObject = aggregation_state; using Transcript = bb::BaseTranscript>; using OinkVerifier = OinkRecursiveVerifier_; + using Output = UltraRecursiveVerifierOutput; explicit UltraRecursiveVerifier_(Builder* builder, const std::shared_ptr& native_verifier_key); explicit UltraRecursiveVerifier_(Builder* builder, const std::shared_ptr& vkey); - AggregationObject verify_proof(const HonkProof& proof, AggregationObject agg_obj); - AggregationObject verify_proof(const StdlibProof& proof, AggregationObject agg_obj); + Output verify_proof(const HonkProof& proof, AggregationObject agg_obj); + Output verify_proof(const StdlibProof& proof, AggregationObject agg_obj); std::shared_ptr key; std::shared_ptr pcs_verification_key; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp index 5e9eb7727ff..86ab9028de1 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp @@ -211,7 +211,9 @@ template class RecursiveVerifierTest : public testing aggregation_state agg_obj = init_default_aggregation_state(outer_circuit); - auto pairing_points = verifier.verify_proof(inner_proof, agg_obj); + bb::stdlib::recursion::honk::UltraRecursiveVerifierOutput output = + verifier.verify_proof(inner_proof, agg_obj); + aggregation_state pairing_points = output.agg_obj; info("Recursive Verifier: num gates = ", outer_circuit.get_estimated_num_finalized_gates()); // Check for a failure flag in the recursive verifier circuit diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/group/cycle_group.cpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/group/cycle_group.cpp index f7f632e298b..ab196d6d1c2 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/group/cycle_group.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/group/cycle_group.cpp @@ -1606,6 +1606,6 @@ template cycle_group cycle_group::operator/ template class cycle_group; template class cycle_group; template class cycle_group; -template struct cycle_group::cycle_scalar; +template class cycle_group; } // namespace bb::stdlib diff --git a/barretenberg/cpp/src/barretenberg/stdlib/transcript/transcript.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/transcript/transcript.test.cpp index debefb03a5d..d133798224a 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/transcript/transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/transcript/transcript.test.cpp @@ -6,6 +6,7 @@ #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp" +#include "barretenberg/stdlib_circuit_builders/ultra_rollup_recursive_flavor.hpp" #include "barretenberg/transcript/transcript.hpp" #include "barretenberg/ultra_honk/decider_proving_key.hpp" #include "barretenberg/ultra_honk/ultra_prover.hpp" diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/circuit_simulator.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/circuit_simulator.hpp index 14c55eac6b2..5d8221ee15b 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/circuit_simulator.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/circuit_simulator.hpp @@ -189,6 +189,23 @@ class CircuitSimulatorBN254 { [[nodiscard]] bool check_circuit() const { return !_failed; } + size_t create_ROM_array([[maybe_unused]] const size_t array_size) { return {}; } + + void set_ROM_element_pair([[maybe_unused]] const size_t rom_id, + [[maybe_unused]] const size_t index_value, + [[maybe_unused]] const std::array& value_witnesses) + {} + uint32_t read_ROM_array([[maybe_unused]] const size_t rom_id, [[maybe_unused]] const uint32_t index_witness) + { + return {}; + } + std::array read_ROM_array_pair([[maybe_unused]] const size_t rom_id, + [[maybe_unused]] const uint32_t index_witness) + { + return {}; + } + void create_ecc_dbl_gate([[maybe_unused]] const ecc_dbl_gate_& in){}; + // Public input indices which contain recursive proof information PairingPointAccumulatorPubInputIndices pairing_point_accumulator_public_input_indices; }; diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_circuit_builder.hpp index 7daa6ded4d7..af513c5509b 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_circuit_builder.hpp @@ -1,4 +1,6 @@ #pragma once +#include + #include "barretenberg/plonk_honk_shared/execution_trace/mega_execution_trace.hpp" #include "barretenberg/stdlib_circuit_builders/op_queue/ecc_op_queue.hpp" #include "barretenberg/trace_to_polynomials/trace_to_polynomials.hpp" @@ -45,7 +47,7 @@ template class MegaCircuitBuilder_ : public UltraCircuitBuilder_ op_queue_in = std::make_shared()) : UltraCircuitBuilder_(size_hint) - , op_queue(op_queue_in) + , op_queue(std::move(op_queue_in)) { PROFILE_THIS(); @@ -75,7 +77,7 @@ template class MegaCircuitBuilder_ : public UltraCircuitBuilder_& public_inputs, size_t varnum) : UltraCircuitBuilder_(/*size_hint=*/0, witness_values, public_inputs, varnum) - , op_queue(op_queue_in) + , op_queue(std::move(op_queue_in)) { // Set indices to constants corresponding to Goblin ECC op codes set_goblin_ecc_op_code_constant_variables(); @@ -153,7 +155,7 @@ template class MegaCircuitBuilder_ : public UltraCircuitBuilder_is_recursive_circuit = recursive; }; UltraCircuitBuilder_(const UltraCircuitBuilder_& other) = default; - UltraCircuitBuilder_(UltraCircuitBuilder_&& other) + UltraCircuitBuilder_(UltraCircuitBuilder_&& other) noexcept : CircuitBuilderBase(std::move(other)) - { - blocks = other.blocks; - constant_variable_indices = other.constant_variable_indices; - - lookup_tables = other.lookup_tables; - range_lists = other.range_lists; - ram_arrays = other.ram_arrays; - rom_arrays = other.rom_arrays; - memory_read_records = other.memory_read_records; - memory_write_records = other.memory_write_records; - cached_partial_non_native_field_multiplications = other.cached_partial_non_native_field_multiplications; - circuit_finalized = other.circuit_finalized; - }; + , blocks(other.blocks) + , constant_variable_indices(other.constant_variable_indices) + , lookup_tables(other.lookup_tables) + , range_lists(other.range_lists) + , ram_arrays(other.ram_arrays) + , rom_arrays(other.rom_arrays) + , memory_read_records(other.memory_read_records) + , memory_write_records(other.memory_write_records) + , cached_partial_non_native_field_multiplications(other.cached_partial_non_native_field_multiplications) + , circuit_finalized(other.circuit_finalized){}; UltraCircuitBuilder_& operator=(const UltraCircuitBuilder_& other) = default; - UltraCircuitBuilder_& operator=(UltraCircuitBuilder_&& other) + UltraCircuitBuilder_& operator=(UltraCircuitBuilder_&& other) noexcept { CircuitBuilderBase::operator=(std::move(other)); blocks = other.blocks; @@ -504,7 +501,6 @@ class UltraCircuitBuilder_ : public CircuitBuilderBase evaluate_non_native_field_multiplication(const non_native_field_witnesses& input); std::array queue_partial_non_native_field_multiplication(const non_native_field_witnesses& input); - typedef std::pair scaled_witness; - typedef std::tuple add_simple; + using scaled_witness = std::pair; + using add_simple = std::tuple; std::array evaluate_non_native_field_subtraction(add_simple limb0, add_simple limb1, add_simple limb2, diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_rollup_recursive_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_rollup_recursive_flavor.hpp new file mode 100644 index 00000000000..96276a00773 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_rollup_recursive_flavor.hpp @@ -0,0 +1,144 @@ +#pragma once +#include "barretenberg/commitment_schemes/commitment_key.hpp" +#include "barretenberg/commitment_schemes/kzg/kzg.hpp" +#include "barretenberg/ecc/curves/bn254/g1.hpp" +#include "barretenberg/flavor/flavor.hpp" +#include "barretenberg/flavor/flavor_macros.hpp" +#include "barretenberg/polynomials/barycentric.hpp" +#include "barretenberg/polynomials/evaluation_domain.hpp" +#include "barretenberg/polynomials/univariate.hpp" +#include "barretenberg/stdlib/primitives/curves/bn254.hpp" +#include "barretenberg/stdlib/primitives/field/field.hpp" +#include "barretenberg/stdlib/transcript/transcript.hpp" +#include "barretenberg/stdlib_circuit_builders/ultra_circuit_builder.hpp" +#include "barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp" +#include "barretenberg/stdlib_circuit_builders/ultra_rollup_flavor.hpp" + +namespace bb { + +/** + * @brief The recursive counterpart to the "native" UltraRollupFlavor. + * @details This flavor can be used to instantiate a recursive Mega Honk verifier for a proof created using the + * MegaZKFlavor. It is similar in structure to its native counterpart with two main differences: 1) the + * curve types are stdlib types (e.g. field_t instead of field) and 2) it does not specify any Prover related types + * (e.g. Polynomial, ExtendedEdges, etc.) since we do not emulate prover computation in circuits, i.e. it only makes + * sense to instantiate a Verifier with this flavor. + * + * @note Unlike conventional flavors, "recursive" flavors are templated by a builder (much like native vs stdlib types). + * This is because the flavor itself determines the details of the underlying verifier algorithm (i.e. the set of + * relations), while the Builder determines the arithmetization of that algorithm into a circuit. + * + * @tparam BuilderType Determines the arithmetization of the verifier circuit defined based on this flavor. + */ +template class UltraRollupRecursiveFlavor_ : public UltraRecursiveFlavor_ { + public: + using CircuitBuilder = BuilderType; // Determines arithmetization of circuit instantiated with this flavor + using NativeFlavor = UltraRollupFlavor; + using Curve = UltraRecursiveFlavor_::Curve; + using PCS = KZG; + using GroupElement = typename Curve::Element; + using Commitment = typename Curve::Element; + using FF = typename Curve::ScalarField; + using VerifierCommitmentKey = bb::VerifierCommitmentKey; + using NativeVerificationKey = NativeFlavor::VerificationKey; + + /** + * @brief The verification key is responsible for storing the commitments to the precomputed (non-witnessk) + * polynomials used by the verifier. + * + * @note Note the discrepancy with what sort of data is stored here vs in the proving key. We may want to resolve + * that, and split out separate PrecomputedPolynomials/Commitments data for clarity but also for portability of our + * circuits. + */ + class VerificationKey + : public VerificationKey_, VerifierCommitmentKey> { + public: + bool contains_ipa_claim; // needs to be a circuit constant + IPAClaimPubInputIndices ipa_claim_public_input_indices; // needs to be a circuit constant + + VerificationKey(const size_t circuit_size, const size_t num_public_inputs) + { + // TODO(https://github.com/AztecProtocol/barretenberg/issues/983): Think about if these should be witnesses + this->circuit_size = circuit_size; + this->log_circuit_size = numeric::get_msb(circuit_size); + this->num_public_inputs = num_public_inputs; + }; + /** + * @brief Construct a new Verification Key with stdlib types from a provided native verification key + * + * @param builder + * @param native_key Native verification key from which to extract the precomputed commitments + */ + VerificationKey(CircuitBuilder* builder, const std::shared_ptr& native_key) + : contains_ipa_claim(native_key->contains_ipa_claim) + , ipa_claim_public_input_indices(native_key->ipa_claim_public_input_indices) + { + this->pcs_verification_key = native_key->pcs_verification_key; + this->circuit_size = native_key->circuit_size; + this->log_circuit_size = numeric::get_msb(this->circuit_size); + this->num_public_inputs = native_key->num_public_inputs; + this->pub_inputs_offset = native_key->pub_inputs_offset; + this->contains_pairing_point_accumulator = native_key->contains_pairing_point_accumulator; + this->pairing_point_accumulator_public_input_indices = + native_key->pairing_point_accumulator_public_input_indices; + + // Generate stdlib commitments (biggroup) from the native counterparts + for (auto [commitment, native_commitment] : zip_view(this->get_all(), native_key->get_all())) { + commitment = Commitment::from_witness(builder, native_commitment); + } + }; + + /** + * @brief Deserialize a verification key from a vector of field elements + * + * @param builder + * @param elements + */ + VerificationKey(CircuitBuilder& builder, std::span elements) + { + using namespace bb::stdlib::field_conversion; + + size_t num_frs_read = 0; + + this->circuit_size = uint64_t(deserialize_from_frs(builder, elements, num_frs_read).get_value()); + this->num_public_inputs = uint64_t(deserialize_from_frs(builder, elements, num_frs_read).get_value()); + this->pub_inputs_offset = uint64_t(deserialize_from_frs(builder, elements, num_frs_read).get_value()); + this->contains_pairing_point_accumulator = + bool(deserialize_from_frs(builder, elements, num_frs_read).get_value()); + for (uint32_t& idx : this->pairing_point_accumulator_public_input_indices) { + idx = uint32_t(deserialize_from_frs(builder, elements, num_frs_read).get_value()); + } + contains_ipa_claim = bool(deserialize_from_frs(builder, elements, num_frs_read).get_value()); + for (uint32_t& idx : this->ipa_claim_public_input_indices) { + idx = uint32_t(deserialize_from_frs(builder, elements, num_frs_read).get_value()); + } + + for (Commitment& commitment : this->get_all()) { + commitment = deserialize_from_frs(builder, elements, num_frs_read); + } + } + + /** + * @brief Construct a VerificationKey from a set of corresponding witness indices + * + * @param builder + * @param witness_indices + * @return VerificationKey + */ + static VerificationKey from_witness_indices(CircuitBuilder& builder, + const std::span witness_indices) + { + std::vector vkey_fields; + vkey_fields.reserve(witness_indices.size()); + for (const auto& idx : witness_indices) { + vkey_fields.emplace_back(FF::from_witness_index(&builder, idx)); + } + return VerificationKey(builder, vkey_fields); + } + }; + + // Reuse the VerifierCommitments from Ultra + using VerifierCommitments = UltraFlavor::VerifierCommitments_; +}; + +} // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp index ad9f2eacb99..c706a8e69ad 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp @@ -310,7 +310,7 @@ template class DeciderProvingKey_ { proving_key.public_inputs.emplace_back(proving_key.polynomials.w_r[idx]); } - if constexpr (HasIPAAccumulatorFlavor) { // Set the IPA claim indices + if constexpr (HasIPAAccumulator) { // Set the IPA claim indices proving_key.ipa_claim_public_input_indices = circuit.ipa_claim_public_input_indices; proving_key.contains_ipa_claim = circuit.contains_ipa_claim; proving_key.ipa_proof = circuit.ipa_proof; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp index ad8ed0139ee..b14c4a6774d 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp @@ -32,7 +32,7 @@ template bool UltraVerifier_::verify_proof(const HonkP }; // Parse out the nested IPA claim using key->ipa_claim_public_input_indices and runs the native IPA verifier. - if constexpr (HasIPAAccumulatorFlavor) { + if constexpr (HasIPAAccumulator) { if (verification_key->verification_key->contains_ipa_claim) { OpeningClaim ipa_claim; std::array bigfield_limbs;