diff --git a/barretenberg/cpp/src/barretenberg/srs/factories/mem_bn254_crs_factory.cpp b/barretenberg/cpp/src/barretenberg/srs/factories/mem_bn254_crs_factory.cpp index 3dff9aec750..ed9ab38739f 100644 --- a/barretenberg/cpp/src/barretenberg/srs/factories/mem_bn254_crs_factory.cpp +++ b/barretenberg/cpp/src/barretenberg/srs/factories/mem_bn254_crs_factory.cpp @@ -60,7 +60,7 @@ MemBn254CrsFactory::MemBn254CrsFactory(std::vector const& po std::shared_ptr> MemBn254CrsFactory::get_prover_crs(size_t degree) { if (prover_crs_->get_monomial_size() < degree) { - throw_or_abort(format("prover trying to get too many points in MemGrumpkinCrsFactory! ", + throw_or_abort(format("prover trying to get too many points in MemBn254CrsFactory! ", prover_crs_->get_monomial_size(), " vs ", degree)); @@ -72,7 +72,7 @@ std::shared_ptr> MemBn254CrsFactor { if (prover_crs_->get_monomial_size() < degree) { - throw_or_abort(format("verifier trying to get too many points in MemGrumpkinCrsFactory! ", + throw_or_abort(format("verifier trying to get too many points in MemBn254CrsFactory! ", prover_crs_->get_monomial_size(), " vs ", degree)); 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 cb5012bbaec..3c5a432d248 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 @@ -175,7 +175,7 @@ template class ProtogalaxyRecursiveTests : public tes * @brief Tests that a valid recursive fold works as expected. * */ - static void test_recursive_folding() + static void test_recursive_folding(const size_t num_verifiers = 1) { // Create two arbitrary circuits for the first round of folding InnerBuilder builder1; @@ -204,14 +204,30 @@ template class ProtogalaxyRecursiveTests : public tes auto verifier = FoldingRecursiveVerifier{ &folding_circuit, recursive_decider_vk_1, { recursive_decider_vk_2 } }; - verifier.verify_folding_proof(stdlib_proof); - info("Folding Recursive Verifier: num gates = ", folding_circuit.get_num_gates()); + std::shared_ptr accumulator; + for (size_t idx = 0; idx < num_verifiers; idx++) { + accumulator = verifier.verify_folding_proof(stdlib_proof); + if (idx < num_verifiers - 1) { // else the transcript is null in the test below + verifier = FoldingRecursiveVerifier{ &folding_circuit, + accumulator, + { std::make_shared( + &folding_circuit, decider_vk_1->verification_key) } }; + } + } + info("Folding Recursive Verifier: num gates unfinalized = ", folding_circuit.num_gates); EXPECT_EQ(folding_circuit.failed(), false) << folding_circuit.err(); // Perform native folding verification and ensure it returns the same result (either true or false) as // calling check_circuit on the recursive folding verifier InnerFoldingVerifier native_folding_verifier({ decider_vk_1, decider_vk_2 }); + std::shared_ptr native_accumulator; native_folding_verifier.verify_folding_proof(folding_proof.proof); + for (size_t idx = 0; idx < num_verifiers; idx++) { + native_accumulator = native_folding_verifier.verify_folding_proof(folding_proof.proof); + if (idx < num_verifiers - 1) { // else the transcript is null in the test below + native_folding_verifier = InnerFoldingVerifier{ { native_accumulator, decider_vk_1 } }; + } + } // Ensure that the underlying native and recursive folding verification algorithms agree by ensuring the // manifestsproduced by each agree. @@ -226,7 +242,11 @@ template class ProtogalaxyRecursiveTests : public tes // Check for a failure flag in the recursive verifier circuit if constexpr (!IsSimulator) { + // inefficiently check finalized size + folding_circuit.finalize_circuit(/* ensure_nonzero= */ true); + info("Folding Recursive Verifier: num gates finalized = ", folding_circuit.num_gates); auto decider_pk = std::make_shared(folding_circuit); + info("Dyadic size of verifier circuit: ", decider_pk->proving_key.circuit_size); OuterProver prover(decider_pk); auto honk_vk = std::make_shared(decider_pk->proving_key); OuterVerifier verifier(honk_vk); @@ -405,6 +425,11 @@ TYPED_TEST(ProtogalaxyRecursiveTests, RecursiveFoldingTest) TestFixture::test_recursive_folding(); } +TYPED_TEST(ProtogalaxyRecursiveTests, RecursiveFoldingTwiceTest) +{ + TestFixture::test_recursive_folding(/* num_verifiers= */ 2); +} + TYPED_TEST(ProtogalaxyRecursiveTests, FullProtogalaxyRecursiveTest) { diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_circuit_builder.cpp index 3b547ae0fed..3accdd2b758 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_circuit_builder.cpp @@ -10,10 +10,15 @@ using namespace bb::crypto; namespace bb { -template void MegaCircuitBuilder_::finalize_circuit() +template void MegaCircuitBuilder_::finalize_circuit(const bool ensure_nonzero) { + if (ensure_nonzero && !this->circuit_finalized) { + // do the mega part of ensuring all polynomials are nonzero; ultra part will be done inside of + // Ultra::finalize_circuit + add_mega_gates_to_ensure_all_polys_are_non_zero(); + } // All of the gates involved in finalization are part of the Ultra arithmetization - UltraCircuitBuilder_>::finalize_circuit(); + UltraCircuitBuilder_>::finalize_circuit(ensure_nonzero); } /** @@ -26,11 +31,8 @@ template void MegaCircuitBuilder_::finalize_circuit() // TODO(https://github.com/AztecProtocol/barretenberg/issues/1066): This function adds valid (but arbitrary) gates to // ensure that the circuit which includes them will not result in any zero-polynomials. It also ensures that the first // coefficient of the wire polynomials is zero, which is required for them to be shiftable. -template void MegaCircuitBuilder_::add_gates_to_ensure_all_polys_are_non_zero() +template void MegaCircuitBuilder_::add_mega_gates_to_ensure_all_polys_are_non_zero() { - // Most polynomials are handled via the conventional Ultra method - UltraCircuitBuilder_>::add_gates_to_ensure_all_polys_are_non_zero(); - // All that remains is to handle databus related and poseidon2 related polynomials. In what follows we populate the // calldata with some mock data then constuct a single calldata read gate @@ -62,6 +64,23 @@ template void MegaCircuitBuilder_::add_gates_to_ensure_all_pol this->queue_ecc_eq(); } +/** + * @brief Ensure all polynomials have at least one non-zero coefficient to avoid commiting to the zero-polynomial. + * This only adds gates for the Goblin polynomials. Most polynomials are handled via the Ultra method, + * which should be done by a separate call to the Ultra builder's non zero polynomial gates method. + * + * @param in Structure containing variables and witness selectors + */ +// TODO(https://github.com/AztecProtocol/barretenberg/issues/1066): This function adds valid (but arbitrary) gates to +// ensure that the circuit which includes them will not result in any zero-polynomials. It also ensures that the first +// coefficient of the wire polynomials is zero, which is required for them to be shiftable. +template void MegaCircuitBuilder_::add_ultra_and_mega_gates_to_ensure_all_polys_are_non_zero() +{ + // Most polynomials are handled via the conventional Ultra method + UltraCircuitBuilder_>::add_gates_to_ensure_all_polys_are_non_zero(); + add_mega_gates_to_ensure_all_polys_are_non_zero(); +} + /** * @brief Add simple point addition operation to the op queue and add corresponding gates * 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 37fe7724153..3663dcb1599 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 @@ -109,8 +109,9 @@ template class MegaCircuitBuilder_ : public UltraCircuitBuilder_ class MegaCircuitBuilder_ : public UltraCircuitBuilder_ builder; // instantiate new builder size_t num_gates_prior = builder.get_num_gates(); - builder.add_gates_to_ensure_all_polys_are_non_zero(); + builder.add_ultra_and_mega_gates_to_ensure_all_polys_are_non_zero(); size_t num_gates_post = builder.get_num_gates(); // accounts for finalization gates return num_gates_post - num_gates_prior; diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_circuit_builder.cpp index b87b30f356d..0d554b80c13 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_circuit_builder.cpp @@ -13,7 +13,8 @@ namespace bb { -template void UltraCircuitBuilder_::finalize_circuit() +template +void UltraCircuitBuilder_::finalize_circuit(const bool ensure_nonzero) { /** * First of all, add the gates related to ROM arrays and range lists. @@ -41,6 +42,9 @@ template void UltraCircuitBuilder_:: * our circuit is finalized, and we must not to execute these functions again. */ if (!circuit_finalized) { + if (ensure_nonzero) { + add_gates_to_ensure_all_polys_are_non_zero(); + } process_non_native_field_multiplications(); process_ROM_arrays(); process_RAM_arrays(); 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 567268caf16..ed3f12aae53 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 @@ -421,7 +421,7 @@ class UltraCircuitBuilder_ : public CircuitBuilderBase class DeciderProvingKey_ { std::shared_ptr commitment_key = nullptr) { BB_OP_COUNT_TIME_NAME("DeciderProvingKey(Circuit&)"); - circuit.add_gates_to_ensure_all_polys_are_non_zero(); - circuit.finalize_circuit(); + circuit.finalize_circuit(/* ensure_nonzero = */ true); // Set flag indicating whether the polynomials will be constructed with fixed block sizes for each gate type const bool is_structured = (trace_structure != TraceStructure::NONE);