diff --git a/barretenberg/cpp/src/aztec/honk/sumcheck/polynomials/pow.hpp b/barretenberg/cpp/src/aztec/honk/sumcheck/polynomials/pow.hpp index ac82005e03cc..8cd92ac17ef5 100644 --- a/barretenberg/cpp/src/aztec/honk/sumcheck/polynomials/pow.hpp +++ b/barretenberg/cpp/src/aztec/honk/sumcheck/polynomials/pow.hpp @@ -18,7 +18,7 @@ namespace honk::sumcheck { * ζ^{i} = ζ^{ ∑_{0≤l #include #include - using namespace honk::sumcheck; +/** + * We want to test if all three relations (namely, ArithmeticRelation, GrandProductComputationRelation, + * GrandProductInitializationRelation) provide correct contributions by manually computing their + * contributions with deterministic and random inputs. The relations are supposed to work with + * univariates (edges) of degree one (length 2) and spit out polynomials of corresponding degrees. We have + * MAX_RELATION_LENGTH = 5, meaning the output of a relation can atmost be a degree 5 polynomial. Hence, + * we use a method compute_mock_extended_edges() which starts with degree one input polynomial (two evaluation + points), + * extends them (using barycentric formula) to six evaluation points, and stores them to an array of polynomials. + */ +static const size_t input_univariate_length = 2; +static constexpr size_t FULL_RELATION_LENGTH = 5; +static const size_t NUM_POLYNOMIALS = bonk::StandardArithmetization::NUM_POLYNOMIALS; namespace honk_relation_tests { @@ -18,42 +31,40 @@ template class SumcheckRelation : public testing::Test { public: template using Univariate = Univariate; template using UnivariateView = UnivariateView; - static constexpr size_t FULL_RELATION_LENGH = 5; - static const size_t NUM_POLYNOMIALS = bonk::StandardArithmetization::NUM_POLYNOMIALS; using POLYNOMIAL = bonk::StandardArithmetization::POLYNOMIAL; - // TODO(luke): may want to make this more flexible/genericzs - // TODO(Adrian): Accept FULL_RELATION_LENGH as a template parameter for this function only, so that the test can + // TODO(Adrian): Accept FULL_RELATION_LENGTH as a template parameter for this function only, so that the test can // decide to which degree the polynomials must be extended. Possible accept an existing list of "edges" and extend // them to the degree. - static std::array, NUM_POLYNOMIALS> compute_mock_extended_edges() + static std::array, NUM_POLYNOMIALS> compute_mock_extended_edges( + std::array, NUM_POLYNOMIALS>& input_univariates) { - // TODO(Cody): build from Univariate<2>'s? - // evaluation form, i.e. w_l(0) = 1, w_l(1) = 2,.. The poly is x+1. - auto w_l = Univariate<5>({ 1, 2, 3, 4, 5 }); - auto w_r = Univariate<5>({ 1, 2, 3, 4, 5 }); - auto w_o = Univariate<5>({ 1, 2, 3, 4, 5 }); - auto z_perm = Univariate<5>({ 1, 2, 3, 4, 5 }); - // Note: z_perm and z_perm_shift can be any linear poly for the sake of the tests but should not be be equal to - // each other In order to avoid a trivial computation in the case of the grand_product_computation_relation. - // Values here were chosen so that output univariates in tests are small positive numbers. - auto z_perm_shift = Univariate<5>({ 0, 1, 2, 3, 4 }); // this is not real shifted data - auto q_m = Univariate<5>({ 1, 2, 3, 4, 5 }); - auto q_l = Univariate<5>({ 1, 2, 3, 4, 5 }); - auto q_r = Univariate<5>({ 1, 2, 3, 4, 5 }); - auto q_o = Univariate<5>({ 1, 2, 3, 4, 5 }); - auto q_c = Univariate<5>({ 1, 2, 3, 4, 5 }); - auto sigma_1 = Univariate<5>({ 1, 2, 3, 4, 5 }); - auto sigma_2 = Univariate<5>({ 1, 2, 3, 4, 5 }); - auto sigma_3 = Univariate<5>({ 1, 2, 3, 4, 5 }); - auto id_1 = Univariate<5>({ 1, 2, 3, 4, 5 }); - auto id_2 = Univariate<5>({ 1, 2, 3, 4, 5 }); - auto id_3 = Univariate<5>({ 1, 2, 3, 4, 5 }); - auto lagrange_first = Univariate<5>({ 1, 2, 3, 4, 5 }); - auto lagrange_last = Univariate<5>({ 1, 2, 3, 4, 5 }); - + BarycentricData barycentric_2_to_max = + BarycentricData(); + std::array, NUM_POLYNOMIALS> extended_univariates; + for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { + extended_univariates[i] = barycentric_2_to_max.extend(input_univariates[i]); + } + auto w_l = Univariate(extended_univariates[0]); + auto w_r = Univariate(extended_univariates[1]); + auto w_o = Univariate(extended_univariates[2]); + auto z_perm = Univariate(extended_univariates[3]); + auto z_perm_shift = Univariate(extended_univariates[4]); // this is not real shifted data + auto q_m = Univariate(extended_univariates[5]); + auto q_l = Univariate(extended_univariates[6]); + auto q_r = Univariate(extended_univariates[7]); + auto q_o = Univariate(extended_univariates[8]); + auto q_c = Univariate(extended_univariates[9]); + auto sigma_1 = Univariate(extended_univariates[10]); + auto sigma_2 = Univariate(extended_univariates[11]); + auto sigma_3 = Univariate(extended_univariates[12]); + auto id_1 = Univariate(extended_univariates[13]); + auto id_2 = Univariate(extended_univariates[14]); + auto id_3 = Univariate(extended_univariates[15]); + auto lagrange_first = Univariate(extended_univariates[16]); + auto lagrange_last = Univariate(extended_univariates[17]); // Construct extended edges array in order determined by enum - std::array, bonk::StandardArithmetization::NUM_POLYNOMIALS> extended_edges; + std::array, NUM_POLYNOMIALS> extended_edges; extended_edges[POLYNOMIAL::W_L] = w_l; extended_edges[POLYNOMIAL::W_R] = w_r; extended_edges[POLYNOMIAL::W_O] = w_o; @@ -128,15 +139,16 @@ template class SumcheckRelation : public testing::Test { * @param extended_edges * @param relation_parameters */ - static void validate_evaluations(const Univariate& expected_evals, - const auto relation, - const std::array, NUM_POLYNOMIALS>& extended_edges, - const RelationParameters& relation_parameters) + static void validate_evaluations( + const Univariate& expected_evals, + const auto relation, + const std::array, NUM_POLYNOMIALS>& extended_edges, + const RelationParameters& relation_parameters) { // Compute the expression index-by-index - Univariate expected_evals_index{ 0 }; - for (size_t i = 0; i < FULL_RELATION_LENGH; ++i) { + Univariate expected_evals_index{ 0 }; + for (size_t i = 0; i < FULL_RELATION_LENGTH; ++i) { // Get an array of the same size as `extended_edges` with only the i-th element of each extended edge. std::array evals_i = transposed_univariate_array_at(extended_edges, i); // Evaluate the relation @@ -147,6 +159,7 @@ template class SumcheckRelation : public testing::Test { // Compute the expression using the class, that converts the extended edges to UnivariateView auto expected_evals_view = Univariate(0); + // The scaling factor is essentially 1 since we are working with degree 1 univariates relation.add_edge_contribution(expected_evals_view, extended_edges, relation_parameters, 1); // Tiny hack to reduce `expected_evals` to be of size `relation.RELATION_LENGTH` @@ -155,7 +168,6 @@ template class SumcheckRelation : public testing::Test { EXPECT_EQ(expected_evals_restricted, expected_evals_view); }; }; - using FieldTypes = testing::Types; TYPED_TEST_SUITE(SumcheckRelation, FieldTypes); @@ -165,92 +177,141 @@ TYPED_TEST(SumcheckRelation, ArithmeticRelation) { SUMCHECK_RELATION_TYPE_ALIASES using MULTIVARIATE = bonk::StandardArithmetization::POLYNOMIAL; - - const auto extended_edges = TestFixture::compute_mock_extended_edges(); const auto relation_parameters = TestFixture::compute_mock_relation_parameters(); - - auto relation = ArithmeticRelation(); - // Manually compute the expected edge contribution - const auto& w_l = extended_edges[MULTIVARIATE::W_L]; - const auto& w_r = extended_edges[MULTIVARIATE::W_R]; - const auto& w_o = extended_edges[MULTIVARIATE::W_O]; - const auto& q_m = extended_edges[MULTIVARIATE::Q_M]; - const auto& q_l = extended_edges[MULTIVARIATE::Q_L]; - const auto& q_r = extended_edges[MULTIVARIATE::Q_R]; - const auto& q_o = extended_edges[MULTIVARIATE::Q_O]; - const auto& q_c = extended_edges[MULTIVARIATE::Q_C]; - - // We first compute the evaluations using UnivariateViews, with the provided hard-coded formula. - // Ensure that expression changes are detected. - // expected_evals, length 4, extends to { { 5, 22, 57, 116, 205} }; - auto expected_evals = (q_m * w_r * w_l) + (q_r * w_r) + (q_l * w_l) + (q_o * w_o) + (q_c); - this->validate_evaluations(expected_evals, relation, extended_edges, relation_parameters); + auto run_test = [&relation_parameters](bool is_random_input) { + std::array, NUM_POLYNOMIALS> extended_edges; + std::array, NUM_POLYNOMIALS> input_polynomials; + if (!is_random_input) { + // evaluation form, i.e. input_univariate(0) = 1, input_univariate(1) = 2,.. The polynomial is x+1. + for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { + input_polynomials[i] = Univariate({ 1, 2 }); + } + extended_edges = TestFixture::compute_mock_extended_edges(input_polynomials); + } else { + // input_univariates are random polynomials of degree one + for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { + input_polynomials[i] = + Univariate({ FF::random_element(), FF::random_element() }); + } + extended_edges = TestFixture::compute_mock_extended_edges(input_polynomials); + }; + auto relation = ArithmeticRelation(); + // Manually compute the expected edge contribution + const auto& w_l = extended_edges[MULTIVARIATE::W_L]; + const auto& w_r = extended_edges[MULTIVARIATE::W_R]; + const auto& w_o = extended_edges[MULTIVARIATE::W_O]; + const auto& q_m = extended_edges[MULTIVARIATE::Q_M]; + const auto& q_l = extended_edges[MULTIVARIATE::Q_L]; + const auto& q_r = extended_edges[MULTIVARIATE::Q_R]; + const auto& q_o = extended_edges[MULTIVARIATE::Q_O]; + const auto& q_c = extended_edges[MULTIVARIATE::Q_C]; + + // We first compute the evaluations using UnivariateViews, with the provided hard-coded formula. + // Ensure that expression changes are detected. + // expected_evals, length 4, extends to { { 5, 22, 57, 116, 205} } for input polynomial {1, 2} + auto expected_evals = (q_m * w_r * w_l) + (q_r * w_r) + (q_l * w_l) + (q_o * w_o) + (q_c); + TestFixture::validate_evaluations(expected_evals, relation, extended_edges, relation_parameters); + }; + run_test(/* is_random_input=*/true); + run_test(/* is_random_input=*/false); }; TYPED_TEST(SumcheckRelation, GrandProductComputationRelation) { SUMCHECK_RELATION_TYPE_ALIASES using MULTIVARIATE = bonk::StandardArithmetization::POLYNOMIAL; - - const auto extended_edges = TestFixture::compute_mock_extended_edges(); const auto relation_parameters = TestFixture::compute_mock_relation_parameters(); - - auto relation = GrandProductComputationRelation(); - - const auto& beta = relation_parameters.beta; - const auto& gamma = relation_parameters.gamma; - const auto& public_input_delta = relation_parameters.public_input_delta; - // TODO(luke): Write a test that illustrates the following? - // Note: the below z_perm_shift = X^2 will fail because it results in a relation of degree 2*1*1*1 = 5 which - // cannot be represented by 5 points. Therefore when we do the calculation then barycentrically extend, we are - // effectively exprapolating a 4th degree polynomial instead of the correct 5th degree poly - // auto z_perm_shift = Univariate({ 1, 4, 9, 16, 25 }); // X^2 - - // Manually compute the expected edge contribution - const auto& w_1 = extended_edges[MULTIVARIATE::W_L]; - const auto& w_2 = extended_edges[MULTIVARIATE::W_R]; - const auto& w_3 = extended_edges[MULTIVARIATE::W_O]; - const auto& sigma_1 = extended_edges[MULTIVARIATE::SIGMA_1]; - const auto& sigma_2 = extended_edges[MULTIVARIATE::SIGMA_2]; - const auto& sigma_3 = extended_edges[MULTIVARIATE::SIGMA_3]; - const auto& id_1 = extended_edges[MULTIVARIATE::ID_1]; - const auto& id_2 = extended_edges[MULTIVARIATE::ID_1]; - const auto& id_3 = extended_edges[MULTIVARIATE::ID_1]; - const auto& z_perm = extended_edges[MULTIVARIATE::Z_PERM]; - const auto& z_perm_shift = extended_edges[MULTIVARIATE::Z_PERM_SHIFT]; - const auto& lagrange_first = extended_edges[MULTIVARIATE::LAGRANGE_FIRST]; - const auto& lagrange_last = extended_edges[MULTIVARIATE::LAGRANGE_LAST]; - - // We first compute the evaluations using UnivariateViews, with the provided hard-coded formula. - // Ensure that expression changes are detected. - // expected_evals in the below step { { 27, 250, 1029, 2916, 6655 } } - { { 27, 125, 343, 729, 1331 } } - auto expected_evals = (z_perm + lagrange_first) * (w_1 + id_1 * beta + gamma) * (w_2 + id_2 * beta + gamma) * - (w_3 + id_3 * beta + gamma) - - (z_perm_shift + lagrange_last * public_input_delta) * (w_1 + sigma_1 * beta + gamma) * - (w_2 + sigma_2 * beta + gamma) * (w_3 + sigma_3 * beta + gamma); - - this->validate_evaluations(expected_evals, relation, extended_edges, relation_parameters); + auto run_test = [&relation_parameters](bool is_random_input) { + std::array, NUM_POLYNOMIALS> extended_edges; + std::array, NUM_POLYNOMIALS> input_polynomials; + if (!is_random_input) { + // evaluation form, i.e. input_univariate(0) = 1, input_univariate(1) = 2,.. The polynomial is x+1. + for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { + input_polynomials[i] = Univariate({ 1, 2 }); + } + extended_edges = TestFixture::compute_mock_extended_edges(input_polynomials); + } else { + // input_univariates are random polynomials of degree one + for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { + input_polynomials[i] = + Univariate({ FF::random_element(), FF::random_element() }); + } + extended_edges = TestFixture::compute_mock_extended_edges(input_polynomials); + }; + auto relation = GrandProductComputationRelation(); + + const auto& beta = relation_parameters.beta; + const auto& gamma = relation_parameters.gamma; + const auto& public_input_delta = relation_parameters.public_input_delta; + // TODO(luke): Write a test that illustrates the following? + // Note: the below z_perm_shift = X^2 will fail because it results in a relation of degree 2*1*1*1 = 5 which + // cannot be represented by 5 points. Therefore when we do the calculation then barycentrically extend, we are + // effectively exprapolating a 4th degree polynomial instead of the correct 5th degree poly + // auto z_perm_shift = Univariate({ 1, 4, 9, 16, 25 }); // X^2 + + // Manually compute the expected edge contribution + const auto& w_1 = extended_edges[MULTIVARIATE::W_L]; + const auto& w_2 = extended_edges[MULTIVARIATE::W_R]; + const auto& w_3 = extended_edges[MULTIVARIATE::W_O]; + const auto& sigma_1 = extended_edges[MULTIVARIATE::SIGMA_1]; + const auto& sigma_2 = extended_edges[MULTIVARIATE::SIGMA_2]; + const auto& sigma_3 = extended_edges[MULTIVARIATE::SIGMA_3]; + const auto& id_1 = extended_edges[MULTIVARIATE::ID_1]; + const auto& id_2 = extended_edges[MULTIVARIATE::ID_2]; + const auto& id_3 = extended_edges[MULTIVARIATE::ID_3]; + const auto& z_perm = extended_edges[MULTIVARIATE::Z_PERM]; + const auto& z_perm_shift = extended_edges[MULTIVARIATE::Z_PERM_SHIFT]; + const auto& lagrange_first = extended_edges[MULTIVARIATE::LAGRANGE_FIRST]; + const auto& lagrange_last = extended_edges[MULTIVARIATE::LAGRANGE_LAST]; + + // We first compute the evaluations using UnivariateViews, with the provided hard-coded formula. + // Ensure that expression changes are detected. + // expected_evals in the below step { { 27, 250, 1029, 2916, 6655 } } - { { 27, 125, 343, 729, 1331 } } + auto expected_evals = (z_perm + lagrange_first) * (w_1 + id_1 * beta + gamma) * (w_2 + id_2 * beta + gamma) * + (w_3 + id_3 * beta + gamma) - + (z_perm_shift + lagrange_last * public_input_delta) * (w_1 + sigma_1 * beta + gamma) * + (w_2 + sigma_2 * beta + gamma) * (w_3 + sigma_3 * beta + gamma); + + TestFixture::validate_evaluations(expected_evals, relation, extended_edges, relation_parameters); + }; + run_test(/* is_random_input=*/true); + run_test(/* is_random_input=*/false); }; TYPED_TEST(SumcheckRelation, GrandProductInitializationRelation) { SUMCHECK_RELATION_TYPE_ALIASES using MULTIVARIATE = bonk::StandardArithmetization::POLYNOMIAL; - - const auto extended_edges = TestFixture::compute_mock_extended_edges(); const auto relation_parameters = TestFixture::compute_mock_relation_parameters(); - auto relation = GrandProductInitializationRelation(); - - // Manually compute the expected edge contribution - - const auto& z_perm_shift = extended_edges[MULTIVARIATE::Z_PERM_SHIFT]; - const auto& lagrange_last = extended_edges[MULTIVARIATE::LAGRANGE_LAST]; - // We first compute the evaluations using UnivariateViews, with the provided hard-coded formula. - // Ensure that expression changes are detected. - // expected_evals, lenght 3 (coeff form = x^2 + x), extends to { { 0, 2, 6, 12, 20 } } - auto expected_evals = z_perm_shift * lagrange_last; - - this->validate_evaluations(expected_evals, relation, extended_edges, relation_parameters); + auto run_test = [&relation_parameters](bool is_random_input) { + std::array, NUM_POLYNOMIALS> extended_edges; + std::array, NUM_POLYNOMIALS> input_polynomials; + if (!is_random_input) { + // evaluation form, i.e. input_univariate(0) = 1, input_univariate(1) = 2,.. The polynomial is x+1. + for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { + input_polynomials[i] = Univariate({ 1, 2 }); + } + extended_edges = TestFixture::compute_mock_extended_edges(input_polynomials); + } else { + // input_univariates are random polynomials of degree one + for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { + input_polynomials[i] = + Univariate({ FF::random_element(), FF::random_element() }); + } + extended_edges = TestFixture::compute_mock_extended_edges(input_polynomials); + }; + auto relation = GrandProductInitializationRelation(); + const auto& z_perm_shift = extended_edges[MULTIVARIATE::Z_PERM_SHIFT]; + const auto& lagrange_last = extended_edges[MULTIVARIATE::LAGRANGE_LAST]; + // We first compute the evaluations using UnivariateViews, with the provided hard-coded formula. + // Ensure that expression changes are detected. + // expected_evals, lenght 3 (coeff form = x^2 + x), extends to { { 0, 2, 6, 12, 20 } } + auto expected_evals = z_perm_shift * lagrange_last; + + TestFixture::validate_evaluations(expected_evals, relation, extended_edges, relation_parameters); + }; + run_test(/* is_random_input=*/true); + run_test(/* is_random_input=*/false); }; } // namespace honk_relation_tests \ No newline at end of file diff --git a/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck.test.cpp b/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck.test.cpp index 9e224d9ac635..d15e9d9f3848 100644 --- a/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck.test.cpp +++ b/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck.test.cpp @@ -20,14 +20,13 @@ using namespace honk; using namespace honk::sumcheck; - -namespace test_sumcheck_round { - using Transcript = transcript::StandardTranscript; using FF = barretenberg::fr; const size_t NUM_POLYNOMIALS = bonk::StandardArithmetization::NUM_POLYNOMIALS; using POLYNOMIAL = bonk::StandardArithmetization::POLYNOMIAL; +namespace test_sumcheck_round { + /** * @brief Place polynomials into full_polynomials in the order determined by the StandardArithmetization enum. * @@ -136,29 +135,47 @@ TEST(Sumcheck, PolynomialNormalization) // Todo(Cody): We should not use real constants like this in the tests, at least not in so many of them. const size_t multivariate_d(3); const size_t multivariate_n(1 << multivariate_d); - ; const size_t num_public_inputs(1); - // clang-format off - std::array w_l = { 0, 1, 2, 3, 4, 5, 6, 7 }; - std::array w_r = { 0, 0, 0, 0, 0, 0, 0, 0 }; - std::array w_o = { 0, 0, 0, 0, 0, 0, 0, 0 }; - std::array z_perm = { 0, 0, 0, 0, 0, 0, 0, 0 }; - std::array z_perm_shift = { 0, 0, 0, 0, 0, 0, 0, 0 }; - std::array q_m = { 0, 0, 0, 0, 0, 0, 0, 0 }; - std::array q_l = { 0, 0, 0, 0, 0, 0, 0, 0 }; - std::array q_r = { 0, 0, 0, 0, 0, 0, 0, 0 }; - std::array q_o = { 0, 0, 0, 0, 0, 0, 0, 0 }; - std::array q_c = { 0, 0, 0, 0, 0, 0, 0, 0 }; - std::array sigma_1 = { 0, 0, 0, 0, 0, 0, 0, 0 }; - std::array sigma_2 = { 0, 0, 0, 0, 0, 0, 0, 0 }; - std::array sigma_3 = { 0, 0, 0, 0, 0, 0, 0, 0 }; - std::array id_1 = { 0, 0, 0, 0, 0, 0, 0, 0 }; - std::array id_2 = { 0, 0, 0, 0, 0, 0, 0, 0 }; - std::array id_3 = { 0, 0, 0, 0, 0, 0, 0, 0 }; - std::array lagrange_first = { 0, 0, 0, 0, 0, 0, 0, 0 }; - std::array lagrange_last = { 0, 0, 0, 0, 0, 0, 0, 0 }; - // clang-format on + std::array w_l; + std::array w_r; + std::array w_o; + std::array z_perm; + std::array z_perm_shift; + std::array q_m; + std::array q_l; + std::array q_r; + std::array q_o; + std::array q_c; + std::array sigma_1; + std::array sigma_2; + std::array sigma_3; + std::array id_1; + std::array id_2; + std::array id_3; + std::array lagrange_first; + std::array lagrange_last; + std::array pow_zeta; + for (size_t i = 0; i < multivariate_n; i++) { + w_l[i] = FF::random_element(); + w_r[i] = FF::random_element(); + w_o[i] = FF::random_element(); + z_perm[i] = FF::random_element(); + z_perm_shift[i] = FF::random_element(); + q_m[i] = FF::random_element(); + q_l[i] = FF::random_element(); + q_r[i] = FF::random_element(); + q_o[i] = FF::random_element(); + q_c[i] = FF::random_element(); + sigma_1[i] = FF::random_element(); + sigma_2[i] = FF::random_element(); + sigma_3[i] = FF::random_element(); + id_1[i] = FF::random_element(); + id_2[i] = FF::random_element(); + id_3[i] = FF::random_element(); + lagrange_first[i] = FF::random_element(); + lagrange_last[i] = FF::random_element(); + } auto full_polynomials = construct_full_polynomials(w_l, w_r, @@ -198,7 +215,7 @@ TEST(Sumcheck, PolynomialNormalization) challenges u_i. What does this mean? Here we show that if the multivariate is F(X0, X1, X2) defined as above, then what we get is F(u0, u1, u2) and not, - say F(u3,u2,u1). This is in accordance with Adrian's thesis (cf page 9). + say F(u2, u1, u0). This is in accordance with Adrian's thesis (cf page 9). */ // Get the values of the Lagrange basis polys L_i defined @@ -214,87 +231,99 @@ TEST(Sumcheck, PolynomialNormalization) FF l_6 = (one - u_0) * ( u_1) * ( u_2); FF l_7 = ( u_0) * ( u_1) * ( u_2); // clang-format on - - FF hand_computed_value = l_0 * w_l[0] + l_1 * w_l[1] + l_2 * w_l[2] + l_3 * w_l[3] + l_4 * w_l[4] + l_5 * w_l[5] + - l_6 * w_l[6] + l_7 * w_l[7]; - - EXPECT_EQ(hand_computed_value, sumcheck.folded_polynomials[POLYNOMIAL::W_L][0]); + FF hand_computed_value; + for (size_t i = 0; i < NUM_POLYNOMIALS; i++) { + // full_polynomials[0][0] = w_l[0], full_polynomials[1][1] = w_r[1], and so on. + hand_computed_value = l_0 * full_polynomials[i][0] + l_1 * full_polynomials[i][1] + + l_2 * full_polynomials[i][2] + l_3 * full_polynomials[i][3] + + l_4 * full_polynomials[i][4] + l_5 * full_polynomials[i][5] + + l_6 * full_polynomials[i][6] + l_7 * full_polynomials[i][7]; + EXPECT_EQ(hand_computed_value, sumcheck.folded_polynomials[i][0]); + } } TEST(Sumcheck, Prover) { - const size_t num_polys(bonk::StandardArithmetization::NUM_POLYNOMIALS); - const size_t multivariate_d(2); - const size_t multivariate_n(1 << multivariate_d); - const size_t num_public_inputs(1); - - // const size_t max_relation_length = 4; - - // clang-format off - std::array w_l = { 1, 2, 0, 0}; - std::array w_r = { 1, 2, 0, 0}; - std::array w_o = { 1, 2, 0, 0}; - std::array z_perm = { 1, 2, 0, 0}; - std::array z_perm_shift = { 0, 2, 0, 0}; - std::array q_m = { 1, 2, 0, 0}; - std::array q_l = { 1, 2, 0, 0}; - std::array q_r = { 1, 2, 0, 0}; - std::array q_o = { 1, 2, 0, 0}; - std::array q_c = { 1, 2, 0, 0}; - std::array sigma_1 = { 1, 2, 0, 0}; - std::array sigma_2 = { 1, 2, 0, 0}; - std::array sigma_3 = { 1, 2, 0, 0}; - std::array id_1 = { 1, 2, 0, 0}; - std::array id_2 = { 1, 2, 0, 0}; - std::array id_3 = { 1, 2, 0, 0}; - std::array lagrange_first = { 1, 2, 0, 0}; - std::array lagrange_last = { 1, 2, 0, 0}; - // clang-format on - - auto full_polynomials = construct_full_polynomials(w_l, - w_r, - w_o, - z_perm, - z_perm_shift, - q_m, - q_l, - q_r, - q_o, - q_c, - sigma_1, - sigma_2, - sigma_3, - id_1, - id_2, - id_3, - lagrange_first, - lagrange_last); - - auto transcript = produce_mocked_transcript(multivariate_d, num_public_inputs); - - auto sumcheck = Sumcheck(multivariate_n, transcript); - - sumcheck.execute_prover(full_polynomials); - - FF u_0 = transcript.get_challenge_field_element("u_0"); - FF u_1 = transcript.get_challenge_field_element("u_1"); - std::vector expected_values; - for (auto& polynomial : full_polynomials) { - // using knowledge of inputs here to derive the evaluation - FF expected = polynomial[0] * (FF(1) - u_0) + polynomial[1] * u_0; - expected *= (FF(1) - u_1); - expected_values.emplace_back(expected); - } + auto run_test = [](bool is_random_input) { + const size_t multivariate_d(2); + const size_t multivariate_n(1 << multivariate_d); + const size_t num_public_inputs(1); + std::array, NUM_POLYNOMIALS> input_polynomials; + if (is_random_input) { + for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { + input_polynomials[i] = { + FF::random_element(), FF::random_element(), FF::random_element(), FF::random_element() + }; + } + } else { + for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { + input_polynomials[i] = { 1, 2, 0, 0 }; + } + }; + std::array w_l = input_polynomials[0]; + std::array w_r = input_polynomials[1]; + std::array w_o = input_polynomials[2]; + std::array z_perm = input_polynomials[3]; + std::array z_perm_shift = input_polynomials[4]; + std::array q_m = input_polynomials[5]; + std::array q_l = input_polynomials[6]; + std::array q_r = input_polynomials[7]; + std::array q_o = input_polynomials[8]; + std::array q_c = input_polynomials[9]; + std::array sigma_1 = input_polynomials[10]; + std::array sigma_2 = input_polynomials[11]; + std::array sigma_3 = input_polynomials[12]; + std::array id_1 = input_polynomials[13]; + std::array id_2 = input_polynomials[14]; + std::array id_3 = input_polynomials[15]; + std::array lagrange_first = input_polynomials[16]; + std::array lagrange_last = input_polynomials[17]; + auto full_polynomials = construct_full_polynomials(w_l, + w_r, + w_o, + z_perm, + z_perm_shift, + q_m, + q_l, + q_r, + q_o, + q_c, + sigma_1, + sigma_2, + sigma_3, + id_1, + id_2, + id_3, + lagrange_first, + lagrange_last); - // pull the sumcheck-produced multivariate evals out of the transcript - auto sumcheck_evaluations = transcript.get_field_element_vector("multivariate_evaluations"); - for (size_t poly_idx = 0; poly_idx < num_polys; poly_idx++) { - EXPECT_EQ(sumcheck_evaluations[poly_idx], expected_values[poly_idx]); - } + auto transcript = produce_mocked_transcript(multivariate_d, num_public_inputs); + auto sumcheck = Sumcheck(multivariate_n, transcript); + + sumcheck.execute_prover(full_polynomials); + FF u_0 = transcript.get_challenge_field_element("u_0"); + FF u_1 = transcript.get_challenge_field_element("u_1"); + std::vector expected_values; + for (auto& polynomial : full_polynomials) { + // using knowledge of inputs here to derive the evaluation + FF expected_lo = polynomial[0] * (FF(1) - u_0) + polynomial[1] * u_0; + expected_lo *= (FF(1) - u_1); + FF expected_hi = polynomial[2] * (FF(1) - u_0) + polynomial[3] * u_0; + expected_hi *= u_1; + expected_values.emplace_back(expected_lo + expected_hi); + } + // pull the sumcheck-produced multivariate evals out of the transcript + auto sumcheck_evaluations = transcript.get_field_element_vector("multivariate_evaluations"); + for (size_t poly_idx = 0; poly_idx < NUM_POLYNOMIALS; poly_idx++) { + EXPECT_EQ(sumcheck_evaluations[poly_idx], expected_values[poly_idx]); + } + }; + run_test(/* is_random_input=*/false); + run_test(/* is_random_input=*/true); } // TODO(Cody): write standalone test of the verifier. @@ -378,8 +407,8 @@ TEST(Sumcheck, ProverAndVerifierLonger) } std::array w_r = { 0, 1, 2, 0 }; std::array w_o = { 0, 2, 4, 0 }; - std::array z_perm = { 0, 0, 0, 0 }; - std::array z_perm_shift = { 0, 0, 0, 0 }; + std::array z_perm = { 0, 0, 0, 0 }; + std::array z_perm_shift = { 0, 0, 0, 0 }; std::array q_m = { 0, 0, 1, 0 }; std::array q_l = { 1, 1, 0, 0 }; std::array q_r = { 0, 1, 0, 0 }; diff --git a/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck_round.test.cpp b/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck_round.test.cpp index 8945c531c453..aa796564f616 100644 --- a/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck_round.test.cpp +++ b/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck_round.test.cpp @@ -11,41 +11,48 @@ #include #include +/** + * We want to test if the univariate (S_l in the thesis) computed by the prover in a particular round is correct. We + * also want to verify given the purported evaluations of all the relevant polynomials, the verifer can correctly verify + * the purported evaluation of S_l. For the prover, we use a couple of methods to compute the univariate by the sumcheck + * method `compute_univariate` and by step by step manual computation respectively. For the verifier, we follow a + * similar approach. + */ using namespace honk; using namespace honk::sumcheck; +const size_t max_relation_length = 5; +const size_t input_polynomial_length = 2; +using FF = barretenberg::fr; +const size_t NUM_POLYNOMIALS = bonk::StandardArithmetization::NUM_POLYNOMIALS; +using POLYNOMIAL = bonk::StandardArithmetization::POLYNOMIAL; namespace test_sumcheck_round { - -TEST(SumcheckRound, ComputeUnivariateProver) +/** + * @brief Place polynomials into full_polynomials in the order determined by the StandardArithmetization enum. + * + */ +template +std::array, NUM_POLYNOMIALS> construct_full_polynomials(std::array& w_l, + std::array& w_r, + std::array& w_o, + std::array& z_perm, + std::array& z_perm_shift, + std::array& q_m, + std::array& q_l, + std::array& q_r, + std::array& q_o, + std::array& q_c, + std::array& sigma_1, + std::array& sigma_2, + std::array& sigma_3, + std::array& id_1, + std::array& id_2, + std::array& id_3, + std::array& lagrange_first, + std::array& lagrange_last) { - const size_t NUM_POLYNOMIALS(bonk::StandardArithmetization::NUM_POLYNOMIALS); - // const size_t multivariate_d(1); - const size_t max_relation_length = 5; - - using FF = barretenberg::fr; - - std::array w_l = { 1, 2 }; - std::array w_r = { 1, 2 }; - std::array w_o = { 1, 2 }; - std::array z_perm = { 1, 2 }; - std::array z_perm_shift = { 0, 1 }; // chosen to reuse value computed in tests of grand product relations - std::array q_m = { 1, 2 }; - std::array q_l = { 1, 2 }; - std::array q_r = { 1, 2 }; - std::array q_o = { 1, 2 }; - std::array q_c = { 1, 2 }; - std::array sigma_1 = { 1, 2 }; - std::array sigma_2 = { 1, 2 }; - std::array sigma_3 = { 1, 2 }; - std::array id_1 = { 1, 2 }; - std::array id_2 = { 1, 2 }; - std::array id_3 = { 1, 2 }; - std::array lagrange_first = { 1, 2 }; - std::array lagrange_last = { 1, 2 }; - std::array, NUM_POLYNOMIALS> full_polynomials; - using POLYNOMIAL = bonk::StandardArithmetization::POLYNOMIAL; full_polynomials[POLYNOMIAL::W_L] = w_l; full_polynomials[POLYNOMIAL::W_R] = w_r; full_polynomials[POLYNOMIAL::W_O] = w_o; @@ -65,84 +72,140 @@ TEST(SumcheckRound, ComputeUnivariateProver) full_polynomials[POLYNOMIAL::LAGRANGE_FIRST] = lagrange_first; full_polynomials[POLYNOMIAL::LAGRANGE_LAST] = lagrange_last; - size_t round_size = 1; + return full_polynomials; +} +// The below two methods are used in the test ComputeUnivariateProver +static Univariate compute_round_univariate( + std::array, NUM_POLYNOMIALS>& input_polynomials, + const RelationParameters& relation_parameters) +{ + size_t round_size = 1; auto relations = std::tuple( ArithmeticRelation(), GrandProductComputationRelation(), GrandProductInitializationRelation()); - // Improvement(Cody): This is ugly? Maye supply some/all of this data through "flavor" class? auto round = SumcheckRound(round_size, relations); - const RelationParameters relation_parameters = - RelationParameters{ .zeta = 2, .alpha = 1, .beta = 1, .gamma = 1, .public_input_delta = 1 }; + auto w_l = input_polynomials[0]; + auto w_r = input_polynomials[1]; + auto w_o = input_polynomials[2]; + auto z_perm = input_polynomials[3]; + auto z_perm_shift = input_polynomials[4]; + auto q_m = input_polynomials[5]; + auto q_l = input_polynomials[6]; + auto q_r = input_polynomials[7]; + auto q_o = input_polynomials[8]; + auto q_c = input_polynomials[9]; + auto sigma_1 = input_polynomials[10]; + auto sigma_2 = input_polynomials[11]; + auto sigma_3 = input_polynomials[12]; + auto id_1 = input_polynomials[13]; + auto id_2 = input_polynomials[14]; + auto id_3 = input_polynomials[15]; + auto lagrange_first = input_polynomials[16]; + auto lagrange_last = input_polynomials[17]; - PowUnivariate pow_univariate(relation_parameters.zeta); + auto full_polynomials = construct_full_polynomials(w_l, + w_r, + w_o, + z_perm, + z_perm_shift, + q_m, + q_l, + q_r, + q_o, + q_c, + sigma_1, + sigma_2, + sigma_3, + id_1, + id_2, + id_3, + lagrange_first, + lagrange_last); + PowUnivariate pow_zeta(relation_parameters.zeta); Univariate round_univariate = - round.compute_univariate(full_polynomials, relation_parameters, pow_univariate); - Univariate expected_round_univariate{ { 32, 149, 406, 857, 1556 } }; - EXPECT_EQ(round_univariate, expected_round_univariate); + round.compute_univariate(full_polynomials, relation_parameters, pow_zeta); + return round_univariate; } -TEST(SumcheckRound, ComputeUnivariateVerifier) +static Univariate compute_expected_round_univariate( + std::array, NUM_POLYNOMIALS>& input_univariates, + const RelationParameters& relation_parameters) { - const size_t NUM_POLYNOMIALS(bonk::StandardArithmetization::NUM_POLYNOMIALS); - // const size_t multivariate_d(1); - // const size_t multivariate_n(1 << multivariate_d); - // const size_t max_rezlation_length = 5; + BarycentricData barycentric_2_to_max = + BarycentricData(); + std::array, NUM_POLYNOMIALS> extended_univariates; + for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { + extended_univariates[i] = barycentric_2_to_max.extend(input_univariates[i]); + } + auto w_l_univariate = Univariate(extended_univariates[0]); + auto w_r_univariate = Univariate(extended_univariates[1]); + auto w_o_univariate = Univariate(extended_univariates[2]); + auto z_perm_univariate = Univariate(extended_univariates[3]); + auto z_perm_shift_univariate = + Univariate(extended_univariates[4]); // this is not real shifted data + auto q_m_univariate = Univariate(extended_univariates[5]); + auto q_l_univariate = Univariate(extended_univariates[6]); + auto q_r_univariate = Univariate(extended_univariates[7]); + auto q_o_univariate = Univariate(extended_univariates[8]); + auto q_c_univariate = Univariate(extended_univariates[9]); + auto sigma_1_univariate = Univariate(extended_univariates[10]); + auto sigma_2_univariate = Univariate(extended_univariates[11]); + auto sigma_3_univariate = Univariate(extended_univariates[12]); + auto id_1_univariate = Univariate(extended_univariates[13]); + auto id_2_univariate = Univariate(extended_univariates[14]); + auto id_3_univariate = Univariate(extended_univariates[15]); + auto lagrange_first_univariate = Univariate(extended_univariates[16]); + auto lagrange_last_univariate = Univariate(extended_univariates[17]); - using FF = barretenberg::fr; - - FF w_l = { 1 }; - FF w_r = { 2 }; - FF w_o = { 3 }; - // TODO(Cody): compute permutation value? - FF z_perm = { 0 }; - FF z_perm_shift = { 0 }; - FF q_m = { 4 }; - FF q_l = { 5 }; - FF q_r = { 6 }; - FF q_o = { 7 }; - FF q_c = { 8 }; - FF sigma_1 = { 0 }; - FF sigma_2 = { 0 }; - FF sigma_3 = { 0 }; - FF id_1 = { 0 }; - FF id_2 = { 0 }; - FF id_3 = { 0 }; - FF lagrange_first = { 0 }; - FF lagrange_last = { 0 }; - - // q_m * w_l * w_r + q_l * w_l + q_r * w_r + q_o * w_o + q_c - // = 1 * (4 * 1 * 2 + 5 * 1 + 6 * 2 + 7 * 3 + 8) = 54 - FF expected_full_purported_value = 54; + auto expected_arithmetic_relation = + ((q_m_univariate * w_r_univariate * w_l_univariate) + (q_r_univariate * w_r_univariate) + + (q_l_univariate * w_l_univariate) + (q_o_univariate * w_o_univariate) + (q_c_univariate)); + auto expected_grand_product_computation_relation = + ((z_perm_univariate + lagrange_first_univariate) * + (w_l_univariate + id_1_univariate * relation_parameters.beta + relation_parameters.gamma) * + (w_r_univariate + id_2_univariate * relation_parameters.beta + relation_parameters.gamma) * + (w_o_univariate + id_3_univariate * relation_parameters.beta + relation_parameters.gamma)); + expected_grand_product_computation_relation -= + ((z_perm_shift_univariate + lagrange_last_univariate * relation_parameters.public_input_delta) * + (w_l_univariate + sigma_1_univariate * relation_parameters.beta + relation_parameters.gamma) * + (w_r_univariate + sigma_2_univariate * relation_parameters.beta + relation_parameters.gamma) * + (w_o_univariate + sigma_3_univariate * relation_parameters.beta + relation_parameters.gamma)); + auto expected_grand_product_initialization_relation = (z_perm_shift_univariate * lagrange_last_univariate); + Univariate expected_round_univariate = + expected_arithmetic_relation + expected_grand_product_computation_relation * relation_parameters.alpha + + expected_grand_product_initialization_relation * relation_parameters.alpha * relation_parameters.alpha; + return expected_round_univariate; +} +// The below two methods are used in the test ComputeUnivariateVerifier +static FF compute_full_purported_value(std::array& input_values, + const RelationParameters& relation_parameters) +{ std::vector purported_evaluations; purported_evaluations.resize(NUM_POLYNOMIALS); - - using POLYNOMIAL = bonk::StandardArithmetization::POLYNOMIAL; - purported_evaluations[POLYNOMIAL::W_L] = w_l; - purported_evaluations[POLYNOMIAL::W_R] = w_r; - purported_evaluations[POLYNOMIAL::W_O] = w_o; - purported_evaluations[POLYNOMIAL::Z_PERM] = z_perm; - purported_evaluations[POLYNOMIAL::Z_PERM_SHIFT] = z_perm_shift; - purported_evaluations[POLYNOMIAL::Q_M] = q_m; - purported_evaluations[POLYNOMIAL::Q_L] = q_l; - purported_evaluations[POLYNOMIAL::Q_R] = q_r; - purported_evaluations[POLYNOMIAL::Q_O] = q_o; - purported_evaluations[POLYNOMIAL::Q_C] = q_c; - purported_evaluations[POLYNOMIAL::SIGMA_1] = sigma_1; - purported_evaluations[POLYNOMIAL::SIGMA_2] = sigma_2; - purported_evaluations[POLYNOMIAL::SIGMA_3] = sigma_3; - purported_evaluations[POLYNOMIAL::ID_1] = id_1; - purported_evaluations[POLYNOMIAL::ID_2] = id_2; - purported_evaluations[POLYNOMIAL::ID_3] = id_3; - purported_evaluations[POLYNOMIAL::LAGRANGE_FIRST] = lagrange_first; - purported_evaluations[POLYNOMIAL::LAGRANGE_LAST] = lagrange_last; - - // size_t round_size = 1; + purported_evaluations[POLYNOMIAL::W_L] = input_values[0]; + purported_evaluations[POLYNOMIAL::W_R] = input_values[1]; + purported_evaluations[POLYNOMIAL::W_O] = input_values[2]; + purported_evaluations[POLYNOMIAL::Z_PERM] = input_values[3]; + purported_evaluations[POLYNOMIAL::Z_PERM_SHIFT] = input_values[4]; + purported_evaluations[POLYNOMIAL::Q_M] = input_values[5]; + purported_evaluations[POLYNOMIAL::Q_L] = input_values[6]; + purported_evaluations[POLYNOMIAL::Q_R] = input_values[7]; + purported_evaluations[POLYNOMIAL::Q_O] = input_values[8]; + purported_evaluations[POLYNOMIAL::Q_C] = input_values[9]; + purported_evaluations[POLYNOMIAL::SIGMA_1] = input_values[10]; + purported_evaluations[POLYNOMIAL::SIGMA_2] = input_values[11]; + purported_evaluations[POLYNOMIAL::SIGMA_3] = input_values[12]; + purported_evaluations[POLYNOMIAL::ID_1] = input_values[13]; + purported_evaluations[POLYNOMIAL::ID_2] = input_values[14]; + purported_evaluations[POLYNOMIAL::ID_3] = input_values[15]; + purported_evaluations[POLYNOMIAL::LAGRANGE_FIRST] = input_values[16]; + purported_evaluations[POLYNOMIAL::LAGRANGE_LAST] = input_values[17]; auto relations = std::tuple( ArithmeticRelation(), GrandProductComputationRelation(), GrandProductInitializationRelation()); auto round = SumcheckRound(relations); - const RelationParameters relation_parameters = - RelationParameters{ .zeta = 2, .alpha = -1, .beta = 1, .gamma = 1, .public_input_delta = 1 }; PowUnivariate pow_univariate(relation_parameters.zeta); FF full_purported_value = round.compute_full_honk_relation_purported_value(purported_evaluations, relation_parameters, pow_univariate); - EXPECT_EQ(full_purported_value, expected_full_purported_value); + return full_purported_value; +} + +static FF compute_full_purported_value_expected(std::array& input_values, + const RelationParameters& relation_parameters) +{ + FF w_l = input_values[0]; + FF w_r = input_values[1]; + FF w_o = input_values[2]; + FF z_perm = input_values[3]; + FF z_perm_shift = input_values[4]; + FF q_m = input_values[5]; + FF q_l = input_values[6]; + FF q_r = input_values[7]; + FF q_o = input_values[8]; + FF q_c = input_values[9]; + FF sigma_1 = input_values[10]; + FF sigma_2 = input_values[11]; + FF sigma_3 = input_values[12]; + FF id_1 = input_values[13]; + FF id_2 = input_values[14]; + FF id_3 = input_values[15]; + FF lagrange_first = input_values[16]; + FF lagrange_last = input_values[17]; + auto expected_arithmetic_relation = (q_m * w_r * w_l) + (q_r * w_r) + (q_l * w_l) + (q_o * w_o) + q_c; + auto expected_grand_product_computation_relation = + (z_perm + lagrange_first) * (w_l + id_1 * relation_parameters.beta + relation_parameters.gamma) * + (w_r + id_2 * relation_parameters.beta + relation_parameters.gamma) * + (w_o + id_3 * relation_parameters.beta + relation_parameters.gamma); + expected_grand_product_computation_relation -= + (z_perm_shift + lagrange_last * relation_parameters.public_input_delta) * + (w_l + sigma_1 * relation_parameters.beta + relation_parameters.gamma) * + (w_r + sigma_2 * relation_parameters.beta + relation_parameters.gamma) * + (w_o + sigma_3 * relation_parameters.beta + relation_parameters.gamma); + auto expected_grand_product_initialization_relation = z_perm_shift * lagrange_last; + auto expected_full_purported_value = + expected_arithmetic_relation + expected_grand_product_computation_relation * relation_parameters.alpha + + expected_grand_product_initialization_relation * relation_parameters.alpha * relation_parameters.alpha; + return expected_full_purported_value; +} + +TEST(SumcheckRound, ComputeUnivariateProver) +{ + auto run_test = [](bool is_random_input) { + if (is_random_input) { + std::array, NUM_POLYNOMIALS> input_polynomials; + for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { + input_polynomials[i] = { FF::random_element(), FF::random_element() }; + } + const RelationParameters relation_parameters = + RelationParameters{ .zeta = FF::random_element(), + .alpha = FF::random_element(), + .beta = FF::random_element(), + .gamma = FF::random_element(), + .public_input_delta = FF::random_element() }; + auto round_univariate = compute_round_univariate(input_polynomials, relation_parameters); + // Compute round_univariate manually + std::array, NUM_POLYNOMIALS> input_univariates; + for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { + input_univariates[i] = Univariate(input_polynomials[i]); + } + auto expected_round_univariate = compute_expected_round_univariate(input_univariates, relation_parameters); + EXPECT_EQ(round_univariate, expected_round_univariate); + } else { + std::array, NUM_POLYNOMIALS> input_polynomials; + for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { + input_polynomials[i] = { 1, 2 }; + } + const RelationParameters relation_parameters = + RelationParameters{ .zeta = 1, .alpha = 1, .beta = 1, .gamma = 1, .public_input_delta = 1 }; + auto round_univariate = compute_round_univariate(input_polynomials, relation_parameters); + // Compute round_univariate manually + std::array, NUM_POLYNOMIALS> input_univariates; + for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { + input_univariates[i] = Univariate(input_polynomials[i]); + } + // expected_round_univariate = { 6, 26, 66, 132, 230, 366 } + auto expected_round_univariate = compute_expected_round_univariate(input_univariates, relation_parameters); + EXPECT_EQ(round_univariate, expected_round_univariate); + }; + }; + run_test(/* is_random_input=*/false); + run_test(/* is_random_input=*/true); +} + +TEST(SumcheckRound, ComputeUnivariateVerifier) +{ + auto run_test = [](bool is_random_input) { + if (is_random_input) { + std::array input_values; + for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { + input_values[i] = FF::random_element(); + } + const RelationParameters relation_parameters = + RelationParameters{ .zeta = FF::random_element(), + .alpha = FF::random_element(), + .beta = FF::random_element(), + .gamma = FF::random_element(), + .public_input_delta = FF::random_element() }; + auto full_purported_value = compute_full_purported_value(input_values, relation_parameters); + // Compute round_univariate manually + auto expected_full_purported_value = + compute_full_purported_value_expected(input_values, relation_parameters); + EXPECT_EQ(full_purported_value, expected_full_purported_value); + } else { + std::array input_values; + for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { + input_values[i] = FF(2); + } + const RelationParameters relation_parameters = + RelationParameters{ .zeta = 2, .alpha = 1, .beta = 1, .gamma = 1, .public_input_delta = 1 }; + auto full_purported_value = compute_full_purported_value(input_values, relation_parameters); + // Compute round_univariate manually + auto expected_full_purported_value = + compute_full_purported_value_expected(input_values, relation_parameters); + EXPECT_EQ(full_purported_value, expected_full_purported_value); + }; + }; + run_test(/* is_random_input=*/false); + run_test(/* is_random_input=*/true); } } // namespace test_sumcheck_round