From e056407ac9c95b9ee8e56667534ed0467a3208b1 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Wed, 13 Nov 2024 15:53:36 +0000 Subject: [PATCH 01/25] created row disabling poly --- .../polynomials/row_disabling_polynomial.hpp | 211 ++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp diff --git a/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp new file mode 100644 index 000000000000..4c2d897e7922 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp @@ -0,0 +1,211 @@ +#pragma once +#include "barretenberg/common/compiler_hints.hpp" +#include "barretenberg/common/op_count.hpp" +#include "barretenberg/common/thread.hpp" +#include "barretenberg/stdlib/primitives/bool/bool.hpp" + +#include +#include +namespace bb { +/** + * @brief Struct for the polynomial \f$ L = (1 - L_1(X_0, \ldots, X_{d-1}) - L_2(X_0, \ldots, X_{d-1}) - L_3(X_0, + * \ldots, X_{d-1}) )\f$. + * @details Need to efficiently evaluate this polynomial at any point of the form \f$ (u_0, \ldots, u_{k}, \vec{i} ) \f$ + * where \f$ \vec{i}\f$ belongs to a hypercube. + * First, note \f$ L_1(X_0, \ldots, X_{d-1}) = X_0 \prod_{i=1}^{d-1} (1 - X_i)\f$, \f$ L_2 = (1 - X_0) + * X_1\prod_{i=2}^{n-1} (1 - X_i)\f$ and \f$ L_3(X_0, \ldots, X_{d-1}) = X_0 * X_1 * \prod_{i=2}^{d-1} (1 - X_i) \f$. + * Therefore, \f$ L = (X_0*(1-X_1) + (1 - X_0)* X_1 + X_0 * X_1) * \prod_{i=2}^{d-1} (1- X_i)\f$ which simplifies + * further to \f$ L = (1 + X_0 + X_1 - X_0*X_1) \prod_{i=2}^{d-1} (1- X_i) \f$. + * We could compute the sumcheck univariate contributions from \f$L\f$: \f$ \sum_{i=0}^{2^n-1} L = 2^{n} - 3\f$, because + * \f$ L = 0\f$ at \f$ i = 1, 2, 3\f$ and \f$1\f$ elsewhere. + * After getting the first challenge \f$ u_0 \f$, \f$ L(u_0) = L(u_0, X_1, \ldots, X_{d-1}) = 1 - (1 + u_0 + X_1 - + * u_0\cdot X_1) L_0(X_2,X_3,\ldots, X_{d-1})\f$. It is more useful to have the values of \f$ L(u_0) \f$ on the + * hypercube. + * + * \f$ L_1(u_0, X_1,\ldots, X_{d-1}) = u_0 * L_0 (X_1,\ldots, X_{d-1})\f$, it evaluates to \f$ u_0\f$ at \f$ 0 \f$ and + * is \f$ 0 \f$ elsewehere. + * + * \f$ L_2(u_0, X_1,\ldots, X_{d-1}) = (1-u_0) * L_1 (X_1,\ldots, X_{d-1})\f$, it evaluates to \f$ (1-u_0) \f$ at \f$ 1 + * \f$ and is \f$ 0 \f$ elsewhere. + * + * \f$ L_3(u_0, X_1,\ldots, X_{d-1}) = u_0 * L_1 (X_1,\ldots, X_{d-1})\f$, it evaluates to \f$ u_0 \f$ at \f$ 1\f$ and + * is \f$ 0 \f$ elsewhere. + * Therefore, \f$ L(u_0)(i) = 1 \f$ for $i \neq 0 \f$, \f$ L(u_0)(0) = 1 - u_0 \f$. + * + * We see that the sum of \f$ L(u_0) \f$ over the smaller hypercube is equal to \f$ 2^{d-2} - 2 - (u_0 + 1) \f$. + * The partial eval \f$ L(u_0, u_1) \f$ is given by \f$ 1 - (1+u_0 + u_1 - u_0 \cdot u_1) L_0(X_2, X_3,\ldots, + * X_{d-1})\f$, it is \f$ 1 \f$ outside of \f$ 0 \f$, and is equal to \f$ - u_0 - u_1 + u_0u_1 \f$. + * In the subsequent rounds \f$L(u_0, \ldots, u_i)\f$ is \f$ 1\f$ outside of \f$ 0 \f$ ans is given as + * \f$ 1 - (1+u_0 + u_1 - u_0 \cdot u_1) (1-u_2)\cdots (1 - u_i) L_0(X_{i+1}, \ldots, X_{d-1})\f$ + * @tparam FF + */ +template struct RowDisablingPolynomial { + /** + * @brief The challenges \f$(\beta_0,\ldots, \beta_{d-1}) \f$ + * + */ + std::vector betas; + + /** + * @brief The consecutive evaluations \f$ pow_{\ell}(\beta) = pow_{\beta}(\vec \ell) \f$ for \f$\vec \ell\f$ + * identified with the integers \f$\ell = 0,\ldots, 2^d-1\f$ + * + */ + std::vector beta_products; + /** + * @brief In Round \f$ i\f$ of Sumcheck, it points to the \f$ i \f$-th element in \f$ \vec \beta \f$ + * + */ + size_t current_element_idx = 0; + /** + * @brief In Round \f$ i\f$ of Sumcheck, the periodicity equals to \f$ 2^{i+1}\f$ and represents the fixed interval + * at which elements not containing either of \f$ (\beta_0,\ldots ,β_i)\f$ appear in #beta_products. + * + */ + size_t periodicity = 2; + /** + * @brief The value \f$c_i\f$ obtained by partially evaluating one variable in the power polynomial at each round. + * At the end of Round \f$ i \f$ in the sumcheck protocol, variable \f$X_i\f$ is replaced by the challenge \f$u_i + * \f$. The partial evaluation result is updated to represent \f$ pow_{\beta}(u_0,.., u_{i}) = \prod_{k=0}^{i} ( + * (1-u_k) + u_k\cdot \beta_k) \f$. + * + */ + FF partial_evaluation_result = FF(1); + + /** + * @brief Construct a new RowDisablingPolynomial + * + * @param betas + * @param log_num_monomials + */ + RowDisablingPolynomial(const std::vector& betas, const size_t log_num_monomials) + : betas(betas) + , beta_products(compute_beta_products(betas, log_num_monomials)) + {} + + /** + * @brief Construct a new RowDisablingPolynomial object without expanding to a vector of monomials + * @details The sumcheck verifier does not use beta_products + * + * @param betas + */ + RowDisablingPolynomial(const std::vector& betas) + : betas(betas) + {} + + /** + * @brief Retruns the element in #beta_products at place #idx. + * + * @param idx + * @return FF const& + */ + FF const& operator[](size_t idx) const { return beta_products[idx]; } + /** + * @brief Computes the component at index #current_element_idx in #betas. + * + * @return FF + */ + FF current_element() const { return betas[current_element_idx]; } + + /** + * @brief Evaluate \f$ ((1−X_{i}) + X_{i}\cdot \beta_{i})\f$ at the challenge point \f$ X_{i}=u_{i} \f$. + */ + FF univariate_eval(FF challenge) const { return (FF(1) + (challenge * (betas[current_element_idx] - FF(1)))); }; + + /** + */ + template FF univariate_eval(const FF& challenge, const Bool& dummy_round) const + { + FF beta_or_dummy; + // For the Ultra Recursive flavor to ensure constant size proofs, we perform constant amount of hashing + // producing 28 gate betas and we need to use the betas in the dummy rounds to ensure the permutation related + // selectors stay the same regardless of real circuit size. The other recursive verifiers aren't constant for + // the dummy sumcheck rounds we just use 1 as we only generated real log_n betas + if (current_element_idx < betas.size()) { + beta_or_dummy = betas[current_element_idx]; + } else { + beta_or_dummy = FF::from_witness(challenge.get_context(), 1); + } + FF beta_val = FF::conditional_assign(dummy_round, FF::from_witness(challenge.get_context(), 1), beta_or_dummy); + return (FF(1) + (challenge * (beta_val - FF(1)))); + } + + /** + * @brief Partially evaluate the \f$pow_{\beta} \f$-polynomial at the new challenge and update \f$ c_i \f$ + * @details Update the constant \f$c_{i} \to c_{i+1} \f$ multiplying it by \f$pow_{\beta}\f$'s factor \f$\left( + * (1-X_i) + X_i\cdot \beta_i\right)\vert_{X_i = u_i}\f$ computed by \ref univariate_eval. + * @param challenge \f$ i \f$-th verifier challenge \f$ u_{i}\f$ + */ + void partially_evaluate(FF challenge) + { + FF current_univariate_eval = univariate_eval(challenge); + partial_evaluation_result *= current_univariate_eval; + current_element_idx++; + periodicity *= 2; + } + + /** + * @brief Partially evaluate the \f$pow_{\beta} \f$-polynomial at the new challenge and update \f$ c_i \f$ + * @details Update the constant \f$c_{i} \to c_{i+1} \f$ multiplying it by \f$pow_{\beta}\f$'s factor \f$\left( + * (1-X_i) + X_i\cdot \beta_i\right)\vert_{X_i = u_i}\f$ computed by \ref univariate_eval. + * @param challenge \f$ i \f$-th verifier challenge \f$ u_{i}\f$ + */ + template void partially_evaluate(const FF& challenge, const stdlib::bool_t& dummy) + { + FF current_univariate_eval = univariate_eval(challenge, dummy); + // If dummy round, make no update to the partial_evaluation_result + partial_evaluation_result = FF::conditional_assign( + dummy, partial_evaluation_result, partial_evaluation_result * current_univariate_eval); + current_element_idx++; + periodicity *= 2; + } + + /** + * @brief Given \f$ \vec\beta = (\beta_0,...,\beta_{d-1})\f$ compute \f$ pow_{\ell}(\vec \beta) = pow_{\beta}(\vec + * \ell)\f$ for \f$ \ell =0,\ldots,2^{d}-1\f$. + * + * @param log_num_monomials Determines the number of beta challenges used to compute beta_products (required because + * when we generate CONST_SIZE_PROOF_LOG_N, currently 28, challenges but the real circuit size is less than 1 << + * CONST_SIZE_PROOF_LOG_N, we should compute unnecessarily a vector of beta_products of length 1 << 28 ) + */ + BB_PROFILE static std::vector compute_beta_products(const std::vector& betas, + const size_t log_num_monomials) + { + + size_t pow_size = 1 << log_num_monomials; + std::vector beta_products(pow_size); + + // Determine number of threads for multithreading. + // Note: Multithreading is "on" for every round but we reduce the number of threads from the max available based + // on a specified minimum number of iterations per thread. This eventually leads to the use of a single thread. + // For now we use a power of 2 number of threads simply to ensure the round size is evenly divided. + size_t max_num_threads = get_num_cpus_pow2(); // number of available threads (power of 2) + size_t min_iterations_per_thread = 1 << 6; // min number of iterations for which we'll spin up a unique thread + size_t desired_num_threads = pow_size / min_iterations_per_thread; + size_t num_threads = std::min(desired_num_threads, max_num_threads); // fewer than max if justified + num_threads = num_threads > 0 ? num_threads : 1; // ensure num threads is >= 1 + size_t iterations_per_thread = pow_size / num_threads; // actual iterations per thread + + // TODO(https://github.com/AztecProtocol/barretenberg/issues/864): This computation is asymtotically slow as it + // does pow_size * log(pow_size) work. However, in practice, its super efficient because its trivially + // parallelizable and only takes 45ms for the whole 6 iter IVC benchmark. Its also very readable, so we're + // leaving it unoptimized for now. + parallel_for(num_threads, [&](size_t thread_idx) { + size_t start = thread_idx * iterations_per_thread; + size_t end = (thread_idx + 1) * iterations_per_thread; + for (size_t i = start; i < end; i++) { + auto res = FF(1); + for (size_t j = i, beta_idx = 0; j > 0; j >>= 1, beta_idx++) { + if ((j & 1) == 1) { + res *= betas[beta_idx]; + } + } + beta_products[i] = res; + } + }); + + return beta_products; + } +}; + +} // namespace bb \ No newline at end of file From b53cf64780a3bbcf610eb8278c8d61fd54a535b3 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Thu, 14 Nov 2024 16:43:15 +0000 Subject: [PATCH 02/25] some comments --- .../barretenberg/polynomials/row_disabling_polynomial.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp index 4c2d897e7922..2814028cad21 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp @@ -36,7 +36,10 @@ namespace bb { * The partial eval \f$ L(u_0, u_1) \f$ is given by \f$ 1 - (1+u_0 + u_1 - u_0 \cdot u_1) L_0(X_2, X_3,\ldots, * X_{d-1})\f$, it is \f$ 1 \f$ outside of \f$ 0 \f$, and is equal to \f$ - u_0 - u_1 + u_0u_1 \f$. * In the subsequent rounds \f$L(u_0, \ldots, u_i)\f$ is \f$ 1\f$ outside of \f$ 0 \f$ ans is given as - * \f$ 1 - (1+u_0 + u_1 - u_0 \cdot u_1) (1-u_2)\cdots (1 - u_i) L_0(X_{i+1}, \ldots, X_{d-1})\f$ + * \f$ 1 - (1+u_0 + u_1 - u_0 \cdot u_1) (1-u_2)\cdots (1 - u_i) L_0(X_{i+1}, \ldots, X_{d-1})\f$. + * + * When the prover computes the first sumcheck univariate \f$S_0(X) = \sum L \cdot H(X_0,\ldots, X_{d-1})\f$, + * * @tparam FF */ template struct RowDisablingPolynomial { From c2efe174ea7e26acb912fc59cf00e7b6759b9dd1 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Mon, 18 Nov 2024 16:38:40 +0000 Subject: [PATCH 03/25] disabled rows 1-3, adjusted tests --- .../polynomials/row_disabling_polynomial.hpp | 183 ++-------------- .../mega_zk_flavor.hpp | 2 + .../ultra_zk_flavor.hpp | 2 +- .../src/barretenberg/sumcheck/sumcheck.hpp | 26 ++- .../barretenberg/sumcheck/sumcheck.test.cpp | 34 +-- .../barretenberg/sumcheck/sumcheck_round.hpp | 205 ++++++++++++++---- 6 files changed, 228 insertions(+), 224 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp index 2814028cad21..b8ac353f3b64 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp @@ -38,176 +38,35 @@ namespace bb { * In the subsequent rounds \f$L(u_0, \ldots, u_i)\f$ is \f$ 1\f$ outside of \f$ 0 \f$ ans is given as * \f$ 1 - (1+u_0 + u_1 - u_0 \cdot u_1) (1-u_2)\cdots (1 - u_i) L_0(X_{i+1}, \ldots, X_{d-1})\f$. * - * When the prover computes the first sumcheck univariate \f$S_0(X) = \sum L \cdot H(X_0,\ldots, X_{d-1})\f$, + * When the prover computes the first sumcheck univariate \f$S_k(X) = \sum L \cdot H(X_0,\ldots, X_{d-1})\f$, it has to + * compute \f$ \sum_{i_{k+1},\ldots, i_{d-1}} L(u_0,u_1,\ldots, u_{k-1}, X, i_{k+1},\ldots, i_{d-1}) H(\cdots)\f$ * * @tparam FF */ template struct RowDisablingPolynomial { - /** - * @brief The challenges \f$(\beta_0,\ldots, \beta_{d-1}) \f$ - * - */ - std::vector betas; + // by default it is a constant multilinear polynomial = 1 + FF eval_at_0{ 0 }; + FF eval_at_1{ 1 }; + FF one = FF{ 1 }; + FF zero = FF{ 0 }; - /** - * @brief The consecutive evaluations \f$ pow_{\ell}(\beta) = pow_{\beta}(\vec \ell) \f$ for \f$\vec \ell\f$ - * identified with the integers \f$\ell = 0,\ldots, 2^d-1\f$ - * - */ - std::vector beta_products; - /** - * @brief In Round \f$ i\f$ of Sumcheck, it points to the \f$ i \f$-th element in \f$ \vec \beta \f$ - * - */ - size_t current_element_idx = 0; - /** - * @brief In Round \f$ i\f$ of Sumcheck, the periodicity equals to \f$ 2^{i+1}\f$ and represents the fixed interval - * at which elements not containing either of \f$ (\beta_0,\ldots ,β_i)\f$ appear in #beta_products. - * - */ - size_t periodicity = 2; - /** - * @brief The value \f$c_i\f$ obtained by partially evaluating one variable in the power polynomial at each round. - * At the end of Round \f$ i \f$ in the sumcheck protocol, variable \f$X_i\f$ is replaced by the challenge \f$u_i - * \f$. The partial evaluation result is updated to represent \f$ pow_{\beta}(u_0,.., u_{i}) = \prod_{k=0}^{i} ( - * (1-u_k) + u_k\cdot \beta_k) \f$. - * - */ - FF partial_evaluation_result = FF(1); + RowDisablingPolynomial() = default; - /** - * @brief Construct a new RowDisablingPolynomial - * - * @param betas - * @param log_num_monomials - */ - RowDisablingPolynomial(const std::vector& betas, const size_t log_num_monomials) - : betas(betas) - , beta_products(compute_beta_products(betas, log_num_monomials)) - {} - - /** - * @brief Construct a new RowDisablingPolynomial object without expanding to a vector of monomials - * @details The sumcheck verifier does not use beta_products - * - * @param betas - */ - RowDisablingPolynomial(const std::vector& betas) - : betas(betas) - {} - - /** - * @brief Retruns the element in #beta_products at place #idx. - * - * @param idx - * @return FF const& - */ - FF const& operator[](size_t idx) const { return beta_products[idx]; } - /** - * @brief Computes the component at index #current_element_idx in #betas. - * - * @return FF - */ - FF current_element() const { return betas[current_element_idx]; } - - /** - * @brief Evaluate \f$ ((1−X_{i}) + X_{i}\cdot \beta_{i})\f$ at the challenge point \f$ X_{i}=u_{i} \f$. - */ - FF univariate_eval(FF challenge) const { return (FF(1) + (challenge * (betas[current_element_idx] - FF(1)))); }; - - /** - */ - template FF univariate_eval(const FF& challenge, const Bool& dummy_round) const - { - FF beta_or_dummy; - // For the Ultra Recursive flavor to ensure constant size proofs, we perform constant amount of hashing - // producing 28 gate betas and we need to use the betas in the dummy rounds to ensure the permutation related - // selectors stay the same regardless of real circuit size. The other recursive verifiers aren't constant for - // the dummy sumcheck rounds we just use 1 as we only generated real log_n betas - if (current_element_idx < betas.size()) { - beta_or_dummy = betas[current_element_idx]; - } else { - beta_or_dummy = FF::from_witness(challenge.get_context(), 1); - } - FF beta_val = FF::conditional_assign(dummy_round, FF::from_witness(challenge.get_context(), 1), beta_or_dummy); - return (FF(1) + (challenge * (beta_val - FF(1)))); - } - - /** - * @brief Partially evaluate the \f$pow_{\beta} \f$-polynomial at the new challenge and update \f$ c_i \f$ - * @details Update the constant \f$c_{i} \to c_{i+1} \f$ multiplying it by \f$pow_{\beta}\f$'s factor \f$\left( - * (1-X_i) + X_i\cdot \beta_i\right)\vert_{X_i = u_i}\f$ computed by \ref univariate_eval. - * @param challenge \f$ i \f$-th verifier challenge \f$ u_{i}\f$ - */ - void partially_evaluate(FF challenge) - { - FF current_univariate_eval = univariate_eval(challenge); - partial_evaluation_result *= current_univariate_eval; - current_element_idx++; - periodicity *= 2; - } - - /** - * @brief Partially evaluate the \f$pow_{\beta} \f$-polynomial at the new challenge and update \f$ c_i \f$ - * @details Update the constant \f$c_{i} \to c_{i+1} \f$ multiplying it by \f$pow_{\beta}\f$'s factor \f$\left( - * (1-X_i) + X_i\cdot \beta_i\right)\vert_{X_i = u_i}\f$ computed by \ref univariate_eval. - * @param challenge \f$ i \f$-th verifier challenge \f$ u_{i}\f$ - */ - template void partially_evaluate(const FF& challenge, const stdlib::bool_t& dummy) - { - FF current_univariate_eval = univariate_eval(challenge, dummy); - // If dummy round, make no update to the partial_evaluation_result - partial_evaluation_result = FF::conditional_assign( - dummy, partial_evaluation_result, partial_evaluation_result * current_univariate_eval); - current_element_idx++; - periodicity *= 2; - } - - /** - * @brief Given \f$ \vec\beta = (\beta_0,...,\beta_{d-1})\f$ compute \f$ pow_{\ell}(\vec \beta) = pow_{\beta}(\vec - * \ell)\f$ for \f$ \ell =0,\ldots,2^{d}-1\f$. - * - * @param log_num_monomials Determines the number of beta challenges used to compute beta_products (required because - * when we generate CONST_SIZE_PROOF_LOG_N, currently 28, challenges but the real circuit size is less than 1 << - * CONST_SIZE_PROOF_LOG_N, we should compute unnecessarily a vector of beta_products of length 1 << 28 ) - */ - BB_PROFILE static std::vector compute_beta_products(const std::vector& betas, - const size_t log_num_monomials) + void update_evaluations(FF round_challenge, size_t round_idx) { + if (round_idx == 0) { + eval_at_0 = round_challenge; + eval_at_1 = one; + }; + if (round_idx == 1) { + eval_at_0 = eval_at_0 * (one - round_challenge) + round_challenge; + eval_at_1 = zero; + }; - size_t pow_size = 1 << log_num_monomials; - std::vector beta_products(pow_size); - - // Determine number of threads for multithreading. - // Note: Multithreading is "on" for every round but we reduce the number of threads from the max available based - // on a specified minimum number of iterations per thread. This eventually leads to the use of a single thread. - // For now we use a power of 2 number of threads simply to ensure the round size is evenly divided. - size_t max_num_threads = get_num_cpus_pow2(); // number of available threads (power of 2) - size_t min_iterations_per_thread = 1 << 6; // min number of iterations for which we'll spin up a unique thread - size_t desired_num_threads = pow_size / min_iterations_per_thread; - size_t num_threads = std::min(desired_num_threads, max_num_threads); // fewer than max if justified - num_threads = num_threads > 0 ? num_threads : 1; // ensure num threads is >= 1 - size_t iterations_per_thread = pow_size / num_threads; // actual iterations per thread - - // TODO(https://github.com/AztecProtocol/barretenberg/issues/864): This computation is asymtotically slow as it - // does pow_size * log(pow_size) work. However, in practice, its super efficient because its trivially - // parallelizable and only takes 45ms for the whole 6 iter IVC benchmark. Its also very readable, so we're - // leaving it unoptimized for now. - parallel_for(num_threads, [&](size_t thread_idx) { - size_t start = thread_idx * iterations_per_thread; - size_t end = (thread_idx + 1) * iterations_per_thread; - for (size_t i = start; i < end; i++) { - auto res = FF(1); - for (size_t j = i, beta_idx = 0; j > 0; j >>= 1, beta_idx++) { - if ((j & 1) == 1) { - res *= betas[beta_idx]; - } - } - beta_products[i] = res; - } - }); - - return beta_products; + if (round_idx > 1) { + eval_at_0 = eval_at_0 * (one - round_challenge); + eval_at_1 = zero; + } } }; diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_zk_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_zk_flavor.hpp index 59e3776201d3..32edb43439c8 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_zk_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_zk_flavor.hpp @@ -12,6 +12,8 @@ class MegaZKFlavor : public bb::MegaFlavor { public: // Indicates that this flavor runs with non-ZK Sumcheck. static constexpr bool HasZK = true; + static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MegaFlavor::BATCHED_RELATION_PARTIAL_LENGTH + 1; + /** * @brief Derived class that defines proof structure for Mega proofs, as well as supporting functions. * Note: Made generic for use in MegaRecursive. diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_zk_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_zk_flavor.hpp index f7cc6ba65002..312e6304294d 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_zk_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_zk_flavor.hpp @@ -25,7 +25,7 @@ class UltraFlavorWithZK : public bb::UltraFlavor { static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_total_relation_length(); // Determine the number of evaluations of Prover and Libra Polynomials that the Prover sends to the Verifier in // the rounds of ZK Sumcheck. - static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 1; + static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 2; // Construct the container for the subrelations' contributions using SumcheckTupleOfTuplesOfUnivariates = decltype(create_sumcheck_tuple_of_tuples_of_univariates()); diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp index 887730da4727..32b2b3410822 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp @@ -197,11 +197,17 @@ template class SumcheckProver { std::vector multivariate_challenge; multivariate_challenge.reserve(multivariate_d); size_t round_idx = 0; + auto row_disabling_poly = RowDisablingPolynomial(); // In the first round, we compute the first univariate polynomial and populate the book-keeping table of // #partially_evaluated_polynomials, which has \f$ n/2 \f$ rows and \f$ N \f$ columns. When the Flavor has ZK, // compute_univariate also takes into account the zk_sumcheck_data. - auto round_univariate = round.compute_univariate( - round_idx, full_polynomials, relation_parameters, gate_separators, alpha, zk_sumcheck_data); + auto round_univariate = round.compute_univariate(round_idx, + full_polynomials, + relation_parameters, + gate_separators, + alpha, + zk_sumcheck_data, + row_disabling_poly); vinfo("starting sumcheck rounds..."); { @@ -216,6 +222,7 @@ template class SumcheckProver { // Prepare ZK Sumcheck data for the next round if constexpr (Flavor::HasZK) { update_zk_sumcheck_data(zk_sumcheck_data, round_challenge, round_idx); + row_disabling_poly.update_evaluations(round_challenge, round_idx); }; gate_separators.partially_evaluate(round_challenge); round.round_size = round.round_size >> 1; // TODO(#224)(Cody): Maybe partially_evaluate should do this and @@ -232,7 +239,8 @@ template class SumcheckProver { relation_parameters, gate_separators, alpha, - zk_sumcheck_data); + zk_sumcheck_data, + row_disabling_poly); // Place evaluations of Sumcheck Round Univariate in the transcript transcript->send_to_verifier("Sumcheck:univariate_" + std::to_string(round_idx), round_univariate); FF round_challenge = transcript->template get_challenge("Sumcheck:u_" + std::to_string(round_idx)); @@ -242,6 +250,7 @@ template class SumcheckProver { // Prepare evaluation masking and libra structures for the next round (for ZK Flavors) if constexpr (Flavor::HasZK) { update_zk_sumcheck_data(zk_sumcheck_data, round_challenge, round_idx); + row_disabling_poly.update_evaluations(round_challenge, round_idx); }; gate_separators.partially_evaluate(round_challenge); @@ -564,6 +573,7 @@ template class SumcheckVerifier { if (round_idx < multivariate_d) { bool checked = round.check_sum(round_univariate); verified = verified && checked; + info("verified round ", round_idx, " ", verified); multivariate_challenge.emplace_back(round_challenge); round.compute_next_target_sum(round_univariate, round_challenge); gate_separators.partially_evaluate(round_challenge); @@ -590,10 +600,16 @@ template class SumcheckVerifier { for (auto [eval, transcript_eval] : zip_view(purported_evaluations.get_all(), transcript_evaluations)) { eval = transcript_eval; } + FF correcting_factor = round.compute_correcting_factor(multivariate_challenge, multivariate_d); + // Evaluate the Honk relation at the point (u_0, ..., u_{d-1}) using claimed evaluations of prover polynomials. // In ZK Flavors, the evaluation is corrected by full_libra_purported_value - FF full_honk_purported_value = round.compute_full_relation_purported_value( - purported_evaluations, relation_parameters, gate_separators, alpha, full_libra_purported_value); + FF full_honk_purported_value = round.compute_full_relation_purported_value(purported_evaluations, + relation_parameters, + gate_separators, + alpha, + full_libra_purported_value, + correcting_factor); bool final_check(false); //! [Final Verification Step] if constexpr (IsRecursiveFlavor) { diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp index 88cdfd405e6f..a7f0e9949c01 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp @@ -172,7 +172,7 @@ template class SumcheckTests : public ::testing::Test { // TODO(#225): make the inputs to this test more interesting, e.g. non-trivial permutations void test_prover_verifier_flow() { - const size_t multivariate_d(2); + const size_t multivariate_d(3); const size_t multivariate_n(1 << multivariate_d); // Construct prover polynomials where each is the zero polynomial. @@ -186,19 +186,22 @@ template class SumcheckTests : public ::testing::Test { // Add some non-trivial values to certain polynomials so that the arithmetic relation will have non-trivial // contribution. Note: since all other polynomials are set to 0, all other relations are trivially // satisfied. - std::array w_l; - w_l = { 0, 1, 2, 0 }; - std::array w_r = { 0, 1, 2, 0 }; - std::array w_o = { 0, 2, 4, 0 }; - std::array w_4 = { 0, 0, 0, 0 }; - std::array q_m = { 0, 0, 1, 0 }; - std::array q_l = { 0, 1, 0, 0 }; - std::array q_r = { 0, 1, 0, 0 }; - std::array q_o = { 0, -1, -1, 0 }; - std::array q_c = { 0, 0, 0, 0 }; - std::array q_arith = { 0, 1, 1, 0 }; + std::array w_l = { 0, 0, 0, 0, 0, 1, 2, 0 }; + std::array w_r = { 0, 0, 0, 0, 0, 1, 2, 0 }; + std::array w_o = { 0, 0, 0, 0, 0, 2, 4, 0 }; + std::array w_4 = { 0, 0, 0, 0, 0, 0, 0, 0 }; + std::array q_m = { 0, 0, 0, 0, 0, 0, 1, 0 }; + std::array q_l = { 0, 0, 0, 0, 0, 1, 0, 0 }; + std::array q_r = { 0, 0, 0, 0, 0, 1, 0, 0 }; + std::array q_o = { 0, 0, 0, 0, 0, -1, -1, 0 }; + std::array q_c = { 0, 0, 0, 0, 0, 0, 0, 0 }; + std::array q_arith = { 0, 0, 0, 0, 0, 1, 1, 0 }; // Setting all of these to 0 ensures the GrandProductRelation is satisfied - + if constexpr (Flavor::HasZK) { + w_l[3] = FF::random_element(); + q_o[1] = FF::random_element(); + q_arith[2] = FF::random_element(); + } full_polynomials.w_l = bb::Polynomial(w_l); full_polynomials.w_r = bb::Polynomial(w_r); full_polynomials.w_o = bb::Polynomial(w_o); @@ -341,8 +344,9 @@ template class SumcheckTests : public ::testing::Test { auto verifier_output = sumcheck_verifier.verify(relation_parameters, verifier_alpha, verifier_gate_challenges); auto verified = verifier_output.verified.value(); - - EXPECT_EQ(verified, false); + // In this test, the circuit is of size 4. We disable the rows 1, 2, and 3, while the first is set to 0. + // Therefore, changing the second entry in w_l does not affect the result for ZK fa. + EXPECT_EQ(verified, Flavor::HasZK); }; }; diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp index 758797b8bcc4..938e9cdf6a30 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp @@ -2,6 +2,7 @@ #include "barretenberg/common/thread.hpp" #include "barretenberg/flavor/flavor.hpp" #include "barretenberg/polynomials/gate_separator.hpp" +#include "barretenberg/polynomials/row_disabling_polynomial.hpp" #include "barretenberg/relations/relation_parameters.hpp" #include "barretenberg/relations/relation_types.hpp" #include "barretenberg/relations/utils.hpp" @@ -141,7 +142,8 @@ template class SumcheckProverRound { const bb::RelationParameters& relation_parameters, const bb::GateSeparatorPolynomial& gate_sparators, const RelationSeparator alpha, - ZKSumcheckData zk_sumcheck_data) // only populated when Flavor HasZK + ZKSumcheckData zk_sumcheck_data, + RowDisablingPolynomial row_disabling_poly) // only populated when Flavor HasZK { PROFILE_THIS_NAME("compute_univariate"); @@ -188,12 +190,14 @@ template class SumcheckProverRound { } // For ZK Flavors: The evaluations of the round univariates are masked by the evaluations of Libra univariates if constexpr (Flavor::HasZK) { + const auto contribution_from_disabled_rows = compute_disabled_contribution( + round_idx, polynomials, relation_parameters, gate_sparators, alpha, row_disabling_poly); const auto libra_round_univariate = compute_libra_round_univariate(zk_sumcheck_data, round_idx); // Batch the univariate contributions from each sub-relation to obtain the round univariate const auto round_univariate = batch_over_relations(univariate_accumulators, alpha, gate_sparators); // Mask the round univariate - return round_univariate + libra_round_univariate; + return round_univariate + libra_round_univariate - contribution_from_disabled_rows; } // Batch the univariate contributions from each sub-relation to obtain the round univariate else { @@ -201,18 +205,78 @@ template class SumcheckProverRound { } } + template + SumcheckRoundUnivariate compute_disabled_contribution( + const size_t round_idx, + ProverPolynomialsOrPartiallyEvaluatedMultivariates& polynomials, + const bb::RelationParameters& relation_parameters, + const bb::GateSeparatorPolynomial& gate_sparators, + const RelationSeparator alpha, + const RowDisablingPolynomial row_disabling_poly) // only populated when Flavor HasZK + { + PROFILE_THIS_NAME("compute_univariate"); + SumcheckRoundUnivariate result; + + SumcheckTupleOfTuplesOfUnivariates univariate_accumulator; + // size_t num_edges = (round_idx > 0) ? 2 : 1; + // Construct extended edge containers; one per thread + ExtendedEdges extended_edges; + if (round_idx == 0) { + // Compute H(X,0,...,0) + H(X,1,0,...,0) or H(u_0,..., u_{i-1}, X, 0,...,0) + size_t edge_idx = 0; + extend_edges(extended_edges, polynomials, edge_idx); + accumulate_relation_univariates(univariate_accumulator, + extended_edges, + relation_parameters, + gate_sparators[(edge_idx >> 1) * gate_sparators.periodicity]); + // SumcheckRoundUnivariate first_contribution; + + auto first_contribution = + batch_over_relations(univariate_accumulator, alpha, gate_sparators); + // extend_and_batch_univariates( + // univariate_accumulator, first_contribution, gate_sparators); + auto row_disabler = bb::Univariate({ row_disabling_poly.eval_at_0, row_disabling_poly.eval_at_1 }); + auto row_disabler_extended = row_disabler.template extend_to(); + first_contribution *= row_disabler_extended; + + Utils::zero_univariates(univariate_accumulator); + + edge_idx += 2; + extend_edges(extended_edges, polynomials, edge_idx); + accumulate_relation_univariates(univariate_accumulator, + extended_edges, + relation_parameters, + gate_sparators[(edge_idx >> 1) * gate_sparators.periodicity]); + result = batch_over_relations(univariate_accumulator, alpha, gate_sparators); + result += first_contribution; + } else { + size_t edge_idx = 0; + extend_edges(extended_edges, polynomials, edge_idx); + accumulate_relation_univariates(univariate_accumulator, + extended_edges, + relation_parameters, + gate_sparators[(edge_idx >> 1) * gate_sparators.periodicity]); + + result = batch_over_relations(univariate_accumulator, alpha, gate_sparators); + auto row_disabler = bb::Univariate({ row_disabling_poly.eval_at_0, row_disabling_poly.eval_at_1 }); + auto row_disabler_extended = row_disabler.template extend_to(); + result *= row_disabler_extended; + } + return result; + } + /** * @brief Given a tuple of tuples of extended per-relation contributions, \f$ (t_0, t_1, \ldots, * t_{\text{NUM_SUBRELATIONS}-1}) \f$ and a challenge \f$ \alpha \f$, scale them by the relation separator * \f$\alpha\f$, extend to the correct degree, and take the sum multiplying by \f$pow_{\beta}\f$-contributions. * * @details This method receives as input the univariate accumulators computed by \ref - * accumulate_relation_univariates "accumulate relation univariates" after passing through the entire hypercube and - * applying \ref bb::RelationUtils::add_nested_tuples "add_nested_tuples" method to join the threads. The - * accumulators are scaled using the method \ref bb::RelationUtils< Flavor >::scale_univariates "scale univariates", - * extended to the degree \f$ D \f$ and summed with appropriate \f$pow_{\beta}\f$-factors using \ref - * extend_and_batch_univariates "extend and batch univariates method" to return a vector \f$(\tilde{S}^i(0), \ldots, - * \tilde{S}^i(D))\f$. + * accumulate_relation_univariates "accumulate relation univariates" after passing through the entire hypercube + * and applying \ref bb::RelationUtils::add_nested_tuples "add_nested_tuples" method to join the threads. The + * accumulators are scaled using the method \ref bb::RelationUtils< Flavor >::scale_univariates "scale + * univariates", extended to the degree \f$ D \f$ and summed with appropriate \f$pow_{\beta}\f$-factors using + * \ref extend_and_batch_univariates "extend and batch univariates method" to return a vector + * \f$(\tilde{S}^i(0), \ldots, \tilde{S}^i(D))\f$. * * @param challenge Challenge \f$\alpha\f$. * @param gate_sparators Round \f$pow_{\beta}\f$-factor given by \f$ ( (1−u_i) + u_i\cdot \beta_i )\f$. @@ -233,17 +297,35 @@ template class SumcheckProverRound { return result; } + // template + // static ExtendedUnivariate batch_disabled_rows_over_relations(ContainerOverSubrelations& univariate_accumulators, + // const RelationSeparator& challenge, + // const bb::GateSeparatorPolynomial& + // gate_sparators) + // { + // auto running_challenge = FF(1); + // Utils::scale_univariates(univariate_accumulators, challenge, running_challenge); + + // auto result = ExtendedUnivariate(0); + // extend_and_batch_disabled_rows(univariate_accumulators, result, gate_sparators); + + // // Reset all univariate accumulators to 0 before beginning accumulation in the next round + // Utils::zero_univariates(univariate_accumulators); + // return result; + // } + /** * @brief Extend Univariates then sum them multiplying by the current \f$ pow_{\beta} \f$-contributions. - * @details Since the sub-relations comprising full Honk relation are of different degrees, the computation of the - * evaluations of round univariate \f$ \tilde{S}_{i}(X_{i}) \f$ at points \f$ X_{i} = 0,\ldots, D \f$ requires to - * extend evaluations of individual relations to the domain \f$ 0,\ldots, D\f$. Moreover, linearly independent - * sub-relations, i.e. whose validity is being checked at every point of the hypercube, are multiplied by the - * constant \f$ c_i = pow_\beta(u_0,\ldots, u_{i-1}) \f$ and the current \f$pow_{\beta}\f$-factor \f$ ( (1−X_i) + - * X_i\cdot \beta_i ) \vert_{X_i = k} \f$ for \f$ k = 0,\ldots, D\f$. + * @details Since the sub-relations comprising full Honk relation are of different degrees, the computation of + * the evaluations of round univariate \f$ \tilde{S}_{i}(X_{i}) \f$ at points \f$ X_{i} = 0,\ldots, D \f$ + * requires to extend evaluations of individual relations to the domain \f$ 0,\ldots, D\f$. Moreover, linearly + * independent sub-relations, i.e. whose validity is being checked at every point of the hypercube, are + * multiplied by the constant \f$ c_i = pow_\beta(u_0,\ldots, u_{i-1}) \f$ and the current + * \f$pow_{\beta}\f$-factor \f$ ( (1−X_i) + X_i\cdot \beta_i ) \vert_{X_i = k} \f$ for \f$ k = 0,\ldots, D\f$. * @tparam extended_size Size after extension * @param tuple A tuple of tuples of Univariates - * @param result Round univariate \f$ \tilde{S}^i\f$ represented by its evaluations over \f$ \{0,\ldots, D\} \f$. + * @param result Round univariate \f$ \tilde{S}^i\f$ represented by its evaluations over \f$ \{0,\ldots, D\} + * \f$. * @param gate_sparators Round \f$pow_{\beta}\f$-factor \f$ ( (1−X_i) + X_i\cdot \beta_i )\f$. */ template @@ -262,8 +344,8 @@ template class SumcheckProverRound { using Relation = typename std::tuple_element_t; const bool is_subrelation_linearly_independent = bb::subrelation_is_linearly_independent(); - // Except from the log derivative subrelation, each other subrelation in part is required to be 0 hence we - // multiply by the power polynomial. As the sumcheck prover is required to send a univariate to the + // Except from the log derivative subrelation, each other subrelation in part is required to be 0 hence + // we multiply by the power polynomial. As the sumcheck prover is required to send a univariate to the // verifier, we additionally need a univariate contribution from the pow polynomial which is the // extended_random_polynomial which is the if (!is_subrelation_linearly_independent) { @@ -278,6 +360,33 @@ template class SumcheckProverRound { Utils::apply_to_tuple_of_tuples(tuple, extend_and_sum); } + // template + // static void extend_and_batch_disabled_rows(const TupleOfTuplesOfUnivariates& tuple, + // ExtendedUnivariate& result, + // const bb::GateSeparatorPolynomial& gate_sparators) + // { + // ExtendedUnivariate extended_random_polynomial; + // ExtendedUnivariate extended_row_disabling_polynomial; + + // // Pow-Factor \f$ (1-X) + X\beta_i \f$ + // auto random_polynomial = bb::Univariate({ 1, gate_sparators.current_element() }); + // extended_random_polynomial = random_polynomial.template extend_to(); + + // auto row_disabling_polynomial = bb::Univariate({ 1, 1 }); + // extended_row_disabling_polynomial = row_disabling_polynomial.template + // extend_to(); + + // auto extend_and_sum = [&](Element& element) { + // auto extended = element.template extend_to(); + // // Multiply by the pow polynomial univariate contribution and the partial + // // evaluation result c_i (i.e. \f$ pow(u_0,...,u_{l-1})) \f$ where \f$(u_0,...,u_{i-1})\f$ are the + // // verifier challenges from previous rounds. + // result += extended * row_disabling_polynomial * extended_random_polynomial * + // gate_sparators.partial_evaluation_result; + // }; + // Utils::apply_to_tuple_of_tuples(tuple, extend_and_sum); + // } + /** * @brief Compute Libra round univariate expressed given by the formula \f{align}{ @@ -306,26 +415,28 @@ template class SumcheckProverRound { private: /** - * @brief In Round \f$ i \f$, for a given point \f$ \vec \ell \in \{0,1\}^{d-1 - i}\f$, calculate the contribution - * of each sub-relation to \f$ T^i(X_i) \f$. + * @brief In Round \f$ i \f$, for a given point \f$ \vec \ell \in \{0,1\}^{d-1 - i}\f$, calculate the + *contribution of each sub-relation to \f$ T^i(X_i) \f$. * * @details In Round \f$ i \f$, this method computes the univariate \f$ T^i(X_i) \f$ deined in \ref *SumcheckProverContributionsofPow "this section". It is done as follows: - * - Outer loop: iterate through the "edge" points \f$ (0,\vec \ell) \f$ on the boolean hypercube \f$\{0,1\}\times - * \{0,1\}^{d-1 - i}\f$, i.e. skipping every other point. On each iteration, apply \ref extend_edges "extend edges". + * - Outer loop: iterate through the "edge" points \f$ (0,\vec \ell) \f$ on the boolean hypercube + *\f$\{0,1\}\times + * \{0,1\}^{d-1 - i}\f$, i.e. skipping every other point. On each iteration, apply \ref extend_edges "extend + *edges". * - Inner loop: iterate through the sub-relations, feeding each relation the "the group of edges", i.e. the - * evaluations \f$ P_1(u_0,\ldots, u_{i-1}, k, \vec \ell), \ldots, P_N(u_0,\ldots, u_{i-1}, k, \vec \ell) \f$. Each - * relation Flavor is endowed with \p accumulate method that computes its contribution to \f$ - * T^i(X_{i}) \f$ - *\ref extend_and_batch_univariates "Adding these univariates together", with appropriate scaling factors, produces - *required evaluations of \f$ \tilde S^i \f$. - * @param univariate_accumulators The container for per-thread-per-relation univariate contributions output by \ref - *accumulate_relation_univariates "accumulate relation univariates" for the previous "groups of edges". - * @param extended_edges Contains tuples of evaluations of \f$ P_j\left(u_0,\ldots, u_{i-1}, k, \vec \ell \right) - *\f$, for \f$ j=1,\ldots, N \f$, \f$ k \in \{0,\ldots, D\} \f$ and fixed \f$\vec \ell \in \{0,1\}^{d-1 - i} \f$. - * @param scaling_factor In Round \f$ i \f$, for \f$ (\ell_{i+1}, \ldots, \ell_{d-1}) \in \{0,1\}^{d-1-i}\f$ takes - *an element of \ref bb::GateSeparatorPolynomial< FF >::beta_products "vector of powers of challenges" at index \f$ - *2^{i+1} + * evaluations \f$ P_1(u_0,\ldots, u_{i-1}, k, \vec \ell), \ldots, P_N(u_0,\ldots, u_{i-1}, k, \vec \ell) \f$. + *Each relation Flavor is endowed with \p accumulate method that computes its contribution to \f$ T^i(X_{i}) \f$ + *\ref extend_and_batch_univariates "Adding these univariates together", with appropriate scaling factors, + *produces required evaluations of \f$ \tilde S^i \f$. + * @param univariate_accumulators The container for per-thread-per-relation univariate contributions output by + *\ref accumulate_relation_univariates "accumulate relation univariates" for the previous "groups of edges". + * @param extended_edges Contains tuples of evaluations of \f$ P_j\left(u_0,\ldots, u_{i-1}, k, \vec \ell + *\right) \f$, for \f$ j=1,\ldots, N \f$, \f$ k \in \{0,\ldots, D\} \f$ and fixed \f$\vec \ell \in \{0,1\}^{d-1 + *- i} \f$. + * @param scaling_factor In Round \f$ i \f$, for \f$ (\ell_{i+1}, \ldots, \ell_{d-1}) \in \{0,1\}^{d-1-i}\f$ + *takes an element of \ref bb::GateSeparatorPolynomial< FF >::beta_products "vector of powers of challenges" at + *index \f$ 2^{i+1} *(\ell_{i+1} 2^{i+1} +\ldots + \ell_{d-1} 2^{d-1})\f$. * @result #univariate_accumulators are updated with the contribution from the current group of edges. For each * relation, a univariate of some degree is computed by accumulating the contributions of each group of edges. @@ -406,9 +517,9 @@ template class SumcheckVerifierRound { }; /** * @brief Check that the round target sum is correct - * @details The verifier receives the claimed evaluations of the round univariate \f$ \tilde{S}^i \f$ at \f$X_i = - * 0,\ldots, D \f$ and checks \f$\sigma_i = \tilde{S}^{i-1}(u_{i-1}) \stackrel{?}{=} \tilde{S}^i(0) + \tilde{S}^i(1) - * \f$ + * @details The verifier receives the claimed evaluations of the round univariate \f$ \tilde{S}^i \f$ at \f$X_i + * = 0,\ldots, D \f$ and checks \f$\sigma_i = \tilde{S}^{i-1}(u_{i-1}) \stackrel{?}{=} \tilde{S}^i(0) + + * \tilde{S}^i(1) \f$ * @param univariate Round univariate \f$\tilde{S}^{i}\f$ represented by its evaluations over \f$0,\ldots,D\f$. * */ @@ -426,9 +537,9 @@ template class SumcheckVerifierRound { /** * @brief Check that the round target sum is correct - * @details The verifier receives the claimed evaluations of the round univariate \f$ \tilde{S}^i \f$ at \f$X_i = - * 0,\ldots, D \f$ and checks \f$\sigma_i = \tilde{S}^{i-1}(u_{i-1}) \stackrel{?}{=} \tilde{S}^i(0) + \tilde{S}^i(1) - * \f$ + * @details The verifier receives the claimed evaluations of the round univariate \f$ \tilde{S}^i \f$ at \f$X_i + * = 0,\ldots, D \f$ and checks \f$\sigma_i = \tilde{S}^{i-1}(u_{i-1}) \stackrel{?}{=} \tilde{S}^i(0) + + * \tilde{S}^i(1) \f$ * @param univariate Round univariate \f$\tilde{S}^{i}\f$ represented by its evaluations over \f$0,\ldots,D\f$. * */ @@ -497,7 +608,8 @@ template class SumcheckVerifierRound { const bb::RelationParameters& relation_parameters, const bb::GateSeparatorPolynomial& gate_sparators, const RelationSeparator alpha, - std::optional full_libra_purported_value = std::nullopt) + const FF full_libra_purported_value = FF{ 0 }, + FF correcting_factor = FF{ 1 }) { // The verifier should never skip computation of contributions from any relation Utils::template accumulate_relation_evaluations_without_skipping<>( @@ -507,12 +619,23 @@ template class SumcheckVerifierRound { FF output{ 0 }; Utils::scale_and_batch_elements(relation_evaluations, alpha, running_challenge, output); if constexpr (Flavor::HasZK) { - output += full_libra_purported_value.value(); + output = output * correcting_factor + full_libra_purported_value; if constexpr (IsECCVMRecursiveFlavor) { output.self_reduce(); } }; return output; } + + FF compute_correcting_factor(std::vector multilinear_challenge, const size_t log_circuit_size) + { + FF one = FF{ 1 }; + FF result = (multilinear_challenge[0] * (one - multilinear_challenge[1]) + multilinear_challenge[1]); + + for (size_t idx = 2; idx < log_circuit_size; idx++) { + result *= (one - multilinear_challenge[idx]); + } + return one - result; + } }; } // namespace bb From ac349113060a9715d278345115486466b6f0e64b Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Tue, 19 Nov 2024 10:21:44 +0000 Subject: [PATCH 04/25] a bit of clean-up --- .../src/barretenberg/eccvm/eccvm_flavor.hpp | 2 +- .../barretenberg/sumcheck/sumcheck_round.hpp | 92 +++---------------- .../translator_vm/translator_flavor.hpp | 2 +- 3 files changed, 17 insertions(+), 79 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp index 778b43551f49..06456c8b29e5 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp @@ -73,7 +73,7 @@ class ECCVMFlavor { // BATCHED_RELATION_PARTIAL_LENGTH = algebraic degree of sumcheck relation *after* multiplying by the `pow_zeta` // random polynomial e.g. For \sum(x) [A(x) * B(x) + C(x)] * PowZeta(X), relation length = 2 and random relation // length = 3 - static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 1; + static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 2; static constexpr size_t NUM_RELATIONS = std::tuple_size::value; // Instantiate the BarycentricData needed to extend each Relation Univariate diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp index 938e9cdf6a30..d2e3010b296e 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp @@ -218,50 +218,32 @@ template class SumcheckProverRound { SumcheckRoundUnivariate result; SumcheckTupleOfTuplesOfUnivariates univariate_accumulator; - // size_t num_edges = (round_idx > 0) ? 2 : 1; - // Construct extended edge containers; one per thread + // Construct extended edge containers ExtendedEdges extended_edges; - if (round_idx == 0) { - // Compute H(X,0,...,0) + H(X,1,0,...,0) or H(u_0,..., u_{i-1}, X, 0,...,0) - size_t edge_idx = 0; - extend_edges(extended_edges, polynomials, edge_idx); - accumulate_relation_univariates(univariate_accumulator, - extended_edges, - relation_parameters, - gate_sparators[(edge_idx >> 1) * gate_sparators.periodicity]); - // SumcheckRoundUnivariate first_contribution; - auto first_contribution = - batch_over_relations(univariate_accumulator, alpha, gate_sparators); - // extend_and_batch_univariates( - // univariate_accumulator, first_contribution, gate_sparators); - auto row_disabler = bb::Univariate({ row_disabling_poly.eval_at_0, row_disabling_poly.eval_at_1 }); - auto row_disabler_extended = row_disabler.template extend_to(); - first_contribution *= row_disabler_extended; + size_t edge_idx = 0; + extend_edges(extended_edges, polynomials, edge_idx); + accumulate_relation_univariates(univariate_accumulator, + extended_edges, + relation_parameters, + gate_sparators[(edge_idx >> 1) * gate_sparators.periodicity]); - Utils::zero_univariates(univariate_accumulator); + result = batch_over_relations(univariate_accumulator, alpha, gate_sparators); + auto row_disabler = bb::Univariate({ row_disabling_poly.eval_at_0, row_disabling_poly.eval_at_1 }); + auto row_disabler_extended = row_disabler.template extend_to(); + result *= row_disabler_extended; + if (round_idx == 0) { edge_idx += 2; + Utils::zero_univariates(univariate_accumulator); extend_edges(extended_edges, polynomials, edge_idx); accumulate_relation_univariates(univariate_accumulator, extended_edges, relation_parameters, gate_sparators[(edge_idx >> 1) * gate_sparators.periodicity]); - result = batch_over_relations(univariate_accumulator, alpha, gate_sparators); - result += first_contribution; - } else { - size_t edge_idx = 0; - extend_edges(extended_edges, polynomials, edge_idx); - accumulate_relation_univariates(univariate_accumulator, - extended_edges, - relation_parameters, - gate_sparators[(edge_idx >> 1) * gate_sparators.periodicity]); - - result = batch_over_relations(univariate_accumulator, alpha, gate_sparators); - auto row_disabler = bb::Univariate({ row_disabling_poly.eval_at_0, row_disabling_poly.eval_at_1 }); - auto row_disabler_extended = row_disabler.template extend_to(); - result *= row_disabler_extended; + result += batch_over_relations(univariate_accumulator, alpha, gate_sparators); } + return result; } @@ -297,23 +279,6 @@ template class SumcheckProverRound { return result; } - // template - // static ExtendedUnivariate batch_disabled_rows_over_relations(ContainerOverSubrelations& univariate_accumulators, - // const RelationSeparator& challenge, - // const bb::GateSeparatorPolynomial& - // gate_sparators) - // { - // auto running_challenge = FF(1); - // Utils::scale_univariates(univariate_accumulators, challenge, running_challenge); - - // auto result = ExtendedUnivariate(0); - // extend_and_batch_disabled_rows(univariate_accumulators, result, gate_sparators); - - // // Reset all univariate accumulators to 0 before beginning accumulation in the next round - // Utils::zero_univariates(univariate_accumulators); - // return result; - // } - /** * @brief Extend Univariates then sum them multiplying by the current \f$ pow_{\beta} \f$-contributions. * @details Since the sub-relations comprising full Honk relation are of different degrees, the computation of @@ -360,33 +325,6 @@ template class SumcheckProverRound { Utils::apply_to_tuple_of_tuples(tuple, extend_and_sum); } - // template - // static void extend_and_batch_disabled_rows(const TupleOfTuplesOfUnivariates& tuple, - // ExtendedUnivariate& result, - // const bb::GateSeparatorPolynomial& gate_sparators) - // { - // ExtendedUnivariate extended_random_polynomial; - // ExtendedUnivariate extended_row_disabling_polynomial; - - // // Pow-Factor \f$ (1-X) + X\beta_i \f$ - // auto random_polynomial = bb::Univariate({ 1, gate_sparators.current_element() }); - // extended_random_polynomial = random_polynomial.template extend_to(); - - // auto row_disabling_polynomial = bb::Univariate({ 1, 1 }); - // extended_row_disabling_polynomial = row_disabling_polynomial.template - // extend_to(); - - // auto extend_and_sum = [&](Element& element) { - // auto extended = element.template extend_to(); - // // Multiply by the pow polynomial univariate contribution and the partial - // // evaluation result c_i (i.e. \f$ pow(u_0,...,u_{l-1})) \f$ where \f$(u_0,...,u_{i-1})\f$ are the - // // verifier challenges from previous rounds. - // result += extended * row_disabling_polynomial * extended_random_polynomial * - // gate_sparators.partial_evaluation_result; - // }; - // Utils::apply_to_tuple_of_tuples(tuple, extend_and_sum); - // } - /** * @brief Compute Libra round univariate expressed given by the formula \f{align}{ diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp index dced2b66d4f3..f922112c1204 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp @@ -100,7 +100,7 @@ class TranslatorFlavor { // BATCHED_RELATION_PARTIAL_LENGTH = algebraic degree of sumcheck relation *after* multiplying by the `pow_zeta` // random polynomial e.g. For \sum(x) [A(x) * B(x) + C(x)] * PowZeta(X), relation length = 2 and random relation // length = 3 - static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 1; + static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 2; static constexpr size_t NUM_RELATIONS = std::tuple_size_v; // define the containers for storing the contributions from each relation in Sumcheck From e449422a98f61a38c77a7269b91025c350ec0300 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Wed, 20 Nov 2024 12:19:16 +0000 Subject: [PATCH 05/25] switched to last rows --- .../polynomials/row_disabling_polynomial.hpp | 12 ++++---- .../barretenberg/sumcheck/sumcheck.test.cpp | 30 +++++++++---------- .../barretenberg/sumcheck/sumcheck_round.hpp | 22 ++++---------- .../barretenberg/ultra_honk/databus.test.cpp | 6 ++-- 4 files changed, 29 insertions(+), 41 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp index b8ac353f3b64..59506c337561 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp @@ -45,8 +45,8 @@ namespace bb { */ template struct RowDisablingPolynomial { // by default it is a constant multilinear polynomial = 1 - FF eval_at_0{ 0 }; - FF eval_at_1{ 1 }; + FF eval_at_0{ 1 }; + FF eval_at_1{ 2 }; FF one = FF{ 1 }; FF zero = FF{ 0 }; @@ -59,13 +59,13 @@ template struct RowDisablingPolynomial { eval_at_1 = one; }; if (round_idx == 1) { - eval_at_0 = eval_at_0 * (one - round_challenge) + round_challenge; - eval_at_1 = zero; + eval_at_0 = zero; + eval_at_1 = eval_at_0 + round_challenge - eval_at_0 * round_challenge; }; if (round_idx > 1) { - eval_at_0 = eval_at_0 * (one - round_challenge); - eval_at_1 = zero; + eval_at_0 = zero; + eval_at_1 = eval_at_1 * round_challenge; } } }; diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp index a7f0e9949c01..4b15a47ab94c 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp @@ -186,22 +186,22 @@ template class SumcheckTests : public ::testing::Test { // Add some non-trivial values to certain polynomials so that the arithmetic relation will have non-trivial // contribution. Note: since all other polynomials are set to 0, all other relations are trivially // satisfied. - std::array w_l = { 0, 0, 0, 0, 0, 1, 2, 0 }; - std::array w_r = { 0, 0, 0, 0, 0, 1, 2, 0 }; - std::array w_o = { 0, 0, 0, 0, 0, 2, 4, 0 }; - std::array w_4 = { 0, 0, 0, 0, 0, 0, 0, 0 }; - std::array q_m = { 0, 0, 0, 0, 0, 0, 1, 0 }; - std::array q_l = { 0, 0, 0, 0, 0, 1, 0, 0 }; - std::array q_r = { 0, 0, 0, 0, 0, 1, 0, 0 }; - std::array q_o = { 0, 0, 0, 0, 0, -1, -1, 0 }; - std::array q_c = { 0, 0, 0, 0, 0, 0, 0, 0 }; - std::array q_arith = { 0, 0, 0, 0, 0, 1, 1, 0 }; + std::array w_l = { 0, 1, 2, 0 }; + std::array w_r = { 0, 1, 2, 0 }; + std::array w_o = { 0, 2, 4, 0 }; + std::array w_4 = { 0, 0, 0, 0 }; + std::array q_m = { 0, 0, 1, 0 }; + std::array q_l = { 0, 1, 0, 0 }; + std::array q_r = { 0, 1, 0, 0 }; + std::array q_o = { 0, -1, -1, 0 }; + std::array q_c = { 0, 0, 0, 0 }; + std::array q_arith = { 0, 1, 1, 0 }; // Setting all of these to 0 ensures the GrandProductRelation is satisfied - if constexpr (Flavor::HasZK) { - w_l[3] = FF::random_element(); - q_o[1] = FF::random_element(); - q_arith[2] = FF::random_element(); - } + // if constexpr (Flavor::HasZK) { + // w_l[7] = FF::random_element(); + // // q_o[1] = FF::random_element(); + // // q_arith[2] = FF::random_element(); + // } full_polynomials.w_l = bb::Polynomial(w_l); full_polynomials.w_r = bb::Polynomial(w_r); full_polynomials.w_o = bb::Polynomial(w_o); diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp index d2e3010b296e..6f05c0ef1f98 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp @@ -191,7 +191,7 @@ template class SumcheckProverRound { // For ZK Flavors: The evaluations of the round univariates are masked by the evaluations of Libra univariates if constexpr (Flavor::HasZK) { const auto contribution_from_disabled_rows = compute_disabled_contribution( - round_idx, polynomials, relation_parameters, gate_sparators, alpha, row_disabling_poly); + polynomials, relation_parameters, gate_sparators, alpha, row_disabling_poly); const auto libra_round_univariate = compute_libra_round_univariate(zk_sumcheck_data, round_idx); // Batch the univariate contributions from each sub-relation to obtain the round univariate const auto round_univariate = @@ -207,7 +207,6 @@ template class SumcheckProverRound { template SumcheckRoundUnivariate compute_disabled_contribution( - const size_t round_idx, ProverPolynomialsOrPartiallyEvaluatedMultivariates& polynomials, const bb::RelationParameters& relation_parameters, const bb::GateSeparatorPolynomial& gate_sparators, @@ -220,8 +219,7 @@ template class SumcheckProverRound { SumcheckTupleOfTuplesOfUnivariates univariate_accumulator; // Construct extended edge containers ExtendedEdges extended_edges; - - size_t edge_idx = 0; + size_t edge_idx = round_size - 2; extend_edges(extended_edges, polynomials, edge_idx); accumulate_relation_univariates(univariate_accumulator, extended_edges, @@ -233,17 +231,6 @@ template class SumcheckProverRound { auto row_disabler_extended = row_disabler.template extend_to(); result *= row_disabler_extended; - if (round_idx == 0) { - edge_idx += 2; - Utils::zero_univariates(univariate_accumulator); - extend_edges(extended_edges, polynomials, edge_idx); - accumulate_relation_univariates(univariate_accumulator, - extended_edges, - relation_parameters, - gate_sparators[(edge_idx >> 1) * gate_sparators.periodicity]); - result += batch_over_relations(univariate_accumulator, alpha, gate_sparators); - } - return result; } @@ -568,10 +555,11 @@ template class SumcheckVerifierRound { FF compute_correcting_factor(std::vector multilinear_challenge, const size_t log_circuit_size) { FF one = FF{ 1 }; - FF result = (multilinear_challenge[0] * (one - multilinear_challenge[1]) + multilinear_challenge[1]); + FF result = + multilinear_challenge[0] + multilinear_challenge[1] - multilinear_challenge[0] * multilinear_challenge[1]; for (size_t idx = 2; idx < log_circuit_size; idx++) { - result *= (one - multilinear_challenge[idx]); + result *= multilinear_challenge[idx]; } return one - result; } diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/databus.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/databus.test.cpp index 01fad4e3974d..772558cbf2ca 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/databus.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/databus.test.cpp @@ -27,9 +27,9 @@ class DataBusTests : public ::testing::Test { // Construct and verify a MegaHonk proof for a given circuit static bool construct_and_verify_proof(MegaCircuitBuilder& builder) { - MegaProver prover{ builder }; - auto verification_key = std::make_shared(prover.proving_key->proving_key); - MegaVerifier verifier{ verification_key }; + MegaZKProver prover{ builder }; + auto verification_key = std::make_shared(prover.proving_key->proving_key); + MegaZKVerifier verifier{ verification_key }; auto proof = prover.construct_proof(); return verifier.verify_proof(proof); } From 6d7c988856b8a1932064af5f3a26773537342eaa Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Wed, 20 Nov 2024 14:45:51 +0000 Subject: [PATCH 06/25] mostly dysfunctional --- .../polynomials/row_disabling_polynomial.hpp | 4 +-- .../stdlib_circuit_builders/mega_flavor.hpp | 4 +-- .../barretenberg/sumcheck/sumcheck.test.cpp | 28 +++++++++++++------ .../ultra_honk/decider_proving_key.cpp | 2 +- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp index 59506c337561..0a261cff808e 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp @@ -59,13 +59,13 @@ template struct RowDisablingPolynomial { eval_at_1 = one; }; if (round_idx == 1) { - eval_at_0 = zero; eval_at_1 = eval_at_0 + round_challenge - eval_at_0 * round_challenge; + eval_at_0 = zero; }; if (round_idx > 1) { - eval_at_0 = zero; eval_at_1 = eval_at_1 * round_challenge; + eval_at_0 = zero; } } }; 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 e87ebe9ea760..1b448811a2bc 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp @@ -65,7 +65,7 @@ class MegaFlavor { // Note: made generic for use in MegaRecursive. template using Relations_ = std::tuple, - bb::UltraPermutationRelation, + // bb::UltraPermutationRelation, bb::LogDerivLookupRelation, bb::DeltaRangeConstraintRelation, bb::EllipticRelation, @@ -78,7 +78,7 @@ class MegaFlavor { static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length(); static constexpr size_t MAX_TOTAL_RELATION_LENGTH = compute_max_total_relation_length(); - static_assert(MAX_TOTAL_RELATION_LENGTH == 11); + // static_assert(MAX_TOTAL_RELATION_LENGTH == 11); // BATCHED_RELATION_PARTIAL_LENGTH = algebraic degree of sumcheck relation *after* multiplying by the `pow_zeta` // random polynomial e.g. For \sum(x) [A(x) * B(x) + C(x)] * PowZeta(X), relation length = 2 and random relation // length = 3 diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp index 4b15a47ab94c..f748a3dc7f3c 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp @@ -181,8 +181,11 @@ template class SumcheckTests : public ::testing::Test { for (auto& poly : zero_polynomials) { poly = bb::Polynomial(multivariate_n); } - auto full_polynomials = construct_ultra_full_polynomials(zero_polynomials); + auto full_polynomials = construct_ultra_full_polynomials(zero_polynomials); + for (size_t idx = 0; idx < multivariate_n; idx++) { + info("coeff z_perm before randomization ", idx, " ", full_polynomials.z_perm[idx]); + } // Add some non-trivial values to certain polynomials so that the arithmetic relation will have non-trivial // contribution. Note: since all other polynomials are set to 0, all other relations are trivially // satisfied. @@ -197,11 +200,18 @@ template class SumcheckTests : public ::testing::Test { std::array q_c = { 0, 0, 0, 0 }; std::array q_arith = { 0, 1, 1, 0 }; // Setting all of these to 0 ensures the GrandProductRelation is satisfied - // if constexpr (Flavor::HasZK) { - // w_l[7] = FF::random_element(); - // // q_o[1] = FF::random_element(); - // // q_arith[2] = FF::random_element(); - // } + if constexpr (Flavor::HasZK) { + w_l[7] = FF::random_element(); + w_r[6] = FF::random_element(); + w_4[6] = FF::random_element(); + auto r = FF::random_element(); + std::array lookup_inverses = { 0, 0, 0, 0, 0, 0, r * r, r }; + full_polynomials.lookup_inverses = bb::Polynomial(lookup_inverses); + std::array z_perm = { 0, 0, 0, 0, 0, 0, 0, 1 }; + full_polynomials.z_perm = bb::Polynomial(z_perm); + // // q_o[1] = FF::random_element(); + // // q_arith[2] = FF::random_element(); + } full_polynomials.w_l = bb::Polynomial(w_l); full_polynomials.w_r = bb::Polynomial(w_r); full_polynomials.w_o = bb::Polynomial(w_o); @@ -212,7 +222,9 @@ template class SumcheckTests : public ::testing::Test { full_polynomials.q_o = bb::Polynomial(q_o); full_polynomials.q_c = bb::Polynomial(q_c); full_polynomials.q_arith = bb::Polynomial(q_arith); - + for (size_t idx = 0; idx < multivariate_n; idx++) { + info("coeff z_perm", idx, " ", full_polynomials.z_perm[idx]); + } // Set aribitrary random relation parameters RelationParameters relation_parameters{ .beta = FF::random_element(), @@ -346,7 +358,7 @@ template class SumcheckTests : public ::testing::Test { auto verified = verifier_output.verified.value(); // In this test, the circuit is of size 4. We disable the rows 1, 2, and 3, while the first is set to 0. // Therefore, changing the second entry in w_l does not affect the result for ZK fa. - EXPECT_EQ(verified, Flavor::HasZK); + EXPECT_EQ(verified, false); }; }; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp index 93a00d5c37cf..ccfd12ff25c4 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp @@ -24,7 +24,7 @@ template size_t DeciderProvingKey_::compute_dyadi // The number of gates is the maximum required by the lookup argument or everything else, plus an optional zero row // to allow for shifts. - size_t total_num_gates = num_zero_rows + std::max(min_size_due_to_lookups, min_size_of_execution_trace); + size_t total_num_gates = 3 + num_zero_rows + std::max(min_size_due_to_lookups, min_size_of_execution_trace); // Next power of 2 (dyadic circuit size) return circuit.get_circuit_subgroup_size(total_num_gates); From f116bd19e89ccf4a41e40a82891202601b29874b Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Wed, 20 Nov 2024 21:44:03 +0000 Subject: [PATCH 07/25] bug fixed --- .../polynomials/row_disabling_polynomial.hpp | 4 ++-- .../stdlib_circuit_builders/mega_flavor.hpp | 2 +- .../barretenberg/sumcheck/sumcheck.test.cpp | 18 +++++++++++------ .../barretenberg/sumcheck/sumcheck_round.hpp | 20 +++++++++++++++++-- .../ultra_honk/decider_proving_key.cpp | 2 +- .../barretenberg/ultra_honk/sumcheck.test.cpp | 14 +++++++++---- 6 files changed, 44 insertions(+), 16 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp index 0a261cff808e..fedefda072a7 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp @@ -45,8 +45,8 @@ namespace bb { */ template struct RowDisablingPolynomial { // by default it is a constant multilinear polynomial = 1 - FF eval_at_0{ 1 }; - FF eval_at_1{ 2 }; + FF eval_at_0{ 0 }; + FF eval_at_1{ 1 }; FF one = FF{ 1 }; FF zero = FF{ 0 }; 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 1b448811a2bc..a42644c4a87c 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp @@ -65,7 +65,7 @@ class MegaFlavor { // Note: made generic for use in MegaRecursive. template using Relations_ = std::tuple, - // bb::UltraPermutationRelation, + bb::UltraPermutationRelation, bb::LogDerivLookupRelation, bb::DeltaRangeConstraintRelation, bb::EllipticRelation, diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp index f748a3dc7f3c..5317f1ef193e 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp @@ -203,12 +203,21 @@ template class SumcheckTests : public ::testing::Test { if constexpr (Flavor::HasZK) { w_l[7] = FF::random_element(); w_r[6] = FF::random_element(); + std::array z_perm = { 0, 0, 0, 0, 0, 0, w_l[7], 0 }; + full_polynomials.z_perm = bb::Polynomial(z_perm); + w_4[6] = FF::random_element(); auto r = FF::random_element(); std::array lookup_inverses = { 0, 0, 0, 0, 0, 0, r * r, r }; full_polynomials.lookup_inverses = bb::Polynomial(lookup_inverses); - std::array z_perm = { 0, 0, 0, 0, 0, 0, 0, 1 }; - full_polynomials.z_perm = bb::Polynomial(z_perm); + std::array ecc_op_wire = { 0, 0, 0, 0, 0, 0, r * r * r, w_4[6] }; + if constexpr (std::is_same::value) { + full_polynomials.ecc_op_wire_1 = bb::Polynomial(ecc_op_wire); + std::array return_data_inverses = { 0, 0, 0, 0, 0, 0, FF(7) * r * r, -r }; + + full_polynomials.return_data_inverses = bb::Polynomial(return_data_inverses); + } + // // q_o[1] = FF::random_element(); // // q_arith[2] = FF::random_element(); } @@ -222,9 +231,6 @@ template class SumcheckTests : public ::testing::Test { full_polynomials.q_o = bb::Polynomial(q_o); full_polynomials.q_c = bb::Polynomial(q_c); full_polynomials.q_arith = bb::Polynomial(q_arith); - for (size_t idx = 0; idx < multivariate_n; idx++) { - info("coeff z_perm", idx, " ", full_polynomials.z_perm[idx]); - } // Set aribitrary random relation parameters RelationParameters relation_parameters{ .beta = FF::random_element(), @@ -358,7 +364,7 @@ template class SumcheckTests : public ::testing::Test { auto verified = verifier_output.verified.value(); // In this test, the circuit is of size 4. We disable the rows 1, 2, and 3, while the first is set to 0. // Therefore, changing the second entry in w_l does not affect the result for ZK fa. - EXPECT_EQ(verified, false); + EXPECT_EQ(verified, Flavor::HasZK); }; }; diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp index 6f05c0ef1f98..983d05eaf4f5 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp @@ -191,7 +191,7 @@ template class SumcheckProverRound { // For ZK Flavors: The evaluations of the round univariates are masked by the evaluations of Libra univariates if constexpr (Flavor::HasZK) { const auto contribution_from_disabled_rows = compute_disabled_contribution( - polynomials, relation_parameters, gate_sparators, alpha, row_disabling_poly); + polynomials, relation_parameters, gate_sparators, alpha, round_idx, row_disabling_poly); const auto libra_round_univariate = compute_libra_round_univariate(zk_sumcheck_data, round_idx); // Batch the univariate contributions from each sub-relation to obtain the round univariate const auto round_univariate = @@ -211,6 +211,7 @@ template class SumcheckProverRound { const bb::RelationParameters& relation_parameters, const bb::GateSeparatorPolynomial& gate_sparators, const RelationSeparator alpha, + const size_t round_idx, const RowDisablingPolynomial row_disabling_poly) // only populated when Flavor HasZK { PROFILE_THIS_NAME("compute_univariate"); @@ -219,7 +220,8 @@ template class SumcheckProverRound { SumcheckTupleOfTuplesOfUnivariates univariate_accumulator; // Construct extended edge containers ExtendedEdges extended_edges; - size_t edge_idx = round_size - 2; + size_t edge_idx = (round_idx == 0) ? round_size - 4 : round_size - 2; + extend_edges(extended_edges, polynomials, edge_idx); accumulate_relation_univariates(univariate_accumulator, extended_edges, @@ -227,10 +229,24 @@ template class SumcheckProverRound { gate_sparators[(edge_idx >> 1) * gate_sparators.periodicity]); result = batch_over_relations(univariate_accumulator, alpha, gate_sparators); + auto row_disabler = bb::Univariate({ row_disabling_poly.eval_at_0, row_disabling_poly.eval_at_1 }); auto row_disabler_extended = row_disabler.template extend_to(); result *= row_disabler_extended; + if (round_idx == 0) { + edge_idx += 2; + extend_edges(extended_edges, polynomials, edge_idx); + accumulate_relation_univariates(univariate_accumulator, + extended_edges, + relation_parameters, + gate_sparators[(edge_idx >> 1) * gate_sparators.periodicity]); + + result += batch_over_relations(univariate_accumulator, alpha, gate_sparators); + } + info("contribution ", edge_idx, " at 0 ", result.value_at(0)); + info("contribution ", edge_idx, " at 1 ", result.value_at(1)); + return result; } diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp index ccfd12ff25c4..93a00d5c37cf 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp @@ -24,7 +24,7 @@ template size_t DeciderProvingKey_::compute_dyadi // The number of gates is the maximum required by the lookup argument or everything else, plus an optional zero row // to allow for shifts. - size_t total_num_gates = 3 + num_zero_rows + std::max(min_size_due_to_lookups, min_size_of_execution_trace); + size_t total_num_gates = num_zero_rows + std::max(min_size_due_to_lookups, min_size_of_execution_trace); // Next power of 2 (dyadic circuit size) return circuit.get_circuit_subgroup_size(total_num_gates); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/sumcheck.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/sumcheck.test.cpp index 2a7c3d5646b5..1ededb918dae 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/sumcheck.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/sumcheck.test.cpp @@ -14,7 +14,7 @@ using namespace bb; -using Flavor = UltraFlavor; +using Flavor = MegaZKFlavor; using FF = typename Flavor::FF; class SumcheckTestsRealCircuit : public ::testing::Test { @@ -28,13 +28,13 @@ class SumcheckTestsRealCircuit : public ::testing::Test { */ TEST_F(SumcheckTestsRealCircuit, Ultra) { - using Flavor = UltraFlavor; + using Flavor = MegaZKFlavor; using FF = typename Flavor::FF; using Transcript = typename Flavor::Transcript; using RelationSeparator = typename Flavor::RelationSeparator; // Create a composer and a dummy circuit with a few gates - auto builder = UltraCircuitBuilder(); + auto builder = MegaCircuitBuilder(); FF a = FF::one(); // Add some basic add gates, with a public input for good measure @@ -162,10 +162,12 @@ TEST_F(SumcheckTestsRealCircuit, Ultra) decider_pk->proving_key.compute_logderivative_inverses(decider_pk->relation_parameters); decider_pk->proving_key.compute_grand_product_polynomial(decider_pk->relation_parameters, decider_pk->final_active_wire_idx + 1); + info("real circuit test size perm: ", decider_pk->final_active_wire_idx + 1); auto prover_transcript = Transcript::prover_init_empty(); auto circuit_size = decider_pk->proving_key.circuit_size; auto log_circuit_size = numeric::get_msb(circuit_size); + info("log circuit size ", log_circuit_size); RelationSeparator prover_alphas; for (size_t idx = 0; idx < prover_alphas.size(); idx++) { @@ -180,10 +182,14 @@ TEST_F(SumcheckTestsRealCircuit, Ultra) prover_transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); } decider_pk->gate_challenges = prover_gate_challenges; + ZKSumcheckData zk_sumcheck_data(log_circuit_size, prover_transcript); + FF r = FF::random_element(); + decider_pk->proving_key.polynomials.z_perm.at(circuit_size - 1) = r; auto prover_output = sumcheck_prover.prove(decider_pk->proving_key.polynomials, decider_pk->relation_parameters, decider_pk->alphas, - decider_pk->gate_challenges); + decider_pk->gate_challenges, + zk_sumcheck_data); auto verifier_transcript = Transcript::verifier_init_empty(prover_transcript); From ad6ab322938f0985da12663759b92980bdda2d67 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Thu, 21 Nov 2024 10:46:33 +0000 Subject: [PATCH 08/25] tests fixed for MegaZKFlavor --- barretenberg/cpp/src/barretenberg/constants.hpp | 2 ++ .../plonk_honk_shared/composer/composer_lib.hpp | 2 +- .../cpp/src/barretenberg/sumcheck/sumcheck.hpp | 10 +++++++++- .../barretenberg/ultra_honk/decider_proving_key.cpp | 3 ++- .../barretenberg/ultra_honk/decider_proving_key.hpp | 11 ++++++----- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/constants.hpp b/barretenberg/cpp/src/barretenberg/constants.hpp index 696eecc0aa53..7c4dee17111f 100644 --- a/barretenberg/cpp/src/barretenberg/constants.hpp +++ b/barretenberg/cpp/src/barretenberg/constants.hpp @@ -16,4 +16,6 @@ static constexpr uint32_t CONST_ECCVM_LOG_N = 16; static constexpr uint32_t MAX_LOOKUP_TABLES_SIZE = 70000; static constexpr uint32_t MAX_DATABUS_SIZE = 10000; + +static constexpr uint32_t MASKING_OFFSET = 3; } // namespace bb \ No newline at end of file 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 1216623ee32a..95fcc1097b8e 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 @@ -54,7 +54,7 @@ void construct_lookup_read_counts(typename Flavor::Polynomial& read_counts, { const size_t tables_size = circuit.get_tables_size(); // TODO(https://github.com/AztecProtocol/barretenberg/issues/1033): construct tables and counts at top of trace - size_t table_offset = dyadic_circuit_size - tables_size; + size_t table_offset = dyadic_circuit_size - tables_size - MASKING_OFFSET; // loop over all tables used in the circuit; each table contains data about the lookups made on it for (auto& table : circuit.lookup_tables) { diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp index 32b2b3410822..df0a247e52be 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp @@ -193,7 +193,15 @@ template class SumcheckProver { { bb::GateSeparatorPolynomial gate_separators(gate_challenges, multivariate_d); - + size_t idx = 0; + for (auto poly : full_polynomials.get_all()) { + if (poly.size() == multivariate_n) { + if (poly.at(multivariate_n - 1) != FF(0)) { + info("prover poly ", idx, " ", poly.at(multivariate_n - 1)); + } + } + idx++; + } std::vector multivariate_challenge; multivariate_challenge.reserve(multivariate_d); size_t round_idx = 0; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp index 93a00d5c37cf..a0efe3774a6c 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp @@ -24,7 +24,8 @@ template size_t DeciderProvingKey_::compute_dyadi // The number of gates is the maximum required by the lookup argument or everything else, plus an optional zero row // to allow for shifts. - size_t total_num_gates = num_zero_rows + std::max(min_size_due_to_lookups, min_size_of_execution_trace); + size_t total_num_gates = + MASKING_OFFSET + num_zero_rows + std::max(min_size_due_to_lookups, min_size_of_execution_trace); // Next power of 2 (dyadic circuit size) return circuit.get_circuit_subgroup_size(total_num_gates); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp index cb9f954d193f..c25259ec74cc 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp @@ -178,8 +178,8 @@ template class DeciderProvingKey_ { proving_key.polynomials.databus_id = Polynomial(proving_key.circuit_size, proving_key.circuit_size); } const size_t max_tables_size = - std::min(static_cast(MAX_LOOKUP_TABLES_SIZE), dyadic_circuit_size - 1); - size_t table_offset = dyadic_circuit_size - max_tables_size; + std::min(static_cast(MAX_LOOKUP_TABLES_SIZE), dyadic_circuit_size - 4); + size_t table_offset = dyadic_circuit_size - max_tables_size - MASKING_OFFSET; { PROFILE_THIS_NAME("allocating table polynomials"); @@ -219,11 +219,12 @@ template class DeciderProvingKey_ { const size_t table_offset = dyadic_circuit_size - std::min(dyadic_circuit_size - 1, static_cast(MAX_LOOKUP_TABLES_SIZE)); - const size_t lookup_inverses_start = std::min(lookup_offset, table_offset); + const size_t lookup_inverses_start = std::min(lookup_offset, table_offset) - MASKING_OFFSET; const size_t lookup_inverses_end = std::min(dyadic_circuit_size, std::max(lookup_offset + circuit.blocks.lookup.get_fixed_size(is_structured), - table_offset + MAX_LOOKUP_TABLES_SIZE)); + table_offset + MAX_LOOKUP_TABLES_SIZE)) - + MASKING_OFFSET; proving_key.polynomials.lookup_inverses = Polynomial( lookup_inverses_end - lookup_inverses_start, dyadic_circuit_size, lookup_inverses_start); if constexpr (HasDataBus) { @@ -289,7 +290,7 @@ template class DeciderProvingKey_ { PROFILE_THIS_NAME("constructing lookup table polynomials"); construct_lookup_table_polynomials( - proving_key.polynomials.get_tables(), circuit, dyadic_circuit_size); + proving_key.polynomials.get_tables(), circuit, dyadic_circuit_size, MASKING_OFFSET); } { From 60c8fb4f8776da14005f6ad329390b52c81f11c7 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Thu, 21 Nov 2024 11:23:55 +0000 Subject: [PATCH 09/25] eccvm circuit size adjusted --- barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp | 3 ++- barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp | 9 --------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp index 3ab0c9c12ed0..115a6376274d 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp @@ -515,7 +515,8 @@ class ECCVMFlavor { const auto [msm_rows, point_table_read_counts] = ECCVMMSMMBuilder::compute_rows( msms, builder.get_number_of_muls(), builder.op_queue->get_num_msm_rows()); - const size_t num_rows = std::max({ point_table_rows.size(), msm_rows.size(), transcript_rows.size() }); + const size_t num_rows = + std::max({ point_table_rows.size(), msm_rows.size(), transcript_rows.size() }) + MASKING_OFFSET; const auto log_num_rows = static_cast(numeric::get_msb64(num_rows)); const size_t dyadic_num_rows = 1UL << (log_num_rows + (1UL << log_num_rows == num_rows ? 0 : 1)); diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp index df0a247e52be..68c4fc4766bf 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp @@ -193,15 +193,6 @@ template class SumcheckProver { { bb::GateSeparatorPolynomial gate_separators(gate_challenges, multivariate_d); - size_t idx = 0; - for (auto poly : full_polynomials.get_all()) { - if (poly.size() == multivariate_n) { - if (poly.at(multivariate_n - 1) != FF(0)) { - info("prover poly ", idx, " ", poly.at(multivariate_n - 1)); - } - } - idx++; - } std::vector multivariate_challenge; multivariate_challenge.reserve(multivariate_d); size_t round_idx = 0; From ca2583999fd086052260ae170981ef7772219c98 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Thu, 21 Nov 2024 13:18:14 +0000 Subject: [PATCH 10/25] ultra fixed --- .../trace_to_polynomials/trace_to_polynomials.cpp | 4 +++- .../ultra_honk/decider_proving_key.cpp | 1 + .../ultra_honk/decider_proving_key.hpp | 14 +++++++++++--- .../src/barretenberg/ultra_honk/sumcheck.test.cpp | 8 +++++--- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.cpp b/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.cpp index 0dc60e9438fb..2a4b57ecede0 100644 --- a/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.cpp +++ b/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.cpp @@ -2,8 +2,8 @@ #include "barretenberg/flavor/plonk_flavors.hpp" #include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp" #include "barretenberg/stdlib_circuit_builders/mega_zk_flavor.hpp" -#include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_keccak_flavor.hpp" +#include "barretenberg/stdlib_circuit_builders/ultra_zk_flavor.hpp" namespace bb { template void TraceToPolynomials::populate_public_inputs_block(Builder& builder) @@ -173,6 +173,8 @@ void TraceToPolynomials::add_ecc_op_wires_to_proving_key(Builder& builde } template class TraceToPolynomials; +template class TraceToPolynomials; + template class TraceToPolynomials; template class TraceToPolynomials; template class TraceToPolynomials; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp index a0efe3774a6c..62f71e23acb3 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp @@ -189,6 +189,7 @@ void DeciderProvingKey_::move_structured_trace_overflow_to_overflow_bloc } template class DeciderProvingKey_; +template class DeciderProvingKey_; template class DeciderProvingKey_; template class DeciderProvingKey_; template class DeciderProvingKey_; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp index c25259ec74cc..0baac8c373cc 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp @@ -6,8 +6,8 @@ #include "barretenberg/plonk_honk_shared/execution_trace/ultra_execution_trace.hpp" #include "barretenberg/relations/relation_parameters.hpp" #include "barretenberg/stdlib_circuit_builders/mega_zk_flavor.hpp" -#include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_keccak_flavor.hpp" +#include "barretenberg/stdlib_circuit_builders/ultra_zk_flavor.hpp" #include "barretenberg/trace_to_polynomials/trace_to_polynomials.hpp" namespace bb { @@ -219,12 +219,20 @@ template class DeciderProvingKey_ { const size_t table_offset = dyadic_circuit_size - std::min(dyadic_circuit_size - 1, static_cast(MAX_LOOKUP_TABLES_SIZE)); - const size_t lookup_inverses_start = std::min(lookup_offset, table_offset) - MASKING_OFFSET; + info("lookup offset ", lookup_offset); + info("table offset ", table_offset); + const size_t masking_offset = + (std::min(lookup_offset, table_offset) > MASKING_OFFSET) ? MASKING_OFFSET : 0; + info("not here with Ultra"); + const size_t lookup_inverses_start = std::min(lookup_offset, table_offset) - masking_offset; const size_t lookup_inverses_end = std::min(dyadic_circuit_size, std::max(lookup_offset + circuit.blocks.lookup.get_fixed_size(is_structured), table_offset + MAX_LOOKUP_TABLES_SIZE)) - - MASKING_OFFSET; + masking_offset; + info("lookup inverses end ", lookup_inverses_end); + info("lookup inverses start ", lookup_inverses_start); + proving_key.polynomials.lookup_inverses = Polynomial( lookup_inverses_end - lookup_inverses_start, dyadic_circuit_size, lookup_inverses_start); if constexpr (HasDataBus) { diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/sumcheck.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/sumcheck.test.cpp index 1ededb918dae..3568321ffd37 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/sumcheck.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/sumcheck.test.cpp @@ -8,13 +8,14 @@ #include "barretenberg/relations/permutation_relation.hpp" #include "barretenberg/relations/ultra_arithmetic_relation.hpp" #include "barretenberg/stdlib_circuit_builders/plookup_tables/fixed_base/fixed_base.hpp" +#include "barretenberg/stdlib_circuit_builders/ultra_zk_flavor.hpp" #include "barretenberg/transcript/transcript.hpp" #include using namespace bb; -using Flavor = MegaZKFlavor; +using Flavor = UltraFlavorWithZK; using FF = typename Flavor::FF; class SumcheckTestsRealCircuit : public ::testing::Test { @@ -28,13 +29,13 @@ class SumcheckTestsRealCircuit : public ::testing::Test { */ TEST_F(SumcheckTestsRealCircuit, Ultra) { - using Flavor = MegaZKFlavor; + using Flavor = UltraFlavorWithZK; using FF = typename Flavor::FF; using Transcript = typename Flavor::Transcript; using RelationSeparator = typename Flavor::RelationSeparator; // Create a composer and a dummy circuit with a few gates - auto builder = MegaCircuitBuilder(); + auto builder = UltraCircuitBuilder(); FF a = FF::one(); // Add some basic add gates, with a public input for good measure @@ -185,6 +186,7 @@ TEST_F(SumcheckTestsRealCircuit, Ultra) ZKSumcheckData zk_sumcheck_data(log_circuit_size, prover_transcript); FF r = FF::random_element(); decider_pk->proving_key.polynomials.z_perm.at(circuit_size - 1) = r; + decider_pk->proving_key.polynomials.lookup_inverses.at(circuit_size - 1) = r.sqr(); auto prover_output = sumcheck_prover.prove(decider_pk->proving_key.polynomials, decider_pk->relation_parameters, decider_pk->alphas, From 254e622c74fba3b3f4957d11eea5fcbcab152848 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Thu, 21 Nov 2024 15:21:45 +0000 Subject: [PATCH 11/25] build fixed --- .../barretenberg/trace_to_polynomials/trace_to_polynomials.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.cpp b/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.cpp index 7d02392f4a71..d68d6acb6925 100644 --- a/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.cpp +++ b/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.cpp @@ -2,6 +2,7 @@ #include "barretenberg/flavor/plonk_flavors.hpp" #include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp" #include "barretenberg/stdlib_circuit_builders/mega_zk_flavor.hpp" +#include "barretenberg/stdlib_circuit_builders/ultra_keccak_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_rollup_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_zk_flavor.hpp" namespace bb { @@ -174,7 +175,6 @@ void TraceToPolynomials::add_ecc_op_wires_to_proving_key(Builder& builde template class TraceToPolynomials; template class TraceToPolynomials; - template class TraceToPolynomials; template class TraceToPolynomials; template class TraceToPolynomials; From e4c239825d096ba25cfc0d910e44694625905173 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Mon, 25 Nov 2024 09:00:25 +0000 Subject: [PATCH 12/25] debugging independent vk hash --- ...slator_delta_range_constraint_relation.hpp | 22 +++++++++---------- .../translator_permutation_relation.hpp | 6 ++--- .../eccvm_verifier/eccvm_recursive_flavor.hpp | 2 +- .../ultra_recursive_verifier.test.cpp | 2 +- .../translator_recursive_flavor.hpp | 2 +- .../src/barretenberg/sumcheck/sumcheck.hpp | 4 ++++ .../barretenberg/sumcheck/sumcheck_round.hpp | 4 ++-- .../ultra_honk/decider_proving_key.hpp | 5 ++--- 8 files changed, 25 insertions(+), 22 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_delta_range_constraint_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_delta_range_constraint_relation.hpp index 448e95ca085d..421093467dd0 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_delta_range_constraint_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_delta_range_constraint_relation.hpp @@ -8,19 +8,19 @@ template class TranslatorDeltaRangeConstraintRelationImpl { using FF = FF_; // 1 + polynomial degree of this relation - static constexpr size_t RELATION_LENGTH = 6; // degree((lagrange_last-1) * D(D - 1)(D - 2)(D - 3)) = 5 + static constexpr size_t RELATION_LENGTH = 65; // degree((lagrange_last-1) * D(D - 1)(D - 2)(D - 3)) = 5 static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ - 6, // ordered_range_constraints_0 step in {0,1,2,3} subrelation - 6, // ordered_range_constraints_1 step in {0,1,2,3} subrelation - 6, // ordered_range_constraints_2 step in {0,1,2,3} subrelation - 6, // ordered_range_constraints_3 step in {0,1,2,3} subrelation - 6, // ordered_range_constraints_4 step in {0,1,2,3} subrelation - 3, // ordered_range_constraints_0 ends with defined maximum value subrelation - 3, // ordered_range_constraints_1 ends with defined maximum value subrelation - 3, // ordered_range_constraints_2 ends with defined maximum value subrelation - 3, // ordered_range_constraints_3 ends with defined maximum value subrelation - 3 // ordered_range_constraints_4 ends with defined maximum value subrelation + 64, // ordered_range_constraints_0 step in {0,1,2,3} subrelation + 64, // ordered_range_constraints_1 step in {0,1,2,3} subrelation + 64, // ordered_range_constraints_2 step in {0,1,2,3} subrelation + 64, // ordered_range_constraints_3 step in {0,1,2,3} subrelation + 64, // ordered_range_constraints_4 step in {0,1,2,3} subrelation + 34, // ordered_range_constraints_0 ends with defined maximum value subrelation + 34, // ordered_range_constraints_1 ends with defined maximum value subrelation + 34, // ordered_range_constraints_2 ends with defined maximum value subrelation + 34, // ordered_range_constraints_3 ends with defined maximum value subrelation + 34 // ordered_range_constraints_4 ends with defined maximum value subrelation }; /** diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_permutation_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_permutation_relation.hpp index 5279ca98d129..377db58a5fd2 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_permutation_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_permutation_relation.hpp @@ -7,11 +7,11 @@ template class TranslatorPermutationRelationImpl { public: using FF = FF_; // 1 + polynomial degree of this relation - static constexpr size_t RELATION_LENGTH = 7; + static constexpr size_t RELATION_LENGTH = 66; static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ - 7, // grand product construction sub-relation - 3 // left-shiftable polynomial sub-relation + 65, // grand product construction sub-relation + 65 // left-shiftable polynomial sub-relation }; /** * @brief The degrees of subrelations considered as polynomials only in witness polynomials, diff --git a/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_flavor.hpp index 637fe115c07c..1087937b4c36 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_flavor.hpp @@ -59,7 +59,7 @@ template class ECCVMRecursiveFlavor_ { // BATCHED_RELATION_PARTIAL_LENGTH = algebraic degree of sumcheck relation *after* multiplying by the `pow_zeta` // random polynomial e.g. For \sum(x) [A(x) * B(x) + C(x)] * PowZeta(X), relation length = 2 and random relation // length = 3 - static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 1; + static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 2; static constexpr size_t NUM_RELATIONS = std::tuple_size::value; // Instantiate the BarycentricData needed to extend each Relation Univariate diff --git a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp index 5e9eb7727ff1..05da0bf132c1 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp @@ -52,7 +52,7 @@ template class RecursiveVerifierTest : public testing InnerBuilder builder; // Create 2^log_n many add gates based on input log num gates - const size_t num_gates = (1 << log_num_gates); + const size_t num_gates = (1 << log_num_gates) - 100; for (size_t i = 0; i < num_gates; ++i) { fr a = fr::random_element(); uint32_t a_idx = builder.add_variable(a); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_flavor.hpp index ffbf91dea89d..01b7a39b3acc 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_flavor.hpp @@ -97,7 +97,7 @@ template class TranslatorRecursiveFlavor_ { // BATCHED_RELATION_PARTIAL_LENGTH = algebraic degree of sumcheck relation *after* multiplying by the `pow_zeta` // random polynomial e.g. For \sum(x) [A(x) * B(x) + C(x)] * PowZeta(X), relation length = 2 and random relation // length = 3 - static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 1; + static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 2; static constexpr size_t NUM_RELATIONS = std::tuple_size_v; // define the containers for storing the contributions from each relation in Sumcheck diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp index 68c4fc4766bf..aea784b993fd 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp @@ -124,6 +124,7 @@ template class SumcheckProver { using Transcript = typename Flavor::Transcript; using RelationSeparator = typename Flavor::RelationSeparator; + /** * @brief The total algebraic degree of the Sumcheck relation \f$ F \f$ as a polynomial in Prover Polynomials * \f$P_1,\ldots, P_N\f$. @@ -192,6 +193,8 @@ template class SumcheckProver { ZKSumcheckData zk_sumcheck_data = ZKSumcheckData()) { + info("Batched relation partial length", BATCHED_RELATION_PARTIAL_LENGTH); + bb::GateSeparatorPolynomial gate_separators(gate_challenges, multivariate_d); std::vector multivariate_challenge; multivariate_challenge.reserve(multivariate_d); @@ -546,6 +549,7 @@ template class SumcheckVerifier { if constexpr (Flavor::HasZK) { round.target_total_sum += libra_total_sum * libra_challenge; }; + for (size_t round_idx = 0; round_idx < CONST_PROOF_SIZE_LOG_N; round_idx++) { // Obtain the round univariate from the transcript std::string round_univariate_label = "Sumcheck:univariate_" + std::to_string(round_idx); diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp index 983d05eaf4f5..8a9814e0e714 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp @@ -244,8 +244,8 @@ template class SumcheckProverRound { result += batch_over_relations(univariate_accumulator, alpha, gate_sparators); } - info("contribution ", edge_idx, " at 0 ", result.value_at(0)); - info("contribution ", edge_idx, " at 1 ", result.value_at(1)); + // info("contribution ", edge_idx, " at 0 ", result.value_at(0)); + // info("contribution ", edge_idx, " at 1 ", result.value_at(1)); return result; } diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp index ba35a2c2c4c8..c32b803ff4ed 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp @@ -179,7 +179,7 @@ template class DeciderProvingKey_ { proving_key.polynomials.databus_id = Polynomial(proving_key.circuit_size, proving_key.circuit_size); } const size_t max_tables_size = - std::min(static_cast(MAX_LOOKUP_TABLES_SIZE), dyadic_circuit_size - 4); + std::min(static_cast(MAX_LOOKUP_TABLES_SIZE), dyadic_circuit_size - 1 - MASKING_OFFSET); size_t table_offset = dyadic_circuit_size - max_tables_size - MASKING_OFFSET; { PROFILE_THIS_NAME("allocating table polynomials"); @@ -219,12 +219,11 @@ template class DeciderProvingKey_ { // at top of trace const size_t table_offset = dyadic_circuit_size - - std::min(dyadic_circuit_size - 1, static_cast(MAX_LOOKUP_TABLES_SIZE)); + std::min(dyadic_circuit_size - 1 - MASKING_OFFSET, static_cast(MAX_LOOKUP_TABLES_SIZE)); info("lookup offset ", lookup_offset); info("table offset ", table_offset); const size_t masking_offset = (std::min(lookup_offset, table_offset) > MASKING_OFFSET) ? MASKING_OFFSET : 0; - info("not here with Ultra"); const size_t lookup_inverses_start = std::min(lookup_offset, table_offset) - masking_offset; const size_t lookup_inverses_end = std::min(dyadic_circuit_size, From c930acd449e182afb8d56ad945300d9610e6a608 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Mon, 25 Nov 2024 10:30:48 +0000 Subject: [PATCH 13/25] clean-up + typed databus tests --- ...slator_delta_range_constraint_relation.hpp | 22 +++--- .../translator_permutation_relation.hpp | 6 +- .../eccvm_verifier/eccvm_recursive_flavor.hpp | 4 +- .../ultra_recursive_verifier.test.cpp | 2 +- .../translator_recursive_flavor.hpp | 2 +- .../stdlib_circuit_builders/mega_flavor.hpp | 2 +- .../ultra_zk_flavor.hpp | 10 +-- .../src/barretenberg/sumcheck/sumcheck.hpp | 11 ++- .../barretenberg/sumcheck/sumcheck.test.cpp | 9 +-- .../barretenberg/sumcheck/sumcheck_round.hpp | 65 ++++++++--------- .../barretenberg/ultra_honk/databus.test.cpp | 70 ++++++++++--------- .../barretenberg/ultra_honk/sumcheck.test.cpp | 14 +--- 12 files changed, 100 insertions(+), 117 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_delta_range_constraint_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_delta_range_constraint_relation.hpp index 421093467dd0..448e95ca085d 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_delta_range_constraint_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_delta_range_constraint_relation.hpp @@ -8,19 +8,19 @@ template class TranslatorDeltaRangeConstraintRelationImpl { using FF = FF_; // 1 + polynomial degree of this relation - static constexpr size_t RELATION_LENGTH = 65; // degree((lagrange_last-1) * D(D - 1)(D - 2)(D - 3)) = 5 + static constexpr size_t RELATION_LENGTH = 6; // degree((lagrange_last-1) * D(D - 1)(D - 2)(D - 3)) = 5 static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ - 64, // ordered_range_constraints_0 step in {0,1,2,3} subrelation - 64, // ordered_range_constraints_1 step in {0,1,2,3} subrelation - 64, // ordered_range_constraints_2 step in {0,1,2,3} subrelation - 64, // ordered_range_constraints_3 step in {0,1,2,3} subrelation - 64, // ordered_range_constraints_4 step in {0,1,2,3} subrelation - 34, // ordered_range_constraints_0 ends with defined maximum value subrelation - 34, // ordered_range_constraints_1 ends with defined maximum value subrelation - 34, // ordered_range_constraints_2 ends with defined maximum value subrelation - 34, // ordered_range_constraints_3 ends with defined maximum value subrelation - 34 // ordered_range_constraints_4 ends with defined maximum value subrelation + 6, // ordered_range_constraints_0 step in {0,1,2,3} subrelation + 6, // ordered_range_constraints_1 step in {0,1,2,3} subrelation + 6, // ordered_range_constraints_2 step in {0,1,2,3} subrelation + 6, // ordered_range_constraints_3 step in {0,1,2,3} subrelation + 6, // ordered_range_constraints_4 step in {0,1,2,3} subrelation + 3, // ordered_range_constraints_0 ends with defined maximum value subrelation + 3, // ordered_range_constraints_1 ends with defined maximum value subrelation + 3, // ordered_range_constraints_2 ends with defined maximum value subrelation + 3, // ordered_range_constraints_3 ends with defined maximum value subrelation + 3 // ordered_range_constraints_4 ends with defined maximum value subrelation }; /** diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_permutation_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_permutation_relation.hpp index 377db58a5fd2..5279ca98d129 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_permutation_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_permutation_relation.hpp @@ -7,11 +7,11 @@ template class TranslatorPermutationRelationImpl { public: using FF = FF_; // 1 + polynomial degree of this relation - static constexpr size_t RELATION_LENGTH = 66; + static constexpr size_t RELATION_LENGTH = 7; static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ - 65, // grand product construction sub-relation - 65 // left-shiftable polynomial sub-relation + 7, // grand product construction sub-relation + 3 // left-shiftable polynomial sub-relation }; /** * @brief The degrees of subrelations considered as polynomials only in witness polynomials, diff --git a/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_flavor.hpp index 1087937b4c36..c634e9a281df 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_flavor.hpp @@ -54,12 +54,12 @@ template class ECCVMRecursiveFlavor_ { // think these two are not needed for recursive verifier land // using GrandProductRelations = std::tuple>; // using LookupRelation = ECCVMLookupRelation; - static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length(); + static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = ECCVMFlavor::MAX_PARTIAL_RELATION_LENGTH; // BATCHED_RELATION_PARTIAL_LENGTH = algebraic degree of sumcheck relation *after* multiplying by the `pow_zeta` // random polynomial e.g. For \sum(x) [A(x) * B(x) + C(x)] * PowZeta(X), relation length = 2 and random relation // length = 3 - static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 2; + static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = ECCVMFlavor::BATCHED_RELATION_PARTIAL_LENGTH; static constexpr size_t NUM_RELATIONS = std::tuple_size::value; // Instantiate the BarycentricData needed to extend each Relation Univariate diff --git a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp index 05da0bf132c1..5e9eb7727ff1 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp @@ -52,7 +52,7 @@ template class RecursiveVerifierTest : public testing InnerBuilder builder; // Create 2^log_n many add gates based on input log num gates - const size_t num_gates = (1 << log_num_gates) - 100; + const size_t num_gates = (1 << log_num_gates); for (size_t i = 0; i < num_gates; ++i) { fr a = fr::random_element(); uint32_t a_idx = builder.add_variable(a); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_flavor.hpp index 01b7a39b3acc..e83001c1e909 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_flavor.hpp @@ -97,7 +97,7 @@ template class TranslatorRecursiveFlavor_ { // BATCHED_RELATION_PARTIAL_LENGTH = algebraic degree of sumcheck relation *after* multiplying by the `pow_zeta` // random polynomial e.g. For \sum(x) [A(x) * B(x) + C(x)] * PowZeta(X), relation length = 2 and random relation // length = 3 - static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 2; + static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = NativeFlavor::BATCHED_RELATION_PARTIAL_LENGTH; static constexpr size_t NUM_RELATIONS = std::tuple_size_v; // define the containers for storing the contributions from each relation in Sumcheck 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 edf8038148ca..aaac39d7a009 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp @@ -78,7 +78,7 @@ class MegaFlavor { static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length(); static constexpr size_t MAX_TOTAL_RELATION_LENGTH = compute_max_total_relation_length(); - // static_assert(MAX_TOTAL_RELATION_LENGTH == 11); + static_assert(MAX_TOTAL_RELATION_LENGTH == 11); // BATCHED_RELATION_PARTIAL_LENGTH = algebraic degree of sumcheck relation *after* multiplying by the `pow_zeta` // random polynomial e.g. For \sum(x) [A(x) * B(x) + C(x)] * PowZeta(X), relation length = 2 and random relation // length = 3 diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_zk_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_zk_flavor.hpp index 312e6304294d..c6ddab34dbe7 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_zk_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_zk_flavor.hpp @@ -20,17 +20,11 @@ class UltraFlavorWithZK : public bb::UltraFlavor { public: // This flavor runs with ZK Sumcheck static constexpr bool HasZK = true; - // Compute the maximum over all partial subrelation lengths incremented by the corresponding subrelation witness - // degrees for the Relations inherited from UltraFlavor - static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_total_relation_length(); // Determine the number of evaluations of Prover and Libra Polynomials that the Prover sends to the Verifier in // the rounds of ZK Sumcheck. - static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 2; + static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = UltraFlavor::BATCHED_RELATION_PARTIAL_LENGTH + 1; // Construct the container for the subrelations' contributions - using SumcheckTupleOfTuplesOfUnivariates = - decltype(create_sumcheck_tuple_of_tuples_of_univariates()); - // Re-define ExtendedEdges to account for the incremented MAX_PARTIAL_RELATION_LENGTH - using ExtendedEdges = ProverUnivariates; + using SumcheckTupleOfTuplesOfUnivariates = decltype(create_sumcheck_tuple_of_tuples_of_univariates()); }; } // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp index aea784b993fd..16d5c16a0eba 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp @@ -124,7 +124,6 @@ template class SumcheckProver { using Transcript = typename Flavor::Transcript; using RelationSeparator = typename Flavor::RelationSeparator; - /** * @brief The total algebraic degree of the Sumcheck relation \f$ F \f$ as a polynomial in Prover Polynomials * \f$P_1,\ldots, P_N\f$. @@ -193,9 +192,8 @@ template class SumcheckProver { ZKSumcheckData zk_sumcheck_data = ZKSumcheckData()) { - info("Batched relation partial length", BATCHED_RELATION_PARTIAL_LENGTH); - bb::GateSeparatorPolynomial gate_separators(gate_challenges, multivariate_d); + std::vector multivariate_challenge; multivariate_challenge.reserve(multivariate_d); size_t round_idx = 0; @@ -549,7 +547,6 @@ template class SumcheckVerifier { if constexpr (Flavor::HasZK) { round.target_total_sum += libra_total_sum * libra_challenge; }; - for (size_t round_idx = 0; round_idx < CONST_PROOF_SIZE_LOG_N; round_idx++) { // Obtain the round univariate from the transcript std::string round_univariate_label = "Sumcheck:univariate_" + std::to_string(round_idx); @@ -576,7 +573,6 @@ template class SumcheckVerifier { if (round_idx < multivariate_d) { bool checked = round.check_sum(round_univariate); verified = verified && checked; - info("verified round ", round_idx, " ", verified); multivariate_challenge.emplace_back(round_challenge); round.compute_next_target_sum(round_univariate, round_challenge); gate_separators.partially_evaluate(round_challenge); @@ -603,7 +599,10 @@ template class SumcheckVerifier { for (auto [eval, transcript_eval] : zip_view(purported_evaluations.get_all(), transcript_evaluations)) { eval = transcript_eval; } - FF correcting_factor = round.compute_correcting_factor(multivariate_challenge, multivariate_d); + FF correcting_factor{ 1 }; + if constexpr (Flavor::HasZK) { + correcting_factor = round.compute_correcting_factor(multivariate_challenge, multivariate_d); + } // Evaluate the Honk relation at the point (u_0, ..., u_{d-1}) using claimed evaluations of prover polynomials. // In ZK Flavors, the evaluation is corrected by full_libra_purported_value diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp index 5317f1ef193e..09e7c4c4066c 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp @@ -181,11 +181,8 @@ template class SumcheckTests : public ::testing::Test { for (auto& poly : zero_polynomials) { poly = bb::Polynomial(multivariate_n); } - auto full_polynomials = construct_ultra_full_polynomials(zero_polynomials); - for (size_t idx = 0; idx < multivariate_n; idx++) { - info("coeff z_perm before randomization ", idx, " ", full_polynomials.z_perm[idx]); - } + // Add some non-trivial values to certain polynomials so that the arithmetic relation will have non-trivial // contribution. Note: since all other polynomials are set to 0, all other relations are trivially // satisfied. @@ -217,9 +214,6 @@ template class SumcheckTests : public ::testing::Test { full_polynomials.return_data_inverses = bb::Polynomial(return_data_inverses); } - - // // q_o[1] = FF::random_element(); - // // q_arith[2] = FF::random_element(); } full_polynomials.w_l = bb::Polynomial(w_l); full_polynomials.w_r = bb::Polynomial(w_r); @@ -231,6 +225,7 @@ template class SumcheckTests : public ::testing::Test { 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{ .beta = FF::random_element(), diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp index 8a9814e0e714..4fd1224f1049 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp @@ -284,16 +284,15 @@ template class SumcheckProverRound { /** * @brief Extend Univariates then sum them multiplying by the current \f$ pow_{\beta} \f$-contributions. - * @details Since the sub-relations comprising full Honk relation are of different degrees, the computation of - * the evaluations of round univariate \f$ \tilde{S}_{i}(X_{i}) \f$ at points \f$ X_{i} = 0,\ldots, D \f$ - * requires to extend evaluations of individual relations to the domain \f$ 0,\ldots, D\f$. Moreover, linearly - * independent sub-relations, i.e. whose validity is being checked at every point of the hypercube, are - * multiplied by the constant \f$ c_i = pow_\beta(u_0,\ldots, u_{i-1}) \f$ and the current - * \f$pow_{\beta}\f$-factor \f$ ( (1−X_i) + X_i\cdot \beta_i ) \vert_{X_i = k} \f$ for \f$ k = 0,\ldots, D\f$. + * @details Since the sub-relations comprising full Honk relation are of different degrees, the computation of the + * evaluations of round univariate \f$ \tilde{S}_{i}(X_{i}) \f$ at points \f$ X_{i} = 0,\ldots, D \f$ requires to + * extend evaluations of individual relations to the domain \f$ 0,\ldots, D\f$. Moreover, linearly independent + * sub-relations, i.e. whose validity is being checked at every point of the hypercube, are multiplied by the + * constant \f$ c_i = pow_\beta(u_0,\ldots, u_{i-1}) \f$ and the current \f$pow_{\beta}\f$-factor \f$ ( (1−X_i) + + * X_i\cdot \beta_i ) \vert_{X_i = k} \f$ for \f$ k = 0,\ldots, D\f$. * @tparam extended_size Size after extension * @param tuple A tuple of tuples of Univariates - * @param result Round univariate \f$ \tilde{S}^i\f$ represented by its evaluations over \f$ \{0,\ldots, D\} - * \f$. + * @param result Round univariate \f$ \tilde{S}^i\f$ represented by its evaluations over \f$ \{0,\ldots, D\} \f$. * @param gate_sparators Round \f$pow_{\beta}\f$-factor \f$ ( (1−X_i) + X_i\cdot \beta_i )\f$. */ template @@ -312,8 +311,8 @@ template class SumcheckProverRound { using Relation = typename std::tuple_element_t; const bool is_subrelation_linearly_independent = bb::subrelation_is_linearly_independent(); - // Except from the log derivative subrelation, each other subrelation in part is required to be 0 hence - // we multiply by the power polynomial. As the sumcheck prover is required to send a univariate to the + // Except from the log derivative subrelation, each other subrelation in part is required to be 0 hence we + // multiply by the power polynomial. As the sumcheck prover is required to send a univariate to the // verifier, we additionally need a univariate contribution from the pow polynomial which is the // extended_random_polynomial which is the if (!is_subrelation_linearly_independent) { @@ -356,28 +355,26 @@ template class SumcheckProverRound { private: /** - * @brief In Round \f$ i \f$, for a given point \f$ \vec \ell \in \{0,1\}^{d-1 - i}\f$, calculate the - *contribution of each sub-relation to \f$ T^i(X_i) \f$. + * @brief In Round \f$ i \f$, for a given point \f$ \vec \ell \in \{0,1\}^{d-1 - i}\f$, calculate the contribution + * of each sub-relation to \f$ T^i(X_i) \f$. * * @details In Round \f$ i \f$, this method computes the univariate \f$ T^i(X_i) \f$ deined in \ref *SumcheckProverContributionsofPow "this section". It is done as follows: - * - Outer loop: iterate through the "edge" points \f$ (0,\vec \ell) \f$ on the boolean hypercube - *\f$\{0,1\}\times - * \{0,1\}^{d-1 - i}\f$, i.e. skipping every other point. On each iteration, apply \ref extend_edges "extend - *edges". + * - Outer loop: iterate through the "edge" points \f$ (0,\vec \ell) \f$ on the boolean hypercube \f$\{0,1\}\times + * \{0,1\}^{d-1 - i}\f$, i.e. skipping every other point. On each iteration, apply \ref extend_edges "extend edges". * - Inner loop: iterate through the sub-relations, feeding each relation the "the group of edges", i.e. the - * evaluations \f$ P_1(u_0,\ldots, u_{i-1}, k, \vec \ell), \ldots, P_N(u_0,\ldots, u_{i-1}, k, \vec \ell) \f$. - *Each relation Flavor is endowed with \p accumulate method that computes its contribution to \f$ T^i(X_{i}) \f$ - *\ref extend_and_batch_univariates "Adding these univariates together", with appropriate scaling factors, - *produces required evaluations of \f$ \tilde S^i \f$. - * @param univariate_accumulators The container for per-thread-per-relation univariate contributions output by - *\ref accumulate_relation_univariates "accumulate relation univariates" for the previous "groups of edges". - * @param extended_edges Contains tuples of evaluations of \f$ P_j\left(u_0,\ldots, u_{i-1}, k, \vec \ell - *\right) \f$, for \f$ j=1,\ldots, N \f$, \f$ k \in \{0,\ldots, D\} \f$ and fixed \f$\vec \ell \in \{0,1\}^{d-1 - *- i} \f$. - * @param scaling_factor In Round \f$ i \f$, for \f$ (\ell_{i+1}, \ldots, \ell_{d-1}) \in \{0,1\}^{d-1-i}\f$ - *takes an element of \ref bb::GateSeparatorPolynomial< FF >::beta_products "vector of powers of challenges" at - *index \f$ 2^{i+1} + * evaluations \f$ P_1(u_0,\ldots, u_{i-1}, k, \vec \ell), \ldots, P_N(u_0,\ldots, u_{i-1}, k, \vec \ell) \f$. Each + * relation Flavor is endowed with \p accumulate method that computes its contribution to \f$ + * T^i(X_{i}) \f$ + *\ref extend_and_batch_univariates "Adding these univariates together", with appropriate scaling factors, produces + *required evaluations of \f$ \tilde S^i \f$. + * @param univariate_accumulators The container for per-thread-per-relation univariate contributions output by \ref + *accumulate_relation_univariates "accumulate relation univariates" for the previous "groups of edges". + * @param extended_edges Contains tuples of evaluations of \f$ P_j\left(u_0,\ldots, u_{i-1}, k, \vec \ell \right) + *\f$, for \f$ j=1,\ldots, N \f$, \f$ k \in \{0,\ldots, D\} \f$ and fixed \f$\vec \ell \in \{0,1\}^{d-1 - i} \f$. + * @param scaling_factor In Round \f$ i \f$, for \f$ (\ell_{i+1}, \ldots, \ell_{d-1}) \in \{0,1\}^{d-1-i}\f$ takes + *an element of \ref bb::GateSeparatorPolynomial< FF >::beta_products "vector of powers of challenges" at index \f$ + *2^{i+1} *(\ell_{i+1} 2^{i+1} +\ldots + \ell_{d-1} 2^{d-1})\f$. * @result #univariate_accumulators are updated with the contribution from the current group of edges. For each * relation, a univariate of some degree is computed by accumulating the contributions of each group of edges. @@ -458,9 +455,9 @@ template class SumcheckVerifierRound { }; /** * @brief Check that the round target sum is correct - * @details The verifier receives the claimed evaluations of the round univariate \f$ \tilde{S}^i \f$ at \f$X_i - * = 0,\ldots, D \f$ and checks \f$\sigma_i = \tilde{S}^{i-1}(u_{i-1}) \stackrel{?}{=} \tilde{S}^i(0) + - * \tilde{S}^i(1) \f$ + * @details The verifier receives the claimed evaluations of the round univariate \f$ \tilde{S}^i \f$ at \f$X_i = + * 0,\ldots, D \f$ and checks \f$\sigma_i = \tilde{S}^{i-1}(u_{i-1}) \stackrel{?}{=} \tilde{S}^i(0) + \tilde{S}^i(1) + * \f$ * @param univariate Round univariate \f$\tilde{S}^{i}\f$ represented by its evaluations over \f$0,\ldots,D\f$. * */ @@ -478,9 +475,9 @@ template class SumcheckVerifierRound { /** * @brief Check that the round target sum is correct - * @details The verifier receives the claimed evaluations of the round univariate \f$ \tilde{S}^i \f$ at \f$X_i - * = 0,\ldots, D \f$ and checks \f$\sigma_i = \tilde{S}^{i-1}(u_{i-1}) \stackrel{?}{=} \tilde{S}^i(0) + - * \tilde{S}^i(1) \f$ + * @details The verifier receives the claimed evaluations of the round univariate \f$ \tilde{S}^i \f$ at \f$X_i = + * 0,\ldots, D \f$ and checks \f$\sigma_i = \tilde{S}^{i-1}(u_{i-1}) \stackrel{?}{=} \tilde{S}^i(0) + \tilde{S}^i(1) + * \f$ * @param univariate Round univariate \f$\tilde{S}^{i}\f$ represented by its evaluations over \f$0,\ldots,D\f$. * */ diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/databus.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/databus.test.cpp index 772558cbf2ca..f1efed42252a 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/databus.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/databus.test.cpp @@ -11,31 +11,34 @@ #include "barretenberg/ultra_honk/ultra_prover.hpp" #include "barretenberg/ultra_honk/ultra_verifier.hpp" +using namespace bb; namespace { -auto& engine = bb::numeric::get_debug_randomness(); -} +auto& engine = numeric::get_debug_randomness(); + +using FlavorTypes = ::testing::Types; -namespace bb { -class DataBusTests : public ::testing::Test { +template class DataBusTests : public ::testing::Test { protected: static void SetUpTestSuite() { bb::srs::init_crs_factory("../srs_db/ignition"); } using Curve = curve::BN254; using FF = Curve::ScalarField; - using Builder = MegaCircuitBuilder; + using Builder = typename Flavor::CircuitBuilder; + using Prover = UltraProver_; + using Verifier = UltraVerifier_; // Construct and verify a MegaHonk proof for a given circuit static bool construct_and_verify_proof(MegaCircuitBuilder& builder) { - MegaZKProver prover{ builder }; - auto verification_key = std::make_shared(prover.proving_key->proving_key); - MegaZKVerifier verifier{ verification_key }; + Prover prover{ builder }; + auto verification_key = std::make_shared(prover.proving_key->proving_key); + Verifier verifier{ verification_key }; auto proof = prover.construct_proof(); return verifier.verify_proof(proof); } // Construct a Mega circuit with some arbitrary sample gates - static MegaCircuitBuilder construct_test_builder() + static Builder construct_test_builder() { auto op_queue = std::make_shared(); auto builder = MegaCircuitBuilder{ op_queue }; @@ -111,54 +114,56 @@ class DataBusTests : public ::testing::Test { } }; +TYPED_TEST_SUITE(DataBusTests, FlavorTypes); + /** * @brief Test proof construction/verification for a circuit with calldata lookup gates * */ -TEST_F(DataBusTests, CallDataRead) +TYPED_TEST(DataBusTests, CallDataRead) { - Builder builder = construct_test_builder(); - construct_circuit_with_calldata_reads(builder); + typename TypeParam::CircuitBuilder builder = this->construct_test_builder(); + this->construct_circuit_with_calldata_reads(builder); - EXPECT_TRUE(construct_and_verify_proof(builder)); + EXPECT_TRUE(this->construct_and_verify_proof(builder)); } /** * @brief Test proof construction/verification for a circuit with secondary_calldata lookup gates * */ -TEST_F(DataBusTests, CallData2Read) +TYPED_TEST(DataBusTests, CallData2Read) { - Builder builder = construct_test_builder(); - construct_circuit_with_secondary_calldata_reads(builder); + typename TypeParam::CircuitBuilder builder = this->construct_test_builder(); + this->construct_circuit_with_secondary_calldata_reads(builder); - EXPECT_TRUE(construct_and_verify_proof(builder)); + EXPECT_TRUE(this->construct_and_verify_proof(builder)); } /** * @brief Test proof construction/verification for a circuit with return data lookup gates * */ -TEST_F(DataBusTests, ReturnDataRead) +TYPED_TEST(DataBusTests, ReturnDataRead) { - Builder builder = construct_test_builder(); - construct_circuit_with_return_data_reads(builder); + typename TypeParam::CircuitBuilder builder = this->construct_test_builder(); + this->construct_circuit_with_return_data_reads(builder); - EXPECT_TRUE(construct_and_verify_proof(builder)); + EXPECT_TRUE(this->construct_and_verify_proof(builder)); } /** * @brief Test proof construction/verification for a circuit with reads from all bus columns * */ -TEST_F(DataBusTests, ReadAll) +TYPED_TEST(DataBusTests, ReadAll) { - Builder builder = construct_test_builder(); - construct_circuit_with_calldata_reads(builder); - construct_circuit_with_secondary_calldata_reads(builder); - construct_circuit_with_return_data_reads(builder); + typename TypeParam::CircuitBuilder builder = this->construct_test_builder(); + this->construct_circuit_with_calldata_reads(builder); + this->construct_circuit_with_secondary_calldata_reads(builder); + this->construct_circuit_with_return_data_reads(builder); - EXPECT_TRUE(construct_and_verify_proof(builder)); + EXPECT_TRUE(this->construct_and_verify_proof(builder)); } /** @@ -166,12 +171,14 @@ TEST_F(DataBusTests, ReadAll) * the read results are correct * */ -TEST_F(DataBusTests, CallDataDuplicateRead) +TYPED_TEST(DataBusTests, CallDataDuplicateRead) { // Construct a circuit and add some ecc op gates and arithmetic gates - auto builder = construct_test_builder(); + typename TypeParam::CircuitBuilder builder = this->construct_test_builder(); + using FF = TypeParam::FF; // Add some values to calldata + std::vector calldata_values = { 7, 10, 3, 12, 1 }; for (auto& val : calldata_values) { builder.add_public_calldata(builder.add_variable(val)); @@ -201,8 +208,7 @@ TEST_F(DataBusTests, CallDataDuplicateRead) EXPECT_EQ(duplicate_read_result_2, expected_read_result_at_1); // Construct and verify Honk proof - bool result = construct_and_verify_proof(builder); + bool result = this->construct_and_verify_proof(builder); EXPECT_TRUE(result); } - -} // namespace bb \ No newline at end of file +} // namespace \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/sumcheck.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/sumcheck.test.cpp index 3568321ffd37..2a7c3d5646b5 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/sumcheck.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/sumcheck.test.cpp @@ -8,14 +8,13 @@ #include "barretenberg/relations/permutation_relation.hpp" #include "barretenberg/relations/ultra_arithmetic_relation.hpp" #include "barretenberg/stdlib_circuit_builders/plookup_tables/fixed_base/fixed_base.hpp" -#include "barretenberg/stdlib_circuit_builders/ultra_zk_flavor.hpp" #include "barretenberg/transcript/transcript.hpp" #include using namespace bb; -using Flavor = UltraFlavorWithZK; +using Flavor = UltraFlavor; using FF = typename Flavor::FF; class SumcheckTestsRealCircuit : public ::testing::Test { @@ -29,7 +28,7 @@ class SumcheckTestsRealCircuit : public ::testing::Test { */ TEST_F(SumcheckTestsRealCircuit, Ultra) { - using Flavor = UltraFlavorWithZK; + using Flavor = UltraFlavor; using FF = typename Flavor::FF; using Transcript = typename Flavor::Transcript; using RelationSeparator = typename Flavor::RelationSeparator; @@ -163,12 +162,10 @@ TEST_F(SumcheckTestsRealCircuit, Ultra) decider_pk->proving_key.compute_logderivative_inverses(decider_pk->relation_parameters); decider_pk->proving_key.compute_grand_product_polynomial(decider_pk->relation_parameters, decider_pk->final_active_wire_idx + 1); - info("real circuit test size perm: ", decider_pk->final_active_wire_idx + 1); auto prover_transcript = Transcript::prover_init_empty(); auto circuit_size = decider_pk->proving_key.circuit_size; auto log_circuit_size = numeric::get_msb(circuit_size); - info("log circuit size ", log_circuit_size); RelationSeparator prover_alphas; for (size_t idx = 0; idx < prover_alphas.size(); idx++) { @@ -183,15 +180,10 @@ TEST_F(SumcheckTestsRealCircuit, Ultra) prover_transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); } decider_pk->gate_challenges = prover_gate_challenges; - ZKSumcheckData zk_sumcheck_data(log_circuit_size, prover_transcript); - FF r = FF::random_element(); - decider_pk->proving_key.polynomials.z_perm.at(circuit_size - 1) = r; - decider_pk->proving_key.polynomials.lookup_inverses.at(circuit_size - 1) = r.sqr(); auto prover_output = sumcheck_prover.prove(decider_pk->proving_key.polynomials, decider_pk->relation_parameters, decider_pk->alphas, - decider_pk->gate_challenges, - zk_sumcheck_data); + decider_pk->gate_challenges); auto verifier_transcript = Transcript::verifier_init_empty(prover_transcript); From f408141a7ed2ad7d74f0b97078fb774c612ea1d6 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Mon, 25 Nov 2024 13:34:45 +0000 Subject: [PATCH 14/25] 4 rows disabled + clean-up --- .../cpp/src/barretenberg/constants.hpp | 2 +- .../polynomials/row_disabling_polynomial.hpp | 24 +++++++++++-------- .../src/barretenberg/sumcheck/sumcheck.hpp | 3 ++- .../barretenberg/sumcheck/sumcheck_round.hpp | 23 ++++-------------- 4 files changed, 22 insertions(+), 30 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/constants.hpp b/barretenberg/cpp/src/barretenberg/constants.hpp index 7c4dee17111f..66670e348c31 100644 --- a/barretenberg/cpp/src/barretenberg/constants.hpp +++ b/barretenberg/cpp/src/barretenberg/constants.hpp @@ -17,5 +17,5 @@ static constexpr uint32_t MAX_LOOKUP_TABLES_SIZE = 70000; static constexpr uint32_t MAX_DATABUS_SIZE = 10000; -static constexpr uint32_t MASKING_OFFSET = 3; +static constexpr uint32_t MASKING_OFFSET = 4; } // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp index fedefda072a7..ebe0e8f297af 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp @@ -45,7 +45,7 @@ namespace bb { */ template struct RowDisablingPolynomial { // by default it is a constant multilinear polynomial = 1 - FF eval_at_0{ 0 }; + FF eval_at_0{ 1 }; FF eval_at_1{ 1 }; FF one = FF{ 1 }; FF zero = FF{ 0 }; @@ -54,19 +54,23 @@ template struct RowDisablingPolynomial { void update_evaluations(FF round_challenge, size_t round_idx) { - if (round_idx == 0) { - eval_at_0 = round_challenge; - eval_at_1 = one; - }; if (round_idx == 1) { - eval_at_1 = eval_at_0 + round_challenge - eval_at_0 * round_challenge; eval_at_0 = zero; - }; + } + if (round_idx >= 2) { + eval_at_1 *= round_challenge; + } + } - if (round_idx > 1) { - eval_at_1 = eval_at_1 * round_challenge; - eval_at_0 = zero; + static FF evaluate_at_challenge(std::vector multivariate_challenge, const size_t log_circuit_size) + { + FF evaluation_at_multivariate_challenge{ 1 }; + + for (size_t idx = 2; idx < log_circuit_size; idx++) { + evaluation_at_multivariate_challenge *= multivariate_challenge[idx]; } + + return evaluation_at_multivariate_challenge; } }; diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp index 16d5c16a0eba..86a11b1a8001 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp @@ -601,7 +601,8 @@ template class SumcheckVerifier { } FF correcting_factor{ 1 }; if constexpr (Flavor::HasZK) { - correcting_factor = round.compute_correcting_factor(multivariate_challenge, multivariate_d); + RowDisablingPolynomial row_disabler = RowDisablingPolynomial(); + correcting_factor = row_disabler.evaluate_at_challenge(multivariate_challenge, multivariate_d); } // Evaluate the Honk relation at the point (u_0, ..., u_{d-1}) using claimed evaluations of prover polynomials. diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp index 4fd1224f1049..0ee7fceaff5a 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp @@ -230,10 +230,6 @@ template class SumcheckProverRound { result = batch_over_relations(univariate_accumulator, alpha, gate_sparators); - auto row_disabler = bb::Univariate({ row_disabling_poly.eval_at_0, row_disabling_poly.eval_at_1 }); - auto row_disabler_extended = row_disabler.template extend_to(); - result *= row_disabler_extended; - if (round_idx == 0) { edge_idx += 2; extend_edges(extended_edges, polynomials, edge_idx); @@ -244,8 +240,11 @@ template class SumcheckProverRound { result += batch_over_relations(univariate_accumulator, alpha, gate_sparators); } - // info("contribution ", edge_idx, " at 0 ", result.value_at(0)); - // info("contribution ", edge_idx, " at 1 ", result.value_at(1)); + if (round_idx > 1) { + auto row_disabler = bb::Univariate({ row_disabling_poly.eval_at_0, row_disabling_poly.eval_at_1 }); + auto row_disabler_extended = row_disabler.template extend_to(); + result *= row_disabler_extended; + } return result; } @@ -564,17 +563,5 @@ template class SumcheckVerifierRound { }; return output; } - - FF compute_correcting_factor(std::vector multilinear_challenge, const size_t log_circuit_size) - { - FF one = FF{ 1 }; - FF result = - multilinear_challenge[0] + multilinear_challenge[1] - multilinear_challenge[0] * multilinear_challenge[1]; - - for (size_t idx = 2; idx < log_circuit_size; idx++) { - result *= multilinear_challenge[idx]; - } - return one - result; - } }; } // namespace bb From 241cfb6968e3fdb2b66ac53de413a0ccc4374213 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Mon, 25 Nov 2024 13:37:16 +0000 Subject: [PATCH 15/25] LookupReadCounts fix --- .../plonk_honk_shared/composer/composer_lib.test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.test.cpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.test.cpp index 0cd69e9f523d..84b04a5e331d 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.test.cpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.test.cpp @@ -55,7 +55,7 @@ TEST_F(ComposerLibTests, LookupReadCounts) // The table polys are constructed at the bottom of the trace, thus so to are the counts/tags // TODO(https://github.com/AztecProtocol/barretenberg/issues/1033): construct tables and counts at top of trace - size_t offset = circuit_size - builder.get_tables_size(); + size_t offset = circuit_size - builder.get_tables_size() - MASKING_OFFSET; // The uint32 XOR lookup table is constructed for 6 bit operands via double for loop that iterates through the left // operand externally (0 to 63) then the right operand internally (0 to 63). Computing (1 XOR 5) will thus result in From 2c729f66b7651785a01676c5bd68e1e0ab6ef629 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Mon, 25 Nov 2024 19:08:01 +0000 Subject: [PATCH 16/25] eccvm fixed --- .../src/barretenberg/eccvm/eccvm_circuit_builder.hpp | 3 ++- .../cpp/src/barretenberg/eccvm/eccvm_prover.cpp | 12 +++++++++++- .../polynomials/row_disabling_polynomial.hpp | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_circuit_builder.hpp index 69f4f1799e6f..6fcea1cb32aa 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_circuit_builder.hpp @@ -4,6 +4,7 @@ #include "./msm_builder.hpp" #include "./precomputed_tables_builder.hpp" #include "./transcript_builder.hpp" +#include "barretenberg/constants.hpp" #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp" #include "barretenberg/honk/proof_system/logderivative_library.hpp" @@ -218,7 +219,7 @@ class ECCVMCircuitBuilder { [[nodiscard]] size_t get_circuit_subgroup_size(const size_t num_rows) const { - const auto num_rows_log2 = static_cast(numeric::get_msb64(num_rows)); + const auto num_rows_log2 = static_cast(numeric::get_msb64(num_rows + MASKING_OFFSET)); size_t num_rows_pow2 = 1UL << (num_rows_log2 + (1UL << num_rows_log2 == num_rows ? 0 : 1)); return num_rows_pow2; } diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp index d95a2f01ad76..bc19c160080b 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp @@ -5,7 +5,6 @@ #include "barretenberg/commitment_schemes/shplonk/shplonk.hpp" #include "barretenberg/common/ref_array.hpp" #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/relations/permutation_relation.hpp" #include "barretenberg/sumcheck/sumcheck.hpp" @@ -46,6 +45,13 @@ void ECCVMProver::execute_preamble_round() void ECCVMProver::execute_wire_commitments_round() { auto wire_polys = key->polynomials.get_wires(); + auto accu = key->polynomials.transcript_accumulator_empty; + info("accu empty size ", accu.size()); + for (size_t idx = 1; idx < accu.size(); idx++) { + if (accu.at(idx) != 0) { + info("idx = ", idx, " ", accu.at(idx)); + } + } auto labels = commitment_labels.get_wires(); for (size_t idx = 0; idx < wire_polys.size(); ++idx) { transcript->send_to_verifier(labels[idx], key->commitment_key->commit(wire_polys[idx])); @@ -85,6 +91,10 @@ void ECCVMProver::execute_grand_product_computation_round() { // Compute permutation grand product and their commitments compute_grand_products(key->polynomials, relation_parameters); + FF random_el_1 = FF::random_element(); + size_t z_size = key->polynomials.z_perm.size(); + info(" gr prod size ", z_size); + key->polynomials.z_perm.at(z_size - 1) = random_el_1; transcript->send_to_verifier(commitment_labels.z_perm, key->commitment_key->commit(key->polynomials.z_perm)); } diff --git a/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp index ebe0e8f297af..892e5786369c 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp @@ -70,7 +70,7 @@ template struct RowDisablingPolynomial { evaluation_at_multivariate_challenge *= multivariate_challenge[idx]; } - return evaluation_at_multivariate_challenge; + return FF(1) - evaluation_at_multivariate_challenge; } }; From 454360214f704489bd24d9916e05fc2ebcad0375 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Mon, 25 Nov 2024 19:11:25 +0000 Subject: [PATCH 17/25] removed print statements --- .../cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp index e6380097b635..b0dd6423e10d 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp @@ -221,8 +221,6 @@ template class DeciderProvingKey_ { const size_t table_offset = dyadic_circuit_size - std::min(dyadic_circuit_size - 1 - MASKING_OFFSET, static_cast(MAX_LOOKUP_TABLES_SIZE)); - info("lookup offset ", lookup_offset); - info("table offset ", table_offset); const size_t masking_offset = (std::min(lookup_offset, table_offset) > MASKING_OFFSET) ? MASKING_OFFSET : 0; const size_t lookup_inverses_start = std::min(lookup_offset, table_offset) - masking_offset; @@ -231,8 +229,6 @@ template class DeciderProvingKey_ { std::max(lookup_offset + circuit.blocks.lookup.get_fixed_size(is_structured), table_offset + MAX_LOOKUP_TABLES_SIZE)) - masking_offset; - info("lookup inverses end ", lookup_inverses_end); - info("lookup inverses start ", lookup_inverses_start); proving_key.polynomials.lookup_inverses = Polynomial( lookup_inverses_end - lookup_inverses_start, dyadic_circuit_size, lookup_inverses_start); From 66760307251a3fa100606bf3fbe8582c01861ce8 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Mon, 25 Nov 2024 19:25:16 +0000 Subject: [PATCH 18/25] docs upd --- .../polynomials/row_disabling_polynomial.hpp | 156 ++++++++++++++---- 1 file changed, 122 insertions(+), 34 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp index 892e5786369c..66fcd969fdd9 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp @@ -8,41 +8,129 @@ #include namespace bb { /** - * @brief Struct for the polynomial \f$ L = (1 - L_1(X_0, \ldots, X_{d-1}) - L_2(X_0, \ldots, X_{d-1}) - L_3(X_0, - * \ldots, X_{d-1}) )\f$. - * @details Need to efficiently evaluate this polynomial at any point of the form \f$ (u_0, \ldots, u_{k}, \vec{i} ) \f$ - * where \f$ \vec{i}\f$ belongs to a hypercube. - * First, note \f$ L_1(X_0, \ldots, X_{d-1}) = X_0 \prod_{i=1}^{d-1} (1 - X_i)\f$, \f$ L_2 = (1 - X_0) - * X_1\prod_{i=2}^{n-1} (1 - X_i)\f$ and \f$ L_3(X_0, \ldots, X_{d-1}) = X_0 * X_1 * \prod_{i=2}^{d-1} (1 - X_i) \f$. - * Therefore, \f$ L = (X_0*(1-X_1) + (1 - X_0)* X_1 + X_0 * X_1) * \prod_{i=2}^{d-1} (1- X_i)\f$ which simplifies - * further to \f$ L = (1 + X_0 + X_1 - X_0*X_1) \prod_{i=2}^{d-1} (1- X_i) \f$. - * We could compute the sumcheck univariate contributions from \f$L\f$: \f$ \sum_{i=0}^{2^n-1} L = 2^{n} - 3\f$, because - * \f$ L = 0\f$ at \f$ i = 1, 2, 3\f$ and \f$1\f$ elsewhere. - * After getting the first challenge \f$ u_0 \f$, \f$ L(u_0) = L(u_0, X_1, \ldots, X_{d-1}) = 1 - (1 + u_0 + X_1 - - * u_0\cdot X_1) L_0(X_2,X_3,\ldots, X_{d-1})\f$. It is more useful to have the values of \f$ L(u_0) \f$ on the - * hypercube. - * - * \f$ L_1(u_0, X_1,\ldots, X_{d-1}) = u_0 * L_0 (X_1,\ldots, X_{d-1})\f$, it evaluates to \f$ u_0\f$ at \f$ 0 \f$ and - * is \f$ 0 \f$ elsewehere. - * - * \f$ L_2(u_0, X_1,\ldots, X_{d-1}) = (1-u_0) * L_1 (X_1,\ldots, X_{d-1})\f$, it evaluates to \f$ (1-u_0) \f$ at \f$ 1 - * \f$ and is \f$ 0 \f$ elsewhere. - * - * \f$ L_3(u_0, X_1,\ldots, X_{d-1}) = u_0 * L_1 (X_1,\ldots, X_{d-1})\f$, it evaluates to \f$ u_0 \f$ at \f$ 1\f$ and - * is \f$ 0 \f$ elsewhere. - * Therefore, \f$ L(u_0)(i) = 1 \f$ for $i \neq 0 \f$, \f$ L(u_0)(0) = 1 - u_0 \f$. - * - * We see that the sum of \f$ L(u_0) \f$ over the smaller hypercube is equal to \f$ 2^{d-2} - 2 - (u_0 + 1) \f$. - * The partial eval \f$ L(u_0, u_1) \f$ is given by \f$ 1 - (1+u_0 + u_1 - u_0 \cdot u_1) L_0(X_2, X_3,\ldots, - * X_{d-1})\f$, it is \f$ 1 \f$ outside of \f$ 0 \f$, and is equal to \f$ - u_0 - u_1 + u_0u_1 \f$. - * In the subsequent rounds \f$L(u_0, \ldots, u_i)\f$ is \f$ 1\f$ outside of \f$ 0 \f$ ans is given as - * \f$ 1 - (1+u_0 + u_1 - u_0 \cdot u_1) (1-u_2)\cdots (1 - u_i) L_0(X_{i+1}, \ldots, X_{d-1})\f$. - * - * When the prover computes the first sumcheck univariate \f$S_k(X) = \sum L \cdot H(X_0,\ldots, X_{d-1})\f$, it has to - * compute \f$ \sum_{i_{k+1},\ldots, i_{d-1}} L(u_0,u_1,\ldots, u_{k-1}, X, i_{k+1},\ldots, i_{d-1}) H(\cdots)\f$ - * - * @tparam FF + * @brief Polynomial for Sumcheck with disabled Rows + * + * \f$ n = 2^d \f$ circuit size + * \f$ L_i \f$ multilinear Lagrange in \f$ d \f$ variables, \f$ i = 0,\ldots, n-1 \f$. + * + * Assume we are given a "valid" execution trace at rows \f$ 0,\ldots, n-5 \f$, i.e., + * \f[ + * \sum_{\mathbb{H} \setminus \{n-1, n-2, n-3, n-4\}} H = 0. + * \f] + * + * We want to pad the witness polynomials with random field elements in rows \f$ n-1, n-2, n-3 \f$. + * Since the commitment to the shift must coincide with the commitment to its unshifted counterpart, + * we have to reserve \f$ 4 \f$ rows at the end to be able to. + * To achieve this, we multiply the Honk relation \f$ H \f$ by the polynomial + * \f[ + * 1 - L = 1 - L_{n-1} - L_{n-2} - L_{n-3} - L_{n-4}. + * \f] + * that vanishes at the last \f$ 4 \f$ rows and is equal to \f$ 1 \f$ everywhere else on the hypercube. + * + * We consider the sumcheck protocol for the modified relation + * \f[ + * \sum_{\mathbb{H}} (1 - L) H = \sum_{\mathbb{H}} H - \sum_{\mathbb{H}} L \cdot H. + * \f] + * + * Note that the target sum remains \f$ 0 \f$ because the contributions from the last rows are multiplied by \f$ 0 \f$. + * + * Recall: + * - \f$ n-1 = 2^d - 1 = (1,1, \ldots, 1) \f$ + * - \f$ n-2 = (0,1,\ldots,1) \f$ + * - \f$ n-3 = (1,0,\ldots,1) \f$ + * - \f$ n-4 = (0,0,\ldots,1) \f$ + * + * ### Round 0: + * \f[ + * \begin{aligned} + * S' &= + * S_{H,0} - \Big(L_{n-1}(X, 1, \ldots, 1) + L_{n-2}(X, 1,\ldots,1)\Big) H(X,1,\ldots, 1) \\ + * &\quad - \Big(L_{n-3}(X, 0,1,\ldots,1) + L_{n-4}(X,0,1,\ldots,1)\Big) H(X,0,1,\ldots,1) + * \end{aligned} + * \f] + * + * We do not modify the algorithm computing \f$ S_{H,0} \f$. Simply add a method that computes the contribution from the + * edges \f$ (0,1,\ldots,1) \f$ and \f$ (1,\ldots,1) \in \mathbb{H}^{d-1} \f$. + * + * First, compute the coefficients in the Lagrange basis of the factor coming from the Lagranges: + * \f[ + * \begin{aligned} + * L_{n-1}(X,\vec{1}) + L_{n-2}(X,\vec{1}) &= X + (1 - X) = 1 \\ + * L_{n-3}(X,0,1,\ldots,1) + L_{n-4}(X,0,1,\ldots,1) &= 1 + * \end{aligned} + * \f] + * + * \f[ + * S'_0 = S_{H,0} - H(X,1,\ldots,1) - H(X,0,1,\ldots,1) + * \f] + * + * ### Round 1: + * \f[ + * \begin{aligned} + * L_{n-1}(u_0,X,\vec{1}) + L_{n-2}(u_0,X,\vec{1}) &= + * u_0 X + (1 - u_0) X = X \\ + * L_{n-3}(u_0,X,\vec{1}) + L_{n-4}(u_0,X,\vec{1}) &= + * u_0 (1 - X) + (1 - u_0)(1 - X) = (1 - X) + * \end{aligned} + * \f] + * + * \f[ + * S'_1 = S_{H,1} - H(X,1,\ldots,1) + * \f] + * + * ### Round 2: + * \f[ + * S'_2 = S_{H,2} - X \cdot H(u_0,u_1,X,1,\ldots,1) + * \f] + * + * ### Rounds i > 1: + * We can compute the restricted sumcheck univariates \f$ S' \f$ in each round as follows: + * \f[ + * \begin{aligned} + * S' = S_{H,i} - + * \Big(L_{n-1}(u_0, \ldots, u_{i-1}, X, 1, \ldots, 1) + L_{n-2}(u_0, \ldots, u_{i-1}, X, 1,\ldots,1) \\ + * + L_{n-3}(u_0, \ldots, u_{i-1}, X, 1,\ldots,1) + L_{n-4}(u_0, \ldots, u_{i-1}, X, 1,\ldots,1)\Big) \\ + * \times H(u_0, \ldots, u_{i-1}, X, 1,\ldots,1) + * \end{aligned} + * \f] + * + * Compute the factor coming from the Lagranges: + * \f[ + * \begin{aligned} + * &\left(u_0 \cdots u_{i-1} + (1 - u_0) u_1 \cdots u_{i-1} + u_0 (1 - u_1) u_2 \cdots u_{i-1} + (1 - u_0)(1 - u_1) u_2 + * \cdots u_{i-1}\right) X \\ + * &= \left(u_0 u_1 + (1 - u_0) u_1 + u_0 (1 - u_1) + (1 - u_0)(1 - u_1)\right) u_2 \cdots u_{i-1} X \\ + * &= 0 \cdot (1 - X) + 1 \cdot u_2 \cdots u_{i-1} \cdot X + * \end{aligned} + * \f] + * + * This way, we get: + * \f[ + * S_{H,i}(X) = S_{H,i} - u_2 \cdots u_{i-1} \cdot X \cdot H(u_0, \ldots, u_{i-1}, X, 1, \ldots, 1). + * \f] + * + * ## The algorithm: + * + * Let \f$ D \f$ be the max partial degree of \f$ H \f$. + * + * 1. Compute \f$ S_{H,i} \f$ without any modifications as a polynomial of degree \f$ D \f$. Extend it to degree \f$ D + + * 1 \f$, because it is the max partial degree of \f$ L \cdot H \f$. + * + * 2. If \f$ i = 0 \f$, compute \f$ H(X,1,1,\ldots,1) + H(X,0,1,\ldots,1) \f$ as a univariate of degree \f$ D \f$, else + * compute \f$ H(u_0, \ldots, u_{i-1}, X, 1, \ldots, 1) \f$ as a univariate of degree \f$ D \f$. Extend to degree \f$ D + * + 1 \f$. + * + * 3. Compute the extension of \f$ L^{(i)} = L(u_0, \ldots, u_{i-1}, X, 1, \ldots, 1) \f$ to the degree \f$ D + 1 \f$ + * polynomial. + * + * 4. Compute the coefficients of the product \f$ L^{(i)} \cdot H^{(i)} \f$. + * + * 5. Compute the coefficients of \f$ S_{H,i} - L^{(i)} \cdot H^{(i)} \f$ (degree \f$ D + 1 \f$ univariate). + * + * The verifier needs to evaluate \f$ 1 - L(u_0, \ldots, u_{d-1}) \f$, which is equal to \f$ 0 \f$ if \f$ d < 2 \f$, and + * is equal to \f$ 1- u_2 \cdots u_{d-1} \f$ otherwise. */ + template struct RowDisablingPolynomial { // by default it is a constant multilinear polynomial = 1 FF eval_at_0{ 1 }; From c96f1a0078e8147f991387eaa8d25624f41dacaa Mon Sep 17 00:00:00 2001 From: iakovenkos <105737703+iakovenkos@users.noreply.github.com> Date: Mon, 25 Nov 2024 20:28:27 +0100 Subject: [PATCH 19/25] removed print statements --- .../cpp/src/barretenberg/eccvm/eccvm_prover.cpp | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp index bc19c160080b..a4a33d1f0ee0 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp @@ -45,13 +45,7 @@ void ECCVMProver::execute_preamble_round() void ECCVMProver::execute_wire_commitments_round() { auto wire_polys = key->polynomials.get_wires(); - auto accu = key->polynomials.transcript_accumulator_empty; - info("accu empty size ", accu.size()); - for (size_t idx = 1; idx < accu.size(); idx++) { - if (accu.at(idx) != 0) { - info("idx = ", idx, " ", accu.at(idx)); - } - } + auto labels = commitment_labels.get_wires(); for (size_t idx = 0; idx < wire_polys.size(); ++idx) { transcript->send_to_verifier(labels[idx], key->commitment_key->commit(wire_polys[idx])); @@ -91,10 +85,6 @@ void ECCVMProver::execute_grand_product_computation_round() { // Compute permutation grand product and their commitments compute_grand_products(key->polynomials, relation_parameters); - FF random_el_1 = FF::random_element(); - size_t z_size = key->polynomials.z_perm.size(); - info(" gr prod size ", z_size); - key->polynomials.z_perm.at(z_size - 1) = random_el_1; transcript->send_to_verifier(commitment_labels.z_perm, key->commitment_key->commit(key->polynomials.z_perm)); } From 377169dfb5db79f8f34c00dbc049abcce78ec0f9 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Tue, 26 Nov 2024 10:25:08 +0000 Subject: [PATCH 20/25] small fixes --- .../cpp/src/barretenberg/constants.hpp | 2 + .../src/barretenberg/eccvm/eccvm_flavor.hpp | 4 +- .../polynomials/row_disabling_polynomial.hpp | 9 ++-- .../mega_zk_flavor.hpp | 2 +- .../src/barretenberg/sumcheck/sumcheck.hpp | 11 ++--- .../barretenberg/sumcheck/sumcheck.test.cpp | 25 +++++++---- .../barretenberg/sumcheck/sumcheck_round.hpp | 44 ++++++++++++------- .../translator_vm/translator_flavor.hpp | 3 +- 8 files changed, 61 insertions(+), 39 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/constants.hpp b/barretenberg/cpp/src/barretenberg/constants.hpp index 66670e348c31..8a4af08e0e0c 100644 --- a/barretenberg/cpp/src/barretenberg/constants.hpp +++ b/barretenberg/cpp/src/barretenberg/constants.hpp @@ -17,5 +17,7 @@ static constexpr uint32_t MAX_LOOKUP_TABLES_SIZE = 70000; static constexpr uint32_t MAX_DATABUS_SIZE = 10000; +// The number of entries in ProverPolynomials reserved for randomness intended to mask witness commitments, witness +// evaluation at the sumcheck challenge, and, if necessary, the evaluation of the corresponding shift static constexpr uint32_t MASKING_OFFSET = 4; } // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp index 115a6376274d..040157daf01d 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp @@ -84,7 +84,9 @@ class ECCVMFlavor { // BATCHED_RELATION_PARTIAL_LENGTH = algebraic degree of sumcheck relation *after* multiplying by the `pow_zeta` // random polynomial e.g. For \sum(x) [A(x) * B(x) + C(x)] * PowZeta(X), relation length = 2 and random relation - // length = 3 + // length = 3. + // The degree has to be further increased by 1 because the relation is multiplied by the Row Disabling // + // Polynomial static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 2; static constexpr size_t NUM_RELATIONS = std::tuple_size::value; diff --git a/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp index 66fcd969fdd9..9133e9303a0a 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp @@ -8,6 +8,7 @@ #include namespace bb { /** + * @struct RowDisablingPolynomial * @brief Polynomial for Sumcheck with disabled Rows * * \f$ n = 2^d \f$ circuit size @@ -132,18 +133,16 @@ namespace bb { */ template struct RowDisablingPolynomial { - // by default it is a constant multilinear polynomial = 1 + // initialized as a constant linear polynomial = 1 FF eval_at_0{ 1 }; FF eval_at_1{ 1 }; - FF one = FF{ 1 }; - FF zero = FF{ 0 }; RowDisablingPolynomial() = default; void update_evaluations(FF round_challenge, size_t round_idx) { if (round_idx == 1) { - eval_at_0 = zero; + eval_at_0 = FF{ 0 }; } if (round_idx >= 2) { eval_at_1 *= round_challenge; @@ -158,7 +157,7 @@ template struct RowDisablingPolynomial { evaluation_at_multivariate_challenge *= multivariate_challenge[idx]; } - return FF(1) - evaluation_at_multivariate_challenge; + return FF{ 1 } - evaluation_at_multivariate_challenge; } }; diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_zk_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_zk_flavor.hpp index 32edb43439c8..dbaac3d0164a 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_zk_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_zk_flavor.hpp @@ -12,8 +12,8 @@ class MegaZKFlavor : public bb::MegaFlavor { public: // Indicates that this flavor runs with non-ZK Sumcheck. static constexpr bool HasZK = true; + // The degree has to be increased because the relation is multiplied by the Row Disabling Polynomial static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MegaFlavor::BATCHED_RELATION_PARTIAL_LENGTH + 1; - /** * @brief Derived class that defines proof structure for Mega proofs, as well as supporting functions. * Note: Made generic for use in MegaRecursive. diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp index 86a11b1a8001..9271d6049c87 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp @@ -197,7 +197,7 @@ template class SumcheckProver { std::vector multivariate_challenge; multivariate_challenge.reserve(multivariate_d); size_t round_idx = 0; - auto row_disabling_poly = RowDisablingPolynomial(); + auto row_disabling_polynomial = RowDisablingPolynomial(); // In the first round, we compute the first univariate polynomial and populate the book-keeping table of // #partially_evaluated_polynomials, which has \f$ n/2 \f$ rows and \f$ N \f$ columns. When the Flavor has ZK, // compute_univariate also takes into account the zk_sumcheck_data. @@ -207,7 +207,7 @@ template class SumcheckProver { gate_separators, alpha, zk_sumcheck_data, - row_disabling_poly); + row_disabling_polynomial); vinfo("starting sumcheck rounds..."); { @@ -222,7 +222,7 @@ template class SumcheckProver { // Prepare ZK Sumcheck data for the next round if constexpr (Flavor::HasZK) { update_zk_sumcheck_data(zk_sumcheck_data, round_challenge, round_idx); - row_disabling_poly.update_evaluations(round_challenge, round_idx); + row_disabling_polynomial.update_evaluations(round_challenge, round_idx); }; gate_separators.partially_evaluate(round_challenge); round.round_size = round.round_size >> 1; // TODO(#224)(Cody): Maybe partially_evaluate should do this and @@ -240,7 +240,7 @@ template class SumcheckProver { gate_separators, alpha, zk_sumcheck_data, - row_disabling_poly); + row_disabling_polynomial); // Place evaluations of Sumcheck Round Univariate in the transcript transcript->send_to_verifier("Sumcheck:univariate_" + std::to_string(round_idx), round_univariate); FF round_challenge = transcript->template get_challenge("Sumcheck:u_" + std::to_string(round_idx)); @@ -250,7 +250,7 @@ template class SumcheckProver { // Prepare evaluation masking and libra structures for the next round (for ZK Flavors) if constexpr (Flavor::HasZK) { update_zk_sumcheck_data(zk_sumcheck_data, round_challenge, round_idx); - row_disabling_poly.update_evaluations(round_challenge, round_idx); + row_disabling_polynomial.update_evaluations(round_challenge, round_idx); }; gate_separators.partially_evaluate(round_challenge); @@ -599,6 +599,7 @@ template class SumcheckVerifier { for (auto [eval, transcript_eval] : zip_view(purported_evaluations.get_all(), transcript_evaluations)) { eval = transcript_eval; } + // For ZK Flavors: the evaluation of the Row Disabling Polynomial at the sumcheck challenge FF correcting_factor{ 1 }; if constexpr (Flavor::HasZK) { RowDisablingPolynomial row_disabler = RowDisablingPolynomial(); diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp index 09e7c4c4066c..ffbc979548e0 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp @@ -197,21 +197,27 @@ template class SumcheckTests : public ::testing::Test { std::array q_c = { 0, 0, 0, 0 }; std::array q_arith = { 0, 1, 1, 0 }; // Setting all of these to 0 ensures the GrandProductRelation is satisfied + + // For ZK Flavors: add some randomness to ProverPolynomials if constexpr (Flavor::HasZK) { w_l[7] = FF::random_element(); w_r[6] = FF::random_element(); - std::array z_perm = { 0, 0, 0, 0, 0, 0, w_l[7], 0 }; - full_polynomials.z_perm = bb::Polynomial(z_perm); - w_4[6] = FF::random_element(); + auto z_1 = FF::random_element(); + auto z_2 = FF::random_element(); auto r = FF::random_element(); + + std::array z_perm = { 0, 0, 0, 0, 0, 0, z_1, z_2 }; std::array lookup_inverses = { 0, 0, 0, 0, 0, 0, r * r, r }; + + full_polynomials.z_perm = bb::Polynomial(z_perm); full_polynomials.lookup_inverses = bb::Polynomial(lookup_inverses); - std::array ecc_op_wire = { 0, 0, 0, 0, 0, 0, r * r * r, w_4[6] }; + if constexpr (std::is_same::value) { - full_polynomials.ecc_op_wire_1 = bb::Polynomial(ecc_op_wire); + std::array ecc_op_wire = { 0, 0, 0, 0, 0, 0, r * r * r, w_4[6] }; std::array return_data_inverses = { 0, 0, 0, 0, 0, 0, FF(7) * r * r, -r }; + full_polynomials.ecc_op_wire_1 = bb::Polynomial(ecc_op_wire); full_polynomials.return_data_inverses = bb::Polynomial(return_data_inverses); } } @@ -275,7 +281,9 @@ template class SumcheckTests : public ::testing::Test { void test_failure_prover_verifier_flow() { - const size_t multivariate_d(2); + // Since the last 4 rows in ZK Flavors are disabled, we extend an invalid circuit of size 4 to size 8 by padding + // with 0. + const size_t multivariate_d(3); const size_t multivariate_n(1 << multivariate_d); // Construct prover polynomials where each is the zero polynomial. @@ -357,9 +365,8 @@ template class SumcheckTests : public ::testing::Test { auto verifier_output = sumcheck_verifier.verify(relation_parameters, verifier_alpha, verifier_gate_challenges); auto verified = verifier_output.verified.value(); - // In this test, the circuit is of size 4. We disable the rows 1, 2, and 3, while the first is set to 0. - // Therefore, changing the second entry in w_l does not affect the result for ZK fa. - EXPECT_EQ(verified, Flavor::HasZK); + + EXPECT_EQ(verified, false); }; }; diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp index 0ee7fceaff5a..b5d857f9fd1e 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp @@ -142,8 +142,8 @@ template class SumcheckProverRound { const bb::RelationParameters& relation_parameters, const bb::GateSeparatorPolynomial& gate_sparators, const RelationSeparator alpha, - ZKSumcheckData zk_sumcheck_data, - RowDisablingPolynomial row_disabling_poly) // only populated when Flavor HasZK + ZKSumcheckData zk_sumcheck_data, // only populated when Flavor HasZK + RowDisablingPolynomial row_disabling_poly) { PROFILE_THIS_NAME("compute_univariate"); @@ -205,6 +205,12 @@ template class SumcheckProverRound { } } + /*! + * @brief For ZK Flavors: A method disabling the last 4 rows of the ProverPolynomials + * + * @details See description of RowDisablingPolynomial + * + */ template SumcheckRoundUnivariate compute_disabled_contribution( ProverPolynomialsOrPartiallyEvaluatedMultivariates& polynomials, @@ -212,14 +218,12 @@ template class SumcheckProverRound { const bb::GateSeparatorPolynomial& gate_sparators, const RelationSeparator alpha, const size_t round_idx, - const RowDisablingPolynomial row_disabling_poly) // only populated when Flavor HasZK + const RowDisablingPolynomial row_disabling_polynomial) { - PROFILE_THIS_NAME("compute_univariate"); - SumcheckRoundUnivariate result; - SumcheckTupleOfTuplesOfUnivariates univariate_accumulator; - // Construct extended edge containers ExtendedEdges extended_edges; + + // In Round 0, we have to compute the contribution from 2 edges: n - 1 = (1,1,...,1) and n-4 = (0,1,...,1). size_t edge_idx = (round_idx == 0) ? round_size - 4 : round_size - 2; extend_edges(extended_edges, polynomials, edge_idx); @@ -228,7 +232,8 @@ template class SumcheckProverRound { relation_parameters, gate_sparators[(edge_idx >> 1) * gate_sparators.periodicity]); - result = batch_over_relations(univariate_accumulator, alpha, gate_sparators); + SumcheckRoundUnivariate result = + batch_over_relations(univariate_accumulator, alpha, gate_sparators); if (round_idx == 0) { edge_idx += 2; @@ -240,10 +245,15 @@ template class SumcheckProverRound { result += batch_over_relations(univariate_accumulator, alpha, gate_sparators); } + + // In later Rounds, the contribution from the main relation is multiplied by the exntension of the linear + // polynomial (0, u_2*...*u_{d-1}) (in Lagrange basis) if (round_idx > 1) { - auto row_disabler = bb::Univariate({ row_disabling_poly.eval_at_0, row_disabling_poly.eval_at_1 }); - auto row_disabler_extended = row_disabler.template extend_to(); - result *= row_disabler_extended; + auto row_disabling_factor = + bb::Univariate({ row_disabling_polynomial.eval_at_0, row_disabling_polynomial.eval_at_1 }); + auto row_disabling_factor_extended = + row_disabling_factor.template extend_to(); + result *= row_disabling_factor_extended; } return result; @@ -255,12 +265,12 @@ template class SumcheckProverRound { * \f$\alpha\f$, extend to the correct degree, and take the sum multiplying by \f$pow_{\beta}\f$-contributions. * * @details This method receives as input the univariate accumulators computed by \ref - * accumulate_relation_univariates "accumulate relation univariates" after passing through the entire hypercube - * and applying \ref bb::RelationUtils::add_nested_tuples "add_nested_tuples" method to join the threads. The - * accumulators are scaled using the method \ref bb::RelationUtils< Flavor >::scale_univariates "scale - * univariates", extended to the degree \f$ D \f$ and summed with appropriate \f$pow_{\beta}\f$-factors using - * \ref extend_and_batch_univariates "extend and batch univariates method" to return a vector - * \f$(\tilde{S}^i(0), \ldots, \tilde{S}^i(D))\f$. + * accumulate_relation_univariates "accumulate relation univariates" after passing through the entire hypercube and + * applying \ref bb::RelationUtils::add_nested_tuples "add_nested_tuples" method to join the threads. The + * accumulators are scaled using the method \ref bb::RelationUtils< Flavor >::scale_univariates "scale univariates", + * extended to the degree \f$ D \f$ and summed with appropriate \f$pow_{\beta}\f$-factors using \ref + * extend_and_batch_univariates "extend and batch univariates method" to return a vector \f$(\tilde{S}^i(0), \ldots, + * \tilde{S}^i(D))\f$. * * @param challenge Challenge \f$\alpha\f$. * @param gate_sparators Round \f$pow_{\beta}\f$-factor given by \f$ ( (1−u_i) + u_i\cdot \beta_i )\f$. diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp index 557dccf199e8..0221f95fedfa 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp @@ -123,7 +123,8 @@ class TranslatorFlavor { // BATCHED_RELATION_PARTIAL_LENGTH = algebraic degree of sumcheck relation *after* multiplying by the `pow_zeta` // random polynomial e.g. For \sum(x) [A(x) * B(x) + C(x)] * PowZeta(X), relation length = 2 and random relation - // length = 3 + // length = 3. + // The degree has to be further increased because the relation is multiplied by the Row Disabling Polynomial static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 2; static constexpr size_t NUM_RELATIONS = std::tuple_size_v; From 0ea2ddd2b5625137433bfa16b5382a89e25de54a Mon Sep 17 00:00:00 2001 From: iakovenkos <105737703+iakovenkos@users.noreply.github.com> Date: Tue, 26 Nov 2024 11:26:58 +0100 Subject: [PATCH 21/25] -empty line --- barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp index a4a33d1f0ee0..4a4cfe0a6d23 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp @@ -45,7 +45,6 @@ void ECCVMProver::execute_preamble_round() void ECCVMProver::execute_wire_commitments_round() { auto wire_polys = key->polynomials.get_wires(); - auto labels = commitment_labels.get_wires(); for (size_t idx = 0; idx < wire_polys.size(); ++idx) { transcript->send_to_verifier(labels[idx], key->commitment_key->commit(wire_polys[idx])); From d8f5f5950945596f41998e35ac686f3f5f3b032b Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Wed, 4 Dec 2024 13:03:36 +0000 Subject: [PATCH 22/25] clean-up --- .../src/barretenberg/sumcheck/sumcheck.hpp | 2 +- .../barretenberg/sumcheck/sumcheck_round.hpp | 34 ++++++------------- 2 files changed, 11 insertions(+), 25 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp index 9271d6049c87..6bb555ad49e5 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp @@ -197,7 +197,7 @@ template class SumcheckProver { std::vector multivariate_challenge; multivariate_challenge.reserve(multivariate_d); size_t round_idx = 0; - auto row_disabling_polynomial = RowDisablingPolynomial(); + RowDisablingPolynomial row_disabling_polynomial; // In the first round, we compute the first univariate polynomial and populate the book-keeping table of // #partially_evaluated_polynomials, which has \f$ n/2 \f$ rows and \f$ N \f$ columns. When the Flavor has ZK, // compute_univariate also takes into account the zk_sumcheck_data. diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp index b5d857f9fd1e..b9cdb0303f88 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp @@ -189,6 +189,7 @@ template class SumcheckProverRound { Utils::add_nested_tuples(univariate_accumulators, accumulators); } // For ZK Flavors: The evaluations of the round univariates are masked by the evaluations of Libra univariates + // and corrected by subtracting the contribution from the disabled rows if constexpr (Flavor::HasZK) { const auto contribution_from_disabled_rows = compute_disabled_contribution( polynomials, relation_parameters, gate_sparators, alpha, round_idx, row_disabling_poly); @@ -222,39 +223,24 @@ template class SumcheckProverRound { { SumcheckTupleOfTuplesOfUnivariates univariate_accumulator; ExtendedEdges extended_edges; + SumcheckRoundUnivariate result; // In Round 0, we have to compute the contribution from 2 edges: n - 1 = (1,1,...,1) and n-4 = (0,1,...,1). - size_t edge_idx = (round_idx == 0) ? round_size - 4 : round_size - 2; + size_t start_edge_idx = (round_idx == 0) ? round_size - 4 : round_size - 2; - extend_edges(extended_edges, polynomials, edge_idx); - accumulate_relation_univariates(univariate_accumulator, - extended_edges, - relation_parameters, - gate_sparators[(edge_idx >> 1) * gate_sparators.periodicity]); - - SumcheckRoundUnivariate result = - batch_over_relations(univariate_accumulator, alpha, gate_sparators); - - if (round_idx == 0) { - edge_idx += 2; + for (size_t edge_idx = start_edge_idx; edge_idx < round_size; edge_idx += 2) { + info(edge_idx); extend_edges(extended_edges, polynomials, edge_idx); accumulate_relation_univariates(univariate_accumulator, extended_edges, relation_parameters, gate_sparators[(edge_idx >> 1) * gate_sparators.periodicity]); - - result += batch_over_relations(univariate_accumulator, alpha, gate_sparators); - } - - // In later Rounds, the contribution from the main relation is multiplied by the exntension of the linear - // polynomial (0, u_2*...*u_{d-1}) (in Lagrange basis) - if (round_idx > 1) { - auto row_disabling_factor = - bb::Univariate({ row_disabling_polynomial.eval_at_0, row_disabling_polynomial.eval_at_1 }); - auto row_disabling_factor_extended = - row_disabling_factor.template extend_to(); - result *= row_disabling_factor_extended; } + result = batch_over_relations(univariate_accumulator, alpha, gate_sparators); + auto row_disabling_factor = + bb::Univariate({ row_disabling_polynomial.eval_at_0, row_disabling_polynomial.eval_at_1 }); + auto row_disabling_factor_extended = row_disabling_factor.template extend_to(); + result *= row_disabling_factor_extended; return result; } From 1dfbd6cb2258631c87854629d8728fdf195adb1f Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Wed, 4 Dec 2024 13:57:24 +0000 Subject: [PATCH 23/25] removed print --- barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp index b9cdb0303f88..3cdfe004070c 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp @@ -229,7 +229,6 @@ template class SumcheckProverRound { size_t start_edge_idx = (round_idx == 0) ? round_size - 4 : round_size - 2; for (size_t edge_idx = start_edge_idx; edge_idx < round_size; edge_idx += 2) { - info(edge_idx); extend_edges(extended_edges, polynomials, edge_idx); accumulate_relation_univariates(univariate_accumulator, extended_edges, From f2f4da09d4ace7b4adf9a33621c3f3f6c972a05e Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Mon, 16 Dec 2024 15:30:59 +0000 Subject: [PATCH 24/25] resolved comments --- .../polynomials/row_disabling_polynomial.hpp | 19 +++++++++++++++++-- .../barretenberg/sumcheck/sumcheck_round.hpp | 5 +++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp index 9133e9303a0a..e5c2abe7f67e 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/row_disabling_polynomial.hpp @@ -138,7 +138,16 @@ template struct RowDisablingPolynomial { FF eval_at_1{ 1 }; RowDisablingPolynomial() = default; - + /** + * @brief Compute the evaluations of L^{(i)} at 0 and 1. + * + * @details In every round, the contribution from the Honk relation computed at + * disabled rows has to be mutiplied by \f$ L^{(i)} \f$, which is a linear combination of Lagrange polynomials + * defined above. + * + * @param round_challenge Sumcheck round challenge + * @param round_idx Sumcheck round index + */ void update_evaluations(FF round_challenge, size_t round_idx) { if (round_idx == 1) { @@ -148,7 +157,13 @@ template struct RowDisablingPolynomial { eval_at_1 *= round_challenge; } } - + /** + * @brief Compute the evaluation of \f$ 1 - L \f$ at the sumcheck challenge + * + * @param multivariate_challenge + * @param log_circuit_size + * @return FF + */ static FF evaluate_at_challenge(std::vector multivariate_challenge, const size_t log_circuit_size) { FF evaluation_at_multivariate_challenge{ 1 }; diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp index 3cdfe004070c..95515bf0d631 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp @@ -236,9 +236,10 @@ template class SumcheckProverRound { gate_sparators[(edge_idx >> 1) * gate_sparators.periodicity]); } result = batch_over_relations(univariate_accumulator, alpha, gate_sparators); - auto row_disabling_factor = + bb::Univariate row_disabling_factor = bb::Univariate({ row_disabling_polynomial.eval_at_0, row_disabling_polynomial.eval_at_1 }); - auto row_disabling_factor_extended = row_disabling_factor.template extend_to(); + SumcheckRoundUnivariate row_disabling_factor_extended = + row_disabling_factor.template extend_to(); result *= row_disabling_factor_extended; return result; From b290c54cd94bf83de7ea9574c170ccec4460c734 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Mon, 16 Dec 2024 16:33:53 +0000 Subject: [PATCH 25/25] removed redundant print --- .../cpp/src/barretenberg/ultra_honk/mega_transcript.test.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/mega_transcript.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/mega_transcript.test.cpp index 2902057f62ab..31f345c83d15 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/mega_transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/mega_transcript.test.cpp @@ -240,7 +240,6 @@ TYPED_TEST(MegaTranscriptTests, VerifierManifestConsistency) // Check consistency between the manifests generated by the prover and verifier auto prover_manifest = prover.transcript->get_manifest(); - prover_manifest.print(); auto verifier_manifest = verifier.transcript->get_manifest();