Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
barycentric.test.cpp
Go to the documentation of this file.
5#include "univariate.hpp"
6#include <gtest/gtest.h>
7
8using namespace bb;
9
10template <class FF> class BarycentricDataTests : public testing::Test {};
11
12using FieldTypes = testing::Types<bb::fr>;
14
15#define BARYCENTIC_DATA_TESTS_TYPE_ALIASES using FF = TypeParam;
16
22TYPED_TEST(BarycentricDataTests, CompileTimeComputation)
23{
25 const size_t domain_size(2);
26 const size_t num_evals(10);
27
29}
30
32{
34 const size_t domain_size(2);
35 const size_t num_evals(10);
36 auto f = Univariate<FF, domain_size>({ 1, 2 });
37 auto expected_result = Univariate<FF, num_evals>({ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
38 auto result = f.template extend_to<num_evals>();
39 EXPECT_EQ(result, expected_result);
40}
41
43{
45 static constexpr size_t initial_size(2);
46 static constexpr size_t domain_size(10);
47 auto f = Univariate<FF, domain_size>({ 1, 2, 0, 0, 0, 0, 0, 0, 0, 0 });
48 auto expected_result = Univariate<FF, domain_size>({ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
49 f.template self_extend_from<initial_size>();
50 EXPECT_EQ(f, expected_result);
51}
52
54{
56 const size_t domain_size(2);
57 auto f = Univariate<FF, domain_size>({ 1, 2 });
58 FF u = 5;
60 auto result = f.evaluate(u);
61 EXPECT_EQ(result, expected_result);
62}
63
64TYPED_TEST(BarycentricDataTests, BarycentricData2to3)
65{
67
68 const size_t domain_size = 2;
69 const size_t num_evals = 3;
71 std::array<FF, 3> expected_big_domain{ { 0, 1, 2 } };
72 std::array<FF, 2> expected_denominators{ { -1, 1 } };
73 std::array<FF, 3> expected_full_numerator_values{ { 0, 0, 2 } };
74 EXPECT_EQ(barycentric.big_domain, expected_big_domain);
75 EXPECT_EQ(barycentric.lagrange_denominators, expected_denominators);
76 EXPECT_EQ(barycentric.full_numerator_values, expected_full_numerator_values);
77
78 // e1(X) = 1*(1-X) + 2*X = 1 + X
79 Univariate<FF, 2> e1{ { 1, 2 } };
81 FF calculated_val_at_u = e1.evaluate(u);
82 EXPECT_EQ(u + 1, calculated_val_at_u);
83
84 Univariate<FF, 3> ext1 = e1.template extend_to<num_evals>();
85 Univariate<FF, 3> expected{ { 1, 2, 3 } };
86 EXPECT_EQ(ext1, expected);
87}
88
89TYPED_TEST(BarycentricDataTests, BarycentricData5to6)
90{
92
93 const size_t domain_size = 5;
94 const size_t num_evals = 6;
95
96 // Note: we are able to represent a degree 4 polynomial with 5 points thus this
97 // extension will succeed. It would fail for values on a polynomial of degree > 4.
98 Univariate<FF, domain_size> e1{ { 1, 3, 25, 109, 321 } }; // X^4 + X^3 + 1
99 Univariate<FF, num_evals> ext1 = e1.template extend_to<num_evals>();
100 Univariate<FF, num_evals> expected{ { 1, 3, 25, 109, 321, 751 } };
101 EXPECT_EQ(ext1, expected);
102}
103
110
111// Verify that BarycentricDataRunTime computes the same precomputed arrays as the compile-time native version
112TEST(BarycentricDataRunTimeTests, DataArraysMatchCompileTime2to3)
113{
114 constexpr size_t domain_size = 2;
115 constexpr size_t num_evals = 3;
118
119 for (size_t i = 0; i < RuntimeData::big_domain_size; ++i) {
120 EXPECT_EQ(RuntimeData::big_domain[i].get_value(), NativeData::big_domain[i]);
121 }
122 for (size_t i = 0; i < domain_size; ++i) {
123 EXPECT_EQ(RuntimeData::lagrange_denominators[i].get_value(), NativeData::lagrange_denominators[i]);
124 }
125 for (size_t i = 0; i < domain_size * num_evals; ++i) {
126 EXPECT_EQ(RuntimeData::precomputed_denominator_inverses[i].get_value(),
127 NativeData::precomputed_denominator_inverses[i]);
128 }
129 for (size_t i = 0; i < num_evals; ++i) {
130 EXPECT_EQ(RuntimeData::full_numerator_values[i].get_value(), NativeData::full_numerator_values[i]);
131 }
132}
133
134TEST(BarycentricDataRunTimeTests, DataArraysMatchCompileTime5to6)
135{
136 constexpr size_t domain_size = 5;
137 constexpr size_t num_evals = 6;
140
141 for (size_t i = 0; i < RuntimeData::big_domain_size; ++i) {
142 EXPECT_EQ(RuntimeData::big_domain[i].get_value(), NativeData::big_domain[i]);
143 }
144 for (size_t i = 0; i < domain_size; ++i) {
145 EXPECT_EQ(RuntimeData::lagrange_denominators[i].get_value(), NativeData::lagrange_denominators[i]);
146 }
147 for (size_t i = 0; i < domain_size * num_evals; ++i) {
148 EXPECT_EQ(RuntimeData::precomputed_denominator_inverses[i].get_value(),
149 NativeData::precomputed_denominator_inverses[i]);
150 }
151 for (size_t i = 0; i < num_evals; ++i) {
152 EXPECT_EQ(RuntimeData::full_numerator_values[i].get_value(), NativeData::full_numerator_values[i]);
153 }
154}
155
156// Evaluate a linear polynomial f(X) = 1 + X at a witness point
157TEST(BarycentricDataRunTimeTests, Evaluate)
158{
160 constexpr size_t domain_size = 2;
161
162 // f(X) = 1 + X: f(0)=1, f(1)=2
166
168 auto result = f.evaluate(u);
169 EXPECT_EQ(result.get_value(), bb::fr(6)); // f(5) = 1 + 5 = 6
170
171 EXPECT_TRUE(CircuitChecker::check(builder));
172}
173
174// Extend a degree-1 polynomial from 2 to 10 evaluations
175TEST(BarycentricDataRunTimeTests, Extend)
176{
178 constexpr size_t domain_size = 2;
179 constexpr size_t num_evals = 10;
180
181 // X + 1: f(0)=1, f(1)=2
184 auto ext1 = e1.template extend_to<num_evals>();
185
186 std::array<bb::fr, num_evals> expected = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
187 for (size_t i = 0; i < num_evals; ++i) {
188 EXPECT_EQ(ext1.value_at(i).get_value(), expected[i]);
189 }
190
191 EXPECT_TRUE(CircuitChecker::check(builder));
192}
193
194// Extend a degree-4 polynomial from 5 to 6 evaluations using the general barycentric path (LENGTH >= 5)
195TEST(BarycentricDataRunTimeTests, Extend5to6)
196{
198 constexpr size_t domain_size = 5;
199 constexpr size_t num_evals = 6;
200
201 // X^4 + X^3 + 1: f(0)=1, f(1)=3, f(2)=25, f(3)=109, f(4)=321
205 witness_ct(&builder, bb::fr(109)),
206 witness_ct(&builder, bb::fr(321)) });
207 auto ext1 = e1.template extend_to<num_evals>();
208
209 std::array<bb::fr, num_evals> expected = { 1, 3, 25, 109, 321, 751 };
210 for (size_t i = 0; i < num_evals; ++i) {
211 EXPECT_EQ(ext1.value_at(i).get_value(), expected[i]);
212 }
213
214 EXPECT_TRUE(CircuitChecker::check(builder));
215}
#define BARYCENTIC_DATA_TESTS_TYPE_ALIASES
bb::stdlib::witness_t< Builder > witness_ct
Compile-time variant: precomputed arrays are static constexpr.
Run-time variant: precomputed arrays are inline static const.
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
A univariate polynomial represented by its values on {0, 1,..., domain_end - 1}.
Fr & value_at(size_t i)
AluTraceBuilder builder
Definition alu.test.cpp:124
bool expected_result
testing::Types< bb::fr > FieldTypes
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
TYPED_TEST_SUITE(CommitmentKeyTest, Curves)
TYPED_TEST(CommitmentKeyTest, CommitToZeroPoly)
UltraCircuitBuilder_< UltraExecutionTraceBlocks > UltraCircuitBuilder
TEST(BoomerangMegaCircuitBuilder, BasicCircuit)
std::conditional_t< is_field_type_v< Fr >, BarycentricDataCompileTime< Fr, domain_end, num_evals >, BarycentricDataRunTime< Fr, domain_end, num_evals > > BarycentricData
Exposes BarycentricData with compile time arrays if the type is bberg::field and runtime arrays other...
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
static field random_element(numeric::RNG *engine=nullptr) noexcept