Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
grand_product_library.test.cpp
Go to the documentation of this file.
4
5#include <gtest/gtest.h>
6using namespace bb;
7
8template <class FF> class GrandProductTests : public testing::Test {
9
11
12 public:
14
15 static void populate_span(auto& polynomial_view, const auto& polynomial)
16 {
17 ASSERT_LE(polynomial_view.size(), polynomial.size());
18 for (size_t idx = 0; idx < polynomial.size(); idx++) {
19 polynomial_view[idx] = polynomial[idx];
20 }
21 };
22
31 template <typename Flavor> static void test_permutation_grand_product_construction()
32 {
34
35 // Set a mock circuit size
36 static const size_t circuit_size = 8;
37
38 // Construct a ProverPolynomials object with completely random polynomials
39 ProverPolynomials prover_polynomials;
40 for (auto& poly : prover_polynomials.get_to_be_shifted()) {
41 poly = Polynomial::random(circuit_size, /*shiftable*/ 1);
42 }
43 for (auto& poly : prover_polynomials.get_all()) {
44 if (poly.is_empty()) {
45 poly = Polynomial::random(circuit_size);
46 }
47 }
48 // Zero out z_perm — compute_grand_product will fill the active region and expects
49 // z_perm[gp_start] = 0 as the initial value of the running product.
50 prover_polynomials.z_perm = Polynomial::shiftable(circuit_size, circuit_size);
51
52 // Get random challenges
53 auto beta = FF::random_element();
54 auto gamma = FF::random_element();
55
57 .eta = 0,
58 .beta = beta,
59 .gamma = gamma,
60 .public_input_delta = 1,
61 };
62
63 compute_grand_product<Flavor, typename bb::UltraPermutationRelation<FF>>(prover_polynomials, params);
64
65 // Method 2: Compute z_perm locally using the simplest non-optimized syntax possible. The comment below,
66 // which describes the computation in 4 steps, is adapted from a similar comment in
67 // compute_grand_product_polynomial.
68 /*
69 * Assume Flavor::NUM_WIRES 3. Z_perm may be defined in terms of its values
70 * on X_i = 0,1,...,n-1 as Z_perm[0] = 0 and for i = 1:n-1
71 *
72 * (w_1(j) + β⋅id_1(j) + γ) ⋅ (w_2(j) + β⋅id_2(j) + γ) ⋅ (w_3(j) + β⋅id_3(j) + γ)
73 * Z_perm[i] = ∏ --------------------------------------------------------------------------------
74 * (w_1(j) + β⋅σ_1(j) + γ) ⋅ (w_2(j) + β⋅σ_2(j) + γ) ⋅ (w_3(j) + β⋅σ_3(j) + γ)
75 *
76 * where ∏ := ∏_{j=0:i-1} and id_i(X) = id(X) + n*(i-1). These evaluations are constructed over the
77 * course of three steps. For expositional simplicity, write Z_perm[i] as
78 *
79 * A_1(j) ⋅ A_2(j) ⋅ A_3(j)
80 * Z_perm[i] = ∏ --------------------------
81 * B_1(j) ⋅ B_2(j) ⋅ B_3(j)
82 *
83 * Step 1) Compute the 2*Flavor::NUM_WIRES length-n polynomials A_i and B_i
84 * Step 2) Compute the 2*Flavor::NUM_WIRES length-n polynomials ∏ A_i(j) and ∏ B_i(j)
85 * Step 3) Compute the two length-n polynomials defined by
86 * numer[i] = ∏ A_1(j)⋅A_2(j)⋅A_3(j), and denom[i] = ∏ B_1(j)⋅B_2(j)⋅B_3(j)
87 * Step 4) Compute Z_perm[i+1] = numer[i]/denom[i] (recall: Z_perm[0] = 1)
88 */
89
90 // Grand product starts after disabled rows (for flavors with row-disabling polynomial)
91 constexpr size_t gp_start = Flavor::TRACE_OFFSET;
92 constexpr size_t active_size = circuit_size - gp_start;
93
94 // Make scratch space for the numerator and denominator accumulators.
97
98 auto wires = prover_polynomials.get_wires();
99 auto sigmas = prover_polynomials.get_sigmas();
100 auto ids = prover_polynomials.get_ids();
101 // Step (1)
102 for (size_t i = 0; i < active_size; ++i) {
103 const size_t poly_idx = i + gp_start;
104 for (size_t k = 0; k < Flavor::NUM_WIRES; ++k) {
105 numerator_accum[k][i] = wires[k][poly_idx] + (ids[k][poly_idx] * beta) + gamma;
106 denominator_accum[k][i] = wires[k][poly_idx] + (sigmas[k][poly_idx] * beta) + gamma;
107 }
108 }
109
110 // Step (2)
111 for (size_t k = 0; k < Flavor::NUM_WIRES; ++k) {
112 for (size_t i = 0; i < active_size - 1; ++i) {
113 numerator_accum[k][i + 1] *= numerator_accum[k][i];
114 denominator_accum[k][i + 1] *= denominator_accum[k][i];
115 }
116 }
117
118 // Step (3)
119 for (size_t i = 0; i < active_size; ++i) {
120 for (size_t k = 1; k < Flavor::NUM_WIRES; ++k) {
121 numerator_accum[0][i] *= numerator_accum[k][i];
122 denominator_accum[0][i] *= denominator_accum[k][i];
123 }
124 }
125
126 // Step (4)
127 Polynomial z_permutation_expected(circuit_size);
128 for (size_t i = 0; i < active_size - 1; ++i) {
129 z_permutation_expected.at(gp_start + i + 1) = numerator_accum[0][i] / denominator_accum[0][i];
130 }
131
132 // Check consistency between locally computed z_perm and the one computed by the prover library.
133 // Only compare the active region (after disabled rows); masking values at rows 1..3 are random.
134 for (size_t i = gp_start; i < circuit_size; ++i) {
135 EXPECT_EQ(prover_polynomials.z_perm[i], z_permutation_expected[i]) << "Mismatch at index " << i;
136 }
137 };
138};
139
140using FieldTypes = testing::Types<bb::fr>;
142
143TYPED_TEST(GrandProductTests, GrandProductPermutation)
144{
145 TestFixture::template test_permutation_grand_product_construction<UltraFlavor>();
146}
static void test_permutation_grand_product_construction()
Check consistency of the computation of the permutation grand product polynomial z_permutation.
static void populate_span(auto &polynomial_view, const auto &polynomial)
A container for the prover polynomials.
static constexpr size_t NUM_WIRES
static constexpr size_t TRACE_OFFSET
static Polynomial random(size_t size, size_t start_index=0)
static Polynomial shiftable(size_t virtual_size, bool masked=false)
Utility to create a shiftable polynomial of given virtual size.
Fr & at(size_t index)
Our mutable accessor, unlike operator[]. We abuse precedent a bit to differentiate at() and operator[...
typename ECCVMFlavor::ProverPolynomials ProverPolynomials
testing::Types< bb::fr > FieldTypes
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
TYPED_TEST_SUITE(CommitmentKeyTest, Curves)
TYPED_TEST(CommitmentKeyTest, CommitToZeroPoly)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
Container for parameters used by the grand product (permutation, lookup) Honk relations.
static field random_element(numeric::RNG *engine=nullptr) noexcept