From 9d9679724fecdd0f8617fce666712f9531fbee1b Mon Sep 17 00:00:00 2001 From: TohruKohrita Date: Thu, 12 Oct 2023 15:44:20 +0000 Subject: [PATCH 01/15] added basic structure for quotient method --- .../honk/pcs/zeromorph/zeromorph.hpp | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp index 30b9a64eb6d..2c324bd8c48 100644 --- a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp @@ -36,6 +36,50 @@ template class ZeroMorphProver_ { static const size_t N_max = 1 << 22; public: + /** + * @brief + * + * @param polynomial + * @param u_challenge + * @return std::vector + */ + static std::vector compute_multilinear_quotients_efficient(Polynomial polynomial, std::span u_challenge) + { + size_t log_N = numeric::get_msb(polynomial.size()); + // The size of the multilinear challenge must equal the log of the polynomial size + ASSERT(log_N == u_challenge.size()); + + // Define the vector of quotients q_k, k = 0, ..., log_N-1 + std::vector quotients; + for (size_t k = 0; k < log_N; ++k) { + size_t size = 1 << k; + quotients.emplace_back(Polynomial(size)); // degree 2^k - 1 + } + + // Compute the q_k in reverse order, i.e. q_{n-1}, ..., q_0 + for (size_t k = 0; k < log_N; ++k) { + // Define partial evaluation point u' = (u_k, ..., u_{n-1}) + auto evaluation_point_size = static_cast(k + 1); + std::vector u_partial(u_challenge.end() - evaluation_point_size, u_challenge.end()); + + // Compute f' = f(X_0,...,X_{k-1}, u') + auto f_1 = polynomial.partial_evaluate_mle(u_partial); + + // Increment first element to get altered partial evaluation point u'' = (u_k + 1, u_{k+1}, ..., u_{n-1}) + u_partial[0] += 1; + + // Compute f'' = f(X_0,...,X_{k-1}, u'') + auto f_2 = polynomial.partial_evaluate_mle(u_partial); + + // Compute q_k = f''(X_0,...,X_{k-1}) - f'(X_0,...,X_{k-1}) + auto q_k = f_2; + q_k -= f_1; + + quotients[log_N - k - 1] = q_k; + } + + return quotients; + } /** * @brief Compute multivariate quotients q_k(X_0, ..., X_{k-1}) for f(X_0, ..., X_{d-1}) * @details Given multilinear polynomial f = f(X_0, ..., X_{d-1}) for which f(u) = v, compute q_k such that: From dead65767184e567ce9ddf27d6d4d3d9b4280a07 Mon Sep 17 00:00:00 2001 From: TohruKohrita Date: Thu, 12 Oct 2023 16:10:29 +0000 Subject: [PATCH 02/15] added quotient algo test --- .../honk/pcs/zeromorph/zeromorph.test.cpp | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp index c4c4dd95984..99e87285b6a 100644 --- a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp @@ -496,6 +496,49 @@ using CurveTypes = ::testing::Types; TYPED_TEST_SUITE(ZeroMorphTest, CurveTypes); TYPED_TEST_SUITE(ZeroMorphWithConcatenationTest, CurveTypes); +TYPED_TEST(ZeroMorphTest, QuotientConstructionEfficient) +{ + // Define some useful type aliases + using ZeroMorphProver = ZeroMorphProver_; + using Fr = typename TypeParam::ScalarField; + using Polynomial = barretenberg::Polynomial; + + // Define size parameters + size_t N = 16; + size_t log_N = numeric::get_msb(N); + + // Construct a random multilinear polynomial f, and (u,v) such that f(u) = v. + Polynomial multilinear_f = this->random_polynomial(N); + std::vector u_challenge = this->random_evaluation_point(log_N); + Fr v_evaluation = multilinear_f.evaluate_mle(u_challenge); + + // Compute the multilinear quotients q_k = q_k(X_0, ..., X_{k-1}) + std::vector quotients = ZeroMorphProver::compute_multilinear_quotients_efficient(multilinear_f, u_challenge); + + // Show that the q_k were properly constructed by showing that the identity holds at a random multilinear challenge + // z, i.e. f(z) - v - \sum_{k=0}^{d-1} (z_k - u_k)q_k(z) = 0 + std::vector z_challenge = this->random_evaluation_point(log_N); + + Fr result = multilinear_f.evaluate_mle(z_challenge); + result -= v_evaluation; + for (size_t k = 0; k < log_N; ++k) { + auto q_k_eval = Fr(0); + if (k == 0) { + // q_0 = a_0 is a constant polynomial so it's evaluation is simply its constant coefficient + q_k_eval = quotients[k][0]; + } else { + // Construct (u_0, ..., u_{k-1}) + auto subrange_size = static_cast(k); + std::vector z_partial(z_challenge.begin(), z_challenge.begin() + subrange_size); + q_k_eval = quotients[k].evaluate_mle(z_partial); + } + // result = result - (z_k - u_k) * q_k(u_0, ..., u_{k-1}) + result -= (z_challenge[k] - u_challenge[k]) * q_k_eval; + } + + EXPECT_EQ(result, 0); +} + /** * @brief Test method for computing q_k given multilinear f * @details Given f = f(X_0, ..., X_{d-1}), and (u,v) such that f(u) = v, compute q_k = q_k(X_0, ..., X_{k-1}) such that From 7424d57ff154042357cee684c5e9cbb673b78478 Mon Sep 17 00:00:00 2001 From: TohruKohrita Date: Fri, 20 Oct 2023 10:24:17 +0000 Subject: [PATCH 03/15] added compute_multilinear_quotients_efficient --- .../honk/pcs/zeromorph/zeromorph.hpp | 40 ++++++++++++------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp index 2c324bd8c48..b6521f6b647 100644 --- a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp @@ -56,26 +56,36 @@ template class ZeroMorphProver_ { quotients.emplace_back(Polynomial(size)); // degree 2^k - 1 } - // Compute the q_k in reverse order, i.e. q_{n-1}, ..., q_0 - for (size_t k = 0; k < log_N; ++k) { - // Define partial evaluation point u' = (u_k, ..., u_{n-1}) - auto evaluation_point_size = static_cast(k + 1); - std::vector u_partial(u_challenge.end() - evaluation_point_size, u_challenge.end()); + // Compute the first 2^{n-1} coefficients of q_{n-1} + size_t size_q = 1 << (log_N-1); + Polynomial q; - // Compute f' = f(X_0,...,X_{k-1}, u') - auto f_1 = polynomial.partial_evaluate_mle(u_partial); + for (size_t l = 0; l < size_q; ++l) { + q[l] = polynomial[size_q + l] - polynomial[l]; + } - // Increment first element to get altered partial evaluation point u'' = (u_k + 1, u_{k+1}, ..., u_{n-1}) - u_partial[0] += 1; + quotients[log_N - 1] = q; - // Compute f'' = f(X_0,...,X_{k-1}, u'') - auto f_2 = polynomial.partial_evaluate_mle(u_partial); + // Compute the first 2^k coefficients of q_k in reverse order from k= n-2, i.e. q_{n-2}, ..., q_0 + //Define the intermediate polynomial f + Polynomial f; - // Compute q_k = f''(X_0,...,X_{k-1}) - f'(X_0,...,X_{k-1}) - auto q_k = f_2; - q_k -= f_1; + for (size_t k = 0; k < log_N -1; ++k) { + // Compute f = f_{n-1-k} + for (size_t l = 0; l < size_q; ++l) { + f[l] = polynomial[l] + u_challenge[log_N-1-k]*q[l]; + } - quotients[log_N - k - 1] = q_k; + size_q = size_q/2; + q = 0; + + for (size_t l = 0; l < size_q; ++l) { + q[l] = f[size_q + l] - f[l]; + } + + quotients[log_N - k - 1] = q; + polynomial = f; + f=0; } return quotients; From 2d5fe3adbf594620d443ac40b2c0c8d3ee73d6ab Mon Sep 17 00:00:00 2001 From: TohruKohrita Date: Fri, 20 Oct 2023 14:49:55 +0000 Subject: [PATCH 04/15] fix --- .../honk/pcs/zeromorph/zeromorph.hpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp index b6521f6b647..0bb2e579fe0 100644 --- a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp @@ -58,8 +58,7 @@ template class ZeroMorphProver_ { // Compute the first 2^{n-1} coefficients of q_{n-1} size_t size_q = 1 << (log_N-1); - Polynomial q; - + Polynomial q = Polynomial(size_q); for (size_t l = 0; l < size_q; ++l) { q[l] = polynomial[size_q + l] - polynomial[l]; } @@ -68,24 +67,24 @@ template class ZeroMorphProver_ { // Compute the first 2^k coefficients of q_k in reverse order from k= n-2, i.e. q_{n-2}, ..., q_0 //Define the intermediate polynomial f - Polynomial f; - + Polynomial f = Polynomial(size_q); + Polynomial g = polynomial; for (size_t k = 0; k < log_N -1; ++k) { - // Compute f = f_{n-1-k} + // Compute f = f_{k+1} for (size_t l = 0; l < size_q; ++l) { - f[l] = polynomial[l] + u_challenge[log_N-1-k]*q[l]; + f[l] = g[l] + u_challenge[log_N-1-k] * q[l]; } size_q = size_q/2; - q = 0; + q = Polynomial(size_q); for (size_t l = 0; l < size_q; ++l) { q[l] = f[size_q + l] - f[l]; } - quotients[log_N - k - 1] = q; - polynomial = f; - f=0; + quotients[log_N - k - 2] = q; + g = f; + f = Polynomial(size_q); } return quotients; From 1620a4eabd37d24f6e9d88306fae9efa395652be Mon Sep 17 00:00:00 2001 From: TohruKohrita Date: Tue, 24 Oct 2023 15:05:15 +0000 Subject: [PATCH 05/15] intermediate commit, work with luke poly -> vec --- .../honk/pcs/zeromorph/zeromorph.hpp | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp index 0bb2e579fe0..7b2c3bcb7a1 100644 --- a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp @@ -65,26 +65,31 @@ template class ZeroMorphProver_ { quotients[log_N - 1] = q; + std::vector f_k; + f_k.resize(size_q); + + std::vector g(polynomial.data(), polynomial.data()+size_q); + // Compute the first 2^k coefficients of q_k in reverse order from k= n-2, i.e. q_{n-2}, ..., q_0 - //Define the intermediate polynomial f - Polynomial f = Polynomial(size_q); - Polynomial g = polynomial; - for (size_t k = 0; k < log_N -1; ++k) { - // Compute f = f_{k+1} + //Define the intermediate polynomial f_k + // Polynomial f_k = Polynomial(size_q); + // Polynomial g = polynomial; + for (size_t k = 1; k < log_N ; ++k) { + // Compute f_k for (size_t l = 0; l < size_q; ++l) { - f[l] = g[l] + u_challenge[log_N-1-k] * q[l]; + f_k[l] = g[l] + u_challenge[log_N-k] * q[l]; } size_q = size_q/2; q = Polynomial(size_q); for (size_t l = 0; l < size_q; ++l) { - q[l] = f[size_q + l] - f[l]; + q[l] = f_k[size_q + l] - f_k[l]; } - quotients[log_N - k - 2] = q; - g = f; - f = Polynomial(size_q); + quotients[log_N - k - 1] = q; + g = f_k; + // f = Polynomial(size_q); } return quotients; From afac697d434a345f87e4053e016acb64f6db1e72 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Tue, 24 Oct 2023 20:44:56 +0000 Subject: [PATCH 06/15] fix build and use efficient algo in prove function --- .../honk/pcs/zeromorph/zeromorph.hpp | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp index 7b2c3bcb7a1..ddcf1aad9fc 100644 --- a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp @@ -37,13 +37,14 @@ template class ZeroMorphProver_ { public: /** - * @brief - * - * @param polynomial - * @param u_challenge - * @return std::vector + * @brief + * + * @param polynomial + * @param u_challenge + * @return std::vector */ - static std::vector compute_multilinear_quotients_efficient(Polynomial polynomial, std::span u_challenge) + static std::vector compute_multilinear_quotients_efficient(Polynomial polynomial, + std::span u_challenge) { size_t log_N = numeric::get_msb(polynomial.size()); // The size of the multilinear challenge must equal the log of the polynomial size @@ -57,7 +58,7 @@ template class ZeroMorphProver_ { } // Compute the first 2^{n-1} coefficients of q_{n-1} - size_t size_q = 1 << (log_N-1); + size_t size_q = 1 << (log_N - 1); Polynomial q = Polynomial(size_q); for (size_t l = 0; l < size_q; ++l) { q[l] = polynomial[size_q + l] - polynomial[l]; @@ -68,19 +69,19 @@ template class ZeroMorphProver_ { std::vector f_k; f_k.resize(size_q); - std::vector g(polynomial.data(), polynomial.data()+size_q); + std::vector g(polynomial.data().get(), polynomial.data().get() + size_q); // Compute the first 2^k coefficients of q_k in reverse order from k= n-2, i.e. q_{n-2}, ..., q_0 - //Define the intermediate polynomial f_k + // Define the intermediate polynomial f_k // Polynomial f_k = Polynomial(size_q); // Polynomial g = polynomial; - for (size_t k = 1; k < log_N ; ++k) { - // Compute f_k + for (size_t k = 1; k < log_N; ++k) { + // Compute f_k for (size_t l = 0; l < size_q; ++l) { - f_k[l] = g[l] + u_challenge[log_N-k] * q[l]; + f_k[l] = g[l] + u_challenge[log_N - k] * q[l]; } - size_q = size_q/2; + size_q = size_q / 2; q = Polynomial(size_q); for (size_t l = 0; l < size_q; ++l) { @@ -404,7 +405,7 @@ template class ZeroMorphProver_ { f_polynomial += g_batched.shifted(); // Compute the multilinear quotients q_k = q_k(X_0, ..., X_{k-1}) - auto quotients = compute_multilinear_quotients(f_polynomial, u_challenge); + auto quotients = compute_multilinear_quotients_efficient(f_polynomial, u_challenge); // Compute and send commitments C_{q_k} = [q_k], k = 0,...,d-1 std::vector q_k_commitments; From 7094574ac4809d0ac6c378ae4550d59c1cb5c7fa Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 25 Oct 2023 17:06:22 +0000 Subject: [PATCH 07/15] auto format test file --- .../cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp index 99e87285b6a..b4b858465c3 100644 --- a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp @@ -513,7 +513,8 @@ TYPED_TEST(ZeroMorphTest, QuotientConstructionEfficient) Fr v_evaluation = multilinear_f.evaluate_mle(u_challenge); // Compute the multilinear quotients q_k = q_k(X_0, ..., X_{k-1}) - std::vector quotients = ZeroMorphProver::compute_multilinear_quotients_efficient(multilinear_f, u_challenge); + std::vector quotients = + ZeroMorphProver::compute_multilinear_quotients_efficient(multilinear_f, u_challenge); // Show that the q_k were properly constructed by showing that the identity holds at a random multilinear challenge // z, i.e. f(z) - v - \sum_{k=0}^{d-1} (z_k - u_k)q_k(z) = 0 From 608e43e0553c788a962668a5824186df7daedb4d Mon Sep 17 00:00:00 2001 From: TohruKohrita Date: Thu, 26 Oct 2023 08:43:15 +0000 Subject: [PATCH 08/15] removed old algorithm for q_k --- .../honk/pcs/zeromorph/zeromorph.hpp | 64 ++----------------- 1 file changed, 4 insertions(+), 60 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp index ddcf1aad9fc..ca2d0e1b70e 100644 --- a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp @@ -37,11 +37,11 @@ template class ZeroMorphProver_ { public: /** - * @brief + * @brief Compute the degree < 2^k truncation of multivariate quotients q_k(X_0, ..., X_{k-1}) for f(X_0, ..., X_{d-1}) * - * @param polynomial - * @param u_challenge - * @return std::vector + * @param polynomial Multilinear polynomial f(X_0, ..., X_{d-1}) + * @param u_challenge Multivariate challenge u = (u_0, ..., u_{d-1}) + * @return std::vector degree < 2^k truncation of q_k */ static std::vector compute_multilinear_quotients_efficient(Polynomial polynomial, std::span u_challenge) @@ -95,62 +95,6 @@ template class ZeroMorphProver_ { return quotients; } - /** - * @brief Compute multivariate quotients q_k(X_0, ..., X_{k-1}) for f(X_0, ..., X_{d-1}) - * @details Given multilinear polynomial f = f(X_0, ..., X_{d-1}) for which f(u) = v, compute q_k such that: - * - * f(X_0, ..., X_{d-1}) - v = \sum_{k=0}^{d-1} (X_k - u_k)q_k(X_0, ..., X_{k-1}) - * - * The polynomials q_k can be computed explicitly as the difference of the partial evaluation of f in the last - * (n - k) variables at, respectively, u'' = (u_k + 1, u_{k+1}, ..., u_{n-1}) and u' = (u_k, ..., u_{n-1}). I.e. - * - * q_k(X_0, ..., X_{k-1}) = f(X_0,...,X_{k-1}, u'') - f(X_0,...,X_{k-1}, u') - * - * @note In practice, 2^d is equal to the circuit size N - * - * TODO(#739): This method has been designed for clarity at the expense of efficiency. Implement the more efficient - * algorithm detailed in the latest versions of the ZeroMorph paper. - * @param polynomial Multilinear polynomial f(X_0, ..., X_{d-1}) - * @param u_challenge Multivariate challenge u = (u_0, ..., u_{d-1}) - * @return std::vector The quotients q_k - */ - static std::vector compute_multilinear_quotients(Polynomial polynomial, std::span u_challenge) - { - size_t log_N = numeric::get_msb(polynomial.size()); - // The size of the multilinear challenge must equal the log of the polynomial size - ASSERT(log_N == u_challenge.size()); - - // Define the vector of quotients q_k, k = 0, ..., log_N-1 - std::vector quotients; - for (size_t k = 0; k < log_N; ++k) { - size_t size = 1 << k; - quotients.emplace_back(Polynomial(size)); // degree 2^k - 1 - } - - // Compute the q_k in reverse order, i.e. q_{n-1}, ..., q_0 - for (size_t k = 0; k < log_N; ++k) { - // Define partial evaluation point u' = (u_k, ..., u_{n-1}) - auto evaluation_point_size = static_cast(k + 1); - std::vector u_partial(u_challenge.end() - evaluation_point_size, u_challenge.end()); - - // Compute f' = f(X_0,...,X_{k-1}, u') - auto f_1 = polynomial.partial_evaluate_mle(u_partial); - - // Increment first element to get altered partial evaluation point u'' = (u_k + 1, u_{k+1}, ..., u_{n-1}) - u_partial[0] += 1; - - // Compute f'' = f(X_0,...,X_{k-1}, u'') - auto f_2 = polynomial.partial_evaluate_mle(u_partial); - - // Compute q_k = f''(X_0,...,X_{k-1}) - f'(X_0,...,X_{k-1}) - auto q_k = f_2; - q_k -= f_1; - - quotients[log_N - k - 1] = q_k; - } - - return quotients; - } /** * @brief Construct batched, lifted-degree univariate quotient \hat{q} = \sum_k y^k * X^{N - d_k - 1} * q_k From d78d5d9033e9dbea605566e4b0960058a008df74 Mon Sep 17 00:00:00 2001 From: TohruKohrita Date: Thu, 26 Oct 2023 08:47:07 +0000 Subject: [PATCH 09/15] removed old QuotientConstruction test --- .../honk/pcs/zeromorph/zeromorph.test.cpp | 49 ++----------------- 1 file changed, 3 insertions(+), 46 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp index b4b858465c3..259d9f09d0c 100644 --- a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp @@ -496,50 +496,6 @@ using CurveTypes = ::testing::Types; TYPED_TEST_SUITE(ZeroMorphTest, CurveTypes); TYPED_TEST_SUITE(ZeroMorphWithConcatenationTest, CurveTypes); -TYPED_TEST(ZeroMorphTest, QuotientConstructionEfficient) -{ - // Define some useful type aliases - using ZeroMorphProver = ZeroMorphProver_; - using Fr = typename TypeParam::ScalarField; - using Polynomial = barretenberg::Polynomial; - - // Define size parameters - size_t N = 16; - size_t log_N = numeric::get_msb(N); - - // Construct a random multilinear polynomial f, and (u,v) such that f(u) = v. - Polynomial multilinear_f = this->random_polynomial(N); - std::vector u_challenge = this->random_evaluation_point(log_N); - Fr v_evaluation = multilinear_f.evaluate_mle(u_challenge); - - // Compute the multilinear quotients q_k = q_k(X_0, ..., X_{k-1}) - std::vector quotients = - ZeroMorphProver::compute_multilinear_quotients_efficient(multilinear_f, u_challenge); - - // Show that the q_k were properly constructed by showing that the identity holds at a random multilinear challenge - // z, i.e. f(z) - v - \sum_{k=0}^{d-1} (z_k - u_k)q_k(z) = 0 - std::vector z_challenge = this->random_evaluation_point(log_N); - - Fr result = multilinear_f.evaluate_mle(z_challenge); - result -= v_evaluation; - for (size_t k = 0; k < log_N; ++k) { - auto q_k_eval = Fr(0); - if (k == 0) { - // q_0 = a_0 is a constant polynomial so it's evaluation is simply its constant coefficient - q_k_eval = quotients[k][0]; - } else { - // Construct (u_0, ..., u_{k-1}) - auto subrange_size = static_cast(k); - std::vector z_partial(z_challenge.begin(), z_challenge.begin() + subrange_size); - q_k_eval = quotients[k].evaluate_mle(z_partial); - } - // result = result - (z_k - u_k) * q_k(u_0, ..., u_{k-1}) - result -= (z_challenge[k] - u_challenge[k]) * q_k_eval; - } - - EXPECT_EQ(result, 0); -} - /** * @brief Test method for computing q_k given multilinear f * @details Given f = f(X_0, ..., X_{d-1}), and (u,v) such that f(u) = v, compute q_k = q_k(X_0, ..., X_{k-1}) such that @@ -548,7 +504,7 @@ TYPED_TEST(ZeroMorphTest, QuotientConstructionEfficient) * f(X_0, ..., X_{d-1}) - v = \sum_{k=0}^{d-1} (X_k - u_k)q_k(X_0, ..., X_{k-1}) * */ -TYPED_TEST(ZeroMorphTest, QuotientConstruction) +TYPED_TEST(ZeroMorphTest, QuotientConstructionEfficient) { // Define some useful type aliases using ZeroMorphProver = ZeroMorphProver_; @@ -565,7 +521,8 @@ TYPED_TEST(ZeroMorphTest, QuotientConstruction) Fr v_evaluation = multilinear_f.evaluate_mle(u_challenge); // Compute the multilinear quotients q_k = q_k(X_0, ..., X_{k-1}) - std::vector quotients = ZeroMorphProver::compute_multilinear_quotients(multilinear_f, u_challenge); + std::vector quotients = + ZeroMorphProver::compute_multilinear_quotients_efficient(multilinear_f, u_challenge); // Show that the q_k were properly constructed by showing that the identity holds at a random multilinear challenge // z, i.e. f(z) - v - \sum_{k=0}^{d-1} (z_k - u_k)q_k(z) = 0 From 7e90d1c1a243180e1d46c6bb862f7735d832d0fc Mon Sep 17 00:00:00 2001 From: TohruKohrita Date: Thu, 26 Oct 2023 08:51:40 +0000 Subject: [PATCH 10/15] Give a proper name to a function --- .../cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp | 4 ++-- .../src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp index ca2d0e1b70e..e888fa4f125 100644 --- a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp @@ -43,7 +43,7 @@ template class ZeroMorphProver_ { * @param u_challenge Multivariate challenge u = (u_0, ..., u_{d-1}) * @return std::vector degree < 2^k truncation of q_k */ - static std::vector compute_multilinear_quotients_efficient(Polynomial polynomial, + static std::vector compute_multilinear_quotients(Polynomial polynomial, std::span u_challenge) { size_t log_N = numeric::get_msb(polynomial.size()); @@ -349,7 +349,7 @@ template class ZeroMorphProver_ { f_polynomial += g_batched.shifted(); // Compute the multilinear quotients q_k = q_k(X_0, ..., X_{k-1}) - auto quotients = compute_multilinear_quotients_efficient(f_polynomial, u_challenge); + auto quotients = compute_multilinear_quotients(f_polynomial, u_challenge); // Compute and send commitments C_{q_k} = [q_k], k = 0,...,d-1 std::vector q_k_commitments; diff --git a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp index 259d9f09d0c..c77634400a1 100644 --- a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp @@ -504,7 +504,7 @@ TYPED_TEST_SUITE(ZeroMorphWithConcatenationTest, CurveTypes); * f(X_0, ..., X_{d-1}) - v = \sum_{k=0}^{d-1} (X_k - u_k)q_k(X_0, ..., X_{k-1}) * */ -TYPED_TEST(ZeroMorphTest, QuotientConstructionEfficient) +TYPED_TEST(ZeroMorphTest, QuotientConstruction) { // Define some useful type aliases using ZeroMorphProver = ZeroMorphProver_; @@ -522,7 +522,7 @@ TYPED_TEST(ZeroMorphTest, QuotientConstructionEfficient) // Compute the multilinear quotients q_k = q_k(X_0, ..., X_{k-1}) std::vector quotients = - ZeroMorphProver::compute_multilinear_quotients_efficient(multilinear_f, u_challenge); + ZeroMorphProver::compute_multilinear_quotients(multilinear_f, u_challenge); // Show that the q_k were properly constructed by showing that the identity holds at a random multilinear challenge // z, i.e. f(z) - v - \sum_{k=0}^{d-1} (z_k - u_k)q_k(z) = 0 From 39f6a5622b403d029495d120d164480643807ba1 Mon Sep 17 00:00:00 2001 From: TohruKohrita Date: Thu, 26 Oct 2023 09:14:06 +0000 Subject: [PATCH 11/15] modify comments --- .../cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp | 4 ++-- .../src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp index e888fa4f125..85400796faa 100644 --- a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp @@ -37,11 +37,11 @@ template class ZeroMorphProver_ { public: /** - * @brief Compute the degree < 2^k truncation of multivariate quotients q_k(X_0, ..., X_{k-1}) for f(X_0, ..., X_{d-1}) + * @brief Compute multivariate quotients q_k(X_0, ..., X_{k-1}) for f(X_0, ..., X_{d-1}) * * @param polynomial Multilinear polynomial f(X_0, ..., X_{d-1}) * @param u_challenge Multivariate challenge u = (u_0, ..., u_{d-1}) - * @return std::vector degree < 2^k truncation of q_k + * @return std::vector The quotients q_k */ static std::vector compute_multilinear_quotients(Polynomial polynomial, std::span u_challenge) diff --git a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp index c77634400a1..c4c4dd95984 100644 --- a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.test.cpp @@ -521,8 +521,7 @@ TYPED_TEST(ZeroMorphTest, QuotientConstruction) Fr v_evaluation = multilinear_f.evaluate_mle(u_challenge); // Compute the multilinear quotients q_k = q_k(X_0, ..., X_{k-1}) - std::vector quotients = - ZeroMorphProver::compute_multilinear_quotients(multilinear_f, u_challenge); + std::vector quotients = ZeroMorphProver::compute_multilinear_quotients(multilinear_f, u_challenge); // Show that the q_k were properly constructed by showing that the identity holds at a random multilinear challenge // z, i.e. f(z) - v - \sum_{k=0}^{d-1} (z_k - u_k)q_k(z) = 0 From 1460c665d29d2d7aa3b413375f5338ab0c340e06 Mon Sep 17 00:00:00 2001 From: TohruKohrita Date: Thu, 26 Oct 2023 09:17:09 +0000 Subject: [PATCH 12/15] editorial --- .../cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp index 85400796faa..769dd9a0f6a 100644 --- a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp @@ -57,7 +57,7 @@ template class ZeroMorphProver_ { quotients.emplace_back(Polynomial(size)); // degree 2^k - 1 } - // Compute the first 2^{n-1} coefficients of q_{n-1} + // Compute the coefficients of q_{n-1} size_t size_q = 1 << (log_N - 1); Polynomial q = Polynomial(size_q); for (size_t l = 0; l < size_q; ++l) { @@ -71,10 +71,7 @@ template class ZeroMorphProver_ { std::vector g(polynomial.data().get(), polynomial.data().get() + size_q); - // Compute the first 2^k coefficients of q_k in reverse order from k= n-2, i.e. q_{n-2}, ..., q_0 - // Define the intermediate polynomial f_k - // Polynomial f_k = Polynomial(size_q); - // Polynomial g = polynomial; + // 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) { // Compute f_k for (size_t l = 0; l < size_q; ++l) { @@ -90,7 +87,6 @@ template class ZeroMorphProver_ { quotients[log_N - k - 1] = q; g = f_k; - // f = Polynomial(size_q); } return quotients; From 4461cb6aa81a9976b6892d5b95531330f8c49c9d Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Thu, 26 Oct 2023 14:27:14 +0000 Subject: [PATCH 13/15] run formatter --- .../cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp index 769dd9a0f6a..7a5ebad66d0 100644 --- a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp @@ -43,8 +43,7 @@ template class ZeroMorphProver_ { * @param u_challenge Multivariate challenge u = (u_0, ..., u_{d-1}) * @return std::vector The quotients q_k */ - static std::vector compute_multilinear_quotients(Polynomial polynomial, - std::span u_challenge) + static std::vector compute_multilinear_quotients(Polynomial polynomial, std::span u_challenge) { size_t log_N = numeric::get_msb(polynomial.size()); // The size of the multilinear challenge must equal the log of the polynomial size From 9243075f3b9187d679a5225d3b27f58d423c01b3 Mon Sep 17 00:00:00 2001 From: TohruKohrita Date: Fri, 27 Oct 2023 12:11:57 +0000 Subject: [PATCH 14/15] add detailed description of the algorithm --- .../barretenberg/honk/pcs/zeromorph/zeromorph.hpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp index 7a5ebad66d0..363317b8468 100644 --- a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp @@ -37,7 +37,20 @@ template class ZeroMorphProver_ { public: /** - * @brief Compute multivariate quotients q_k(X_0, ..., X_{k-1}) for f(X_0, ..., X_{d-1}) + * @brief Compute multivariate quotients q_k(X_0, ..., X_{k-1}) for f(X_0, ..., X_{n-1}) + * @details Starting from the coefficients of f, compute q_k inductively from k = n - 1, to k = 0. + * f needs to be updated at each step. + * + * First, compute q_{n-1} of size N/2 by + * q_{n-1}[l] = f[N/2 + l ] - f[l]. + * + * Update f by f[l] <- f[l] + u_{n-1} * q_{n-1}[l]; f now has size N/2. + * Compute q_{n-2} of size N/(2^2) by + * q_{n-2}[l] = f[N/2^2 + l] - f[l]. + * + * Update f by f[l] <- f[l] + u_{n-2} * q_{n-2}[l]; f now has size N/(2^2). + * Compute q_{n-3} of size N/(2^3) by + * q_{n-3}[l] = f[N/2^3 + l] - f[l]. Repeat similarly until you reach q_0. * * @param polynomial Multilinear polynomial f(X_0, ..., X_{d-1}) * @param u_challenge Multivariate challenge u = (u_0, ..., u_{d-1}) From 3664cbe8924ed73849bb6bf671e2eddb389d9d72 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Fri, 27 Oct 2023 14:08:14 +0000 Subject: [PATCH 15/15] format --- .../cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp index 363317b8468..483c9f8095e 100644 --- a/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/pcs/zeromorph/zeromorph.hpp @@ -39,8 +39,8 @@ template class ZeroMorphProver_ { /** * @brief Compute multivariate quotients q_k(X_0, ..., X_{k-1}) for f(X_0, ..., X_{n-1}) * @details Starting from the coefficients of f, compute q_k inductively from k = n - 1, to k = 0. - * f needs to be updated at each step. - * + * f needs to be updated at each step. + * * First, compute q_{n-1} of size N/2 by * q_{n-1}[l] = f[N/2 + l ] - f[l]. *