Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
polynomial.test.cpp
Go to the documentation of this file.
1#include <cstddef>
2#include <gtest/gtest.h>
3
6
7// Simple test/demonstration of shifted functionality
8TEST(Polynomial, Shifted)
9{
10 using FF = bb::fr;
11 using Polynomial = bb::Polynomial<FF>;
12 const size_t SIZE = 10;
13 auto poly = Polynomial::random(SIZE, /*shiftable*/ 1);
14
15 // Instantiate the shift via the shited method
16 auto poly_shifted = poly.shifted();
17
18 EXPECT_EQ(poly_shifted.size(), poly.size());
19
20 // The shift is indeed the shift
21 for (size_t i = 0; i < poly_shifted.size() - 1; ++i) {
22 EXPECT_EQ(poly_shifted.get(i), poly.get(i + 1));
23 }
24
25 // If I change the original polynomial, the shift is updated accordingly
26 poly.at(3) = 25;
27 for (size_t i = 0; i < poly_shifted.size() - 1; ++i) {
28 EXPECT_EQ(poly_shifted.get(i), poly.get(i + 1));
29 }
30}
31
32// Simple test/demonstration of reverse functionality
33TEST(Polynomial, Reversed)
34{
35 using FF = bb::fr;
36 using Polynomial = bb::Polynomial<FF>;
37 const size_t SIZE = 10;
38 const size_t VIRTUAL_SIZE = 20;
39 const size_t START_IDX = 2;
40 const size_t END_IDX = SIZE + START_IDX;
41 auto poly = Polynomial::random(SIZE, VIRTUAL_SIZE, START_IDX);
42
43 // Instantiate the shift via the reverse method
44 auto poly_reversed = poly.reverse();
45
46 EXPECT_EQ(poly_reversed.size(), poly.size());
47 EXPECT_EQ(poly_reversed.virtual_size(), poly.end_index());
48
49 // The reversed is indeed the reversed
50 for (size_t i = 0; i < END_IDX; ++i) {
51 EXPECT_EQ(poly_reversed.get(END_IDX - 1 - i), poly.get(i));
52 }
53
54 // If I change the original polynomial, the reversed polynomial is not updated
55 FF initial_value = poly.at(3);
56 poly.at(3) = 25;
57 EXPECT_EQ(poly_reversed.at(END_IDX - 4), initial_value);
58}
59
60// Simple test/demonstration of share functionality
61TEST(Polynomial, Share)
62{
63 using FF = bb::fr;
64 using Polynomial = bb::Polynomial<FF>;
65 const size_t SIZE = 10;
66 auto poly = Polynomial::random(SIZE);
67
68 // "clone" the poly via the share method
69 auto poly_clone = poly.share();
70
71 // The two are indeed equal
72 EXPECT_EQ(poly_clone, poly);
73
74 // Changing one changes the other
75 poly.at(3) = 25;
76 EXPECT_EQ(poly_clone, poly);
77
78 poly_clone.at(2) = 13;
79 EXPECT_EQ(poly_clone, poly);
80
81 // If reset the original poly, it will no longer be equal to the clone made earlier
82 // Note: if we had not made a clone, the memory from the original poly would be leaked
83 auto poly2 = Polynomial::random(SIZE);
84 poly = poly2.share();
85
86 EXPECT_NE(poly_clone, poly);
87}
88
89// Simple test/demonstration of various edge conditions
90TEST(Polynomial, Indices)
91{
92 auto poly = bb::Polynomial<bb::fr>::random(100, /*offset*/ 1);
93 EXPECT_TRUE(poly.is_shiftable());
94 EXPECT_EQ((*poly.indices().begin()), poly.start_index());
95 EXPECT_EQ(std::get<0>(*poly.indexed_values().begin()), poly.start_index());
96 EXPECT_EQ(std::get<1>(*poly.indexed_values().begin()), poly[poly.start_index()]);
97}
98
99#ifndef NDEBUG
100// Only run in an assert-enabled test suite.
101TEST(Polynomial, AddScaledEdgeConditions)
102{
103 // Suppress warnings about fork(), we're OK with the edge cases.
104 GTEST_FLAG_SET(death_test_style, "threadsafe");
105 using FF = bb::fr;
106 auto test_subset_good = []() {
107 // Contained within poly
108 auto poly = bb::Polynomial<FF>::random(4, /*start index*/ 0);
109 poly.add_scaled(bb::Polynomial<FF>::random(4, /*start index*/ 1), 1);
110 };
111 ASSERT_NO_FATAL_FAILURE(test_subset_good());
112 auto test_subset_bad1 = []() {
113 // Not contained within poly
114 auto poly = bb::Polynomial<FF>::random(4, /*start index*/ 1);
115 poly.add_scaled(bb::Polynomial<FF>::random(4, /*start index*/ 0), 1);
116 };
117 ASSERT_THROW_OR_ABORT(test_subset_bad1(), ".*start_index.*other.start_index.*");
118 auto test_subset_bad2 = []() {
119 // Not contained within poly
120 auto poly = bb::Polynomial<FF>::random(4, /*start index*/ 0);
121 poly.add_scaled(bb::Polynomial<FF>::random(5, /*start index*/ 0), 1);
122 };
123 ASSERT_THROW_OR_ABORT(test_subset_bad2(), ".*end_index.*other.end_index.*");
124}
125
126TEST(Polynomial, OperatorAddEdgeConditions)
127{
128 // Suppress warnings about fork(), we're OK with the edge cases.
129 GTEST_FLAG_SET(death_test_style, "threadsafe");
130 using FF = bb::fr;
131 auto test_subset_good = []() {
132 // Contained within poly
133 auto poly = bb::Polynomial<FF>::random(4, /*start index*/ 0);
134 poly += bb::Polynomial<FF>::random(4, /*start index*/ 1);
135 };
136 ASSERT_NO_FATAL_FAILURE(test_subset_good());
137 auto test_subset_bad1 = []() {
138 // Not contained within poly
139 auto poly = bb::Polynomial<FF>::random(4, /*start index*/ 1);
140 poly += bb::Polynomial<FF>::random(4, /*start index*/ 0);
141 };
142 ASSERT_THROW_OR_ABORT(test_subset_bad1(), ".*start_index.*other.start_index.*");
143 auto test_subset_bad2 = []() {
144 // Not contained within poly
145 auto poly = bb::Polynomial<FF>::random(4, /*start index*/ 0);
146 poly += bb::Polynomial<FF>::random(5, /*start index*/ 0);
147 };
148 ASSERT_THROW_OR_ABORT(test_subset_bad2(), ".*end_index.*other.end_index.*");
149}
150
151TEST(Polynomial, OperatorSubtractEdgeConditions)
152{
153 // Suppress warnings about fork(), we're OK with the edge cases.
154 GTEST_FLAG_SET(death_test_style, "threadsafe");
155 using FF = bb::fr;
156 auto test_subset_good = []() {
157 // Contained within poly
158 auto poly = bb::Polynomial<FF>::random(4, /*start index*/ 0);
159 poly -= bb::Polynomial<FF>::random(4, /*start index*/ 1);
160 };
161 ASSERT_NO_FATAL_FAILURE(test_subset_good());
162 auto test_subset_bad1 = []() {
163 // Not contained within poly
164 auto poly = bb::Polynomial<FF>::random(4, /*start index*/ 1);
165 poly -= bb::Polynomial<FF>::random(4, /*start index*/ 0);
166 };
167 ASSERT_THROW_OR_ABORT(test_subset_bad1(), ".*start_index.*other.start_index.*");
168 auto test_subset_bad2 = []() {
169 // Not contained within poly
170 auto poly = bb::Polynomial<FF>::random(4, /*start index*/ 0);
171 poly -= bb::Polynomial<FF>::random(5, /*start index*/ 0);
172 };
173 ASSERT_THROW_OR_ABORT(test_subset_bad2(), ".*end_index.*other.end_index.*");
174}
175
176// Makes a vector fully of the virtual_size aka degree + 1
177TEST(Polynomial, Full)
178{
179 // Suppress warnings about fork(), we're OK with the edge cases.
180 GTEST_FLAG_SET(death_test_style, "threadsafe");
181 using FF = bb::fr;
182 size_t degree_plus_1 = 10;
183 auto full_good = [=]() {
184 auto poly = bb::Polynomial<FF>::random(1, degree_plus_1, /*start index*/ degree_plus_1 - 1);
185 poly = poly.full();
186 poly -= bb::Polynomial<FF>::random(degree_plus_1, /*start index*/ 0);
187 };
188 ASSERT_NO_FATAL_FAILURE(full_good());
189 auto no_full_bad = [=]() {
190 auto poly = bb::Polynomial<FF>::random(1, degree_plus_1, /*start index*/ degree_plus_1 - 1);
191 poly -= bb::Polynomial<FF>::random(degree_plus_1, /*start index*/ 0);
192 };
193 ASSERT_THROW_OR_ABORT(no_full_bad(), ".*start_index.*other.start_index.*");
194}
195
196#endif
#define ASSERT_THROW_OR_ABORT(statement, matcher)
Definition assert.hpp:191
Structured polynomial class that represents the coefficients 'a' of a_0 + a_1 x .....
static Polynomial random(size_t size, size_t start_index=0)
field< Bn254FrParams > fr
Definition fr.hpp:155
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
TEST(Polynomial, Shifted)