diff --git a/barretenberg/cpp/src/barretenberg/bb/main.cpp b/barretenberg/cpp/src/barretenberg/bb/main.cpp index 2d9d5d9e382..593a38c5597 100644 --- a/barretenberg/cpp/src/barretenberg/bb/main.cpp +++ b/barretenberg/cpp/src/barretenberg/bb/main.cpp @@ -590,7 +590,7 @@ void prove_tube(const std::string& output_path) } ClientIVC verifier{ builder, input }; - verifier.verify(proof); + ClientIVC::Output client_ivc_rec_verifier_output = verifier.verify(proof); PairingPointAccumulatorIndices current_aggregation_object = stdlib::recursion::init_default_agg_obj_indices(*builder); @@ -599,6 +599,12 @@ void prove_tube(const std::string& output_path) // This is currently just setting the aggregation object to the default one. builder->add_pairing_point_accumulator(current_aggregation_object); + // The tube only calls an IPA recursive verifier once, so we can just add this IPA claim and proof + // TODO(https://github.com/AztecProtocol/barretenberg/issues/1154): We shouldn't add these to the public inputs for + // now since we don't handle them correctly. Uncomment when we start using UltraRollupHonk in the rollup. + // builder->add_ipa_claim(client_ivc_rec_verifier_output.opening_claim.get_witness_indices()); + // builder->ipa_proof = convert_stdlib_proof_to_native(client_ivc_rec_verifier_output.ipa_transcript->proof_data); + using Prover = UltraProver_; using Verifier = UltraVerifier_; Prover tube_prover{ *builder }; @@ -622,8 +628,9 @@ void prove_tube(const std::string& output_path) write_file(tubeAsFieldsVkPath, { data.begin(), data.end() }); info("Native verification of the tube_proof"); - Verifier tube_verifier(tube_verification_key); - bool verified = tube_verifier.verify_proof(tube_proof); + auto ipa_verification_key = std::make_shared>(1 << CONST_ECCVM_LOG_N); + Verifier tube_verifier(tube_verification_key, ipa_verification_key); + bool verified = tube_verifier.verify_proof(tube_proof, builder->ipa_proof); info("Tube proof verification: ", verified); } @@ -1066,7 +1073,7 @@ UltraProver_ compute_valid_prover(const std::string& bytecodePath, using Prover = UltraProver_; bool honk_recursion = false; - if constexpr (IsAnyOf) { + if constexpr (IsAnyOf) { honk_recursion = true; } auto constraint_system = get_constraint_system(bytecodePath, honk_recursion); @@ -1132,14 +1139,22 @@ template bool verify_honk(const std::string& proof_path, { using VerificationKey = Flavor::VerificationKey; using Verifier = UltraVerifier_; - using VerifierCommitmentKey = bb::VerifierCommitmentKey; auto g2_data = get_bn254_g2_data(CRS_PATH); srs::init_crs_factory({}, g2_data); auto proof = from_buffer>(read_file(proof_path)); auto vk = std::make_shared(from_buffer(read_file(vk_path))); - vk->pcs_verification_key = std::make_shared(); - Verifier verifier{ vk }; + vk->pcs_verification_key = std::make_shared>(); + + // 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) { + init_grumpkin_crs(1 << 16); + vk->contains_ipa_claim = false; + ipa_verification_key = std::make_shared>(1 << CONST_ECCVM_LOG_N); + } + Verifier verifier{ vk, ipa_verification_key }; bool verified = verifier.verify_proof(proof); diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp index 9119e17f6ea..ce873d3cafd 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp @@ -25,7 +25,7 @@ void ClientIVC::instantiate_stdlib_verification_queue( size_t key_idx = 0; for (auto& [proof, vkey, type] : verification_queue) { // Construct stdlib proof directly from the internal native queue data - auto stdlib_proof = bb::convert_proof_to_witness(&circuit, proof); + auto stdlib_proof = bb::convert_native_proof_to_stdlib(&circuit, proof); // Use the provided stdlib vkey if present, otherwise construct one from the internal native queue auto stdlib_vkey = @@ -261,7 +261,7 @@ HonkProof ClientIVC::construct_and_prove_hiding_circuit() auto stdlib_decider_vk = std::make_shared(&builder, verification_queue[0].honk_verification_key); - auto stdlib_proof = bb::convert_proof_to_witness(&builder, fold_proof); + auto stdlib_proof = bb::convert_native_proof_to_stdlib(&builder, fold_proof); // Perform recursive folding verification of the last folding proof FoldingRecursiveVerifier folding_verifier{ &builder, stdlib_verifier_accumulator, { stdlib_decider_vk } }; diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/claim.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/claim.hpp index 129cb4df521..27917a072fa 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/claim.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/claim.hpp @@ -1,7 +1,9 @@ #pragma once #include "barretenberg/commitment_schemes/commitment_key.hpp" +#include "barretenberg/plonk_honk_shared/types/aggregation_object_type.hpp" #include "barretenberg/polynomials/polynomial.hpp" +#include "barretenberg/stdlib/primitives/curves/grumpkin.hpp" namespace bb { /** @@ -51,6 +53,32 @@ template class OpeningClaim { // commitment to univariate polynomial p(X) Commitment commitment; + IPAClaimIndices get_witness_indices() const + requires(std::is_same_v>) + { + return { opening_pair.challenge.binary_basis_limbs[0].element.normalize().witness_index, + opening_pair.challenge.binary_basis_limbs[1].element.normalize().witness_index, + opening_pair.challenge.binary_basis_limbs[2].element.normalize().witness_index, + opening_pair.challenge.binary_basis_limbs[3].element.normalize().witness_index, + // TODO(https://github.com/AztecProtocol/barretenberg/issues/1153): Uncomment this when we turn the + // eval into witnesses. + // opening_pair.evaluation.binary_basis_limbs[0].element.normalize().witness_index, + // opening_pair.evaluation.binary_basis_limbs[1].element.normalize().witness_index, + // opening_pair.evaluation.binary_basis_limbs[2].element.normalize().witness_index, + // opening_pair.evaluation.binary_basis_limbs[3].element.normalize().witness_index, + commitment.x.normalize().witness_index, // no idea if we need these normalize() calls... + commitment.y.normalize().witness_index }; + } + + auto get_native_opening_claim() const + requires(Curve::is_stdlib_type) + { + return OpeningClaim{ + { static_cast(opening_pair.challenge.get_value()), + static_cast(opening_pair.evaluation.get_value()) }, + commitment.get_value() + }; + } /** * @brief inefficiently check that the claim is correct by recomputing the commitment * and evaluating the polynomial in r. diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp index 3a0afa05a06..c3e5bae6705 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp @@ -749,8 +749,8 @@ template class IPA { } /** - * @brief Takes two IPA claims and accumulates them into 1 IPA claim. - * @details We create an IPA accumulator by running the IPA recursive verifier on each claim. Then, we generate challenges, and use these challenges to compute the new accumulator. We also create the accumulated polynomial. + * @brief Takes two IPA claims and accumulates them into 1 IPA claim. Also computes IPA proof for the claim. + * @details We create an IPA accumulator by running the IPA recursive verifier on each claim. Then, we generate challenges, and use these challenges to compute the new accumulator. We also create the accumulated polynomial, and generate the IPA proof for the accumulated claim. * More details are described here: https://hackmd.io/IXoLIPhVT_ej8yhZ_Ehvuw?both. * * @param verifier_ck @@ -758,11 +758,12 @@ template class IPA { * @param claim_1 * @param transcript_2 * @param claim_2 - * @return std::pair, Polynomial> + * @return std::pair, HonkProof> */ - static std::pair, Polynomial> accumulate(auto& transcript_1, OpeningClaim claim_1, auto& transcript_2, OpeningClaim claim_2) + static std::pair, HonkProof> accumulate(const std::shared_ptr>& ck, auto& transcript_1, OpeningClaim claim_1, auto& transcript_2, OpeningClaim claim_2) requires Curve::is_stdlib_type { + using NativeCurve = curve::Grumpkin; using Builder = typename Curve::Builder; // Step 1: Run the verifier for each IPA instance VerifierAccumulator pair_1 = reduce_verify(claim_1, transcript_1); @@ -793,7 +794,23 @@ template class IPA { for (Fr u_inv_i : pair_2.u_challenges_inv) { native_u_challenges_inv_2.push_back(bb::fq(u_inv_i.get_value())); } - return {output_claim, create_challenge_poly(uint32_t(pair_1.log_poly_length.get_value()), native_u_challenges_inv_1, uint32_t(pair_2.log_poly_length.get_value()), native_u_challenges_inv_2, fq(alpha.get_value()))}; + + // Compute proof for the claim + auto prover_transcript = std::make_shared(); + const OpeningPair opening_pair{ bb::fq(output_claim.opening_pair.challenge.get_value()), + bb::fq(output_claim.opening_pair.evaluation.get_value()) }; + Polynomial challenge_poly = create_challenge_poly(uint32_t(pair_1.log_poly_length.get_value()), native_u_challenges_inv_1, uint32_t(pair_2.log_poly_length.get_value()), native_u_challenges_inv_2, fq(alpha.get_value())); + + ASSERT(challenge_poly.evaluate(opening_pair.challenge) == opening_pair.evaluation && "Opening claim does not hold for challenge polynomial."); + + IPA::compute_opening_proof(ck, { challenge_poly, opening_pair }, prover_transcript); + + // Since we know this circuit will not have any more IPA claims to accumulate, add IPA Claim to public inputs of circuit and add the proof to the builder. + Builder* builder = r.get_context(); + builder->add_ipa_claim(output_claim.get_witness_indices()); + builder->ipa_proof = prover_transcript->proof_data; + + return {output_claim, prover_transcript->proof_data}; } }; diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/ipa_recursive.test.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/ipa_recursive.test.cpp index 8b59b2b90b8..fa55d812441 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/ipa_recursive.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/ipa_recursive.test.cpp @@ -56,8 +56,8 @@ class IPARecursiveTests : public CommitmentTest { OpeningClaim stdlib_opening_claim{ { stdlib_x, stdlib_eval }, stdlib_comm }; // Construct stdlib verifier transcript - auto recursive_verifier_transcript = - std::make_shared(bb::convert_proof_to_witness(&builder, prover_transcript->proof_data)); + auto recursive_verifier_transcript = std::make_shared( + bb::convert_native_proof_to_stdlib(&builder, prover_transcript->proof_data)); return { recursive_verifier_transcript, stdlib_opening_claim }; } @@ -158,25 +158,21 @@ class IPARecursiveTests : public CommitmentTest { // Creates two IPA accumulators and accumulators from the two claims. Also constructs the accumulated h // polynomial. - auto [output_claim, challenge_poly] = RecursiveIPA::accumulate(transcript_1, claim_1, transcript_2, claim_2); + auto [output_claim, ipa_proof] = + RecursiveIPA::accumulate(this->ck(), transcript_1, claim_1, transcript_2, claim_2); builder.finalize_circuit(/*ensure_nonzero=*/false); info("Circuit with 2 IPA Recursive Verifiers and IPA Accumulation num finalized gates = ", builder.get_num_finalized_gates()); EXPECT_TRUE(CircuitChecker::check(builder)); - // Run the IPA prover on this new accumulated claim. - auto prover_transcript = std::make_shared(); const OpeningPair opening_pair{ bb::fq(output_claim.opening_pair.challenge.get_value()), bb::fq(output_claim.opening_pair.evaluation.get_value()) }; Commitment native_comm = output_claim.commitment.get_value(); const OpeningClaim opening_claim{ opening_pair, native_comm }; - NativeIPA::compute_opening_proof(this->ck(), { challenge_poly, opening_pair }, prover_transcript); - - EXPECT_EQ(challenge_poly.evaluate(opening_pair.challenge), opening_pair.evaluation); // Natively verify this proof to check it. - auto verifier_transcript = std::make_shared(prover_transcript->proof_data); + auto verifier_transcript = std::make_shared(ipa_proof); auto result = NativeIPA::reduce_verify(this->vk(), opening_claim, verifier_transcript); EXPECT_TRUE(result); diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/shplemini.test.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/shplemini.test.cpp index b94b0c95085..97051dc2b08 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/shplemini.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/shplemini.test.cpp @@ -88,7 +88,7 @@ TEST(ShpleminiRecursionTest, ProveAndVerifySingle) N, RefVector(f_polynomials), RefVector(g_polynomials), u_challenge, commitment_key, prover_transcript); KZG::compute_opening_proof(commitment_key, prover_opening_claims, prover_transcript); Builder builder; - StdlibProof stdlib_proof = bb::convert_proof_to_witness(&builder, prover_transcript->proof_data); + StdlibProof stdlib_proof = bb::convert_native_proof_to_stdlib(&builder, prover_transcript->proof_data); auto stdlib_verifier_transcript = std::make_shared(stdlib_proof); stdlib_verifier_transcript->template receive_from_prover("Init"); diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/zeromorph.test.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/zeromorph.test.cpp index 5c6f22d6af4..fb70282a51f 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/zeromorph.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/zeromorph.test.cpp @@ -95,7 +95,7 @@ TEST(ZeroMorphRecursionTest, ProveAndVerifySingle) prover_transcript); Builder builder; - StdlibProof stdlib_proof = bb::convert_proof_to_witness(&builder, prover_transcript->proof_data); + StdlibProof stdlib_proof = bb::convert_native_proof_to_stdlib(&builder, prover_transcript->proof_data); auto stdlib_verifier_transcript = std::make_shared(stdlib_proof); [[maybe_unused]] auto _ = stdlib_verifier_transcript->template receive_from_prover("Init"); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index d0eb9d767d6..1cb9bb642bd 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -299,7 +299,7 @@ void process_plonk_recursion_constraints(Builder& builder, // they want these constants set by keeping the nested aggregation object attached to // the proof as public inputs. As this is the only object that can prepended to the // proof if the proof is above the expected size (with public inputs stripped) - PairingPointAccumPubInputIndices nested_aggregation_object = {}; + PairingPointAccumulatorPubInputIndices nested_aggregation_object = {}; // If the proof has public inputs attached to it, we should handle setting the nested // aggregation object if (constraint.proof.size() > proof_size_no_pub_inputs) { @@ -343,16 +343,9 @@ void process_plonk_recursion_constraints(Builder& builder, // inputs. if (!constraint_system.recursion_constraints.empty()) { - // First add the output aggregation object as public inputs - // Set the indices as public inputs because they are no longer being - // created in ACIR - for (const auto& idx : current_output_aggregation_object) { - builder.set_public_input(idx); - } - // Make sure the verification key records the public input indices of the // final recursion output. - builder.set_pairing_point_accumulator(current_output_aggregation_object); + builder.add_pairing_point_accumulator(current_output_aggregation_object); } } diff --git a/barretenberg/cpp/src/barretenberg/examples/join_split/join_split.test.cpp b/barretenberg/cpp/src/barretenberg/examples/join_split/join_split.test.cpp index f56dbf882e7..677e30f198c 100644 --- a/barretenberg/cpp/src/barretenberg/examples/join_split/join_split.test.cpp +++ b/barretenberg/cpp/src/barretenberg/examples/join_split/join_split.test.cpp @@ -33,8 +33,8 @@ using namespace bb::join_split_example::proofs::notes::native; using key_pair = join_split_example::fixtures::grumpkin_key_pair; auto create_account_leaf_data(fr const& account_alias_hash, - grumpkin::g1::affine_element const& owner_key, - grumpkin::g1::affine_element const& signing_key) + bb::grumpkin::g1::affine_element const& owner_key, + bb::grumpkin::g1::affine_element const& signing_key) { return notes::native::account::account_note{ account_alias_hash, owner_key, signing_key }.commit(); } @@ -869,7 +869,7 @@ TEST_P(test_allow_chain_to_other_users_fail, ) { join_split_tx tx = simple_setup(); tx.allow_chain = GetParam(); - tx.output_note[tx.allow_chain - 1].owner = grumpkin::g1::element::random_element(); // i.e. not owned by self. + tx.output_note[tx.allow_chain - 1].owner = bb::grumpkin::g1::element::random_element(); // i.e. not owned by self. auto result = sign_and_verify_logic(tx, user.owner); EXPECT_FALSE(result.valid); EXPECT_EQ(result.err, "inter-user chaining disallowed"); @@ -1028,7 +1028,7 @@ TEST_F(join_split_tests, test_total_output_value_larger_than_total_input_value_f TEST_F(join_split_tests, test_different_input_note_owners_fails) { join_split_tx tx = simple_setup({ 1, 2 }); - tx.input_note[0].owner = grumpkin::g1::affine_element::hash_to_curve({ 1 }); + tx.input_note[0].owner = bb::grumpkin::g1::affine_element::hash_to_curve({ 1 }); auto result = sign_and_verify_logic(tx, user.owner); EXPECT_FALSE(result.valid); @@ -1073,7 +1073,7 @@ TEST_F(join_split_tests, test_different_note_account_required_vs_account_require TEST_F(join_split_tests, test_wrong_input_note_owner_fails) { join_split_tx tx = simple_setup(); - tx.input_note[0].owner = grumpkin::g1::element::random_element(); + tx.input_note[0].owner = bb::grumpkin::g1::element::random_element(); tx.input_note[1].owner = tx.input_note[0].owner; auto result = sign_and_verify_logic(tx, user.owner); @@ -1084,8 +1084,8 @@ TEST_F(join_split_tests, test_wrong_input_note_owner_fails) TEST_F(join_split_tests, test_random_output_note_owners) { join_split_tx tx = simple_setup(); - tx.output_note[0].owner = grumpkin::g1::element::random_element(); - tx.output_note[1].owner = grumpkin::g1::element::random_element(); + tx.output_note[0].owner = bb::grumpkin::g1::element::random_element(); + tx.output_note[1].owner = bb::grumpkin::g1::element::random_element(); EXPECT_TRUE(sign_and_verify_logic(tx, user.owner).valid); } @@ -1097,7 +1097,7 @@ TEST_F(join_split_tests, test_random_output_note_owners) TEST_F(join_split_tests, test_wrong_account_private_key_fails) { join_split_tx tx = simple_setup(); - tx.account_private_key = grumpkin::fr::random_element(); + tx.account_private_key = bb::grumpkin::fr::random_element(); auto result = sign_and_verify_logic(tx, user.owner); EXPECT_FALSE(result.valid); diff --git a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp index f0b7158e5c6..b170033f7b2 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp @@ -110,7 +110,7 @@ template class ProvingKey_ { public: size_t circuit_size; bool contains_pairing_point_accumulator; - PairingPointAccumPubInputIndices pairing_point_accumulator_public_input_indices; + PairingPointAccumulatorPubInputIndices pairing_point_accumulator_public_input_indices; bb::EvaluationDomain evaluation_domain; std::shared_ptr commitment_key; size_t num_public_inputs; @@ -152,7 +152,7 @@ class VerificationKey_ : public PrecomputedCommitments { using Commitment = typename VerifierCommitmentKey::Commitment; std::shared_ptr pcs_verification_key; bool contains_pairing_point_accumulator = false; - PairingPointAccumPubInputIndices pairing_point_accumulator_public_input_indices = {}; + PairingPointAccumulatorPubInputIndices pairing_point_accumulator_public_input_indices = {}; uint64_t pub_inputs_offset = 0; bool operator==(const VerificationKey_&) const = default; @@ -323,6 +323,7 @@ template constexpr auto create_tuple_of_arrays_of_values() namespace bb { class UltraFlavor; class UltraFlavorWithZK; +class UltraRollupFlavor; class ECCVMFlavor; class UltraKeccakFlavor; class MegaFlavor; @@ -357,10 +358,10 @@ template concept IsPlonkFlavor = IsAnyOf; template -concept IsUltraPlonkOrHonk = IsAnyOf; +concept IsUltraPlonkOrHonk = IsAnyOf; template -concept IsUltraFlavor = IsAnyOf; +concept IsUltraFlavor = IsAnyOf; template concept IsMegaFlavor = IsAnyOf>; template concept HasDataBus = IsMegaFlavor; +template +concept HasIPAAccumulatorFlavor = IsAnyOf; + template concept IsRecursiveFlavor = IsAnyOf, UltraRecursiveFlavor_, @@ -395,6 +399,7 @@ template concept IsECCVMRecursiveFlavor = IsAnyOf concept IsFoldingFlavor = IsAnyOf(&builder, function_accum.verification_key); - auto proof = bb::convert_proof_to_witness(&builder, function_accum.proof); + auto proof = bb::convert_native_proof_to_stdlib(&builder, function_accum.proof); RecursiveVerifier verifier1{ &builder, verification_key }; verifier1.verify_proof( proof, stdlib::recursion::init_default_aggregation_state(builder)); @@ -221,7 +221,7 @@ class GoblinMockCircuits { if (!prev_kernel_accum.proof.empty()) { auto verification_key = std::make_shared(&builder, prev_kernel_accum.verification_key); - auto proof = bb::convert_proof_to_witness(&builder, prev_kernel_accum.proof); + auto proof = bb::convert_native_proof_to_stdlib(&builder, prev_kernel_accum.proof); RecursiveVerifier verifier2{ &builder, verification_key }; verifier2.verify_proof( proof, stdlib::recursion::init_default_aggregation_state(builder)); diff --git a/barretenberg/cpp/src/barretenberg/plonk/proof_system/proving_key/proving_key.hpp b/barretenberg/cpp/src/barretenberg/plonk/proof_system/proving_key/proving_key.hpp index e0a2097adda..eedd49442d0 100644 --- a/barretenberg/cpp/src/barretenberg/plonk/proof_system/proving_key/proving_key.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk/proof_system/proving_key/proving_key.hpp @@ -25,7 +25,7 @@ struct proving_key_data { uint32_t circuit_size; uint32_t num_public_inputs; bool contains_pairing_point_accumulator; - PairingPointAccumPubInputIndices pairing_point_accumulator_public_input_indices; + PairingPointAccumulatorPubInputIndices pairing_point_accumulator_public_input_indices; std::vector memory_read_records; std::vector memory_write_records; #ifdef __wasm__ @@ -60,7 +60,7 @@ struct proving_key { size_t log_circuit_size; size_t num_public_inputs; bool contains_pairing_point_accumulator = false; - PairingPointAccumPubInputIndices pairing_point_accumulator_public_input_indices; + PairingPointAccumulatorPubInputIndices pairing_point_accumulator_public_input_indices; std::vector memory_read_records; // Used by UltraPlonkComposer only; for ROM, RAM reads. std::vector memory_write_records; // Used by UltraPlonkComposer only, for RAM writes. diff --git a/barretenberg/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.hpp b/barretenberg/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.hpp index face2fba637..f3b84e29fc9 100644 --- a/barretenberg/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk/proof_system/verification_key/verification_key.hpp @@ -18,7 +18,7 @@ struct verification_key_data { uint32_t num_public_inputs; std::map commitments; bool contains_pairing_point_accumulator = false; - PairingPointAccumPubInputIndices pairing_point_accumulator_public_input_indices; + PairingPointAccumulatorPubInputIndices pairing_point_accumulator_public_input_indices; bool is_recursive_circuit = false; // for serialization: update with any new fields @@ -99,7 +99,7 @@ struct verification_key { bb::fr z_pow_n; // ʓ^n (ʓ being the 'evaluation challenge') bool contains_pairing_point_accumulator = false; - PairingPointAccumPubInputIndices pairing_point_accumulator_public_input_indices; + PairingPointAccumulatorPubInputIndices pairing_point_accumulator_public_input_indices; bool is_recursive_circuit = false; diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/types/aggregation_object_type.hpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/types/aggregation_object_type.hpp index 5f9bb79cda6..99608cc626f 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/types/aggregation_object_type.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/types/aggregation_object_type.hpp @@ -7,10 +7,14 @@ namespace bb { // An aggregation state is represented by two G1 affine elements. Each G1 point has // two field element coordinates (x, y). Thus, four base field elements // Four limbs are used when simulating a non-native field using the bigfield class, so 16 total field elements. -constexpr uint32_t PAIRING_POINT_ACCUMULATOR_SIZE = 16; +static constexpr uint32_t PAIRING_POINT_ACCUMULATOR_SIZE = 16; // PairingPointAccumulatorIndices represents an array of 16 witness indices pointing to the nested aggregation object. using PairingPointAccumulatorIndices = std::array; -// PairingPointAccumPubInputIndices represents an array of 16 public input indices pointing to the witness indices of -// the nested aggregation object. -using PairingPointAccumPubInputIndices = std::array; +// PairingPointAccumulatorPubInputIndices represents an array of 16 public input indices pointing to the witness indices +// of the nested aggregation object. +using PairingPointAccumulatorPubInputIndices = std::array; + +static constexpr uint32_t IPA_CLAIM_SIZE = 6; +using IPAClaimIndices = std::array; +using IPAClaimPubInputIndices = std::array; } // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/stdlib/client_ivc_verifier/client_ivc_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/client_ivc_verifier/client_ivc_recursive_verifier.cpp index 15f7ce40f3d..90a7df0e894 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/client_ivc_verifier/client_ivc_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/client_ivc_verifier/client_ivc_recursive_verifier.cpp @@ -8,7 +8,7 @@ namespace bb::stdlib::recursion::honk { * @todo (https://github.com/AztecProtocol/barretenberg/issues/934): Add logic for accumulating the pairing points * produced by the verifiers (and potentially IPA accumulators for ECCVM verifier) */ -void ClientIVCRecursiveVerifier::verify(const ClientIVC::Proof& proof) +ClientIVCRecursiveVerifier::Output ClientIVCRecursiveVerifier::verify(const ClientIVC::Proof& proof) { // Construct stdlib Mega verification key auto stdlib_mega_vk = @@ -24,7 +24,9 @@ void ClientIVCRecursiveVerifier::verify(const ClientIVC::Proof& proof) // Perform Goblin recursive verification GoblinVerifier goblin_verifier{ builder.get(), verifier_input.goblin_input }; - goblin_verifier.verify(proof.goblin_proof); + GoblinRecursiveVerifierOutput output = goblin_verifier.verify(proof.goblin_proof); + + return output; } } // namespace bb::stdlib::recursion::honk \ No newline at end of file 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 d6954bb0532..4381b1f5faf 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 @@ -21,6 +21,8 @@ class ClientIVCRecursiveVerifier { using Proof = ClientIVC::Proof; using FoldVerifierInput = FoldingVerifier::VerifierInput; using GoblinVerifierInput = GoblinVerifier::VerifierInput; + using Output = GoblinRecursiveVerifierOutput; + struct VerifierInput { std::shared_ptr mega_verification_key; GoblinVerifierInput goblin_input; @@ -30,7 +32,7 @@ class ClientIVCRecursiveVerifier { : builder(builder) , verifier_input(verifier_input){}; - void verify(const ClientIVC::Proof&); + Output verify(const ClientIVC::Proof&); private: std::shared_ptr builder; 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 aff80907915..3c4cc8a4a2c 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 @@ -16,7 +16,7 @@ class ClientIVCRecursionTests : public testing::Test { using TranslatorVK = GoblinVerifier::TranslatorVerificationKey; using Proof = ClientIVC::Proof; using Flavor = UltraRecursiveFlavor_; - using NativeFlavor = Flavor::NativeFlavor; + using NativeFlavor = UltraRollupFlavor; using UltraRecursiveVerifier = UltraRecursiveVerifier_; static void SetUpTestSuite() @@ -74,6 +74,8 @@ TEST_F(ClientIVCRecursionTests, NativeVerification) */ TEST_F(ClientIVCRecursionTests, Basic) { + using CIVCRecVerifierOutput = ClientIVCRecursiveVerifier::Output; + // Generate a genuine ClientIVC prover output ClientIVC ivc{ {}, /*auto_verify_mode=*/true }; auto [proof, verifier_input] = construct_client_ivc_prover_output(ivc); @@ -83,7 +85,7 @@ TEST_F(ClientIVCRecursionTests, Basic) ClientIVCVerifier verifier{ builder, verifier_input }; // Generate the recursive verification circuit - verifier.verify(proof); + CIVCRecVerifierOutput output = verifier.verify(proof); EXPECT_EQ(builder->failed(), false) << builder->err(); @@ -95,6 +97,8 @@ TEST_F(ClientIVCRecursionTests, Basic) TEST_F(ClientIVCRecursionTests, ClientTubeBase) { + using CIVCRecVerifierOutput = ClientIVCRecursiveVerifier::Output; + // Generate a genuine ClientIVC prover output ClientIVC ivc{ {}, /*auto_verify_mode=*/true }; auto [proof, verifier_input] = construct_client_ivc_prover_output(ivc); @@ -104,10 +108,15 @@ TEST_F(ClientIVCRecursionTests, ClientTubeBase) ClientIVCVerifier verifier{ tube_builder, verifier_input }; // Generate the recursive verification circuit - verifier.verify(proof); + CIVCRecVerifierOutput client_ivc_rec_verifier_output = verifier.verify(proof); + // TODO(https://github.com/AztecProtocol/barretenberg/issues/1069): fix this by taking it from the output instead of + // just using default. tube_builder->add_pairing_point_accumulator( stdlib::recursion::init_default_agg_obj_indices(*tube_builder)); + // The tube only calls an IPA recursive verifier once, so we can just add this IPA claim and proof + tube_builder->add_ipa_claim(client_ivc_rec_verifier_output.opening_claim.get_witness_indices()); + tube_builder->ipa_proof = convert_stdlib_proof_to_native(client_ivc_rec_verifier_output.ipa_transcript->proof_data); info("ClientIVC Recursive Verifier: num prefinalized gates = ", tube_builder->num_gates); @@ -116,14 +125,21 @@ 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); - UltraProver tube_prover{ proving_key }; + auto proving_key = std::make_shared>(*tube_builder); + UltraProver_ tube_prover{ proving_key }; auto native_tube_proof = tube_prover.construct_proof(); + // Natively verify the tube proof + auto native_vk_with_ipa = std::make_shared(proving_key->proving_key); + auto ipa_verification_key = std::make_shared>(1 << CONST_ECCVM_LOG_N); + 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. 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_proof_to_witness(&base_builder, native_tube_proof); + 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)); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_verifier.cpp index dd1868f2cc6..a9422482854 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_verifier.cpp @@ -15,8 +15,11 @@ ECCVMRecursiveVerifier_::ECCVMRecursiveVerifier_( /** * @brief This function verifies an ECCVM Honk proof for given program settings up to sumcheck. + * */ -template void ECCVMRecursiveVerifier_::verify_proof(const ECCVMProof& proof) +template +std::pair, std::shared_ptr::Transcript>> +ECCVMRecursiveVerifier_::verify_proof(const ECCVMProof& proof) { using Curve = typename Flavor::Curve; using Shplemini = ShpleminiVerifier_; @@ -25,8 +28,8 @@ template void ECCVMRecursiveVerifier_::verify_proof(co RelationParameters relation_parameters; - StdlibProof stdlib_proof = bb::convert_proof_to_witness(builder, proof.pre_ipa_proof); - StdlibProof stdlib_ipa_proof = bb::convert_proof_to_witness(builder, proof.ipa_proof); + StdlibProof stdlib_proof = bb::convert_native_proof_to_stdlib(builder, proof.pre_ipa_proof); + StdlibProof stdlib_ipa_proof = bb::convert_native_proof_to_stdlib(builder, proof.ipa_proof); transcript = std::make_shared(stdlib_proof); ipa_transcript = std::make_shared(stdlib_ipa_proof); @@ -142,10 +145,8 @@ template void ECCVMRecursiveVerifier_::verify_proof(co const OpeningClaim batch_opening_claim = Shplonk::reduce_verification(key->pcs_verification_key->get_g1_identity(), opening_claims, transcript); - // TODO(https://github.com/AztecProtocol/barretenberg/issues/1142): Handle this return value correctly. - const typename PCS::VerifierAccumulator batched_opening_accumulator = - PCS::reduce_verify(batch_opening_claim, ipa_transcript); ASSERT(sumcheck_verified); + return { batch_opening_claim, ipa_transcript }; } template class ECCVMRecursiveVerifier_>; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_verifier.hpp index 58103e9644b..729740aa707 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_verifier.hpp @@ -21,7 +21,7 @@ template class ECCVMRecursiveVerifier_ { const std::shared_ptr& native_verifier_key); // TODO(https://github.com/AztecProtocol/barretenberg/issues/991): switch recursive verifiers to StdlibProof - void verify_proof(const ECCVMProof& proof); + std::pair, std::shared_ptr> verify_proof(const ECCVMProof& proof); std::shared_ptr key; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_verifier.test.cpp index 0aae8567845..8c5581e22b6 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_verifier.test.cpp @@ -83,7 +83,8 @@ template class ECCVMRecursiveTests : public ::testing info("ECCVM Recursive Verifier"); OuterBuilder outer_circuit; RecursiveVerifier verifier{ &outer_circuit, verification_key }; - verifier.verify_proof(proof); + auto [opening_claim, ipa_transcript] = verifier.verify_proof(proof); + 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/encryption/schnorr/schnorr.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/encryption/schnorr/schnorr.test.cpp index ea93c1c161d..a852624235a 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/encryption/schnorr/schnorr.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/encryption/schnorr/schnorr.test.cpp @@ -7,14 +7,13 @@ #include "schnorr.hpp" using namespace bb; -using namespace bb::stdlib; using namespace bb::crypto; using Builder = UltraCircuitBuilder; -using bool_ct = bool_t; -using byte_array_ct = byte_array; -using field_ct = field_t; -using witness_ct = witness_t; +using bool_ct = stdlib::bool_t; +using byte_array_ct = stdlib::byte_array; +using field_ct = stdlib::field_t; +using witness_ct = stdlib::witness_t; /** * @test Test circuit verifying a Schnorr signature generated by \see{crypto::schnorr_verify_signature}. @@ -42,10 +41,10 @@ TEST(stdlib_schnorr, schnorr_verify_signature) message_string, account.public_key, signature); EXPECT_EQ(first_result, true); - cycle_group pub_key{ witness_ct(&builder, account.public_key.x), - witness_ct(&builder, account.public_key.y), - false }; - schnorr_signature_bits sig = schnorr_convert_signature(&builder, signature); + stdlib::cycle_group pub_key{ witness_ct(&builder, account.public_key.x), + witness_ct(&builder, account.public_key.y), + false }; + stdlib::schnorr_signature_bits sig = stdlib::schnorr_convert_signature(&builder, signature); byte_array_ct message(&builder, message_string); schnorr_verify_signature(message, pub_key, sig); @@ -84,10 +83,10 @@ TEST(stdlib_schnorr, verify_signature_failure) EXPECT_EQ(native_result, false); // check stdlib verification with account 2 public key fails - cycle_group pub_key2_ct{ witness_ct(&builder, account2.public_key.x), - witness_ct(&builder, account2.public_key.y), - false }; - schnorr_signature_bits sig = schnorr_convert_signature(&builder, signature); + stdlib::cycle_group pub_key2_ct{ witness_ct(&builder, account2.public_key.x), + witness_ct(&builder, account2.public_key.y), + false }; + stdlib::schnorr_signature_bits sig = stdlib::schnorr_convert_signature(&builder, signature); byte_array_ct message(&builder, message_string); schnorr_verify_signature(message, pub_key2_ct, sig); @@ -118,10 +117,10 @@ TEST(stdlib_schnorr, schnorr_signature_verification_result) longer_string, account.public_key, signature); EXPECT_EQ(first_result, true); - cycle_group pub_key{ witness_ct(&builder, account.public_key.x), - witness_ct(&builder, account.public_key.y), - false }; - schnorr_signature_bits sig = schnorr_convert_signature(&builder, signature); + stdlib::cycle_group pub_key{ witness_ct(&builder, account.public_key.x), + witness_ct(&builder, account.public_key.y), + false }; + stdlib::schnorr_signature_bits sig = stdlib::schnorr_convert_signature(&builder, signature); byte_array_ct message(&builder, longer_string); bool_ct signature_result = schnorr_signature_verification_result(message, pub_key, sig); EXPECT_EQ(signature_result.witness_bool, true); @@ -161,10 +160,10 @@ TEST(stdlib_schnorr, signature_verification_result_failure) EXPECT_EQ(native_result, false); // check stdlib verification with account 2 public key fails - cycle_group pub_key2_ct{ witness_ct(&builder, account2.public_key.x), - witness_ct(&builder, account2.public_key.y), - false }; - schnorr_signature_bits sig = schnorr_convert_signature(&builder, signature); + stdlib::cycle_group pub_key2_ct{ witness_ct(&builder, account2.public_key.x), + witness_ct(&builder, account2.public_key.y), + false }; + stdlib::schnorr_signature_bits sig = stdlib::schnorr_convert_signature(&builder, signature); byte_array_ct message(&builder, message_string); bool_ct signature_result = schnorr_signature_verification_result(message, pub_key2_ct, sig); EXPECT_EQ(signature_result.witness_bool, false); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.cpp index 8a6980ff4b0..b9bf165bc96 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.cpp @@ -8,11 +8,11 @@ namespace bb::stdlib::recursion::honk { * @todo https://github.com/AztecProtocol/barretenberg/issues/934: Add logic for accumulating the pairing points * produced by the translator and merge verifier (and potentially IPA accumulators for ECCVM verifier) */ -void GoblinRecursiveVerifier::verify(const GoblinProof& proof) +GoblinRecursiveVerifierOutput GoblinRecursiveVerifier::verify(const GoblinProof& proof) { // Run the ECCVM recursive verifier ECCVMVerifier eccvm_verifier{ builder, verification_keys.eccvm_verification_key }; - eccvm_verifier.verify_proof(proof.eccvm_proof); + auto [opening_claim, ipa_transcript] = eccvm_verifier.verify_proof(proof.eccvm_proof); // Run the Translator recursive verifier TranslatorVerifier translator_verifier{ builder, @@ -36,5 +36,6 @@ void GoblinRecursiveVerifier::verify(const GoblinProof& proof) MergeVerifier merge_verifier{ builder }; merge_verifier.verify_proof(proof.merge_proof); + return { opening_claim, ipa_transcript }; } } // namespace bb::stdlib::recursion::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.hpp index 92ae344af66..a3c0828ce90 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.hpp @@ -5,6 +5,16 @@ #include "barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.hpp" namespace bb::stdlib::recursion::honk { + +struct GoblinRecursiveVerifierOutput { + using Builder = UltraCircuitBuilder; + using ECCVMFlavor = ECCVMRecursiveFlavor_; + using Curve = grumpkin; + using Transcript = bb::BaseTranscript>; + OpeningClaim opening_claim; + std::shared_ptr ipa_transcript; +}; + class GoblinRecursiveVerifier { public: // Goblin Recursive Verifier circuit is using Ultra arithmetisation @@ -35,7 +45,7 @@ class GoblinRecursiveVerifier { * * @todo(https://github.com/AztecProtocol/barretenberg/issues/991): The GoblinProof should aleady be a stdlib proof */ - void verify(const GoblinProof&); + GoblinRecursiveVerifierOutput verify(const GoblinProof&); private: Builder* builder; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.test.cpp index 80ee773f2df..a7f9512ec9b 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.test.cpp @@ -113,7 +113,7 @@ TEST_F(GoblinRecursiveVerifierTests, ECCVMFailure) // Tamper with the ECCVM proof for (auto& val : proof.eccvm_proof.pre_ipa_proof) { - if (val > 0) { // tamper by finding the tenth non-zero value and incrementing it by 1 + if (val > 0) { // tamper by finding the first non-zero value and incrementing it by 1 // tamper by finding the first non-zero value // and incrementing it by 1 val += 1; @@ -123,8 +123,18 @@ TEST_F(GoblinRecursiveVerifierTests, ECCVMFailure) Builder builder; GoblinRecursiveVerifier verifier{ &builder, verifier_input }; - - EXPECT_DEBUG_DEATH(verifier.verify(proof), "(ipa_relation.get_value.* == -opening_claim.commitment.get_value.*)"); + GoblinRecursiveVerifierOutput goblin_rec_verifier_output = verifier.verify(proof); + + auto crs_factory = + std::make_shared>("../srs_db/grumpkin", 1 << CONST_ECCVM_LOG_N); + auto grumpkin_verifier_commitment_key = + std::make_shared>(1 << CONST_ECCVM_LOG_N, crs_factory); + OpeningClaim native_claim = goblin_rec_verifier_output.opening_claim.get_native_opening_claim(); + auto native_ipa_transcript = std::make_shared( + convert_stdlib_proof_to_native(goblin_rec_verifier_output.ipa_transcript->proof_data)); + + EXPECT_FALSE( + IPA::reduce_verify(grumpkin_verifier_commitment_key, native_claim, native_ipa_transcript)); } /** diff --git a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/merge_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/merge_recursive_verifier.cpp index 593564fe4ed..6f3ea52555c 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/merge_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/merge_recursive_verifier.cpp @@ -19,7 +19,7 @@ std::array::Element, 2> MergeRecursiveVerifier_ stdlib_proof = bb::convert_proof_to_witness(builder, proof); + StdlibProof stdlib_proof = bb::convert_native_proof_to_stdlib(builder, proof); transcript = std::make_shared(stdlib_proof); // Receive commitments [t_i^{shift}], [T_{i-1}], and [T_i] diff --git a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/decider_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/decider_recursive_verifier.cpp index 57fc7f27b08..162a890e5ff 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/decider_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/decider_recursive_verifier.cpp @@ -19,7 +19,7 @@ std::array DeciderRecursiveVerifier_:: using VerifierCommitments = typename Flavor::VerifierCommitments; using Transcript = typename Flavor::Transcript; - StdlibProof stdlib_proof = bb::convert_proof_to_witness(builder, proof); + StdlibProof stdlib_proof = bb::convert_native_proof_to_stdlib(builder, proof); transcript = std::make_shared(stdlib_proof); VerifierCommitments commitments{ accumulator->verification_key, accumulator->witness_commitments }; 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 26c2297b41d..2bd074dfd97 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 @@ -27,7 +27,7 @@ template UltraRecursiveVerifier_::AggregationObject UltraRecursiveVerifier_::verify_proof( const HonkProof& proof, AggregationObject agg_obj) { - StdlibProof stdlib_proof = bb::convert_proof_to_witness(builder, proof); + StdlibProof stdlib_proof = bb::convert_native_proof_to_stdlib(builder, proof); return verify_proof(stdlib_proof, agg_obj); } diff --git a/barretenberg/cpp/src/barretenberg/stdlib/plonk_recursion/verification_key/verification_key.hpp b/barretenberg/cpp/src/barretenberg/stdlib/plonk_recursion/verification_key/verification_key.hpp index fc4f6ad3993..5fc139f72ba 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/plonk_recursion/verification_key/verification_key.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/plonk_recursion/verification_key/verification_key.hpp @@ -240,7 +240,7 @@ template struct verification_key { Builder* ctx, const std::vector>& fields, bool inner_proof_contains_pairing_point_accumulator = false, - PairingPointAccumPubInputIndices pairing_point_accumulator_public_input_indices = {}) + PairingPointAccumulatorPubInputIndices pairing_point_accumulator_public_input_indices = {}) { std::vector fields_raw; std::shared_ptr key = std::make_shared(); @@ -446,7 +446,7 @@ template struct verification_key { plonk::PolynomialManifest polynomial_manifest; // Used to check in the circuit if a proof contains any aggregated state. bool contains_pairing_point_accumulator = false; - PairingPointAccumPubInputIndices pairing_point_accumulator_public_input_indices; + PairingPointAccumulatorPubInputIndices pairing_point_accumulator_public_input_indices; size_t program_width = 4; Builder* context; }; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/protogalaxy_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/protogalaxy_recursive_verifier.test.cpp index 84a1b22d036..81586173b6c 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/protogalaxy_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/protogalaxy_recursive_verifier.test.cpp @@ -203,7 +203,8 @@ template class ProtogalaxyRecursiveTests : public tes auto recursive_decider_vk_1 = std::make_shared(&folding_circuit, decider_vk_1); auto recursive_decider_vk_2 = std::make_shared(&folding_circuit, decider_vk_2->verification_key); - StdlibProof stdlib_proof = bb::convert_proof_to_witness(&folding_circuit, folding_proof.proof); + StdlibProof stdlib_proof = + bb::convert_native_proof_to_stdlib(&folding_circuit, folding_proof.proof); auto verifier = FoldingRecursiveVerifier{ &folding_circuit, recursive_decider_vk_1, { recursive_decider_vk_2 } }; @@ -292,7 +293,8 @@ template class ProtogalaxyRecursiveTests : public tes auto recursive_decider_vk_1 = std::make_shared(&folding_circuit, decider_vk_1); auto recursive_decider_vk_2 = std::make_shared(&folding_circuit, decider_vk_2->verification_key); - StdlibProof stdlib_proof = bb::convert_proof_to_witness(&folding_circuit, folding_proof.proof); + StdlibProof stdlib_proof = + bb::convert_native_proof_to_stdlib(&folding_circuit, folding_proof.proof); auto verifier = FoldingRecursiveVerifier{ &folding_circuit, recursive_decider_vk_1, { recursive_decider_vk_2 } }; @@ -398,7 +400,8 @@ template class ProtogalaxyRecursiveTests : public tes std::make_shared(&folding_circuit, verifier_accumulator); auto recursive_decider_vk_2 = std::make_shared(&folding_circuit, verifier_inst->verification_key); - StdlibProof stdlib_proof = bb::convert_proof_to_witness(&folding_circuit, folding_proof.proof); + StdlibProof stdlib_proof = + bb::convert_native_proof_to_stdlib(&folding_circuit, folding_proof.proof); auto verifier = FoldingRecursiveVerifier{ &folding_circuit, recursive_decider_vk_1, { recursive_decider_vk_2 } }; @@ -436,7 +439,8 @@ template class ProtogalaxyRecursiveTests : public tes auto recursive_decider_vk_1 = std::make_shared(&verifier_circuit, honk_vk_1); auto recursive_decider_vk_2 = std::make_shared(&verifier_circuit, honk_vk_2); - StdlibProof stdlib_proof = bb::convert_proof_to_witness(&verifier_circuit, fold_result.proof); + StdlibProof stdlib_proof = + bb::convert_native_proof_to_stdlib(&verifier_circuit, fold_result.proof); auto verifier = FoldingRecursiveVerifier{ &verifier_circuit, recursive_decider_vk_1, { recursive_decider_vk_2 } }; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/transcript/transcript.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/transcript/transcript.test.cpp index 0344b1f8835..debefb03a5d 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/transcript/transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/transcript/transcript.test.cpp @@ -111,7 +111,7 @@ TEST(RecursiveHonkTranscript, InterfacesMatch) EXPECT_EQ(prover_transcript.get_manifest(), native_transcript.get_manifest()); // Instantiate a stdlib Transcript and perform the same operations - StdlibProof stdlib_proof = bb::convert_proof_to_witness(&builder, proof_data); + StdlibProof stdlib_proof = bb::convert_native_proof_to_stdlib(&builder, proof_data); StdlibTranscript transcript{ stdlib_proof }; perform_mock_verifier_transcript_operations(transcript); @@ -164,7 +164,7 @@ TEST(RecursiveHonkTranscript, ReturnValuesMatch) auto [native_alpha, native_beta] = native_transcript.template get_challenges("alpha", "beta"); // Perform the same operations with the stdlib verifier transcript - StdlibProof stdlib_proof = bb::convert_proof_to_witness(&builder, proof_data); + StdlibProof stdlib_proof = bb::convert_native_proof_to_stdlib(&builder, proof_data); StdlibTranscript stdlib_transcript{ stdlib_proof }; auto stdlib_scalar = stdlib_transcript.template receive_from_prover("scalar"); auto stdlib_commitment = stdlib_transcript.template receive_from_prover("commitment"); @@ -210,7 +210,7 @@ TEST(RecursiveTranscript, InfinityConsistencyGrumpkin) verifier_transcript.receive_from_prover("infinity"); auto verifier_challenge = verifier_transcript.get_challenge("challenge"); - StdlibProof stdlib_proof = bb::convert_proof_to_witness(&builder, proof_data); + StdlibProof stdlib_proof = bb::convert_native_proof_to_stdlib(&builder, proof_data); StdlibTranscript stdlib_transcript{ stdlib_proof }; auto stdlib_infinity = stdlib_transcript.receive_from_prover("infinity"); EXPECT_TRUE(stdlib_infinity.is_point_at_infinity().get_value()); @@ -248,7 +248,7 @@ TEST(RecursiveTranscript, InfinityConsistencyBN254) verifier_transcript.receive_from_prover("infinity"); auto verifier_challenge = verifier_transcript.get_challenge("challenge"); - StdlibProof stdlib_proof = bb::convert_proof_to_witness(&builder, proof_data); + StdlibProof stdlib_proof = bb::convert_native_proof_to_stdlib(&builder, proof_data); StdlibTranscript stdlib_transcript{ stdlib_proof }; auto stdlib_commitment = stdlib_transcript.receive_from_prover("infinity"); EXPECT_TRUE(stdlib_commitment.is_point_at_infinity().get_value()); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.cpp index 2849fdd48b5..ce321b18ea8 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.cpp @@ -66,7 +66,7 @@ std::array TranslatorRecursiveVerifier_ stdlib_proof = bb::convert_proof_to_witness(builder, proof); + StdlibProof stdlib_proof = bb::convert_native_proof_to_stdlib(builder, proof); transcript->load_proof(stdlib_proof); batching_challenge_v = transcript->template get_challenge("Translation:batching_challenge"); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.test.cpp index 27de41a35d3..1e2ab4beac0 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.test.cpp @@ -75,7 +75,7 @@ template class TranslatorRecursiveTests : public ::te OuterBuilder outer_circuit; // Mock a previous verifier that would in reality be the ECCVM recursive verifier - StdlibProof stdlib_proof = bb::convert_proof_to_witness(&outer_circuit, fake_inital_proof); + StdlibProof stdlib_proof = bb::convert_native_proof_to_stdlib(&outer_circuit, fake_inital_proof); auto transcript = std::make_shared(stdlib_proof); transcript->template receive_from_prover("init"); diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/circuit_builder_base.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/circuit_builder_base.hpp index 642b8f0ba82..28b2c9ad8f6 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/circuit_builder_base.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/circuit_builder_base.hpp @@ -37,9 +37,13 @@ template class CircuitBuilderBase { std::map tau; // Public input indices which contain recursive proof information - PairingPointAccumPubInputIndices pairing_point_accumulator_public_input_indices; + PairingPointAccumulatorPubInputIndices pairing_point_accumulator_public_input_indices; bool contains_pairing_point_accumulator = false; + // Public input indices which contain the output IPA opening claim + IPAClaimPubInputIndices ipa_claim_public_input_indices; + bool contains_ipa_claim = false; + // We know from the CLI arguments during proving whether a circuit should use a prover which produces // proofs that are friendly to verify in a circuit themselves. A verifier does not need a full circuit // description and should be able to verify a proof with just the verification key and the proof. @@ -206,18 +210,9 @@ template class CircuitBuilderBase { * @param proof_output_witness_indices Witness indices that need to become public and stored as recurisve proof * specific */ - void add_pairing_point_accumulator(const PairingPointAccumulatorIndices& proof_output_witness_indices); + void add_pairing_point_accumulator(const PairingPointAccumulatorIndices& pairing_point_accum_witness_indices); - /** - * TODO: We can remove this and use `add_pairing_point_accumulator` once my question has been addressed - * TODO: using `add_pairing_point_accumulator` also means that we will need to remove the cde which is - * TODO: adding the public_inputs - * @brief Update pairing_point_accumulator_public_input_indices with existing public inputs that represent a - * recursive proof - * - * @param proof_output_witness_indices - */ - void set_pairing_point_accumulator(const PairingPointAccumulatorIndices& proof_output_witness_indices); + void add_ipa_claim(const IPAClaimIndices& ipa_claim_witness_indices); bool failed() const; const std::string& err() const; diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/circuit_builder_base_impl.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/circuit_builder_base_impl.hpp index a192a8587b3..e3e4bbcfe9d 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/circuit_builder_base_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/circuit_builder_base_impl.hpp @@ -237,34 +237,35 @@ void CircuitBuilderBase::assert_valid_variables(const std::vector template void CircuitBuilderBase::add_pairing_point_accumulator( - const PairingPointAccumulatorIndices& proof_output_witness_indices) + const PairingPointAccumulatorIndices& pairing_point_accum_witness_indices) { if (contains_pairing_point_accumulator) { - failure("added recursive proof when one already exists"); + failure("added pairing point accumulator when one already exists"); ASSERT(0); } contains_pairing_point_accumulator = true; size_t i = 0; - for (const auto& idx : proof_output_witness_indices) { + for (const auto& idx : pairing_point_accum_witness_indices) { set_public_input(idx); pairing_point_accumulator_public_input_indices[i] = static_cast(public_inputs.size() - 1); ++i; } } -template -void CircuitBuilderBase::set_pairing_point_accumulator( - const PairingPointAccumulatorIndices& proof_output_witness_indices) +template void CircuitBuilderBase::add_ipa_claim(const IPAClaimIndices& ipa_claim_witness_indices) { - if (contains_pairing_point_accumulator) { - failure("added recursive proof when one already exists"); + if (contains_ipa_claim) { + failure("added IPA claim when one already exists"); ASSERT(0); } - contains_pairing_point_accumulator = true; - for (size_t i = 0; i < proof_output_witness_indices.size(); ++i) { - pairing_point_accumulator_public_input_indices[i] = - get_public_input_index(real_variable_index[proof_output_witness_indices[i]]); + contains_ipa_claim = true; + + size_t i = 0; + for (const auto& idx : ipa_claim_witness_indices) { + set_public_input(idx); + ipa_claim_public_input_indices[i] = static_cast(public_inputs.size() - 1); + ++i; } } 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 dc8ed11da34..017c04e8d0d 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/circuit_simulator.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/circuit_simulator.hpp @@ -191,7 +191,7 @@ class CircuitSimulatorBN254 { [[nodiscard]] bool check_circuit() const { return !_failed; } // Public input indices which contain recursive proof information - PairingPointAccumPubInputIndices pairing_point_accumulator_public_input_indices; + PairingPointAccumulatorPubInputIndices pairing_point_accumulator_public_input_indices; }; class SimulatorCircuitChecker { diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp index e87ebe9ea76..1db6dde5c7d 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp @@ -625,7 +625,7 @@ class MegaFlavor { const size_t num_public_inputs, const size_t pub_inputs_offset, const bool contains_pairing_point_accumulator, - const PairingPointAccumPubInputIndices& pairing_point_accumulator_public_input_indices, + const PairingPointAccumulatorPubInputIndices& pairing_point_accumulator_public_input_indices, const DatabusPropagationData& databus_propagation_data, const Commitment& q_m, const Commitment& q_c, diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_circuit_builder.hpp index 058d6fca95a..572e095f604 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_circuit_builder.hpp @@ -330,6 +330,8 @@ class UltraCircuitBuilder_ : public CircuitBuilderBase ipa_proof; + void process_non_native_field_multiplications(); UltraCircuitBuilder_(const size_t size_hint = 0) : CircuitBuilderBase(size_hint) diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp index d8be56ad096..8d69028950f 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp @@ -284,7 +284,6 @@ class UltraFlavor { }; }; - public: /** * @brief A field element for each entity of the flavor. These entities represent the prover polynomials * evaluated at one point. @@ -468,7 +467,7 @@ class UltraFlavor { const uint64_t num_public_inputs, const uint64_t pub_inputs_offset, const bool contains_pairing_point_accumulator, - const PairingPointAccumPubInputIndices& pairing_point_accumulator_public_input_indices, + const PairingPointAccumulatorPubInputIndices& pairing_point_accumulator_public_input_indices, const Commitment& q_m, const Commitment& q_c, const Commitment& q_l, diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_rollup_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_rollup_flavor.hpp new file mode 100644 index 00000000000..102b5ca6e63 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_rollup_flavor.hpp @@ -0,0 +1,170 @@ +#pragma once +#include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp" + +namespace bb { + +class UltraRollupFlavor : public bb::UltraFlavor { + public: + using UltraFlavor::UltraFlavor; + class ProvingKey : public UltraFlavor::ProvingKey { + public: + using UltraFlavor::ProvingKey::ProvingKey; + bool contains_ipa_claim; + IPAClaimPubInputIndices ipa_claim_public_input_indices; + HonkProof ipa_proof; + }; + + /** + * @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; + IPAClaimPubInputIndices ipa_claim_public_input_indices; + + bool operator==(const VerificationKey&) const = default; + VerificationKey() = default; + VerificationKey(const size_t circuit_size, const size_t num_public_inputs) + : VerificationKey_(circuit_size, num_public_inputs) + {} + VerificationKey(ProvingKey& proving_key) + : contains_ipa_claim(proving_key.contains_ipa_claim) + , ipa_claim_public_input_indices(proving_key.ipa_claim_public_input_indices) + { + this->pcs_verification_key = std::make_shared(); + 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; + this->contains_pairing_point_accumulator = proving_key.contains_pairing_point_accumulator; + this->pairing_point_accumulator_public_input_indices = + proving_key.pairing_point_accumulator_public_input_indices; + + if (proving_key.commitment_key == nullptr) { + proving_key.commitment_key = std::make_shared(proving_key.circuit_size); + } + for (auto [polynomial, commitment] : zip_view(proving_key.polynomials.get_precomputed(), this->get_all())) { + commitment = proving_key.commitment_key->commit(polynomial); + } + } + // TODO(https://github.com/AztecProtocol/barretenberg/issues/964): Clean the boilerplate + // up. + VerificationKey(const uint64_t circuit_size, + const uint64_t num_public_inputs, + const uint64_t pub_inputs_offset, + const bool contains_pairing_point_accumulator, + const PairingPointAccumulatorPubInputIndices& pairing_point_accumulator_public_input_indices, + const bool contains_ipa_claim, + const IPAClaimPubInputIndices& ipa_claim_public_input_indices, + const Commitment& q_m, + const Commitment& q_c, + const Commitment& q_l, + const Commitment& q_r, + const Commitment& q_o, + const Commitment& q_4, + const Commitment& q_arith, + const Commitment& q_delta_range, + const Commitment& q_elliptic, + const Commitment& q_aux, + const Commitment& q_lookup, + const Commitment& q_poseidon2_external, + const Commitment& q_poseidon2_internal, + const Commitment& sigma_1, + const Commitment& sigma_2, + const Commitment& sigma_3, + const Commitment& sigma_4, + const Commitment& id_1, + const Commitment& id_2, + const Commitment& id_3, + const Commitment& id_4, + const Commitment& table_1, + const Commitment& table_2, + const Commitment& table_3, + const Commitment& table_4, + const Commitment& lagrange_first, + const Commitment& lagrange_last) + : contains_ipa_claim(contains_ipa_claim) + , ipa_claim_public_input_indices(ipa_claim_public_input_indices) + { + this->circuit_size = circuit_size; + this->log_circuit_size = numeric::get_msb(this->circuit_size); + this->num_public_inputs = num_public_inputs; + this->pub_inputs_offset = pub_inputs_offset; + this->contains_pairing_point_accumulator = contains_pairing_point_accumulator; + this->pairing_point_accumulator_public_input_indices = pairing_point_accumulator_public_input_indices; + this->q_m = q_m; + this->q_c = q_c; + this->q_l = q_l; + this->q_r = q_r; + this->q_o = q_o; + this->q_4 = q_4; + this->q_arith = q_arith; + this->q_delta_range = q_delta_range; + this->q_elliptic = q_elliptic; + this->q_aux = q_aux; + this->q_lookup = q_lookup; + this->q_poseidon2_external = q_poseidon2_external; + this->q_poseidon2_internal = q_poseidon2_internal; + this->sigma_1 = sigma_1; + this->sigma_2 = sigma_2; + this->sigma_3 = sigma_3; + this->sigma_4 = sigma_4; + this->id_1 = id_1; + this->id_2 = id_2; + this->id_3 = id_3; + this->id_4 = id_4; + this->table_1 = table_1; + this->table_2 = table_2; + this->table_3 = table_3; + this->table_4 = table_4; + this->lagrange_first = lagrange_first; + this->lagrange_last = lagrange_last; + } + + // For serialising and deserialising data + MSGPACK_FIELDS(circuit_size, + log_circuit_size, + num_public_inputs, + pub_inputs_offset, + contains_pairing_point_accumulator, + pairing_point_accumulator_public_input_indices, + contains_ipa_claim, + ipa_claim_public_input_indices, + q_m, + q_c, + q_l, + q_r, + q_o, + q_4, + q_arith, + q_delta_range, + q_elliptic, + q_aux, + q_lookup, + q_poseidon2_external, + q_poseidon2_internal, + sigma_1, + sigma_2, + sigma_3, + sigma_4, + id_1, + id_2, + id_3, + id_4, + table_1, + table_2, + table_3, + table_4, + lagrange_first, + lagrange_last); + }; + + using VerifierCommitments = VerifierCommitments_; +}; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.cpp b/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.cpp index 0dc60e9438f..f778a03c503 100644 --- a/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.cpp +++ b/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.cpp @@ -4,6 +4,7 @@ #include "barretenberg/stdlib_circuit_builders/mega_zk_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_keccak_flavor.hpp" +#include "barretenberg/stdlib_circuit_builders/ultra_rollup_flavor.hpp" namespace bb { template void TraceToPolynomials::populate_public_inputs_block(Builder& builder) @@ -174,6 +175,7 @@ void TraceToPolynomials::add_ecc_op_wires_to_proving_key(Builder& builde template class TraceToPolynomials; template class TraceToPolynomials; +template class TraceToPolynomials; template class TraceToPolynomials; template class TraceToPolynomials; template class TraceToPolynomials; diff --git a/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp b/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp index 06f69bdcb13..fa7853a3d96 100644 --- a/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp +++ b/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp @@ -441,7 +441,7 @@ template class BaseTranscript { }; template -static bb::StdlibProof convert_proof_to_witness(Builder* builder, const HonkProof& proof) +static bb::StdlibProof convert_native_proof_to_stdlib(Builder* builder, const HonkProof& proof) { bb::StdlibProof result; for (const auto& element : proof) { @@ -450,6 +450,15 @@ static bb::StdlibProof convert_proof_to_witness(Builder* builder, const return result; } +template static bb::HonkProof convert_stdlib_proof_to_native(const StdlibProof& proof) +{ + bb::HonkProof result; + for (const auto& element : proof) { + result.push_back(element.get_value()); + } + return result; +} + using NativeTranscript = BaseTranscript; /////////////////////////////////////////// diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_prover.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_prover.cpp index bdee7b3d8cd..60760a7c416 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_prover.cpp @@ -110,6 +110,7 @@ template HonkProof DeciderProver_::construct_proo } template class DeciderProver_; +template class DeciderProver_; template class DeciderProver_; template class DeciderProver_; template class DeciderProver_; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_prover.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_prover.hpp index b4f54e9cf96..1d8a7a85424 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_prover.hpp @@ -5,6 +5,7 @@ #include "barretenberg/stdlib_circuit_builders/mega_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/mega_zk_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp" +#include "barretenberg/stdlib_circuit_builders/ultra_rollup_flavor.hpp" #include "barretenberg/sumcheck/sumcheck_output.hpp" #include "barretenberg/sumcheck/zk_sumcheck_data.hpp" #include "barretenberg/transcript/transcript.hpp" diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp index 93a00d5c37c..e82b2ccacf9 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp @@ -189,6 +189,7 @@ void DeciderProvingKey_::move_structured_trace_overflow_to_overflow_bloc template class DeciderProvingKey_; template class DeciderProvingKey_; +template class DeciderProvingKey_; template class DeciderProvingKey_; template class DeciderProvingKey_; 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 cb9f954d193..442d4dcea53 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp @@ -8,6 +8,7 @@ #include "barretenberg/stdlib_circuit_builders/mega_zk_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_keccak_flavor.hpp" +#include "barretenberg/stdlib_circuit_builders/ultra_rollup_flavor.hpp" #include "barretenberg/trace_to_polynomials/trace_to_polynomials.hpp" namespace bb { @@ -307,12 +308,17 @@ template class DeciderProvingKey_ { proving_key.public_inputs.emplace_back(proving_key.polynomials.w_r[idx]); } - // Set the recursive proof indices + if constexpr (HasIPAAccumulatorFlavor) { // 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; + } + // Set the pairing point accumulator indices proving_key.pairing_point_accumulator_public_input_indices = circuit.pairing_point_accumulator_public_input_indices; proving_key.contains_pairing_point_accumulator = circuit.contains_pairing_point_accumulator; - if constexpr (IsMegaFlavor) { // Set databus commitment propagation data + if constexpr (HasDataBus) { // Set databus commitment propagation data proving_key.databus_propagation_data = circuit.databus_propagation_data; } auto end = std::chrono::steady_clock::now(); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_verifier.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_verifier.cpp index 996df320f95..22e93f76360 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_verifier.cpp @@ -89,6 +89,7 @@ template bool DeciderVerifier_::verify() template class DeciderVerifier_; template class DeciderVerifier_; +template class DeciderVerifier_; template class DeciderVerifier_; template class DeciderVerifier_; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp index cbea1470ab5..1137e11adda 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp @@ -264,6 +264,7 @@ template typename Flavor::RelationSeparator OinkProver; template class OinkProver; +template class OinkProver; template class OinkProver; template class OinkProver; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_verifier.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_verifier.cpp index bd7aa34fb88..8196f7f77e7 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_verifier.cpp @@ -3,6 +3,7 @@ #include "barretenberg/stdlib_circuit_builders/mega_zk_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_keccak_flavor.hpp" +#include "barretenberg/stdlib_circuit_builders/ultra_rollup_flavor.hpp" namespace bb { @@ -160,6 +161,7 @@ template typename Flavor::RelationSeparator OinkVerifier< template class OinkVerifier; template class OinkVerifier; +template class OinkVerifier; template class OinkVerifier; template class OinkVerifier; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp index b96d3d80748..152605af4b6 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp @@ -63,6 +63,7 @@ template HonkProof UltraProver_::construct_proof( template class UltraProver_; template class UltraProver_; +template class UltraProver_; template class UltraProver_; template class UltraProver_; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.hpp index 1ad13e57374..11264c72162 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.hpp @@ -3,6 +3,7 @@ #include "barretenberg/relations/relation_parameters.hpp" #include "barretenberg/stdlib_circuit_builders/mega_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp" +#include "barretenberg/stdlib_circuit_builders/ultra_rollup_flavor.hpp" #include "barretenberg/sumcheck/sumcheck_output.hpp" #include "barretenberg/transcript/transcript.hpp" #include "barretenberg/ultra_honk/decider_proving_key.hpp" diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp index d43f4cadb1c..ad8ed0139ee 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp @@ -1,4 +1,5 @@ #include "./ultra_verifier.hpp" +#include "barretenberg/commitment_schemes/ipa/ipa.hpp" #include "barretenberg/numeric/bitop/get_msb.hpp" #include "barretenberg/transcript/transcript.hpp" #include "barretenberg/ultra_honk/oink_verifier.hpp" @@ -9,7 +10,7 @@ namespace bb { * @brief This function verifies an Ultra Honk proof for a given Flavor. * */ -template bool UltraVerifier_::verify_proof(const HonkProof& proof) +template bool UltraVerifier_::verify_proof(const HonkProof& proof, const HonkProof& ipa_proof) { using FF = typename Flavor::FF; @@ -22,6 +23,40 @@ template bool UltraVerifier_::verify_proof(const HonkP transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx))); } + const auto recover_fq_from_public_inputs = [](std::array limbs) { + const uint256_t limb = uint256_t(limbs[0]) + + (uint256_t(limbs[1]) << stdlib::NUM_LIMB_BITS_IN_FIELD_SIMULATION) + + (uint256_t(limbs[2]) << (stdlib::NUM_LIMB_BITS_IN_FIELD_SIMULATION * 2)) + + (uint256_t(limbs[3]) << (stdlib::NUM_LIMB_BITS_IN_FIELD_SIMULATION * 3)); + return fq(limb); + }; + + // Parse out the nested IPA claim using key->ipa_claim_public_input_indices and runs the native IPA verifier. + if constexpr (HasIPAAccumulatorFlavor) { + 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]] + }; + + // verify the ipa_proof with this claim + auto ipa_transcript = std::make_shared(ipa_proof); + bool ipa_result = IPA::reduce_verify(ipa_verification_key, ipa_claim, ipa_transcript); + if (!ipa_result) { + return false; + } + } + } + DeciderVerifier decider_verifier{ verification_key, transcript }; return decider_verifier.verify(); @@ -29,6 +64,7 @@ template bool UltraVerifier_::verify_proof(const HonkP template class UltraVerifier_; template class UltraVerifier_; +template class UltraVerifier_; template class UltraVerifier_; template class UltraVerifier_; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.hpp index 7365303b655..effd6a3de94 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.hpp @@ -12,23 +12,27 @@ template class UltraVerifier_ { using FF = typename Flavor::FF; using Commitment = typename Flavor::Commitment; using VerificationKey = typename Flavor::VerificationKey; - using VerifierCommitmentKey = typename Flavor::VerifierCommitmentKey; using Transcript = typename Flavor::Transcript; using DeciderVK = DeciderVerificationKey_; using DeciderVerifier = DeciderVerifier_; public: - explicit UltraVerifier_(const std::shared_ptr& verifier_key) + explicit UltraVerifier_( + const std::shared_ptr& verifier_key, + const std::shared_ptr>& ipa_verification_key = nullptr) : verification_key(std::make_shared(verifier_key)) + , ipa_verification_key(ipa_verification_key) {} - bool verify_proof(const HonkProof& proof); + bool verify_proof(const HonkProof& proof, const HonkProof& ipa_proof = {}); std::shared_ptr transcript{ nullptr }; std::shared_ptr verification_key; + std::shared_ptr> ipa_verification_key; }; using UltraVerifier = UltraVerifier_; +using UltraRollupVerifier = UltraVerifier_; using UltraKeccakVerifier = UltraVerifier_; using MegaVerifier = UltraVerifier_; using MegaZKVerifier = UltraVerifier_; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/recursive_verifier.cpp index d61e6d7f0be..71518f7b6cf 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/recursive_verifier.cpp @@ -48,7 +48,7 @@ template AvmRecursiveVerifier_::AggregationObject AvmRecursiveVerifier_::verify_proof( const HonkProof& proof, const std::vector>& public_inputs_vec_nt, AggregationObject agg_obj) { - StdlibProof stdlib_proof = bb::convert_proof_to_witness(builder, proof); + StdlibProof stdlib_proof = bb::convert_native_proof_to_stdlib(builder, proof); std::vector> public_inputs_ct; public_inputs_ct.reserve(public_inputs_vec_nt.size()); diff --git a/bb-pilcom/bb-pil-backend/templates/recursive_verifier.cpp.hbs b/bb-pilcom/bb-pil-backend/templates/recursive_verifier.cpp.hbs index 3e7d779b523..80e5538a7d1 100644 --- a/bb-pilcom/bb-pil-backend/templates/recursive_verifier.cpp.hbs +++ b/bb-pilcom/bb-pil-backend/templates/recursive_verifier.cpp.hbs @@ -48,7 +48,7 @@ template {{name}}RecursiveVerifier_::AggregationObject {{name}}RecursiveVerifier_::verify_proof( const HonkProof& proof, const std::vector>& public_inputs_vec_nt, AggregationObject agg_obj) { - StdlibProof stdlib_proof = bb::convert_proof_to_witness(builder, proof); + StdlibProof stdlib_proof = bb::convert_native_proof_to_stdlib(builder, proof); std::vector> public_inputs_ct; public_inputs_ct.reserve(public_inputs_vec_nt.size()); diff --git a/yarn-project/bb-prover/src/prover/bb_private_kernel_prover.ts b/yarn-project/bb-prover/src/prover/bb_private_kernel_prover.ts index 4de354a0b56..7f16b0292fd 100644 --- a/yarn-project/bb-prover/src/prover/bb_private_kernel_prover.ts +++ b/yarn-project/bb-prover/src/prover/bb_private_kernel_prover.ts @@ -338,7 +338,7 @@ export class BBNativePrivateKernelProver implements PrivateKernelProver { ); if (vkResult.status === BB_RESULT.FAILURE) { - this.log.error(`Failed to generate proof for ${circuitType}${dbgCircuitName}: ${vkResult.reason}`); + this.log.error(`Failed to generate verification key for ${circuitType}${dbgCircuitName}: ${vkResult.reason}`); throw new Error(vkResult.reason); } diff --git a/yarn-project/bb-prover/src/prover/bb_prover.ts b/yarn-project/bb-prover/src/prover/bb_prover.ts index d4db2fbd376..f737b093a38 100644 --- a/yarn-project/bb-prover/src/prover/bb_prover.ts +++ b/yarn-project/bb-prover/src/prover/bb_prover.ts @@ -555,7 +555,7 @@ export class BBNativeRollupProver implements ServerCircuitProver { const provingResult = await generateTubeProof(this.config.bbBinaryPath, bbWorkingDirectory, logger.verbose); if (provingResult.status === BB_RESULT.FAILURE) { - logger.error(`Failed to generate proof for tube proof: ${provingResult.reason}`); + logger.error(`Failed to generate proof for tube circuit: ${provingResult.reason}`); throw new ProvingError(provingResult.reason, provingResult, provingResult.retry); } return provingResult;