From 5ca513881409880e8581a3fc6c9f3b3452087957 Mon Sep 17 00:00:00 2001 From: ludamad Date: Tue, 13 Aug 2024 21:08:42 -0400 Subject: [PATCH] chore(bb): prereq work for polynomial mem optimization (#7949) This PR: Splitting the implementation of plonk and honk into different polynomial classes. Greater work: We will be moving to 'polynomials with more structure' -> aka tracking a size and a virtual size* where 'size' is actually allocated memory, and virtual size is conceptually all 0's. This should save a good deal of memory. * I would call virtual size one more than the degree of the polynomial, but it's actually a bit weird to call it that when [size, virtual size) indices are all 0 coefficients. It's more like one more than the maximum degree of the polynomial, and only really used as an upper bound for loops or debug bounds checks. --- .../benchmark/basics_bench/basics.bench.cpp | 1 + .../benchmark/ipa_bench/ipa.bench.cpp | 4 +- .../commitment_schemes/commit.bench.cpp | 1 + .../commitment_schemes/commitment_key.hpp | 1 - .../commitment_key.test.hpp | 1 - .../commitment_schemes/gemini/gemini.cpp | 2 +- .../commitment_schemes/gemini/gemini.hpp | 2 +- .../commitment_schemes/ipa/ipa.fuzzer.cpp | 3 +- .../commitment_schemes/ipa/ipa.hpp | 2 +- .../commitment_schemes/ipa/ipa.test.cpp | 1 - .../commitment_schemes/kzg/kzg.hpp | 1 - .../commitment_schemes/kzg/kzg.test.cpp | 1 - .../shplonk/shplonk.test.cpp | 1 - .../commitment_schemes/verification_key.hpp | 1 - .../zeromorph/zeromorph.hpp | 2 +- .../eccvm/eccvm_circuit_builder.hpp | 1 + .../eccvm/eccvm_composer.test.cpp | 1 - .../src/barretenberg/eccvm/eccvm_flavor.hpp | 1 + .../src/barretenberg/eccvm/eccvm_prover.cpp | 1 - .../cpp/src/barretenberg/flavor/flavor.hpp | 18 +- .../src/barretenberg/flavor/flavor.test.cpp | 3 +- .../src/barretenberg/flavor/plonk_flavors.hpp | 4 +- .../cpp/src/barretenberg/goblin/goblin.hpp | 1 + .../honk/proof_system/permutation_library.hpp | 1 - .../src/barretenberg/honk/utils/testing.hpp | 1 - .../plonk/composer/standard_composer.cpp | 2 +- .../commitment_scheme/commitment_scheme.hpp | 2 +- .../commitment_scheme.test.cpp | 2 +- .../plonk/proof_system/prover/prover.cpp | 2 +- .../proof_system/proving_key/proving_key.hpp | 2 +- .../utils/generalized_permutation.hpp | 2 +- .../plonk/proof_system/utils/permutation.hpp | 2 +- .../permutation_widget_impl.hpp | 2 +- .../plonk/work_queue/work_queue.cpp | 2 +- .../composer/composer_lib.hpp | 2 +- .../composer/permutation_lib.hpp | 8 +- .../library/grand_product_library.hpp | 1 - .../polynomials/legacy_polynomial.cpp | 527 ++++++++++++++++++ .../polynomials/legacy_polynomial.hpp | 331 +++++++++++ .../polynomials/legacy_polynomial.test.cpp | 61 ++ ...bench.cpp => legacy_polynomials.bench.cpp} | 0 .../barretenberg/polynomials/polynomial.cpp | 506 ++++++----------- .../barretenberg/polynomials/polynomial.hpp | 271 ++++----- .../polynomials/polynomial.test.cpp | 10 +- .../polynomial_arithmetic.test.cpp | 32 +- .../polynomials/polynomial_store.cpp | 4 +- .../polynomials/polynomial_store.hpp | 4 +- .../polynomials/polynomial_store.test.cpp | 18 +- .../polynomials/polynomial_store_cache.hpp | 4 +- .../polynomials/polynomial_store_wasm.cpp | 4 +- .../polynomials/polynomial_store_wasm.hpp | 4 +- .../barretenberg/polynomials/serialize.hpp | 2 +- .../shared_shifted_virtual_zeroes_array.hpp | 52 ++ .../protogalaxy/protogalaxy_prover.hpp | 8 +- .../protogalaxy/protogalaxy_prover_impl.hpp | 3 +- .../protogalaxy/protogalaxy_verifier.cpp | 2 +- .../relations/databus_lookup_relation.hpp | 1 - .../relations/ecc_vm/ecc_lookup_relation.hpp | 1 - .../relations/ecc_vm/ecc_set_relation.hpp | 1 - .../generic_lookup_relation.hpp | 1 - .../generic_permutation_relation.hpp | 1 - .../relations/logderiv_lookup_relation.hpp | 1 - .../protogalaxy_recursive_verifier.cpp | 1 - .../protogalaxy_recursive_verifier.test.cpp | 2 +- .../grand_product_library.test.cpp | 1 - .../stdlib_circuit_builders/mega_flavor.hpp | 1 + .../mega_recursive_flavor.hpp | 1 - .../ultra_circuit_builder.hpp | 1 - .../stdlib_circuit_builders/ultra_keccak.hpp | 1 - .../ultra_recursive_flavor.hpp | 1 - .../barretenberg/sumcheck/sumcheck.test.cpp | 36 +- .../translator_vm/translator_flavor.hpp | 1 + .../barretenberg/vm/avm/generated/flavor.hpp | 1 - .../barretenberg/vm/avm/generated/prover.cpp | 1 - .../vm/avm/generated/verifier.cpp | 1 - .../bb-pil-backend/templates/flavor.hpp.hbs | 13 +- .../bb-pil-backend/templates/prover.cpp.hbs | 1 - .../bb-pil-backend/templates/verifier.cpp.hbs | 1 - 78 files changed, 1363 insertions(+), 635 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/polynomials/legacy_polynomial.cpp create mode 100644 barretenberg/cpp/src/barretenberg/polynomials/legacy_polynomial.hpp create mode 100644 barretenberg/cpp/src/barretenberg/polynomials/legacy_polynomial.test.cpp rename barretenberg/cpp/src/barretenberg/polynomials/{polynomials.bench.cpp => legacy_polynomials.bench.cpp} (100%) create mode 100644 barretenberg/cpp/src/barretenberg/polynomials/shared_shifted_virtual_zeroes_array.hpp diff --git a/barretenberg/cpp/src/barretenberg/benchmark/basics_bench/basics.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/basics_bench/basics.bench.cpp index a4cd2917cd0..00da0386848 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/basics_bench/basics.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/basics_bench/basics.bench.cpp @@ -24,6 +24,7 @@ #include "barretenberg/common/op_count.hpp" #include "barretenberg/common/thread.hpp" #include "barretenberg/ecc/curves/bn254/bn254.hpp" +#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/srs/global_crs.hpp" #include diff --git a/barretenberg/cpp/src/barretenberg/benchmark/ipa_bench/ipa.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/ipa_bench/ipa.bench.cpp index fac0f30f3b5..e099e100826 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/ipa_bench/ipa.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/ipa_bench/ipa.bench.cpp @@ -1,4 +1,5 @@ #include "barretenberg/commitment_schemes/ipa/ipa.hpp" +#include "barretenberg/polynomials/polynomial.hpp" #include using namespace benchmark; @@ -7,6 +8,7 @@ using namespace bb; namespace { using Curve = curve::Grumpkin; using Fr = Curve::ScalarField; +using Polynomial = Polynomial; constexpr size_t MIN_POLYNOMIAL_DEGREE_LOG2 = 10; constexpr size_t MAX_POLYNOMIAL_DEGREE_LOG2 = 16; @@ -31,7 +33,7 @@ void ipa_open(State& state) noexcept state.PauseTiming(); size_t n = 1 << static_cast(state.range(0)); // Construct the polynomial - Polynomial poly(n); + Polynomial poly(n); for (size_t i = 0; i < n; ++i) { poly[i] = Fr::random_element(&engine); } diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/commit.bench.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/commit.bench.cpp index 88a27cd1b6c..f0b20c0a03c 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/commit.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/commit.bench.cpp @@ -1,5 +1,6 @@ #include "barretenberg/commitment_schemes/commitment_key.hpp" +#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/srs/factories/mem_bn254_crs_factory.hpp" #include diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.hpp index c6b23b071e7..ab67227424b 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.hpp @@ -10,7 +10,6 @@ #include "barretenberg/common/op_count.hpp" #include "barretenberg/ecc/scalar_multiplication/scalar_multiplication.hpp" #include "barretenberg/numeric/bitop/pow.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/polynomial_arithmetic.hpp" #include "barretenberg/srs/factories/crs_factory.hpp" #include "barretenberg/srs/factories/file_crs_factory.hpp" diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.test.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.test.hpp index e91b61bbad5..00d7c39343b 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.test.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.test.hpp @@ -3,7 +3,6 @@ #include "barretenberg/commitment_schemes/commitment_key.hpp" #include "barretenberg/commitment_schemes/verification_key.hpp" #include "barretenberg/ecc/curves/bn254/g1.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/srs/factories/file_crs_factory.hpp" #include "claim.hpp" diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.cpp index 19e815f8ab5..4422abdee0d 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.cpp @@ -53,7 +53,7 @@ namespace bb { * @return std::vector */ template -std::vector> GeminiProver_::compute_gemini_polynomials( +std::vector::Polynomial> GeminiProver_::compute_gemini_polynomials( std::span mle_opening_point, Polynomial&& batched_unshifted, Polynomial&& batched_to_be_shifted) { const size_t num_variables = mle_opening_point.size(); // m diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp index 94fbd5c43c7..23142078def 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp @@ -59,7 +59,7 @@ namespace bb { */ template struct GeminiProverOutput { std::vector> opening_pairs; - std::vector> witnesses; + std::vector> witnesses; }; namespace gemini { diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.fuzzer.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.fuzzer.cpp index df6c3ec3115..b8893ed4300 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.fuzzer.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.fuzzer.cpp @@ -3,7 +3,6 @@ #include "./mock_transcript.hpp" #include "barretenberg/commitment_schemes/commitment_key.hpp" #include "barretenberg/commitment_schemes/verification_key.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/srs/factories/file_crs_factory.hpp" namespace bb { @@ -36,6 +35,8 @@ class ProxyCaller { }; } // namespace bb +using namespace bb; + /** * @brief Initialize SRS, commitment key, verification key * diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp index 0fcc7c65841..bdb31f2eac5 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp @@ -127,7 +127,7 @@ template class IPA { * 7. Compute \f$\vec{b}_{i-1}=\vec{b}_{i\_low}+u_{i-1}^{-1}\cdot \vec{b}_{i\_high}\f$​ * *7. Send the final \f$\vec{a}_{0} = (a_0)\f$ to the verifier - */ + */ template static void compute_opening_proof_internal(const std::shared_ptr& ck, const ProverOpeningClaim& opening_claim, diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.test.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.test.cpp index db8a2597a5b..97c701075cc 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.test.cpp @@ -6,7 +6,6 @@ #include "barretenberg/common/mem.hpp" #include "barretenberg/ecc/curves/bn254/fq12.hpp" #include "barretenberg/ecc/curves/types.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/polynomial_arithmetic.hpp" #include #include diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.hpp index 1c403dc22cc..0a1a873412c 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.hpp @@ -3,7 +3,6 @@ #include "../claim.hpp" #include "barretenberg/commitment_schemes/commitment_key.hpp" #include "barretenberg/commitment_schemes/verification_key.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/transcript/transcript.hpp" #include diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.test.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.test.cpp index 5dd1fa892c4..42cf6b9f8fb 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.test.cpp @@ -5,7 +5,6 @@ #include "../commitment_key.test.hpp" #include "barretenberg/commitment_schemes/claim.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/ecc/curves/bn254/g1.hpp" diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplonk.test.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplonk.test.cpp index 299ee846a2a..73e726ed34c 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplonk.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplonk.test.cpp @@ -9,7 +9,6 @@ #include "../commitment_key.test.hpp" #include "barretenberg/commitment_schemes/claim.hpp" -#include "barretenberg/polynomials/polynomial.hpp" namespace bb { template class ShplonkTest : public CommitmentTest {}; diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/verification_key.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/verification_key.hpp index 909a40cd439..953e66b7534 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/verification_key.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/verification_key.hpp @@ -11,7 +11,6 @@ #include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp" #include "barretenberg/ecc/scalar_multiplication/scalar_multiplication.hpp" #include "barretenberg/numeric/bitop/pow.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/polynomial_arithmetic.hpp" #include "barretenberg/srs/global_crs.hpp" diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp index 4f66c019c89..aa0cf5b0273 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp @@ -90,7 +90,7 @@ template class ZeroMorphProver_ { std::vector f_k; f_k.resize(size_q); - std::vector g(polynomial.data().get(), polynomial.data().get() + size_q); + std::vector g(polynomial.data(), polynomial.data() + size_q); // Compute q_k in reverse order from k= n-2, i.e. q_{n-2}, ..., q_0 for (size_t k = 1; k < log_N; ++k) { diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_circuit_builder.hpp index 815659ee3aa..5d560639642 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_circuit_builder.hpp @@ -8,6 +8,7 @@ #include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp" #include "barretenberg/honk/proof_system/logderivative_library.hpp" #include "barretenberg/honk/proof_system/permutation_library.hpp" +#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/relations/relation_parameters.hpp" #include "barretenberg/stdlib_circuit_builders/op_queue/ecc_op_queue.hpp" diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_composer.test.cpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_composer.test.cpp index c3ae908ff71..d77bb7433c5 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_composer.test.cpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_composer.test.cpp @@ -8,7 +8,6 @@ #include "barretenberg/eccvm/eccvm_verifier.hpp" #include "barretenberg/numeric/uint256/uint256.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_delta.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/relations/permutation_relation.hpp" #include "barretenberg/relations/relation_parameters.hpp" #include "barretenberg/sumcheck/sumcheck_round.hpp" diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp index 3c2e164cb97..89b3b5a1593 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp @@ -7,6 +7,7 @@ #include "barretenberg/flavor/flavor.hpp" #include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/flavor/relation_definitions.hpp" +#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/ecc_vm/ecc_bools_relation.hpp" #include "barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp" diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp index 830eb760683..2bfc2b565ed 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp @@ -6,7 +6,6 @@ #include "barretenberg/honk/proof_system/logderivative_library.hpp" #include "barretenberg/honk/proof_system/permutation_library.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_library.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/relations/permutation_relation.hpp" #include "barretenberg/sumcheck/sumcheck.hpp" diff --git a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp index edc0c6ebaaa..db63d9cb0cd 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp @@ -411,20 +411,20 @@ concept IsHonkFlavor = IsAnyOf concept IsUltraFlavor = IsAnyOf; -template +template concept IsGoblinFlavor = IsAnyOf, MegaRecursiveFlavor_, MegaRecursiveFlavor_>; -template -concept IsRecursiveFlavor = IsAnyOf, - UltraRecursiveFlavor_, +template +concept IsRecursiveFlavor = IsAnyOf, + UltraRecursiveFlavor_, UltraRecursiveFlavor_, MegaRecursiveFlavor_, MegaRecursiveFlavor_, -MegaRecursiveFlavor_, -TranslatorRecursiveFlavor_, -TranslatorRecursiveFlavor_, +MegaRecursiveFlavor_, +TranslatorRecursiveFlavor_, +TranslatorRecursiveFlavor_, TranslatorRecursiveFlavor_, ECCVMRecursiveFlavor_>; @@ -433,7 +433,7 @@ template concept IsECCVMRecursiveFlavor = IsAnyOf concept IsGrumpkinFlavor = IsAnyOf; -template concept IsFoldingFlavor = IsAnyOf concept IsFoldingFlavor = IsAnyOf concept IsFoldingFlavor = IsAnyOf, UltraRecursiveFlavor_, UltraRecursiveFlavor_, - MegaRecursiveFlavor_, + MegaRecursiveFlavor_, MegaRecursiveFlavor_, MegaRecursiveFlavor_>; template diff --git a/barretenberg/cpp/src/barretenberg/flavor/flavor.test.cpp b/barretenberg/cpp/src/barretenberg/flavor/flavor.test.cpp index 06d24472a9a..da3681c37ad 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/flavor.test.cpp +++ b/barretenberg/cpp/src/barretenberg/flavor/flavor.test.cpp @@ -1,4 +1,3 @@ -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/srs/factories/crs_factory.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp" #include @@ -78,7 +77,7 @@ TEST(Flavor, GetRow) }); Flavor::ProverPolynomials prover_polynomials; for (auto [poly, entry] : zip_view(prover_polynomials.get_all(), data)) { - poly = entry; + poly = Flavor::Polynomial(entry); } auto row0 = prover_polynomials.get_row(0); auto row1 = prover_polynomials.get_row(1); diff --git a/barretenberg/cpp/src/barretenberg/flavor/plonk_flavors.hpp b/barretenberg/cpp/src/barretenberg/flavor/plonk_flavors.hpp index bad2062b805..c215edb0695 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/plonk_flavors.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/plonk_flavors.hpp @@ -12,7 +12,7 @@ class Standard { using ProvingKey = plonk::proving_key; using Curve = curve::BN254; using FF = Curve::ScalarField; - using Polynomial = bb::Polynomial; + using Polynomial = bb::LegacyPolynomial; static constexpr size_t NUM_WIRES = CircuitBuilder::NUM_WIRES; // Whether or not the first row of the execution trace is reserved for 0s to enable shifts static constexpr bool has_zero_row = false; @@ -24,7 +24,7 @@ class Ultra { using ProvingKey = plonk::proving_key; using Curve = curve::BN254; using FF = Curve::ScalarField; - using Polynomial = bb::Polynomial; + using Polynomial = bb::LegacyPolynomial; static constexpr size_t NUM_WIRES = CircuitBuilder::NUM_WIRES; // Whether or not the first row of the execution trace is reserved for 0s to enable shifts static constexpr bool has_zero_row = false; diff --git a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp index e9a073d559e..dd108df0be6 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp @@ -7,6 +7,7 @@ #include "barretenberg/goblin/mock_circuits.hpp" #include "barretenberg/goblin/types.hpp" #include "barretenberg/plonk_honk_shared/instance_inspector.hpp" +#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/stdlib/honk_recursion/verifier/merge_recursive_verifier.hpp" #include "barretenberg/stdlib_circuit_builders/mega_circuit_builder.hpp" #include "barretenberg/stdlib_circuit_builders/mega_flavor.hpp" diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp index e42d5e41d98..5ef1cc1bbbd 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp @@ -1,7 +1,6 @@ #pragma once #include "barretenberg/common/ref_vector.hpp" #include "barretenberg/common/zip_view.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/relations/relation_parameters.hpp" #include diff --git a/barretenberg/cpp/src/barretenberg/honk/utils/testing.hpp b/barretenberg/cpp/src/barretenberg/honk/utils/testing.hpp index b9f1fb8f4d8..7b0de5d5677 100644 --- a/barretenberg/cpp/src/barretenberg/honk/utils/testing.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/utils/testing.hpp @@ -1,6 +1,5 @@ #pragma once #include "barretenberg/common/zip_view.hpp" -#include "barretenberg/polynomials/polynomial.hpp" namespace bb { /** diff --git a/barretenberg/cpp/src/barretenberg/plonk/composer/standard_composer.cpp b/barretenberg/cpp/src/barretenberg/plonk/composer/standard_composer.cpp index aa47b807998..fdfb2903590 100644 --- a/barretenberg/cpp/src/barretenberg/plonk/composer/standard_composer.cpp +++ b/barretenberg/cpp/src/barretenberg/plonk/composer/standard_composer.cpp @@ -6,7 +6,7 @@ #include "barretenberg/plonk/proof_system/widgets/transition_widgets/arithmetic_widget.hpp" #include "barretenberg/plonk_honk_shared/composer/composer_lib.hpp" #include "barretenberg/plonk_honk_shared/composer/permutation_lib.hpp" -#include "barretenberg/polynomials/polynomial.hpp" +#include "barretenberg/polynomials/legacy_polynomial.hpp" #include #include diff --git a/barretenberg/cpp/src/barretenberg/plonk/proof_system/commitment_scheme/commitment_scheme.hpp b/barretenberg/cpp/src/barretenberg/plonk/proof_system/commitment_scheme/commitment_scheme.hpp index 800af9d672d..88cba1adddd 100644 --- a/barretenberg/cpp/src/barretenberg/plonk/proof_system/commitment_scheme/commitment_scheme.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk/proof_system/commitment_scheme/commitment_scheme.hpp @@ -1,5 +1,5 @@ #pragma once -#include "../../../polynomials/polynomial.hpp" +#include "../../../polynomials/legacy_polynomial.hpp" #include "../../../polynomials/polynomial_arithmetic.hpp" #include "../types/commitment_open_proof.hpp" #include "../types/program_settings.hpp" diff --git a/barretenberg/cpp/src/barretenberg/plonk/proof_system/commitment_scheme/commitment_scheme.test.cpp b/barretenberg/cpp/src/barretenberg/plonk/proof_system/commitment_scheme/commitment_scheme.test.cpp index 299b1f83e1b..bcc58f7abe8 100644 --- a/barretenberg/cpp/src/barretenberg/plonk/proof_system/commitment_scheme/commitment_scheme.test.cpp +++ b/barretenberg/cpp/src/barretenberg/plonk/proof_system/commitment_scheme/commitment_scheme.test.cpp @@ -5,7 +5,7 @@ #include "../types/program_settings.hpp" #include "barretenberg/common/mem.hpp" #include "barretenberg/plonk/work_queue/work_queue.hpp" -#include "barretenberg/polynomials/polynomial.hpp" +#include "barretenberg/polynomials/legacy_polynomial.hpp" #include "barretenberg/polynomials/polynomial_arithmetic.hpp" #include "barretenberg/srs/factories/file_crs_factory.hpp" #include diff --git a/barretenberg/cpp/src/barretenberg/plonk/proof_system/prover/prover.cpp b/barretenberg/cpp/src/barretenberg/plonk/proof_system/prover/prover.cpp index 07a0dadbf2c..3011122a4e3 100644 --- a/barretenberg/cpp/src/barretenberg/plonk/proof_system/prover/prover.cpp +++ b/barretenberg/cpp/src/barretenberg/plonk/proof_system/prover/prover.cpp @@ -3,7 +3,7 @@ #include "barretenberg/ecc/scalar_multiplication/scalar_multiplication.hpp" #include "barretenberg/plonk/proof_system/types/prover_settings.hpp" #include "barretenberg/polynomials/iterate_over_domain.hpp" -#include "barretenberg/polynomials/polynomial.hpp" +#include "barretenberg/polynomials/legacy_polynomial.hpp" #include "barretenberg/polynomials/polynomial_arithmetic.hpp" #include 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 817f4b2d1f1..3952179f12b 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 @@ -8,7 +8,7 @@ #include "barretenberg/plonk/proof_system/types/polynomial_manifest.hpp" #include "barretenberg/plonk_honk_shared/types/aggregation_object_type.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" -#include "barretenberg/polynomials/polynomial.hpp" +#include "barretenberg/polynomials/legacy_polynomial.hpp" #include "barretenberg/srs/factories/crs_factory.hpp" #ifdef __wasm__ diff --git a/barretenberg/cpp/src/barretenberg/plonk/proof_system/utils/generalized_permutation.hpp b/barretenberg/cpp/src/barretenberg/plonk/proof_system/utils/generalized_permutation.hpp index eeb09526502..ca154eb88f6 100644 --- a/barretenberg/cpp/src/barretenberg/plonk/proof_system/utils/generalized_permutation.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk/proof_system/utils/generalized_permutation.hpp @@ -1,7 +1,7 @@ #pragma once #include "barretenberg/numeric/bitop/get_msb.hpp" #include "barretenberg/polynomials/iterate_over_domain.hpp" -#include "barretenberg/polynomials/polynomial.hpp" +#include "barretenberg/polynomials/legacy_polynomial.hpp" namespace bb::plonk { template diff --git a/barretenberg/cpp/src/barretenberg/plonk/proof_system/utils/permutation.hpp b/barretenberg/cpp/src/barretenberg/plonk/proof_system/utils/permutation.hpp index ad50503df8d..ab95ddb05cd 100644 --- a/barretenberg/cpp/src/barretenberg/plonk/proof_system/utils/permutation.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk/proof_system/utils/permutation.hpp @@ -3,7 +3,7 @@ #include "barretenberg/common/throw_or_abort.hpp" #include "barretenberg/numeric/bitop/get_msb.hpp" #include "barretenberg/polynomials/iterate_over_domain.hpp" -#include "barretenberg/polynomials/polynomial.hpp" +#include "barretenberg/polynomials/legacy_polynomial.hpp" namespace bb::plonk { diff --git a/barretenberg/cpp/src/barretenberg/plonk/proof_system/widgets/random_widgets/permutation_widget_impl.hpp b/barretenberg/cpp/src/barretenberg/plonk/proof_system/widgets/random_widgets/permutation_widget_impl.hpp index 387ed72dc56..9947a38baa0 100644 --- a/barretenberg/cpp/src/barretenberg/plonk/proof_system/widgets/random_widgets/permutation_widget_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk/proof_system/widgets/random_widgets/permutation_widget_impl.hpp @@ -4,7 +4,7 @@ #include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp" #include "barretenberg/plonk/proof_system/public_inputs/public_inputs.hpp" #include "barretenberg/polynomials/iterate_over_domain.hpp" -#include "barretenberg/polynomials/polynomial.hpp" +#include "barretenberg/polynomials/legacy_polynomial.hpp" #include "barretenberg/polynomials/polynomial_arithmetic.hpp" #include "barretenberg/transcript/transcript.hpp" diff --git a/barretenberg/cpp/src/barretenberg/plonk/work_queue/work_queue.cpp b/barretenberg/cpp/src/barretenberg/plonk/work_queue/work_queue.cpp index 9128f542457..571876b06c6 100644 --- a/barretenberg/cpp/src/barretenberg/plonk/work_queue/work_queue.cpp +++ b/barretenberg/cpp/src/barretenberg/plonk/work_queue/work_queue.cpp @@ -1,6 +1,6 @@ #include "work_queue.hpp" #include "barretenberg/ecc/scalar_multiplication/scalar_multiplication.hpp" -#include "barretenberg/polynomials/polynomial.hpp" +#include "barretenberg/polynomials/legacy_polynomial.hpp" #include "barretenberg/polynomials/polynomial_arithmetic.hpp" namespace bb::plonk { diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.hpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.hpp index d4e75dc9e14..543f282fb05 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.hpp @@ -9,7 +9,7 @@ namespace bb { template -void construct_lookup_table_polynomials(RefArray table_polynomials, +void construct_lookup_table_polynomials(const RefArray& table_polynomials, const typename Flavor::CircuitBuilder& circuit, size_t dyadic_circuit_size, size_t additional_offset = 0) diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/permutation_lib.hpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/permutation_lib.hpp index 52bd04ec97d..8ae6aad831c 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/permutation_lib.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/permutation_lib.hpp @@ -13,7 +13,6 @@ #include "barretenberg/flavor/flavor.hpp" #include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp" #include "barretenberg/polynomials/iterate_over_domain.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include #include @@ -347,10 +346,11 @@ void compute_monomial_and_coset_fft_polynomials_from_lagrange(std::string label, * @brief Compute Lagrange Polynomials L_0 and L_{n-1} and put them in the polynomial cache */ template -inline std::tuple, Polynomial> compute_first_and_last_lagrange_polynomials(const size_t circuit_size) +inline std::tuple, LegacyPolynomial> compute_first_and_last_lagrange_polynomials( + const size_t circuit_size) { - Polynomial lagrange_polynomial_0(circuit_size); - Polynomial lagrange_polynomial_n_min_1(circuit_size); + LegacyPolynomial lagrange_polynomial_0(circuit_size); + LegacyPolynomial lagrange_polynomial_n_min_1(circuit_size); lagrange_polynomial_0[0] = 1; lagrange_polynomial_n_min_1[circuit_size - 1] = 1; diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/library/grand_product_library.hpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/library/grand_product_library.hpp index 43d01587541..fd988bfd042 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/library/grand_product_library.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/library/grand_product_library.hpp @@ -3,7 +3,6 @@ #include "barretenberg/common/thread.hpp" #include "barretenberg/common/zip_view.hpp" #include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/relations/relation_parameters.hpp" #include diff --git a/barretenberg/cpp/src/barretenberg/polynomials/legacy_polynomial.cpp b/barretenberg/cpp/src/barretenberg/polynomials/legacy_polynomial.cpp new file mode 100644 index 00000000000..717a10e44eb --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/polynomials/legacy_polynomial.cpp @@ -0,0 +1,527 @@ +#include "legacy_polynomial.hpp" +#include "barretenberg/common/assert.hpp" +#include "barretenberg/common/slab_allocator.hpp" +#include "barretenberg/common/thread.hpp" +#include "barretenberg/numeric/bitop/pow.hpp" +#include "polynomial_arithmetic.hpp" +#include +#include +#include +#include +#include +#include +#include +#include + +namespace bb { + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) +template std::shared_ptr _allocate_aligned_memory(const size_t n_elements) +{ + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) + return std::static_pointer_cast(get_mem_slab(sizeof(Fr) * n_elements)); +} + +template void LegacyPolynomial::allocate_backing_memory(size_t n_elements) +{ + size_ = n_elements; + // capacity() is size_ plus padding for shifted polynomials + backing_memory_ = _allocate_aligned_memory(capacity()); + coefficients_ = backing_memory_.get(); +} + +/** + * Constructors / Destructors + **/ + +/** + * @brief Initialize a Polynomial to size 'initial_size', zeroing memory. + * + * @param initial_size The initial size of the polynomial. + */ +template LegacyPolynomial::LegacyPolynomial(size_t initial_size) +{ + allocate_backing_memory(initial_size); + memset(static_cast(coefficients_), 0, sizeof(Fr) * capacity()); +} + +/** + * @brief Initialize a Polynomial to size 'initial_size'. + * Important: This does NOT zero memory. + * + * @param initial_size The initial size of the polynomial. + * @param flag Signals that we do not zero memory. + */ +template LegacyPolynomial::LegacyPolynomial(size_t initial_size, DontZeroMemory flag) +{ + // Flag is unused, but we don't memset 0 if passed. + (void)flag; + allocate_backing_memory(initial_size); +} + +template +LegacyPolynomial::LegacyPolynomial(const LegacyPolynomial& other) + : LegacyPolynomial(other, other.size()) +{} + +// fully copying "expensive" constructor +template +LegacyPolynomial::LegacyPolynomial(const LegacyPolynomial& other, const size_t target_size) +{ + allocate_backing_memory(std::max(target_size, other.size())); + + memcpy(static_cast(coefficients_), static_cast(other.coefficients_), sizeof(Fr) * other.size_); + zero_memory_beyond(other.size_); +} + +// move constructor +template +LegacyPolynomial::LegacyPolynomial(LegacyPolynomial&& other) noexcept + : backing_memory_(std::exchange(other.backing_memory_, nullptr)) + , coefficients_(std::exchange(other.coefficients_, nullptr)) + , size_(std::exchange(other.size_, 0)) +{} + +// span constructor +template LegacyPolynomial::LegacyPolynomial(std::span coefficients) +{ + allocate_backing_memory(coefficients.size()); + memcpy(static_cast(coefficients_), + static_cast(coefficients.data()), + sizeof(Fr) * coefficients.size()); + zero_memory_beyond(size_); +} + +// interpolation constructor +template +LegacyPolynomial::LegacyPolynomial(std::span interpolation_points, std::span evaluations) + : LegacyPolynomial(interpolation_points.size()) +{ + ASSERT(size_ > 0); + + polynomial_arithmetic::compute_efficient_interpolation( + evaluations.data(), coefficients_, interpolation_points.data(), size_); +} + +// Assignments + +// full copy "expensive" assignment +template LegacyPolynomial& LegacyPolynomial::operator=(const LegacyPolynomial& other) +{ + if (this == &other) { + return *this; + } + allocate_backing_memory(other.size_); + memcpy(static_cast(coefficients_), static_cast(other.coefficients_), sizeof(Fr) * other.size_); + zero_memory_beyond(size_); + return *this; +} + +template LegacyPolynomial& LegacyPolynomial::operator=(std::span coefficients) noexcept +{ + // move assign a Polynomial constructed with the span + *this = LegacyPolynomial{ coefficients }; + return *this; +} + +// ####### +template LegacyPolynomial& LegacyPolynomial::operator=(LegacyPolynomial&& other) noexcept +{ + if (&other == this) { + return *this; + } + + // simultaneously set members and clear other + backing_memory_ = std::exchange(other.backing_memory_, nullptr); + coefficients_ = std::exchange(other.coefficients_, nullptr); + size_ = std::exchange(other.size_, 0); + return *this; +} + +template LegacyPolynomial LegacyPolynomial::share() const +{ + LegacyPolynomial p; + p.backing_memory_ = backing_memory_; + p.size_ = size_; + p.coefficients_ = coefficients_; + return p; +} + +template Fr LegacyPolynomial::evaluate(const Fr& z, const size_t target_size) const +{ + return polynomial_arithmetic::evaluate(coefficients_, z, target_size); +} + +template Fr LegacyPolynomial::evaluate(const Fr& z) const +{ + return polynomial_arithmetic::evaluate(coefficients_, z, size_); +} + +template bool LegacyPolynomial::operator==(LegacyPolynomial const& rhs) const +{ + // If either is empty, both must be + if (is_empty() || rhs.is_empty()) { + return is_empty() && rhs.is_empty(); + } + // Size must agree + if (size() != rhs.size()) { + return false; + } + // Each coefficient must agree + for (size_t i = 0; i < size(); i++) { + if (coefficients_[i] != rhs.coefficients_[i]) { + return false; + } + } + return true; +} + +/** + * @brief sets a block of memory to all zeroes + * Used to zero out unintialized memory to ensure that, when writing to the polynomial in future, + * memory requests made to the OS do not return virtual pages (performance optimization). + * Used, for example, when one polynomial is instantiated from another one with size_>= other.size_. + * + * @param opening_proof Opening proof computed by `batch_open` + * @param commitment_data Describes each polynomial being opened: its commitment, the opening points used and the + * polynomial evaluations + */ +template void LegacyPolynomial::zero_memory_beyond(const size_t start_position) +{ + size_t end = capacity(); + ASSERT(end >= start_position); + + size_t delta = end - start_position; + if (delta > 0) { + ASSERT(backing_memory_); + memset(static_cast(&coefficients_[start_position]), 0, sizeof(Fr) * delta); + } +} + +/** + * FFTs + **/ + +template +void LegacyPolynomial::fft(const EvaluationDomain& domain) + requires polynomial_arithmetic::SupportsFFT +{ + ASSERT(in_place_operation_viable(domain.size)); + zero_memory_beyond(domain.size); + + polynomial_arithmetic::fft(coefficients_, domain); +} + +template +void LegacyPolynomial::partial_fft(const EvaluationDomain& domain, Fr constant, bool is_coset) + requires polynomial_arithmetic::SupportsFFT +{ + ASSERT(in_place_operation_viable(domain.size)); + zero_memory_beyond(domain.size); + + polynomial_arithmetic::partial_fft(coefficients_, domain, constant, is_coset); +} + +template +void LegacyPolynomial::coset_fft(const EvaluationDomain& domain) + requires polynomial_arithmetic::SupportsFFT +{ + ASSERT(in_place_operation_viable(domain.size)); + zero_memory_beyond(domain.size); + + polynomial_arithmetic::coset_fft(coefficients_, domain); +} + +template +void LegacyPolynomial::coset_fft(const EvaluationDomain& domain, + const EvaluationDomain& large_domain, + const size_t domain_extension) + requires polynomial_arithmetic::SupportsFFT +{ + size_t extended_size = domain.size * domain_extension; + + ASSERT(in_place_operation_viable(extended_size)); + zero_memory_beyond(extended_size); + + polynomial_arithmetic::coset_fft(coefficients_, domain, large_domain, domain_extension); +} + +template +void LegacyPolynomial::coset_fft_with_constant(const EvaluationDomain& domain, const Fr& constant) + requires polynomial_arithmetic::SupportsFFT +{ + ASSERT(in_place_operation_viable(domain.size)); + zero_memory_beyond(domain.size); + + polynomial_arithmetic::coset_fft_with_constant(coefficients_, domain, constant); +} + +template +void LegacyPolynomial::coset_fft_with_generator_shift(const EvaluationDomain& domain, const Fr& constant) + requires polynomial_arithmetic::SupportsFFT +{ + ASSERT(in_place_operation_viable(domain.size)); + zero_memory_beyond(domain.size); + + polynomial_arithmetic::coset_fft_with_generator_shift(coefficients_, domain, constant); +} + +template +void LegacyPolynomial::ifft(const EvaluationDomain& domain) + requires polynomial_arithmetic::SupportsFFT +{ + ASSERT(in_place_operation_viable(domain.size)); + zero_memory_beyond(domain.size); + + polynomial_arithmetic::ifft(coefficients_, domain); +} + +template +void LegacyPolynomial::ifft_with_constant(const EvaluationDomain& domain, const Fr& constant) + requires polynomial_arithmetic::SupportsFFT +{ + ASSERT(in_place_operation_viable(domain.size)); + zero_memory_beyond(domain.size); + + polynomial_arithmetic::ifft_with_constant(coefficients_, domain, constant); +} + +template +void LegacyPolynomial::coset_ifft(const EvaluationDomain& domain) + requires polynomial_arithmetic::SupportsFFT +{ + ASSERT(in_place_operation_viable(domain.size)); + zero_memory_beyond(domain.size); + + polynomial_arithmetic::coset_ifft(coefficients_, domain); +} + +template +Fr LegacyPolynomial::compute_kate_opening_coefficients(const Fr& z) + requires polynomial_arithmetic::SupportsFFT +{ + return polynomial_arithmetic::compute_kate_opening_coefficients(coefficients_, coefficients_, z, size_); +} + +template +Fr LegacyPolynomial::compute_barycentric_evaluation(const Fr& z, const EvaluationDomain& domain) + requires polynomial_arithmetic::SupportsFFT +{ + return polynomial_arithmetic::compute_barycentric_evaluation(coefficients_, domain.size, z, domain); +} + +template +Fr LegacyPolynomial::evaluate_from_fft(const EvaluationDomain& large_domain, + const Fr& z, + const EvaluationDomain& small_domain) + requires polynomial_arithmetic::SupportsFFT + +{ + return polynomial_arithmetic::evaluate_from_fft(coefficients_, large_domain, z, small_domain); +} + +template LegacyPolynomial LegacyPolynomial::shifted() const +{ + ASSERT(size_ > 0); + ASSERT(coefficients_[0].is_zero()); + ASSERT(coefficients_[size_].is_zero()); // relies on MAXIMUM_COEFFICIENT_SHIFT >= 1 + LegacyPolynomial p; + p.backing_memory_ = backing_memory_; + p.size_ = size_; + p.coefficients_ = coefficients_ + 1; + return p; +} + +// TODO(#723): This method is used for the transcript aggregation protocol. For convenience we currently enforce that +// the shift is the same size as the input but this does not need to be the case. Revisit the logic/assertions in this +// method when that issue is addressed. +template void LegacyPolynomial::set_to_right_shifted(std::span coeffs_in, size_t shift_size) +{ + // Ensure we're not trying to shift self + ASSERT(coefficients_ != coeffs_in.data()); + + auto size_in = coeffs_in.size(); + ASSERT(size_in > 0); + + // Ensure that the last shift_size-many input coefficients are zero to ensure no information is lost in the shift. + ASSERT(shift_size <= size_in); + for (size_t i = 0; i < shift_size; ++i) { + size_t idx = size_in - shift_size - 1; + ASSERT(coeffs_in[idx].is_zero()); + } + + // Set size of self equal to size of input and allocate memory + allocate_backing_memory(size_in); + + // Zero out the first shift_size-many coefficients of self + memset(static_cast(coefficients_), 0, sizeof(Fr) * shift_size); + + // Copy all but the last shift_size many input coeffs into self at the shift_size-th index. + std::size_t num_to_copy = size_ - shift_size; + memcpy(static_cast(coefficients_ + shift_size), + static_cast(coeffs_in.data()), + sizeof(Fr) * num_to_copy); + zero_memory_beyond(size_); +} + +template void LegacyPolynomial::add_scaled(std::span other, Fr scaling_factor) +{ + const size_t other_size = other.size(); + ASSERT(in_place_operation_viable(other_size)); + + size_t num_threads = calculate_num_threads(other_size); + size_t range_per_thread = other_size / num_threads; + size_t leftovers = other_size - (range_per_thread * num_threads); + parallel_for(num_threads, [&](size_t j) { + size_t offset = j * range_per_thread; + size_t end = (j == num_threads - 1) ? offset + range_per_thread + leftovers : offset + range_per_thread; + for (size_t i = offset; i < end; ++i) { + coefficients_[i] += scaling_factor * other[i]; + } + }); +} + +template LegacyPolynomial& LegacyPolynomial::operator+=(std::span other) +{ + const size_t other_size = other.size(); + ASSERT(in_place_operation_viable(other_size)); + + size_t num_threads = calculate_num_threads(other_size); + size_t range_per_thread = other_size / num_threads; + size_t leftovers = other_size - (range_per_thread * num_threads); + parallel_for(num_threads, [&](size_t j) { + size_t offset = j * range_per_thread; + size_t end = (j == num_threads - 1) ? offset + range_per_thread + leftovers : offset + range_per_thread; + for (size_t i = offset; i < end; ++i) { + coefficients_[i] += other[i]; + } + }); + + return *this; +} + +template LegacyPolynomial& LegacyPolynomial::operator-=(std::span other) +{ + const size_t other_size = other.size(); + ASSERT(in_place_operation_viable(other_size)); + + size_t num_threads = calculate_num_threads(other_size); + size_t range_per_thread = other_size / num_threads; + size_t leftovers = other_size - (range_per_thread * num_threads); + parallel_for(num_threads, [&](size_t j) { + size_t offset = j * range_per_thread; + size_t end = (j == num_threads - 1) ? offset + range_per_thread + leftovers : offset + range_per_thread; + for (size_t i = offset; i < end; ++i) { + coefficients_[i] -= other[i]; + } + }); + + return *this; +} + +template LegacyPolynomial& LegacyPolynomial::operator*=(const Fr scaling_factor) +{ + ASSERT(in_place_operation_viable()); + + size_t num_threads = calculate_num_threads(size_); + size_t range_per_thread = size_ / num_threads; + size_t leftovers = size_ - (range_per_thread * num_threads); + parallel_for(num_threads, [&](size_t j) { + size_t offset = j * range_per_thread; + size_t end = (j == num_threads - 1) ? offset + range_per_thread + leftovers : offset + range_per_thread; + for (size_t i = offset; i < end; ++i) { + coefficients_[i] *= scaling_factor; + } + }); + + return *this; +} + +template Fr LegacyPolynomial::evaluate_mle(std::span evaluation_points, bool shift) const +{ + const size_t m = evaluation_points.size(); + + // To simplify handling of edge cases, we assume that size_ is always a power of 2 + ASSERT(size_ == static_cast(1 << m)); + + // we do m rounds l = 0,...,m-1. + // in round l, n_l is the size of the buffer containing the polynomial partially evaluated + // at u₀,..., u_l. + // in round 0, this is half the size of n + size_t n_l = 1 << (m - 1); + + // temporary buffer of half the size of the polynomial + // TODO(AD): Make this a polynomial with DontZeroMemory::FLAG + pointer tmp_ptr = _allocate_aligned_memory(sizeof(Fr) * n_l); + auto tmp = tmp_ptr.get(); + + Fr* prev = coefficients_; + if (shift) { + ASSERT(prev[0] == Fr::zero()); + prev++; + } + + Fr u_l = evaluation_points[0]; + for (size_t i = 0; i < n_l; ++i) { + // curr[i] = (Fr(1) - u_l) * prev[i << 1] + u_l * prev[(i << 1) + 1]; + tmp[i] = prev[i << 1] + u_l * (prev[(i << 1) + 1] - prev[i << 1]); + } + // partially evaluate the m-1 remaining points + for (size_t l = 1; l < m; ++l) { + n_l = 1 << (m - l - 1); + u_l = evaluation_points[l]; + for (size_t i = 0; i < n_l; ++i) { + tmp[i] = tmp[i << 1] + u_l * (tmp[(i << 1) + 1] - tmp[i << 1]); + } + } + Fr result = tmp[0]; + return result; +} + +template +LegacyPolynomial LegacyPolynomial::partial_evaluate_mle(std::span evaluation_points) const +{ + // Get size of partial evaluation point u = (u_0,...,u_{m-1}) + const size_t m = evaluation_points.size(); + + // Assert that the size of the polynomial being evaluated is a power of 2 greater than (1 << m) + ASSERT(numeric::is_power_of_two(size_)); + ASSERT(size_ >= static_cast(1 << m)); + size_t n = numeric::get_msb(size_); + + // Partial evaluation is done in m rounds l = 0,...,m-1. At the end of round l, the polynomial has been partially + // evaluated at u_{m-l-1}, ..., u_{m-1} in variables X_{n-l-1}, ..., X_{n-1}. The size of this polynomial is n_l. + size_t n_l = 1 << (n - 1); + + // Temporary buffer of half the size of the polynomial + LegacyPolynomial intermediate(n_l, DontZeroMemory::FLAG); + + // Evaluate variable X_{n-1} at u_{m-1} + Fr u_l = evaluation_points[m - 1]; + + for (size_t i = 0; i < n_l; i++) { + // Initiate our intermediate results using this polynomial. + intermediate[i] = at(i) + u_l * (at(i + n_l) - at(i)); + } + // Evaluate m-1 variables X_{n-l-1}, ..., X_{n-2} at m-1 remaining values u_0,...,u_{m-2}) + for (size_t l = 1; l < m; ++l) { + n_l = 1 << (n - l - 1); + u_l = evaluation_points[m - l - 1]; + for (size_t i = 0; i < n_l; ++i) { + intermediate[i] += u_l * (intermediate[i + n_l] - intermediate[i]); + } + } + + // Construct resulting polynomial g(X_0,…,X_{n-m-1})) = p(X_0,…,X_{n-m-1},u_0,...u_{m-1}) from buffer + LegacyPolynomial result(n_l, DontZeroMemory::FLAG); + for (size_t idx = 0; idx < n_l; ++idx) { + result[idx] = intermediate[idx]; + } + + return result; +} + +template class LegacyPolynomial; +template class LegacyPolynomial; + +} // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/polynomials/legacy_polynomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/legacy_polynomial.hpp new file mode 100644 index 00000000000..28a5afe69ce --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/polynomials/legacy_polynomial.hpp @@ -0,0 +1,331 @@ +#pragma once +#include "barretenberg/common/mem.hpp" +#include "barretenberg/crypto/sha256/sha256.hpp" +#include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp" +#include "evaluation_domain.hpp" +#include "polynomial_arithmetic.hpp" +#include + +namespace bb { + +/** + * @brief Polynomial class that represents the coefficients 'a' of a_0 + a_1 x + a_n x^n of + * a finite field polynomial equation of degree that is at most the size of some zk circuit. + * The polynomial is used to represent the gates of our arithmetized zk programs. + * Polynomials use the majority of the memory in proving, so caution should be used in making sure + * unnecessary copies are avoided, both for avoiding unnecessary memory usage and performance + * due to unnecessary allocations. + * Note: This should not be used for new code, hence the Legacy name. This is only used in older plonk-centric code + * as opposed to newer honk-centric code. + * + * @tparam Fr the finite field type. + */ +template class LegacyPolynomial { + public: + /** + * Implements requirements of `std::ranges::contiguous_range` and `std::ranges::sized_range` + */ + using value_type = Fr; + using difference_type = std::ptrdiff_t; + using reference = value_type&; + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) + using pointer = std::shared_ptr; + using const_pointer = pointer; + using iterator = Fr*; + using const_iterator = Fr const*; + using FF = Fr; + enum class DontZeroMemory { FLAG }; + + LegacyPolynomial(size_t initial_size); + // Constructor that does not initialize values, use with caution to save time. + LegacyPolynomial(size_t initial_size, DontZeroMemory flag); + LegacyPolynomial(const LegacyPolynomial& other); + LegacyPolynomial(const LegacyPolynomial& other, size_t target_size); + + LegacyPolynomial(LegacyPolynomial&& other) noexcept; + + // Create a polynomial from the given fields. + LegacyPolynomial(std::span coefficients); + + // Allow polynomials to be entirely reset/dormant + LegacyPolynomial() = default; + + /** + * @brief Create the degree-(m-1) polynomial T(X) that interpolates the given evaluations. + * We have T(xⱼ) = yⱼ for j=1,...,m + * + * @param interpolation_points (x₁,…,xₘ) + * @param evaluations (y₁,…,yₘ) + */ + LegacyPolynomial(std::span interpolation_points, std::span evaluations); + + // move assignment + LegacyPolynomial& operator=(LegacyPolynomial&& other) noexcept; + LegacyPolynomial& operator=(std::span coefficients) noexcept; + LegacyPolynomial& operator=(const LegacyPolynomial& other); + ~LegacyPolynomial() = default; + + /** + * Return a shallow clone of the polynomial. i.e. underlying memory is shared. + */ + LegacyPolynomial share() const; + + std::array hash() const { return crypto::sha256(byte_span()); } + + void clear() + { + // to keep the invariant that backing_memory_ can handle capacity() we do NOT reset backing_memory_ + // backing_memory_.reset(); + coefficients_ = nullptr; + size_ = 0; + } + + /** + * @brief Check whether or not a polynomial is identically zero + * + */ + bool is_zero() + { + if (is_empty()) { + ASSERT(false); + info("Checking is_zero on an empty Polynomial!"); + } + for (size_t i = 0; i < size(); i++) { + if (coefficients_[i] != 0) { + return false; + } + } + return true; + } + + bool operator==(LegacyPolynomial const& rhs) const; + + // Const and non const versions of coefficient accessors + Fr const& operator[](const size_t i) const { return coefficients_[i]; } + + Fr& operator[](const size_t i) { return coefficients_[i]; } + + Fr const& at(const size_t i) const + { + ASSERT(i < capacity()); + return coefficients_[i]; + }; + + Fr& at(const size_t i) + { + ASSERT(i < capacity()); + return coefficients_[i]; + }; + + Fr evaluate(const Fr& z, size_t target_size) const; + Fr evaluate(const Fr& z) const; + + Fr compute_barycentric_evaluation(const Fr& z, const EvaluationDomain& domain) + requires polynomial_arithmetic::SupportsFFT; + Fr evaluate_from_fft(const EvaluationDomain& large_domain, + const Fr& z, + const EvaluationDomain& small_domain) + requires polynomial_arithmetic::SupportsFFT; + void fft(const EvaluationDomain& domain) + requires polynomial_arithmetic::SupportsFFT; + void partial_fft(const EvaluationDomain& domain, Fr constant = 1, bool is_coset = false) + requires polynomial_arithmetic::SupportsFFT; + void coset_fft(const EvaluationDomain& domain) + requires polynomial_arithmetic::SupportsFFT; + void coset_fft(const EvaluationDomain& domain, + const EvaluationDomain& large_domain, + size_t domain_extension) + requires polynomial_arithmetic::SupportsFFT; + void coset_fft_with_constant(const EvaluationDomain& domain, const Fr& constant) + requires polynomial_arithmetic::SupportsFFT; + void coset_fft_with_generator_shift(const EvaluationDomain& domain, const Fr& constant) + requires polynomial_arithmetic::SupportsFFT; + void ifft(const EvaluationDomain& domain) + requires polynomial_arithmetic::SupportsFFT; + void ifft_with_constant(const EvaluationDomain& domain, const Fr& constant) + requires polynomial_arithmetic::SupportsFFT; + void coset_ifft(const EvaluationDomain& domain) + requires polynomial_arithmetic::SupportsFFT; + Fr compute_kate_opening_coefficients(const Fr& z) + requires polynomial_arithmetic::SupportsFFT; + + bool is_empty() const { return size_ == 0; } + + /** + * @brief Returns an std::span of the left-shift of self. + * + * @details If the n coefficients of self are (0, a₁, …, aₙ₋₁), + * we returns the view of the n-1 coefficients (a₁, …, aₙ₋₁). + */ + LegacyPolynomial shifted() const; + + /** + * @brief Set self to the right shift of input coefficients + * @details Set the size of self to match the input then set coefficients equal to right shift of input. Note: The + * shifted result is constructed with its first shift-many coefficients equal to zero, so we assert that the last + * shift-size many input coefficients are equal to zero to ensure that the relationship f(X) = f_{shift}(X)/X^m + * holds. This is analagous to asserting the first coefficient is 0 in our left-shift-by-one method. + * + * @param coeffs_in + * @param shift_size + */ + void set_to_right_shifted(std::span coeffs_in, size_t shift_size = 1); + + /** + * @brief adds the polynomial q(X) 'other', multiplied by a scaling factor. + * + * @param other q(X) + * @param scaling_factor scaling factor by which all coefficients of q(X) are multiplied + */ + void add_scaled(std::span other, Fr scaling_factor); + + /** + * @brief adds the polynomial q(X) 'other'. + * + * @param other q(X) + */ + LegacyPolynomial& operator+=(std::span other); + + /** + * @brief subtracts the polynomial q(X) 'other'. + * + * @param other q(X) + */ + LegacyPolynomial& operator-=(std::span other); + + /** + * @brief sets this = p(X) to s⋅p(X) + * + * @param scaling_factor s + */ + LegacyPolynomial& operator*=(Fr scaling_factor); + + /** + * @brief evaluates p(X) = ∑ᵢ aᵢ⋅Xⁱ considered as multi-linear extension p(X₀,…,Xₘ₋₁) = ∑ᵢ aᵢ⋅Lᵢ(X₀,…,Xₘ₋₁) + * at u = (u₀,…,uₘ₋₁) + * + * @details this function allocates a temporary buffer of size n/2 + * + * @param evaluation_points an MLE evaluation point u = (u₀,…,uₘ₋₁) + * @param shift evaluates p'(X₀,…,Xₘ₋₁) = 1⋅L₀(X₀,…,Xₘ₋₁) + ∑ᵢ˲₁ aᵢ₋₁⋅Lᵢ(X₀,…,Xₘ₋₁) if true + * @return Fr p(u₀,…,uₘ₋₁) + */ + Fr evaluate_mle(std::span evaluation_points, bool shift = false) const; + + /** + * @brief Partially evaluates in the last k variables a polynomial interpreted as a multilinear extension. + * + * @details Partially evaluates p(X) = (a_0, ..., a_{2^n-1}) considered as multilinear extension p(X_0,…,X_{n-1}) = + * \sum_i a_i*L_i(X_0,…,X_{n-1}) at u = (u_0,…,u_{m-1}), m < n, in the last m variables X_n-m,…,X_{n-1}. The result + * is a multilinear polynomial in n-m variables g(X_0,…,X_{n-m-1})) = p(X_0,…,X_{n-m-1},u_0,...u_{m-1}). + * + * @note Intuitively, partially evaluating in one variable collapses the hypercube in one dimension, halving the + * number of coefficients needed to represent the result. To partially evaluate starting with the first variable (as + * is done in evaluate_mle), the vector of coefficents is halved by combining adjacent rows in a pairwise + * fashion (similar to what is done in Sumcheck via "edges"). To evaluate starting from the last variable, we + * instead bisect the whole vector and combine the two halves. I.e. rather than coefficents being combined with + * their immediate neighbor, they are combined with the coefficient that lives n/2 indices away. + * + * @param evaluation_points an MLE partial evaluation point u = (u_0,…,u_{m-1}) + * @return Polynomial g(X_0,…,X_{n-m-1})) = p(X_0,…,X_{n-m-1},u_0,...u_{m-1}) + */ + LegacyPolynomial partial_evaluate_mle(std::span evaluation_points) const; + + /** + * @brief Divides p(X) by (X-r₁)⋯(X−rₘ) in-place. + * Assumes that p(rⱼ)=0 for all j + * + * @details we specialize the method when only a single root is given. + * if one of the roots is 0, then we first factor all other roots. + * dividing by X requires only a left shift of all coefficient. + * + * @param roots list of roots (r₁,…,rₘ) + */ + void factor_roots(std::span roots) { polynomial_arithmetic::factor_roots(std::span{ *this }, roots); }; + void factor_roots(const Fr& root) { polynomial_arithmetic::factor_roots(std::span{ *this }, root); }; + + iterator begin() { return coefficients_; } + iterator end() { return coefficients_ + size_; } + pointer data() { return backing_memory_; } + + std::span byte_span() const + { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + return { reinterpret_cast(coefficients_), size_ * sizeof(Fr) }; + } + + const_iterator begin() const { return coefficients_; } + const_iterator end() const { return coefficients_ + size_; } + const_pointer data() const { return backing_memory_; } + + std::size_t size() const { return size_; } + std::size_t capacity() const { return size_ + MAXIMUM_COEFFICIENT_SHIFT; } + + static LegacyPolynomial random(const size_t num_coeffs) + { + LegacyPolynomial p(num_coeffs); + std::generate_n(p.begin(), num_coeffs, []() { return Fr::random_element(); }); + return p; + } + + private: + // allocate a fresh memory pointer for backing memory + // DOES NOT initialize memory + void allocate_backing_memory(size_t n_elements); + + // safety check for in place operations + bool in_place_operation_viable(size_t domain_size = 0) { return (size() >= domain_size); } + + void zero_memory_beyond(size_t start_position); + // When a polynomial is instantiated from a size alone, the memory allocated corresponds to + // input size + MAXIMUM_COEFFICIENT_SHIFT to support 'shifted' coefficients efficiently. + const static size_t MAXIMUM_COEFFICIENT_SHIFT = 1; + + // The memory + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) + std::shared_ptr backing_memory_; + // A pointer into backing_memory_ to support std::span-like functionality. This allows for coefficient subsets + // and shifts. + Fr* coefficients_ = nullptr; + // The size_ effectively represents the 'usable' length of the coefficients array but may be less than the true + // 'capacity' of the array. It is not explicitly tied to the degree and is not changed by any operations on the + // polynomial. + size_t size_ = 0; +}; + +template inline std::ostream& operator<<(std::ostream& os, LegacyPolynomial const& p) +{ + if (p.size() == 0) { + return os << "[]"; + } + if (p.size() == 1) { + return os << "[ data " << p[0] << "]"; + } + return os << "[ data\n" + << " " << p[0] << ",\n" + << " " << p[1] << ",\n" + << " ... ,\n" + << " " << p[p.size() - 2] << ",\n" + << " " << p[p.size() - 1] << ",\n" + << "]"; +} + +using polynomial = LegacyPolynomial; + +} // namespace bb + +/** + * The static_assert below ensure that that our Polynomial class correctly models an `std::ranges::contiguous_range`, + * and other requirements that allow us to convert a `Polynomial` to a `std::span`. + * + * This also means we can now iterate over the elements in the vector using a `for(auto ...)` loop, and use various std + * algorithms. + * + * static_assert(std::ranges::contiguous_range); + * static_assert(std::ranges::sized_range); + * static_assert(std::convertible_to>); + * static_assert(std::convertible_to>); + * // cannot convert a const polynomial to a non-const span + * static_assert(!std::convertible_to>); + * static_assert(std::convertible_to>); + */ diff --git a/barretenberg/cpp/src/barretenberg/polynomials/legacy_polynomial.test.cpp b/barretenberg/cpp/src/barretenberg/polynomials/legacy_polynomial.test.cpp new file mode 100644 index 00000000000..79396167c45 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/polynomials/legacy_polynomial.test.cpp @@ -0,0 +1,61 @@ +#include +#include + +#include "barretenberg/polynomials/legacy_polynomial.hpp" + +using namespace bb; + +// Simple test/demonstration of shifted functionality +TEST(LegacyPolynomial, Shifted) +{ + using FF = bb::fr; + using LegacyPolynomial = LegacyPolynomial; + const size_t SIZE = 10; + auto poly = LegacyPolynomial::random(SIZE); + poly[0] = 0; // make it shiftable + + // Instantiate the shift via the shited method + auto poly_shifted = poly.shifted(); + + EXPECT_EQ(poly_shifted.size(), poly.size()); + + // The shift is indeed the shift + for (size_t i = 0; i < poly_shifted.size(); ++i) { + EXPECT_EQ(poly_shifted.at(i), poly.at(i + 1)); + } + + // If I change the original polynomial, the shift is updated accordingly + poly[3] = 25; + for (size_t i = 0; i < poly_shifted.size(); ++i) { + EXPECT_EQ(poly_shifted.at(i), poly.at(i + 1)); + } +} + +// Simple test/demonstration of share functionality +TEST(LegacyPolynomial, Share) +{ + using FF = bb::fr; + using LegacyPolynomial = LegacyPolynomial; + const size_t SIZE = 10; + auto poly = LegacyPolynomial::random(SIZE); + + // "clone" the poly via the share method + auto poly_clone = poly.share(); + + // The two are indeed equal + EXPECT_EQ(poly_clone, poly); + + // Changing one changes the other + poly[3] = 25; + EXPECT_EQ(poly_clone, poly); + + poly_clone[2] = 13; + EXPECT_EQ(poly_clone, poly); + + // If reset the original poly, it will no longer be equal to the clone made earlier + // Note: if we had not made a clone, the memory from the original poly would be leaked + auto poly2 = LegacyPolynomial::random(SIZE); + poly = poly2.share(); + + EXPECT_NE(poly_clone, poly); +} diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomials.bench.cpp b/barretenberg/cpp/src/barretenberg/polynomials/legacy_polynomials.bench.cpp similarity index 100% rename from barretenberg/cpp/src/barretenberg/polynomials/polynomials.bench.cpp rename to barretenberg/cpp/src/barretenberg/polynomials/legacy_polynomials.bench.cpp diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomial.cpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial.cpp index 9971d6943cf..8280d141a66 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial.cpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial.cpp @@ -16,18 +16,28 @@ namespace bb { // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) -template std::shared_ptr _allocate_aligned_memory(const size_t n_elements) +template std::shared_ptr _allocate_aligned_memory(size_t n_elements) { // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) return std::static_pointer_cast(get_mem_slab(sizeof(Fr) * n_elements)); } -template void Polynomial::allocate_backing_memory(size_t n_elements) -{ - size_ = n_elements; - // capacity() is size_ plus padding for shifted polynomials - backing_memory_ = _allocate_aligned_memory(capacity()); - coefficients_ = backing_memory_.get(); +template void Polynomial::allocate_backing_memory(size_t size, size_t virtual_size) +{ + coefficients_ = SharedShiftedVirtualZeroesArray{ + size, /* actual memory size */ + virtual_size, /* virtual size, i.e. until what size do we conceptually have zeroes */ + 0, /* shift, initially 0 */ + _allocate_aligned_memory(size + MAXIMUM_COEFFICIENT_SHIFT) + /* Our backing memory, since shift is 0 it is equal to our memory size. + * We add one to the size here to allow for an efficient shift by 1 that retains size. */ + }; + // We need to zero the extra padding memory that we reserve for shifts. + // We do this here as generally code that does not zero memory and then + // later initializes it won't generally also initialize the padding. + for (size_t i = 0; i < MAXIMUM_COEFFICIENT_SHIFT; i++) { + data()[size + i] = Fr{}; + } } /** @@ -35,28 +45,28 @@ template void Polynomial::allocate_backing_memory(size_t n_ele **/ /** - * @brief Initialize a Polynomial to size 'initial_size', zeroing memory. + * @brief Initialize a Polynomial to size 'size', zeroing memory. * - * @param initial_size The initial size of the polynomial. + * @param size The size of the polynomial. */ -template Polynomial::Polynomial(size_t initial_size) +template Polynomial::Polynomial(size_t size, size_t virtual_size) { - allocate_backing_memory(initial_size); - memset(static_cast(coefficients_), 0, sizeof(Fr) * capacity()); + allocate_backing_memory(size, virtual_size); + memset(static_cast(coefficients_.data()), 0, sizeof(Fr) * size); } /** - * @brief Initialize a Polynomial to size 'initial_size'. + * @brief Initialize a Polynomial to size 'size'. * Important: This does NOT zero memory. * - * @param initial_size The initial size of the polynomial. + * @param size The initial size of the polynomial. * @param flag Signals that we do not zero memory. */ -template Polynomial::Polynomial(size_t initial_size, DontZeroMemory flag) +template Polynomial::Polynomial(size_t size, size_t virtual_size, DontZeroMemory flag) { // Flag is unused, but we don't memset 0 if passed. (void)flag; - allocate_backing_memory(initial_size); + allocate_backing_memory(size, virtual_size); } template @@ -67,39 +77,32 @@ Polynomial::Polynomial(const Polynomial& other) // fully copying "expensive" constructor template Polynomial::Polynomial(const Polynomial& other, const size_t target_size) { - allocate_backing_memory(std::max(target_size, other.size())); + allocate_backing_memory(std::max(target_size, other.size()), other.virtual_size()); - memcpy(static_cast(coefficients_), static_cast(other.coefficients_), sizeof(Fr) * other.size_); - zero_memory_beyond(other.size_); + memcpy(static_cast(coefficients_.data()), + static_cast(other.coefficients_.data()), + sizeof(Fr) * other.size()); + zero_memory_beyond(other.size()); } -// move constructor +// interpolation constructor template -Polynomial::Polynomial(Polynomial&& other) noexcept - : backing_memory_(std::exchange(other.backing_memory_, nullptr)) - , coefficients_(std::exchange(other.coefficients_, nullptr)) - , size_(std::exchange(other.size_, 0)) -{} - -// span constructor -template Polynomial::Polynomial(std::span coefficients) +Polynomial::Polynomial(std::span interpolation_points, + std::span evaluations, + size_t virtual_size) + : Polynomial(interpolation_points.size(), virtual_size) { - allocate_backing_memory(coefficients.size()); - memcpy(static_cast(coefficients_), - static_cast(coefficients.data()), - sizeof(Fr) * coefficients.size()); - zero_memory_beyond(size_); + ASSERT(coefficients_.size_ > 0); + + polynomial_arithmetic::compute_efficient_interpolation( + evaluations.data(), coefficients_.data(), interpolation_points.data(), coefficients_.size_); } -// interpolation constructor -template -Polynomial::Polynomial(std::span interpolation_points, std::span evaluations) - : Polynomial(interpolation_points.size()) +template Polynomial::Polynomial(std::span coefficients, size_t virtual_size) { - ASSERT(size_ > 0); + allocate_backing_memory(coefficients.size(), virtual_size); - polynomial_arithmetic::compute_efficient_interpolation( - evaluations.data(), coefficients_, interpolation_points.data(), size_); + memcpy(static_cast(data()), static_cast(coefficients.data()), sizeof(Fr) * coefficients.size()); } // Assignments @@ -110,52 +113,20 @@ template Polynomial& Polynomial::operator=(const Polynomia if (this == &other) { return *this; } - allocate_backing_memory(other.size_); - memcpy(static_cast(coefficients_), static_cast(other.coefficients_), sizeof(Fr) * other.size_); - zero_memory_beyond(size_); - return *this; -} - -template Polynomial& Polynomial::operator=(std::span coefficients) noexcept -{ - // move assign a Polynomial constructed with the span - *this = Polynomial{ coefficients }; - return *this; -} - -// ####### -template Polynomial& Polynomial::operator=(Polynomial&& other) noexcept -{ - if (&other == this) { - return *this; - } - - // simultaneously set members and clear other - backing_memory_ = std::exchange(other.backing_memory_, nullptr); - coefficients_ = std::exchange(other.coefficients_, nullptr); - size_ = std::exchange(other.size_, 0); + allocate_backing_memory(other.coefficients_.size_, other.coefficients_.virtual_size_); + memcpy(static_cast(coefficients_.data()), + static_cast(other.coefficients_.data()), + sizeof(Fr) * other.coefficients_.size_); return *this; } template Polynomial Polynomial::share() const { Polynomial p; - p.backing_memory_ = backing_memory_; - p.size_ = size_; p.coefficients_ = coefficients_; return p; } -template Fr Polynomial::evaluate(const Fr& z, const size_t target_size) const -{ - return polynomial_arithmetic::evaluate(coefficients_, z, target_size); -} - -template Fr Polynomial::evaluate(const Fr& z) const -{ - return polynomial_arithmetic::evaluate(coefficients_, z, size_); -} - template bool Polynomial::operator==(Polynomial const& rhs) const { // If either is empty, both must be @@ -163,207 +134,146 @@ template bool Polynomial::operator==(Polynomial const& rhs) co return is_empty() && rhs.is_empty(); } // Size must agree - if (size() != rhs.size()) { + if (virtual_size() != rhs.virtual_size()) { return false; } // Each coefficient must agree - for (size_t i = 0; i < size(); i++) { - if (coefficients_[i] != rhs.coefficients_[i]) { + for (size_t i = 0; i < std::max(size(), rhs.size()); i++) { + if (coefficients_.get(i) != rhs.coefficients_.get(i)) { return false; } } return true; } -/** - * @brief sets a block of memory to all zeroes - * Used to zero out unintialized memory to ensure that, when writing to the polynomial in future, - * memory requests made to the OS do not return virtual pages (performance optimization). - * Used, for example, when one polynomial is instantiated from another one with size_>= other.size_. - * - * @param opening_proof Opening proof computed by `batch_open` - * @param commitment_data Describes each polynomial being opened: its commitment, the opening points used and the - * polynomial evaluations - */ -template void Polynomial::zero_memory_beyond(const size_t start_position) +template Polynomial& Polynomial::operator+=(std::span other) { - size_t end = capacity(); - ASSERT(end >= start_position); - - size_t delta = end - start_position; - if (delta > 0) { - ASSERT(backing_memory_); - memset(static_cast(&coefficients_[start_position]), 0, sizeof(Fr) * delta); - } -} - -/** - * FFTs - **/ + const size_t other_size = other.size(); + ASSERT(in_place_operation_viable(other_size)); -template -void Polynomial::fft(const EvaluationDomain& domain) - requires polynomial_arithmetic::SupportsFFT -{ - ASSERT(in_place_operation_viable(domain.size)); - zero_memory_beyond(domain.size); + size_t num_threads = calculate_num_threads(other_size); + size_t range_per_thread = other_size / num_threads; + size_t leftovers = other_size - (range_per_thread * num_threads); + parallel_for(num_threads, [&](size_t j) { + size_t offset = j * range_per_thread; + size_t end = (j == num_threads - 1) ? offset + range_per_thread + leftovers : offset + range_per_thread; + for (size_t i = offset; i < end; ++i) { + coefficients_.data()[i] += other[i]; + } + }); - polynomial_arithmetic::fft(coefficients_, domain); + return *this; } -template -void Polynomial::partial_fft(const EvaluationDomain& domain, Fr constant, bool is_coset) - requires polynomial_arithmetic::SupportsFFT +template Fr Polynomial::evaluate(const Fr& z, const size_t target_size) const { - ASSERT(in_place_operation_viable(domain.size)); - zero_memory_beyond(domain.size); - - polynomial_arithmetic::partial_fft(coefficients_, domain, constant, is_coset); + return polynomial_arithmetic::evaluate(data(), z, target_size); } -template -void Polynomial::coset_fft(const EvaluationDomain& domain) - requires polynomial_arithmetic::SupportsFFT +template Fr Polynomial::evaluate(const Fr& z) const { - ASSERT(in_place_operation_viable(domain.size)); - zero_memory_beyond(domain.size); - - polynomial_arithmetic::coset_fft(coefficients_, domain); + return polynomial_arithmetic::evaluate(data(), z, size()); } -template -void Polynomial::coset_fft(const EvaluationDomain& domain, - const EvaluationDomain& large_domain, - const size_t domain_extension) - requires polynomial_arithmetic::SupportsFFT +template Fr Polynomial::evaluate_mle(std::span evaluation_points, bool shift) const { - size_t extended_size = domain.size * domain_extension; + const size_t m = evaluation_points.size(); - ASSERT(in_place_operation_viable(extended_size)); - zero_memory_beyond(extended_size); + // To simplify handling of edge cases, we assume that size_ is always a power of 2 + ASSERT(size() == static_cast(1 << m)); - polynomial_arithmetic::coset_fft(coefficients_, domain, large_domain, domain_extension); -} + // we do m rounds l = 0,...,m-1. + // in round l, n_l is the size of the buffer containing the Polynomial partially evaluated + // at u₀,..., u_l. + // in round 0, this is half the size of n + size_t n_l = 1 << (m - 1); -template -void Polynomial::coset_fft_with_constant(const EvaluationDomain& domain, const Fr& constant) - requires polynomial_arithmetic::SupportsFFT -{ - ASSERT(in_place_operation_viable(domain.size)); - zero_memory_beyond(domain.size); + // temporary buffer of half the size of the Polynomial + // TODO(AD): Make this a Polynomial with DontZeroMemory::FLAG + auto tmp_ptr = _allocate_aligned_memory(sizeof(Fr) * n_l); + auto tmp = tmp_ptr.get(); + + const Fr* prev = data(); + if (shift) { + ASSERT(prev[0] == Fr::zero()); + prev++; + } - polynomial_arithmetic::coset_fft_with_constant(coefficients_, domain, constant); + Fr u_l = evaluation_points[0]; + for (size_t i = 0; i < n_l; ++i) { + // curr[i] = (Fr(1) - u_l) * prev[i << 1] + u_l * prev[(i << 1) + 1]; + tmp[i] = prev[i << 1] + u_l * (prev[(i << 1) + 1] - prev[i << 1]); + } + // partially evaluate the m-1 remaining points + for (size_t l = 1; l < m; ++l) { + n_l = 1 << (m - l - 1); + u_l = evaluation_points[l]; + for (size_t i = 0; i < n_l; ++i) { + tmp[i] = tmp[i << 1] + u_l * (tmp[(i << 1) + 1] - tmp[i << 1]); + } + } + Fr result = tmp[0]; + return result; } -template -void Polynomial::coset_fft_with_generator_shift(const EvaluationDomain& domain, const Fr& constant) - requires polynomial_arithmetic::SupportsFFT +template Polynomial Polynomial::partial_evaluate_mle(std::span evaluation_points) const { - ASSERT(in_place_operation_viable(domain.size)); - zero_memory_beyond(domain.size); + // Get size of partial evaluation point u = (u_0,...,u_{m-1}) + const size_t m = evaluation_points.size(); - polynomial_arithmetic::coset_fft_with_generator_shift(coefficients_, domain, constant); -} + // Assert that the size of the Polynomial being evaluated is a power of 2 greater than (1 << m) + ASSERT(numeric::is_power_of_two(size())); + ASSERT(size() >= static_cast(1 << m)); + size_t n = numeric::get_msb(size()); -template -void Polynomial::ifft(const EvaluationDomain& domain) - requires polynomial_arithmetic::SupportsFFT -{ - ASSERT(in_place_operation_viable(domain.size)); - zero_memory_beyond(domain.size); + // Partial evaluation is done in m rounds l = 0,...,m-1. At the end of round l, the Polynomial has been + // partially evaluated at u_{m-l-1}, ..., u_{m-1} in variables X_{n-l-1}, ..., X_{n-1}. The size of this + // Polynomial is n_l. + size_t n_l = 1 << (n - 1); - polynomial_arithmetic::ifft(coefficients_, domain); -} + // Temporary buffer of half the size of the Polynomial + Polynomial intermediate(n_l, n_l, DontZeroMemory::FLAG); -template -void Polynomial::ifft_with_constant(const EvaluationDomain& domain, const Fr& constant) - requires polynomial_arithmetic::SupportsFFT -{ - ASSERT(in_place_operation_viable(domain.size)); - zero_memory_beyond(domain.size); + // Evaluate variable X_{n-1} at u_{m-1} + Fr u_l = evaluation_points[m - 1]; - polynomial_arithmetic::ifft_with_constant(coefficients_, domain, constant); -} + for (size_t i = 0; i < n_l; i++) { + // Initiate our intermediate results using this Polynomial. + intermediate[i] = get(i) + u_l * (get(i + n_l) - get(i)); + } + // Evaluate m-1 variables X_{n-l-1}, ..., X_{n-2} at m-1 remaining values u_0,...,u_{m-2}) + for (size_t l = 1; l < m; ++l) { + n_l = 1 << (n - l - 1); + u_l = evaluation_points[m - l - 1]; + for (size_t i = 0; i < n_l; ++i) { + intermediate[i] += u_l * (intermediate[i + n_l] - intermediate[i]); + } + } -template -void Polynomial::coset_ifft(const EvaluationDomain& domain) - requires polynomial_arithmetic::SupportsFFT -{ - ASSERT(in_place_operation_viable(domain.size)); - zero_memory_beyond(domain.size); + // Construct resulting Polynomial g(X_0,…,X_{n-m-1})) = p(X_0,…,X_{n-m-1},u_0,...u_{m-1}) from buffer + Polynomial result(n_l, n_l, DontZeroMemory::FLAG); + for (size_t idx = 0; idx < n_l; ++idx) { + result[idx] = intermediate[idx]; + } - polynomial_arithmetic::coset_ifft(coefficients_, domain); + return result; } template Fr Polynomial::compute_kate_opening_coefficients(const Fr& z) requires polynomial_arithmetic::SupportsFFT { - return polynomial_arithmetic::compute_kate_opening_coefficients(coefficients_, coefficients_, z, size_); + return polynomial_arithmetic::compute_kate_opening_coefficients(data(), data(), z, size()); } template Fr Polynomial::compute_barycentric_evaluation(const Fr& z, const EvaluationDomain& domain) requires polynomial_arithmetic::SupportsFFT { - return polynomial_arithmetic::compute_barycentric_evaluation(coefficients_, domain.size, z, domain); -} - -template -Fr Polynomial::evaluate_from_fft(const EvaluationDomain& large_domain, - const Fr& z, - const EvaluationDomain& small_domain) - requires polynomial_arithmetic::SupportsFFT - -{ - return polynomial_arithmetic::evaluate_from_fft(coefficients_, large_domain, z, small_domain); -} - -template Polynomial Polynomial::shifted() const -{ - ASSERT(size_ > 0); - ASSERT(coefficients_[0].is_zero()); - ASSERT(coefficients_[size_].is_zero()); // relies on MAXIMUM_COEFFICIENT_SHIFT >= 1 - Polynomial p; - p.backing_memory_ = backing_memory_; - p.size_ = size_; - p.coefficients_ = coefficients_ + 1; - return p; -} - -// TODO(#723): This method is used for the transcript aggregation protocol. For convenience we currently enforce that -// the shift is the same size as the input but this does not need to be the case. Revisit the logic/assertions in this -// method when that issue is addressed. -template void Polynomial::set_to_right_shifted(std::span coeffs_in, size_t shift_size) -{ - // Ensure we're not trying to shift self - ASSERT(coefficients_ != coeffs_in.data()); - - auto size_in = coeffs_in.size(); - ASSERT(size_in > 0); - - // Ensure that the last shift_size-many input coefficients are zero to ensure no information is lost in the shift. - ASSERT(shift_size <= size_in); - for (size_t i = 0; i < shift_size; ++i) { - size_t idx = size_in - shift_size - 1; - ASSERT(coeffs_in[idx].is_zero()); - } - - // Set size of self equal to size of input and allocate memory - allocate_backing_memory(size_in); - - // Zero out the first shift_size-many coefficients of self - memset(static_cast(coefficients_), 0, sizeof(Fr) * shift_size); - - // Copy all but the last shift_size many input coeffs into self at the shift_size-th index. - std::size_t num_to_copy = size_ - shift_size; - memcpy(static_cast(coefficients_ + shift_size), - static_cast(coeffs_in.data()), - sizeof(Fr) * num_to_copy); - zero_memory_beyond(size_); + return polynomial_arithmetic::compute_barycentric_evaluation(data(), domain.size, z, domain); } -template void Polynomial::add_scaled(std::span other, Fr scaling_factor) +template Polynomial& Polynomial::operator-=(std::span other) { const size_t other_size = other.size(); ASSERT(in_place_operation_viable(other_size)); @@ -375,31 +285,32 @@ template void Polynomial::add_scaled(std::span other size_t offset = j * range_per_thread; size_t end = (j == num_threads - 1) ? offset + range_per_thread + leftovers : offset + range_per_thread; for (size_t i = offset; i < end; ++i) { - coefficients_[i] += scaling_factor * other[i]; + coefficients_.data()[i] -= other[i]; } }); + + return *this; } -template Polynomial& Polynomial::operator+=(std::span other) +template Polynomial& Polynomial::operator*=(const Fr scaling_factor) { - const size_t other_size = other.size(); - ASSERT(in_place_operation_viable(other_size)); + ASSERT(in_place_operation_viable()); - size_t num_threads = calculate_num_threads(other_size); - size_t range_per_thread = other_size / num_threads; - size_t leftovers = other_size - (range_per_thread * num_threads); + size_t num_threads = calculate_num_threads(size()); + size_t range_per_thread = size() / num_threads; + size_t leftovers = size() - (range_per_thread * num_threads); parallel_for(num_threads, [&](size_t j) { size_t offset = j * range_per_thread; size_t end = (j == num_threads - 1) ? offset + range_per_thread + leftovers : offset + range_per_thread; for (size_t i = offset; i < end; ++i) { - coefficients_[i] += other[i]; + coefficients_.data()[i] *= scaling_factor; } }); return *this; } -template Polynomial& Polynomial::operator-=(std::span other) +template void Polynomial::add_scaled(std::span other, Fr scaling_factor) { const size_t other_size = other.size(); ASSERT(in_place_operation_viable(other_size)); @@ -411,112 +322,43 @@ template Polynomial& Polynomial::operator-=(std::span Polynomial& Polynomial::operator*=(const Fr scaling_factor) -{ - ASSERT(in_place_operation_viable()); - - size_t num_threads = calculate_num_threads(size_); - size_t range_per_thread = size_ / num_threads; - size_t leftovers = size_ - (range_per_thread * num_threads); - parallel_for(num_threads, [&](size_t j) { - size_t offset = j * range_per_thread; - size_t end = (j == num_threads - 1) ? offset + range_per_thread + leftovers : offset + range_per_thread; - for (size_t i = offset; i < end; ++i) { - coefficients_[i] *= scaling_factor; - } - }); - - return *this; -} - -template Fr Polynomial::evaluate_mle(std::span evaluation_points, bool shift) const +/** + * @brief Returns a Polynomial the left-shift of self. + * + * @details If the n coefficients of self are (0, a₁, …, aₙ₋₁), + * we returns the view of the n-1 coefficients (a₁, …, aₙ₋₁). + */ +template Polynomial Polynomial::shifted() const { - const size_t m = evaluation_points.size(); - - // To simplify handling of edge cases, we assume that size_ is always a power of 2 - ASSERT(size_ == static_cast(1 << m)); - - // we do m rounds l = 0,...,m-1. - // in round l, n_l is the size of the buffer containing the polynomial partially evaluated - // at u₀,..., u_l. - // in round 0, this is half the size of n - size_t n_l = 1 << (m - 1); - - // temporary buffer of half the size of the polynomial - // TODO(AD): Make this a polynomial with DontZeroMemory::FLAG - pointer tmp_ptr = _allocate_aligned_memory(sizeof(Fr) * n_l); - auto tmp = tmp_ptr.get(); - - Fr* prev = coefficients_; - if (shift) { - ASSERT(prev[0] == Fr::zero()); - prev++; - } - - Fr u_l = evaluation_points[0]; - for (size_t i = 0; i < n_l; ++i) { - // curr[i] = (Fr(1) - u_l) * prev[i << 1] + u_l * prev[(i << 1) + 1]; - tmp[i] = prev[i << 1] + u_l * (prev[(i << 1) + 1] - prev[i << 1]); - } - // partially evaluate the m-1 remaining points - for (size_t l = 1; l < m; ++l) { - n_l = 1 << (m - l - 1); - u_l = evaluation_points[l]; - for (size_t i = 0; i < n_l; ++i) { - tmp[i] = tmp[i << 1] + u_l * (tmp[(i << 1) + 1] - tmp[i << 1]); - } - } - Fr result = tmp[0]; + ASSERT(data()[0].is_zero()); + ASSERT(size() > 0); + ASSERT(data()[size()].is_zero()); // relies on MAXIMUM_COEFFICIENT_SHIFT >= 1 + Polynomial result; + result.coefficients_ = coefficients_; + result.coefficients_.shift_ += 1; + // We only expect to shift by MAXIMUM_COEFFICIENT_SHIFT + ASSERT(result.coefficients_.shift_ <= MAXIMUM_COEFFICIENT_SHIFT); return result; } -template Polynomial Polynomial::partial_evaluate_mle(std::span evaluation_points) const +/** + * @brief sets a block of memory to all zeroes + * Used, for example, when one Polynomioal is instantiated from another one with size_>= other.size_. + */ +template void Polynomial::zero_memory_beyond(const size_t start_position) { - // Get size of partial evaluation point u = (u_0,...,u_{m-1}) - const size_t m = evaluation_points.size(); - - // Assert that the size of the polynomial being evaluated is a power of 2 greater than (1 << m) - ASSERT(numeric::is_power_of_two(size_)); - ASSERT(size_ >= static_cast(1 << m)); - size_t n = numeric::get_msb(size_); - - // Partial evaluation is done in m rounds l = 0,...,m-1. At the end of round l, the polynomial has been partially - // evaluated at u_{m-l-1}, ..., u_{m-1} in variables X_{n-l-1}, ..., X_{n-1}. The size of this polynomial is n_l. - size_t n_l = 1 << (n - 1); - - // Temporary buffer of half the size of the polynomial - Polynomial intermediate(n_l, DontZeroMemory::FLAG); - - // Evaluate variable X_{n-1} at u_{m-1} - Fr u_l = evaluation_points[m - 1]; - - for (size_t i = 0; i < n_l; i++) { - // Initiate our intermediate results using this polynomial. - intermediate[i] = at(i) + u_l * (at(i + n_l) - at(i)); - } - // Evaluate m-1 variables X_{n-l-1}, ..., X_{n-2} at m-1 remaining values u_0,...,u_{m-2}) - for (size_t l = 1; l < m; ++l) { - n_l = 1 << (n - l - 1); - u_l = evaluation_points[m - l - 1]; - for (size_t i = 0; i < n_l; ++i) { - intermediate[i] += u_l * (intermediate[i + n_l] - intermediate[i]); - } - } + size_t end = size(); + ASSERT(end >= start_position); - // Construct resulting polynomial g(X_0,…,X_{n-m-1})) = p(X_0,…,X_{n-m-1},u_0,...u_{m-1}) from buffer - Polynomial result(n_l, DontZeroMemory::FLAG); - for (size_t idx = 0; idx < n_l; ++idx) { - result[idx] = intermediate[idx]; + size_t delta = end - start_position; + if (delta > 0) { + memset(static_cast(&data()[start_position]), 0, sizeof(Fr) * delta); } - - return result; } template class Polynomial; diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp index 2b3a02a7736..7840699dc65 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp @@ -2,38 +2,49 @@ #include "barretenberg/common/mem.hpp" #include "barretenberg/crypto/sha256/sha256.hpp" #include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp" +#include "barretenberg/polynomials/shared_shifted_virtual_zeroes_array.hpp" #include "evaluation_domain.hpp" #include "polynomial_arithmetic.hpp" #include namespace bb { -enum class DontZeroMemory { FLAG }; +/** + * @brief Structured polynomial class that represents the coefficients 'a' of a_0 + a_1 x + a_n x^n of + * a finite field polynomial equation of degree that is at most the size of some zk circuit. + * Past 'n' it has a virtual size where it conceptually has coefficients all equal to 0. + * Notably, we allow indexing past 'n' up to our virtual size (checked only in a debug build, however). + * The polynomial is used to represent the gates of our arithmetized zk programs. + * Polynomials use the majority of the memory in proving, so caution should be used in making sure + * unnecessary copies are avoided, both for avoiding unnecessary memory usage and performance + * due to unnecessary allocations. + * The polynomial has a maximum degree in the underlying SharedShiftedVirtualZeroesArray, dictated by the circuit size, + * this is just used for debugging as we represent. + * + * @tparam Fr the finite field type. + */ template class Polynomial { public: - /** - * Implements requirements of `std::ranges::contiguous_range` and `std::ranges::sized_range` - */ - using value_type = Fr; - using difference_type = std::ptrdiff_t; - using reference = value_type&; - // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) - using pointer = std::shared_ptr; - using const_pointer = pointer; - using iterator = Fr*; - using const_iterator = Fr const*; using FF = Fr; + enum class DontZeroMemory { FLAG }; - Polynomial(size_t initial_size); + Polynomial(size_t size, size_t virtual_size); + // Intended just for plonk, where size == virtual_size always + Polynomial(size_t size) + : Polynomial(size, size) + {} // Constructor that does not initialize values, use with caution to save time. - Polynomial(size_t initial_size, DontZeroMemory flag); + Polynomial(size_t size, size_t virtual_size, DontZeroMemory flag); Polynomial(const Polynomial& other); Polynomial(const Polynomial& other, size_t target_size); - Polynomial(Polynomial&& other) noexcept; + Polynomial(Polynomial&& other) noexcept = default; + + Polynomial(std::span coefficients, size_t virtual_size); - // Create a polynomial from the given fields. - Polynomial(std::span coefficients); + Polynomial(std::span coefficients) + : Polynomial(coefficients, coefficients.size()) + {} // Allow polynomials to be entirely reset/dormant Polynomial() = default; @@ -45,11 +56,10 @@ template class Polynomial { * @param interpolation_points (x₁,…,xₘ) * @param evaluations (y₁,…,yₘ) */ - Polynomial(std::span interpolation_points, std::span evaluations); + Polynomial(std::span interpolation_points, std::span evaluations, size_t virtual_size); // move assignment - Polynomial& operator=(Polynomial&& other) noexcept; - Polynomial& operator=(std::span coefficients) noexcept; + Polynomial& operator=(Polynomial&& other) noexcept = default; Polynomial& operator=(const Polynomial& other); ~Polynomial() = default; @@ -58,28 +68,20 @@ template class Polynomial { */ Polynomial share() const; - std::array hash() const { return crypto::sha256(byte_span()); } - - void clear() - { - // to keep the invariant that backing_memory_ can handle capacity() we do NOT reset backing_memory_ - // backing_memory_.reset(); - coefficients_ = nullptr; - size_ = 0; - } + void clear() { coefficients_ = SharedShiftedVirtualZeroesArray{}; } /** * @brief Check whether or not a polynomial is identically zero * */ - bool is_zero() + bool is_zero() const { if (is_empty()) { ASSERT(false); info("Checking is_zero on an empty Polynomial!"); } for (size_t i = 0; i < size(); i++) { - if (coefficients_[i] != 0) { + if (coefficients_.data()[i] != 0) { return false; } } @@ -88,106 +90,24 @@ template class Polynomial { bool operator==(Polynomial const& rhs) const; - // Const and non const versions of coefficient accessors - Fr const& operator[](const size_t i) const { return coefficients_[i]; } + void set(size_t i, const Fr& value) { coefficients_.set(i, value); }; + Fr get(size_t i) const { return coefficients_.get(i); }; - Fr& operator[](const size_t i) { return coefficients_[i]; } - - Fr const& at(const size_t i) const - { - ASSERT(i < capacity()); - return coefficients_[i]; - }; + bool is_empty() const { return coefficients_.size_ == 0; } - Fr& at(const size_t i) - { - ASSERT(i < capacity()); - return coefficients_[i]; - }; - - Fr evaluate(const Fr& z, size_t target_size) const; - Fr evaluate(const Fr& z) const; - - Fr compute_barycentric_evaluation(const Fr& z, const EvaluationDomain& domain) - requires polynomial_arithmetic::SupportsFFT; - Fr evaluate_from_fft(const EvaluationDomain& large_domain, - const Fr& z, - const EvaluationDomain& small_domain) - requires polynomial_arithmetic::SupportsFFT; - void fft(const EvaluationDomain& domain) - requires polynomial_arithmetic::SupportsFFT; - void partial_fft(const EvaluationDomain& domain, Fr constant = 1, bool is_coset = false) - requires polynomial_arithmetic::SupportsFFT; - void coset_fft(const EvaluationDomain& domain) - requires polynomial_arithmetic::SupportsFFT; - void coset_fft(const EvaluationDomain& domain, - const EvaluationDomain& large_domain, - size_t domain_extension) - requires polynomial_arithmetic::SupportsFFT; - void coset_fft_with_constant(const EvaluationDomain& domain, const Fr& constant) - requires polynomial_arithmetic::SupportsFFT; - void coset_fft_with_generator_shift(const EvaluationDomain& domain, const Fr& constant) - requires polynomial_arithmetic::SupportsFFT; - void ifft(const EvaluationDomain& domain) - requires polynomial_arithmetic::SupportsFFT; - void ifft_with_constant(const EvaluationDomain& domain, const Fr& constant) - requires polynomial_arithmetic::SupportsFFT; - void coset_ifft(const EvaluationDomain& domain) - requires polynomial_arithmetic::SupportsFFT; - Fr compute_kate_opening_coefficients(const Fr& z) - requires polynomial_arithmetic::SupportsFFT; - - bool is_empty() const { return size_ == 0; } + Fr* begin() { return data(); } + Fr* end() { return data() + size(); } + const Fr* begin() const { return data(); } + const Fr* end() const { return data() + size(); } /** - * @brief Returns an std::span of the left-shift of self. + * @brief Returns a Polynomial the left-shift of self. * * @details If the n coefficients of self are (0, a₁, …, aₙ₋₁), * we returns the view of the n-1 coefficients (a₁, …, aₙ₋₁). */ Polynomial shifted() const; - /** - * @brief Set self to the right shift of input coefficients - * @details Set the size of self to match the input then set coefficients equal to right shift of input. Note: The - * shifted result is constructed with its first shift-many coefficients equal to zero, so we assert that the last - * shift-size many input coefficients are equal to zero to ensure that the relationship f(X) = f_{shift}(X)/X^m - * holds. This is analagous to asserting the first coefficient is 0 in our left-shift-by-one method. - * - * @param coeffs_in - * @param shift_size - */ - void set_to_right_shifted(std::span coeffs_in, size_t shift_size = 1); - - /** - * @brief adds the polynomial q(X) 'other', multiplied by a scaling factor. - * - * @param other q(X) - * @param scaling_factor scaling factor by which all coefficients of q(X) are multiplied - */ - void add_scaled(std::span other, Fr scaling_factor); - - /** - * @brief adds the polynomial q(X) 'other'. - * - * @param other q(X) - */ - Polynomial& operator+=(std::span other); - - /** - * @brief subtracts the polynomial q(X) 'other'. - * - * @param other q(X) - */ - Polynomial& operator-=(std::span other); - - /** - * @brief sets this = p(X) to s⋅p(X) - * - * @param scaling_factor s - */ - Polynomial& operator*=(Fr scaling_factor); - /** * @brief evaluates p(X) = ∑ᵢ aᵢ⋅Xⁱ considered as multi-linear extension p(X₀,…,Xₘ₋₁) = ∑ᵢ aᵢ⋅Lᵢ(X₀,…,Xₘ₋₁) * at u = (u₀,…,uₘ₋₁) @@ -215,9 +135,14 @@ template class Polynomial { * their immediate neighbor, they are combined with the coefficient that lives n/2 indices away. * * @param evaluation_points an MLE partial evaluation point u = (u_0,…,u_{m-1}) - * @return Polynomial g(X_0,…,X_{n-m-1})) = p(X_0,…,X_{n-m-1},u_0,...u_{m-1}) + * @return DensePolynomial g(X_0,…,X_{n-m-1})) = p(X_0,…,X_{n-m-1},u_0,...u_{m-1}) */ - Polynomial partial_evaluate_mle(std::span evaluation_points) const; + Polynomial partial_evaluate_mle(std::span evaluation_points) const; + + Fr compute_barycentric_evaluation(const Fr& z, const EvaluationDomain& domain) + requires polynomial_arithmetic::SupportsFFT; + Fr compute_kate_opening_coefficients(const Fr& z) + requires polynomial_arithmetic::SupportsFFT; /** * @brief Divides p(X) by (X-r₁)⋯(X−rₘ) in-place. @@ -232,34 +157,69 @@ template class Polynomial { void factor_roots(std::span roots) { polynomial_arithmetic::factor_roots(std::span{ *this }, roots); }; void factor_roots(const Fr& root) { polynomial_arithmetic::factor_roots(std::span{ *this }, root); }; - iterator begin() { return coefficients_; } - iterator end() { return coefficients_ + size_; } - pointer data() { return backing_memory_; } + Fr evaluate(const Fr& z, size_t target_size) const; + Fr evaluate(const Fr& z) const; + + /** + * @brief adds the polynomial q(X) 'other', multiplied by a scaling factor. + * + * @param other q(X) + * @param scaling_factor scaling factor by which all coefficients of q(X) are multiplied + */ + void add_scaled(std::span other, Fr scaling_factor); - std::span byte_span() const + /** + * @brief adds the polynomial q(X) 'other'. + * + * @param other q(X) + */ + Polynomial& operator+=(std::span other); + + /** + * @brief subtracts the polynomial q(X) 'other'. + * + * @param other q(X) + */ + Polynomial& operator-=(std::span other); + + /** + * @brief sets this = p(X) to s⋅p(X) + * + * @param scaling_factor s + */ + Polynomial& operator*=(Fr scaling_factor); + + std::span as_span() const { return { coefficients_.data(), coefficients_.data() + coefficients_.size_ }; } + std::span as_span() { return { coefficients_.data(), coefficients_.data() + coefficients_.size_ }; } + std::size_t size() const { return coefficients_.size_; } + std::size_t virtual_size() const { return coefficients_.virtual_size_; } + + Fr* data() { return coefficients_.data(); } + const Fr* data() const { return coefficients_.data(); } + Fr& operator[](size_t i) { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - return { reinterpret_cast(coefficients_), size_ * sizeof(Fr) }; + ASSERT(i < size()); + return coefficients_.data()[i]; + } + const Fr& operator[](size_t i) const + { + ASSERT(i < size()); + return coefficients_.data()[i]; } - const_iterator begin() const { return coefficients_; } - const_iterator end() const { return coefficients_ + size_; } - const_pointer data() const { return backing_memory_; } - - std::size_t size() const { return size_; } - std::size_t capacity() const { return size_ + MAXIMUM_COEFFICIENT_SHIFT; } + static Polynomial random(size_t size) { return random(size, size); } - static Polynomial random(const size_t num_coeffs) + static Polynomial random(size_t size, size_t virtual_size) { - Polynomial p(num_coeffs); - std::generate_n(p.begin(), num_coeffs, []() { return Fr::random_element(); }); + Polynomial p(size, virtual_size, DontZeroMemory::FLAG); + std::generate_n(p.coefficients_.data(), size, []() { return Fr::random_element(); }); return p; } private: // allocate a fresh memory pointer for backing memory // DOES NOT initialize memory - void allocate_backing_memory(size_t n_elements); + void allocate_backing_memory(size_t size, size_t virtual_size); // safety check for in place operations bool in_place_operation_viable(size_t domain_size = 0) { return (size() >= domain_size); } @@ -269,16 +229,9 @@ template class Polynomial { // input size + MAXIMUM_COEFFICIENT_SHIFT to support 'shifted' coefficients efficiently. const static size_t MAXIMUM_COEFFICIENT_SHIFT = 1; - // The memory - // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) - std::shared_ptr backing_memory_; - // A pointer into backing_memory_ to support std::span-like functionality. This allows for coefficient subsets - // and shifts. - Fr* coefficients_ = nullptr; - // The size_ effectively represents the 'usable' length of the coefficients array but may be less than the true - // 'capacity' of the array. It is not explicitly tied to the degree and is not changed by any operations on the - // polynomial. - size_t size_ = 0; + // The underlying memory, with a bespoke (but minimal) shared array struct that fits our needs. + // Namely, it supports polynomial shifts and 'virtual' zeroes past a size up until a 'virtual' size. + SharedShiftedVirtualZeroesArray coefficients_; }; template inline std::ostream& operator<<(std::ostream& os, Polynomial const& p) @@ -298,22 +251,4 @@ template inline std::ostream& operator<<(std::ostream& os, Polynom << "]"; } -using polynomial = Polynomial; - -} // namespace bb - -/** - * The static_assert below ensure that that our Polynomial class correctly models an `std::ranges::contiguous_range`, - * and other requirements that allow us to convert a `Polynomial` to a `std::span`. - * - * This also means we can now iterate over the elements in the vector using a `for(auto ...)` loop, and use various std - * algorithms. - * - * static_assert(std::ranges::contiguous_range); - * static_assert(std::ranges::sized_range); - * static_assert(std::convertible_to>); - * static_assert(std::convertible_to>); - * // cannot convert a const polynomial to a non-const span - * static_assert(!std::convertible_to>); - * static_assert(std::convertible_to>); - */ +} // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomial.test.cpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial.test.cpp index 59e4d5fa747..cc4843e81de 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial.test.cpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial.test.cpp @@ -3,13 +3,11 @@ #include "barretenberg/polynomials/polynomial.hpp" -using namespace bb; - // Simple test/demonstration of shifted functionality TEST(Polynomial, Shifted) { using FF = bb::fr; - using Polynomial = Polynomial; + using Polynomial = bb::Polynomial; const size_t SIZE = 10; auto poly = Polynomial::random(SIZE); poly[0] = 0; // make it shiftable @@ -21,13 +19,13 @@ TEST(Polynomial, Shifted) // The shift is indeed the shift for (size_t i = 0; i < poly_shifted.size(); ++i) { - EXPECT_EQ(poly_shifted.at(i), poly.at(i + 1)); + EXPECT_EQ(poly_shifted.get(i), poly.get(i + 1)); } // If I change the original polynomial, the shift is updated accordingly poly[3] = 25; for (size_t i = 0; i < poly_shifted.size(); ++i) { - EXPECT_EQ(poly_shifted.at(i), poly.at(i + 1)); + EXPECT_EQ(poly_shifted.get(i), poly.get(i + 1)); } } @@ -35,7 +33,7 @@ TEST(Polynomial, Shifted) TEST(Polynomial, Share) { using FF = bb::fr; - using Polynomial = Polynomial; + using Polynomial = bb::Polynomial; const size_t SIZE = 10; auto poly = Polynomial::random(SIZE); diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.test.cpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.test.cpp index 0a58f36b9b3..d400545f063 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.test.cpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.test.cpp @@ -3,7 +3,7 @@ #include "barretenberg/numeric/bitop/get_msb.hpp" #include "barretenberg/numeric/random/engine.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" -#include "polynomial.hpp" +#include "legacy_polynomial.hpp" #include #include #include @@ -1058,7 +1058,7 @@ TYPED_TEST(PolynomialTests, interpolation_constructor_single) auto root = std::array{ FF(3) }; auto eval = std::array{ FF(4) }; - Polynomial t(root, eval); + LegacyPolynomial t(root, eval); ASSERT_EQ(t.size(), 1); ASSERT_EQ(t[0], eval[0]); } @@ -1078,7 +1078,7 @@ TYPED_TEST(PolynomialTests, interpolation_constructor) auto roots_copy(roots); auto evaluations_copy(evaluations); - Polynomial interpolated(roots, evaluations); + LegacyPolynomial interpolated(roots, evaluations); ASSERT_EQ(interpolated.size(), N); ASSERT_EQ(roots, roots_copy); @@ -1098,7 +1098,7 @@ TYPED_TEST(PolynomialTests, evaluate_mle) auto& engine = numeric::get_debug_randomness(); const size_t m = numeric::get_msb(N); EXPECT_EQ(N, 1 << m); - Polynomial poly(N); + LegacyPolynomial poly(N); for (size_t i = 1; i < N - 1; ++i) { poly[i] = FF::random_element(&engine); } @@ -1156,7 +1156,7 @@ TYPED_TEST(PolynomialTests, partial_evaluate_mle) // Initialize a random polynomial using FF = TypeParam; size_t N = 32; - Polynomial poly(N); + LegacyPolynomial poly(N); for (auto& coeff : poly) { coeff = FF::random_element(); } @@ -1193,7 +1193,7 @@ TYPED_TEST(PolynomialTests, factor_roots) auto test_case = [&](size_t NUM_ZERO_ROOTS, size_t NUM_NON_ZERO_ROOTS) { const size_t NUM_ROOTS = NUM_NON_ZERO_ROOTS + NUM_ZERO_ROOTS; - Polynomial poly(N); + LegacyPolynomial poly(N); for (size_t i = NUM_ZERO_ROOTS; i < N; ++i) { poly[i] = FF::random_element(); } @@ -1217,7 +1217,7 @@ TYPED_TEST(PolynomialTests, factor_roots) } if (NUM_NON_ZERO_ROOTS > 0) { - Polynomial interpolated(non_zero_roots, non_zero_evaluations); + LegacyPolynomial interpolated(non_zero_roots, non_zero_evaluations); EXPECT_EQ(interpolated.size(), NUM_NON_ZERO_ROOTS); for (size_t i = 0; i < NUM_NON_ZERO_ROOTS; ++i) { poly[NUM_ZERO_ROOTS + i] -= interpolated[i]; @@ -1229,7 +1229,7 @@ TYPED_TEST(PolynomialTests, factor_roots) EXPECT_EQ(poly.evaluate(roots[i]), FF::zero()) << i; } - Polynomial quotient(poly); + LegacyPolynomial quotient(poly); quotient.factor_roots(roots); // check that (t-r)q(t) == p(t) @@ -1246,7 +1246,7 @@ TYPED_TEST(PolynomialTests, factor_roots) EXPECT_EQ(poly, quotient); } if (NUM_ROOTS == 1) { - Polynomial quotient_single(poly); + LegacyPolynomial quotient_single(poly); quotient_single.factor_roots(roots[0]); EXPECT_EQ(quotient_single, quotient); } @@ -1266,13 +1266,13 @@ TYPED_TEST(PolynomialTests, move_construct_and_assign) // construct a poly with some arbitrary data size_t num_coeffs = 64; - Polynomial polynomial_a(num_coeffs); + LegacyPolynomial polynomial_a(num_coeffs); for (auto& coeff : polynomial_a) { coeff = FF::random_element(); } // construct a new poly from the original via the move constructor - Polynomial polynomial_b(std::move(polynomial_a)); + LegacyPolynomial polynomial_b(std::move(polynomial_a)); // verifiy that source poly is appropriately destroyed EXPECT_EQ(polynomial_a.begin(), nullptr); @@ -1286,7 +1286,7 @@ TYPED_TEST(PolynomialTests, move_construct_and_assign) EXPECT_EQ(polynomial_b.size(), 0); // define a poly with some arbitrary coefficients - Polynomial polynomial_d(num_coeffs); + LegacyPolynomial polynomial_d(num_coeffs); for (auto& coeff : polynomial_d) { coeff = FF::random_element(); } @@ -1305,13 +1305,13 @@ TYPED_TEST(PolynomialTests, default_construct_then_assign) // construct an arbitrary but non-empty polynomial size_t num_coeffs = 64; - Polynomial interesting_poly(num_coeffs); + LegacyPolynomial interesting_poly(num_coeffs); for (auto& coeff : interesting_poly) { coeff = FF::random_element(); } // construct an empty poly via the default constructor - Polynomial poly; + LegacyPolynomial poly; EXPECT_EQ(poly.is_empty(), true); @@ -1337,8 +1337,8 @@ TYPED_TEST(PolynomialTests, RightShift) size_t num_coeffs = 32; size_t num_nonzero_coeffs = 7; size_t shift_magnitude = 21; - Polynomial poly(num_coeffs); - Polynomial right_shifted_poly(num_coeffs); + LegacyPolynomial poly(num_coeffs); + LegacyPolynomial right_shifted_poly(num_coeffs); for (size_t idx = 0; idx < num_nonzero_coeffs; ++idx) { poly[idx] = FF::random_element(); diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store.cpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store.cpp index d23a6106444..f200df7b1e0 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store.cpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store.cpp @@ -1,6 +1,6 @@ #include "polynomial_store.hpp" #include "barretenberg/common/assert.hpp" -#include "barretenberg/polynomials/polynomial.hpp" +#include "barretenberg/polynomials/legacy_polynomial.hpp" #include #include #include @@ -22,7 +22,7 @@ template void PolynomialStore::put(std::string const& key, Pol * @param key string ID of the polynomial * @return Polynomial&; a reference to the polynomial associated with the given key */ -template bb::Polynomial PolynomialStore::get(std::string const& key) +template bb::LegacyPolynomial PolynomialStore::get(std::string const& key) { // info("poly store get: ", key); // Take a shallow copy of the polynomial. Compiler will move the shallow copy to call site. diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store.hpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store.hpp index c18103fefc9..84b67e1e28d 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store.hpp @@ -1,7 +1,7 @@ #pragma once #include "barretenberg/common/assert.hpp" -#include "barretenberg/polynomials/polynomial.hpp" +#include "barretenberg/polynomials/legacy_polynomial.hpp" #include #include #include @@ -11,7 +11,7 @@ namespace bb { template class PolynomialStore { private: - using Polynomial = bb::Polynomial; + using Polynomial = bb::LegacyPolynomial; std::unordered_map polynomial_map; public: diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store.test.cpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store.test.cpp index 649dd60191a..7a7231fb2b1 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store.test.cpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store.test.cpp @@ -1,7 +1,7 @@ #include #include -#include "barretenberg/polynomials/polynomial.hpp" +#include "barretenberg/polynomials/legacy_polynomial.hpp" #include "polynomial_store.hpp" using namespace bb; @@ -12,13 +12,13 @@ TEST(PolynomialStore, PutThenGet) PolynomialStore polynomial_store; // Instantiate a polynomial with random coefficients - Polynomial poly(1024); + LegacyPolynomial poly(1024); for (auto& coeff : poly) { coeff = fr::random_element(); } // Make a copy for comparison after original is moved into container - Polynomial poly_copy(poly); + LegacyPolynomial poly_copy(poly); // Move the poly into the container polynomial_store.put("id", std::move(poly)); @@ -32,7 +32,7 @@ TEST(PolynomialStore, NonexistentKey) { PolynomialStore polynomial_store; - polynomial_store.put("id_1", Polynomial(100)); + polynomial_store.put("id_1", LegacyPolynomial(100)); polynomial_store.get("id_1"); // no problem! @@ -47,9 +47,9 @@ TEST(PolynomialStore, Volume) size_t size2 = 10; size_t size3 = 5000; - Polynomial poly1(size1); - Polynomial poly2(size2); - Polynomial poly3(size3); + LegacyPolynomial poly1(size1); + LegacyPolynomial poly2(size2); + LegacyPolynomial poly3(size3); polynomial_store.put("id_1", std::move(poly1)); polynomial_store.put("id_2", std::move(poly2)); @@ -68,8 +68,8 @@ TEST(PolynomialStore, Remove) PolynomialStore polynomial_store; size_t size1 = 100; size_t size2 = 500; - Polynomial poly1(size1); - Polynomial poly2(size2); + LegacyPolynomial poly1(size1); + LegacyPolynomial poly2(size2); polynomial_store.put("id_1", std::move(poly1)); polynomial_store.put("id_2", std::move(poly2)); diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store_cache.hpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store_cache.hpp index 78b1c7a3e14..0c1c309c5e2 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store_cache.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store_cache.hpp @@ -1,6 +1,6 @@ #pragma once #include "./polynomial_store_wasm.hpp" -#include "barretenberg/polynomials/polynomial.hpp" +#include "barretenberg/polynomials/legacy_polynomial.hpp" #include #include @@ -17,7 +17,7 @@ namespace bb { */ class PolynomialStoreCache { private: - using Polynomial = bb::Polynomial; + using Polynomial = bb::LegacyPolynomial; std::map cache_; std::multimap::iterator> size_map_; PolynomialStoreWasm external_store; diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store_wasm.cpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store_wasm.cpp index 058770a1dce..491ae841f0e 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store_wasm.cpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store_wasm.cpp @@ -1,6 +1,6 @@ #include "polynomial_store_wasm.hpp" #include "barretenberg/env/data_store.hpp" -#include "barretenberg/polynomials/polynomial.hpp" +#include "barretenberg/polynomials/legacy_polynomial.hpp" namespace bb { @@ -11,7 +11,7 @@ template void PolynomialStoreWasm::put(std::string const& key, size_map[key] = value.size(); }; -template bb::Polynomial PolynomialStoreWasm::get(std::string const& key) +template bb::LegacyPolynomial PolynomialStoreWasm::get(std::string const& key) { auto p = Polynomial(size_map[key]); get_data(key.c_str(), (uint8_t*)p.data().get()); diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store_wasm.hpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store_wasm.hpp index ce33260821b..beb704256b6 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store_wasm.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_store_wasm.hpp @@ -1,5 +1,5 @@ #pragma once -#include "barretenberg/polynomials/polynomial.hpp" +#include "barretenberg/polynomials/legacy_polynomial.hpp" #include #include @@ -7,7 +7,7 @@ namespace bb { template class PolynomialStoreWasm { private: - using Polynomial = bb::Polynomial; + using Polynomial = bb::LegacyPolynomial; std::unordered_map size_map; public: diff --git a/barretenberg/cpp/src/barretenberg/polynomials/serialize.hpp b/barretenberg/cpp/src/barretenberg/polynomials/serialize.hpp index afbd340e025..c511ac6cfb1 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/serialize.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/serialize.hpp @@ -1,5 +1,5 @@ #pragma once -#include "polynomial.hpp" +#include "legacy_polynomial.hpp" namespace bb { diff --git a/barretenberg/cpp/src/barretenberg/polynomials/shared_shifted_virtual_zeroes_array.hpp b/barretenberg/cpp/src/barretenberg/polynomials/shared_shifted_virtual_zeroes_array.hpp new file mode 100644 index 00000000000..acc99519e00 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/polynomials/shared_shifted_virtual_zeroes_array.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include "barretenberg/common/assert.hpp" +#include +#include + +// Shared pointer array of a type (in our case, a field) that is +// conceptually filled with 0's until 'virtual_size_', but with actual memory usage +// proportional to 'size'. +// As well, there is a 'shift_' member that can be used when we want to share the underlying array. +// Everything is public as this is intended to be wrapped by another class, namely Polynomial +// The name is a mouthful, but again as an internal bundling of details it is intended to be wrapped by +// something more ergonomic. +template struct SharedShiftedVirtualZeroesArray { + // Method to set the value at a specific index + void set(size_t index, const T& value) + { + ASSERT(index < size_); + data()[index] = value; + } + + // Method to get the value at a specific index + T get(size_t index) const + { + ASSERT(index < virtual_size_); + if (index < size_) { + return data()[index]; + } + return T{}; // Return default element when index is out of the actual filled size + } + + T* data() { return backing_memory_.get() + shift_; } + const T* data() const { return backing_memory_.get() + shift_; } + + // MEMBERS: + // The actual size of the array allocation + // Memory-backed size such that we can set index 0..size()-1. + // Note: We DO NOT reduce our size or virtual size by shift_. This is because + // only support a shift by values that are included in backing_memory_. + // This guarantee is to be upheld by the class that uses SharedShiftedVirtualZeroesArray. + size_t size_ = 0; + // The logical size of the vector, indices size_ to virtual_size - 1 return T{} when indexed. + // This is really mainly used for a debug check that we never index >= virtual_size_; + // Virtual size such that we can get index 0..virtual_size()-1. + size_t virtual_size_ = 0; + // An offset into the array, used to implement shifted polynomials. + size_t shift_ = 0; + + // The memory + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) + std::shared_ptr backing_memory_; +}; \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp index cbfbe35cbda..e45c5448b69 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp @@ -18,7 +18,7 @@ template struct ProtogalaxyProofConstructionState { using ProverInstance = typename ProverInstances_::Instance; std::shared_ptr accumulator; - Polynomial perturbator; + LegacyPolynomial perturbator; std::vector deltas; Univariate combiner_quotient; FF compressed_perturbator; @@ -272,8 +272,8 @@ template class ProtoGalaxyProver_ { * * */ - static Polynomial compute_perturbator(const std::shared_ptr accumulator, - const std::vector& deltas) + static LegacyPolynomial compute_perturbator(const std::shared_ptr accumulator, + const std::vector& deltas) { BB_OP_COUNT_TIME(); auto full_honk_evaluations = compute_full_honk_evaluations( @@ -281,7 +281,7 @@ template class ProtoGalaxyProver_ { const auto betas = accumulator->gate_challenges; assert(betas.size() == deltas.size()); auto coeffs = construct_perturbator_coefficients(betas, deltas, full_honk_evaluations); - return Polynomial(coeffs); + return LegacyPolynomial(coeffs); } OptimisedTupleOfTuplesOfUnivariates optimised_univariate_accumulators; diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_impl.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_impl.hpp index 36774b7c25f..4199e2cf8ed 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_impl.hpp @@ -140,7 +140,8 @@ template void ProtoGalaxyProver_::pertu state.accumulator = get_accumulator(); FF delta = transcript->template get_challenge("delta"); state.deltas = compute_round_challenge_pows(state.accumulator->proving_key.log_circuit_size, delta); - state.perturbator = Polynomial(state.accumulator->proving_key.log_circuit_size + 1); // initialize to all zeros + state.perturbator = + LegacyPolynomial(state.accumulator->proving_key.log_circuit_size + 1); // initialize to all zeros // compute perturbator only if this is not the first round and has an accumulator if (state.accumulator->is_accumulator) { state.perturbator = compute_perturbator(state.accumulator, state.deltas); diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp index 9ffce227620..2bfaa09a7a6 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp @@ -57,7 +57,7 @@ std::shared_ptr ProtoGalaxyVerifier_target_sum; - auto perturbator = Polynomial(perturbator_coeffs); + auto perturbator = LegacyPolynomial(perturbator_coeffs); FF perturbator_challenge = transcript->template get_challenge("perturbator_challenge"); auto perturbator_at_challenge = perturbator.evaluate(perturbator_challenge); diff --git a/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp index 353be1c76ce..519f1031b0a 100644 --- a/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp @@ -3,7 +3,6 @@ #include #include "barretenberg/common/constexpr_utils.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/relation_types.hpp" diff --git a/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp index 687d81d2f73..2ef8c62257f 100644 --- a/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp @@ -3,7 +3,6 @@ #include #include "barretenberg/common/constexpr_utils.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/relation_types.hpp" diff --git a/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_set_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_set_relation.hpp index d958f7a5481..f0c742e24b8 100644 --- a/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_set_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_set_relation.hpp @@ -3,7 +3,6 @@ #include #include "barretenberg/common/constexpr_utils.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/relation_types.hpp" diff --git a/barretenberg/cpp/src/barretenberg/relations/generic_lookup/generic_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/generic_lookup/generic_lookup_relation.hpp index 2f388d0ddbd..320216495bc 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generic_lookup/generic_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generic_lookup/generic_lookup_relation.hpp @@ -20,7 +20,6 @@ #include "barretenberg/common/constexpr_utils.hpp" #include "barretenberg/honk/proof_system/logderivative_library.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/relation_types.hpp" diff --git a/barretenberg/cpp/src/barretenberg/relations/generic_permutation/generic_permutation_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/generic_permutation/generic_permutation_relation.hpp index a34290e7544..9c51976afd0 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generic_permutation/generic_permutation_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generic_permutation/generic_permutation_relation.hpp @@ -11,7 +11,6 @@ #include "barretenberg/common/constexpr_utils.hpp" #include "barretenberg/honk/proof_system/logderivative_library.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/relation_types.hpp" diff --git a/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp index 038e6cd326c..fe66475aded 100644 --- a/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/logderiv_lookup_relation.hpp @@ -4,7 +4,6 @@ #include "barretenberg/common/constexpr_utils.hpp" #include "barretenberg/honk/proof_system/logderivative_library.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/relation_types.hpp" diff --git a/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/protogalaxy_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/protogalaxy_recursive_verifier.cpp index 437fb0422bd..91eebe93ddb 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/protogalaxy_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/protogalaxy_recursive_verifier.cpp @@ -1,6 +1,5 @@ #include "protogalaxy_recursive_verifier.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_delta.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/stdlib/honk_recursion/verifier/recursive_instances.hpp" namespace bb::stdlib::recursion::honk { diff --git a/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/protogalaxy_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/protogalaxy_recursive_verifier.test.cpp index 504481a0e7f..1c5a5697ec7 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/protogalaxy_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/honk_recursion/verifier/protogalaxy_recursive_verifier.test.cpp @@ -159,7 +159,7 @@ template class ProtoGalaxyRecursiveTests : public tes coeffs.emplace_back(el); coeffs_ct.emplace_back(fr_ct(&builder, el)); } - Polynomial poly(coeffs); + LegacyPolynomial poly(coeffs); fr point = fr::random_element(); fr_ct point_ct(fr_ct(&builder, point)); auto res1 = poly.evaluate(point); diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/grand_product_library.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/grand_product_library.test.cpp index 0bf80a8db8c..845a1ea28f6 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/grand_product_library.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/grand_product_library.test.cpp @@ -1,7 +1,6 @@ #include "barretenberg/plonk_honk_shared/library/grand_product_library.hpp" #include "barretenberg/ecc/curves/bn254/bn254.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp" #include "barretenberg/srs/factories/file_crs_factory.hpp" 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 0a672b3ea15..618b726c2ff 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp @@ -7,6 +7,7 @@ #include "barretenberg/honk/proof_system/types/proof.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_delta.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_library.hpp" +#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/auxiliary_relation.hpp" #include "barretenberg/relations/databus_lookup_relation.hpp" diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_recursive_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_recursive_flavor.hpp index d7cadaabf79..2378d7580be 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_recursive_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_recursive_flavor.hpp @@ -6,7 +6,6 @@ #include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/polynomials/barycentric.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/stdlib/honk_recursion/transcript/transcript.hpp" #include "barretenberg/stdlib/primitives/curves/bn254.hpp" 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 fadbb9a6f16..931245f7876 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 @@ -5,7 +5,6 @@ #include "barretenberg/plonk_honk_shared/types/circuit_type.hpp" #include "barretenberg/plonk_honk_shared/types/merkle_hash_type.hpp" #include "barretenberg/plonk_honk_shared/types/pedersen_commitment_type.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/stdlib_circuit_builders/op_queue/ecc_op_queue.hpp" #include "barretenberg/stdlib_circuit_builders/plookup_tables/plookup_tables.hpp" #include "barretenberg/stdlib_circuit_builders/plookup_tables/types.hpp" diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_keccak.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_keccak.hpp index 30db8636251..7f28be204a2 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_keccak.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_keccak.hpp @@ -8,7 +8,6 @@ #include "barretenberg/plonk_honk_shared/library/grand_product_library.hpp" #include "barretenberg/polynomials/barycentric.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/auxiliary_relation.hpp" #include "barretenberg/relations/delta_range_constraint_relation.hpp" diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp index 7112f622026..c1ef2c14190 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp @@ -6,7 +6,6 @@ #include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/polynomials/barycentric.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/auxiliary_relation.hpp" #include "barretenberg/relations/delta_range_constraint_relation.hpp" diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp index bfc9b0facac..ebbb6b4e191 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp @@ -1,5 +1,6 @@ #include "sumcheck.hpp" #include "barretenberg/ecc/curves/bn254/fr.hpp" +#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/relations/auxiliary_relation.hpp" #include "barretenberg/relations/delta_range_constraint_relation.hpp" #include "barretenberg/relations/elliptic_relation.hpp" @@ -15,13 +16,14 @@ using namespace bb; namespace { using Flavor = UltraFlavor; using FF = typename Flavor::FF; +using Polynomial = Polynomial; using ProverPolynomials = typename Flavor::ProverPolynomials; using RelationSeparator = Flavor::RelationSeparator; const size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES; -Polynomial random_poly(size_t size) +Polynomial random_poly(size_t size) { - auto poly = bb::Polynomial(size); + auto poly = Polynomial(size); for (auto& coeff : poly) { coeff = FF::random_element(); } @@ -51,7 +53,7 @@ TEST_F(SumcheckTests, PolynomialNormalization) // Randomly construct the prover polynomials that are input to Sumcheck. // Note: ProverPolynomials are defined as spans so the polynomials they point to need to exist in memory. - std::array, NUM_POLYNOMIALS> random_polynomials; + std::array, NUM_POLYNOMIALS> random_polynomials; for (auto& poly : random_polynomials) { poly = random_poly(multivariate_n); } @@ -114,7 +116,7 @@ TEST_F(SumcheckTests, PolynomialNormalization) // full polynomials at challenge u via the evaluate_mle() function std::vector u_challenge = { u_0, u_1, u_2 }; for (auto [full_poly, claimed_eval] : zip_view(full_polynomials.get_all(), output.claimed_evaluations.get_all())) { - Polynomial poly(full_poly); + bb::Polynomial poly(full_poly); auto v_expected = poly.evaluate_mle(u_challenge); EXPECT_EQ(v_expected, claimed_eval); } @@ -127,7 +129,7 @@ TEST_F(SumcheckTests, Prover) // Randomly construct the prover polynomials that are input to Sumcheck. // Note: ProverPolynomials are defined as spans so the polynomials they point to need to exist in memory. - std::array, NUM_POLYNOMIALS> random_polynomials; + std::array, NUM_POLYNOMIALS> random_polynomials; for (auto& poly : random_polynomials) { poly = random_poly(multivariate_n); } @@ -174,9 +176,9 @@ TEST_F(SumcheckTests, ProverAndVerifierSimple) // Construct prover polynomials where each is the zero polynomial. // Note: ProverPolynomials are defined as spans so the polynomials they point to need to exist in memory. - std::array, NUM_POLYNOMIALS> zero_polynomials; + std::array, NUM_POLYNOMIALS> zero_polynomials; for (auto& poly : zero_polynomials) { - poly = Polynomial(multivariate_n); + poly = bb::Polynomial(multivariate_n); } auto full_polynomials = construct_ultra_full_polynomials(zero_polynomials); @@ -199,16 +201,16 @@ TEST_F(SumcheckTests, ProverAndVerifierSimple) std::array q_arith = { 0, 1, 1, 0 }; // Setting all of these to 0 ensures the GrandProductRelation is satisfied - full_polynomials.w_l = w_l; - full_polynomials.w_r = w_r; - full_polynomials.w_o = w_o; - full_polynomials.w_4 = w_4; - full_polynomials.q_m = q_m; - full_polynomials.q_l = q_l; - full_polynomials.q_r = q_r; - full_polynomials.q_o = q_o; - full_polynomials.q_c = q_c; - full_polynomials.q_arith = q_arith; + full_polynomials.w_l = bb::Polynomial(w_l); + full_polynomials.w_r = bb::Polynomial(w_r); + full_polynomials.w_o = bb::Polynomial(w_o); + full_polynomials.w_4 = bb::Polynomial(w_4); + full_polynomials.q_m = bb::Polynomial(q_m); + full_polynomials.q_l = bb::Polynomial(q_l); + full_polynomials.q_r = bb::Polynomial(q_r); + full_polynomials.q_o = bb::Polynomial(q_o); + full_polynomials.q_c = bb::Polynomial(q_c); + full_polynomials.q_arith = bb::Polynomial(q_arith); // Set aribitrary random relation parameters RelationParameters relation_parameters{ diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp index 82c633d9aa3..22bb710e84a 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp @@ -7,6 +7,7 @@ #include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/flavor/relation_definitions.hpp" #include "barretenberg/honk/proof_system/permutation_library.hpp" +#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/relation_parameters.hpp" #include "barretenberg/relations/translator_vm/translator_decomposition_relation.hpp" diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp index 5aa967235c2..4ab4e1ecf90 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp @@ -10,7 +10,6 @@ #include "barretenberg/flavor/flavor.hpp" #include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/transcript/transcript.hpp" #include "barretenberg/vm/avm/generated/flavor_settings.hpp" diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/prover.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/prover.cpp index d5cbab1767e..41e801b4c83 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/prover.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/prover.cpp @@ -8,7 +8,6 @@ #include "barretenberg/honk/proof_system/logderivative_library.hpp" #include "barretenberg/honk/proof_system/permutation_library.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_library.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/relations/permutation_relation.hpp" #include "barretenberg/sumcheck/sumcheck.hpp" diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/verifier.cpp index e1375bc8b1b..40137e3d457 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/verifier.cpp @@ -5,7 +5,6 @@ #include "barretenberg/commitment_schemes/zeromorph/zeromorph.hpp" #include "barretenberg/numeric/bitop/get_msb.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/transcript/transcript.hpp" namespace bb { diff --git a/bb-pilcom/bb-pil-backend/templates/flavor.hpp.hbs b/bb-pilcom/bb-pil-backend/templates/flavor.hpp.hbs index 416d7de916f..8318a084de8 100644 --- a/bb-pilcom/bb-pil-backend/templates/flavor.hpp.hbs +++ b/bb-pilcom/bb-pil-backend/templates/flavor.hpp.hbs @@ -10,7 +10,6 @@ #include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/transcript/transcript.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/flavor/flavor.hpp" #include "barretenberg/vm/{{snakeCase name}}/generated/flavor_settings.hpp" @@ -41,7 +40,7 @@ template using tuple_cat_t = decltype(std::tuple_cat(std:: namespace bb { class {{name}}Flavor { - public: + public: using Curve = {{name}}FlavorSettings::Curve; using G1 = {{name}}FlavorSettings::G1; using PCS = {{name}}FlavorSettings::PCS; @@ -59,7 +58,7 @@ class {{name}}Flavor { // This flavor would not be used with ZK Sumcheck static constexpr bool HasZK = false; - static constexpr size_t NUM_PRECOMPUTED_ENTITIES = {{len fixed}}; + static constexpr size_t NUM_PRECOMPUTED_ENTITIES = {{len fixed}}; static constexpr size_t NUM_WITNESS_ENTITIES = {{len witness}}; static constexpr size_t NUM_SHIFTED_ENTITIES = {{len shifted}}; static constexpr size_t NUM_WIRES = NUM_WITNESS_ENTITIES + NUM_PRECOMPUTED_ENTITIES; @@ -144,7 +143,7 @@ class {{name}}Flavor { , public ShiftedEntities { public: DEFINE_COMPOUND_GET_ALL(PrecomputedEntities, WitnessEntities, ShiftedEntities) - + auto get_unshifted() { return concatenate(PrecomputedEntities::get_all(), WitnessEntities::get_all()); } @@ -160,7 +159,7 @@ class {{name}}Flavor { using Base = ProvingKeyAvm_, WitnessEntities, CommitmentKey>; using Base::Base; - auto get_to_be_shifted() { + auto get_to_be_shifted() { return {{name}}Flavor::get_to_be_shifted(*this); } }; @@ -180,7 +179,7 @@ class {{name}}Flavor { using BaseDataType = const FF; using DataType = BaseDataType&; - {{!-- + {{!-- We define the flavor members here again to avoid having to make this class inherit from AllEntities. If we did inherit from AllEntities, we have to define a special constructor for AllEntities, and all the classes that AllEntities inherits from, in cascade. @@ -202,7 +201,7 @@ class {{name}}Flavor { ProverPolynomials(ProverPolynomials&& o) noexcept = default; ProverPolynomials& operator=(ProverPolynomials&& o) noexcept = default; ~ProverPolynomials() = default; - + ProverPolynomials(ProvingKey& proving_key); [[nodiscard]] size_t get_polynomial_size() const { return {{witness.0}}.size(); } diff --git a/bb-pilcom/bb-pil-backend/templates/prover.cpp.hbs b/bb-pilcom/bb-pil-backend/templates/prover.cpp.hbs index d053ab7104d..c70f7c36639 100644 --- a/bb-pilcom/bb-pil-backend/templates/prover.cpp.hbs +++ b/bb-pilcom/bb-pil-backend/templates/prover.cpp.hbs @@ -8,7 +8,6 @@ #include "barretenberg/honk/proof_system/logderivative_library.hpp" #include "barretenberg/honk/proof_system/permutation_library.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_library.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/relations/permutation_relation.hpp" #include "barretenberg/sumcheck/sumcheck.hpp" diff --git a/bb-pilcom/bb-pil-backend/templates/verifier.cpp.hbs b/bb-pilcom/bb-pil-backend/templates/verifier.cpp.hbs index acc5346c665..57910fa1adb 100644 --- a/bb-pilcom/bb-pil-backend/templates/verifier.cpp.hbs +++ b/bb-pilcom/bb-pil-backend/templates/verifier.cpp.hbs @@ -5,7 +5,6 @@ #include "barretenberg/commitment_schemes/zeromorph/zeromorph.hpp" #include "barretenberg/numeric/bitop/get_msb.hpp" -#include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/transcript/transcript.hpp" namespace bb {