Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
field_conversion.test.cpp
Go to the documentation of this file.
4#include <gtest/gtest.h>
5
7
8template <typename Builder> using fr = field_t<Builder>;
9template <typename Builder> using fq = bigfield<Builder, bb::Bn254FqParams>;
11template <typename Builder> using grumpkin_element = cycle_group<Builder>;
12
13template <typename Builder> class stdlib_field_conversion : public ::testing::Test {
14 public:
16 // Serialize and deserialize
17 template <typename T> void check_conversion(T in, bool valid_circuit = true, bool point_at_infinity = false)
18 {
19 size_t len = Codec::template calc_num_fields<T>();
20 auto frs = Codec::serialize_to_fields(in);
21 EXPECT_EQ(len, frs.size());
22 auto out = Codec::template deserialize_from_fields<T>(frs);
23 bool expected = std::is_same_v<Builder, UltraCircuitBuilder> ? !point_at_infinity : true;
24
25 EXPECT_EQ(in.get_value() == out.get_value(), expected);
26
27 auto ctx = in.get_context();
28
29 EXPECT_EQ(CircuitChecker::check(*ctx), valid_circuit);
30 }
31
32 template <typename T> void check_conversion_iterable(T x)
33 {
34 size_t len = Codec::template calc_num_fields<T>();
35 auto frs = Codec::template serialize_to_fields<T>(x);
36 EXPECT_EQ(len, frs.size());
37 auto y = Codec::template deserialize_from_fields<T>(frs);
38 EXPECT_EQ(x.size(), y.size());
39 for (auto [val1, val2] : zip_view(x, y)) {
40 EXPECT_EQ(val1.get_value(), val2.get_value());
41 }
42 }
43};
44
45using BuilderTypes = testing::Types<UltraCircuitBuilder, MegaCircuitBuilder>;
46
48
53{
54 using Builder = TypeParam;
56 bb::fr field_element_val(
57 std::string("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789")); // 256 bits
58 fr<Builder> field_element(&builder, field_element_val);
59 this->check_conversion(field_element);
60
61 field_element_val = bb::fr::modulus_minus_two; // modulus - 2
62 field_element = fr<Builder>(&builder, field_element_val);
63 this->check_conversion(field_element);
64
65 field_element_val = bb::fr(1);
66 field_element = fr<Builder>(&builder, field_element_val);
67 this->check_conversion(field_element);
68}
69
73TYPED_TEST(stdlib_field_conversion, FieldConversionGrumpkinFr)
74{
75 using Builder = TypeParam;
77
78 // Constructing bigfield objects with bb::fq values
79 bb::fq field_element_val(
80 std::string("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789")); // 256 bits
81 this->check_conversion(fq<Builder>::from_witness(&builder, field_element_val));
82}
83
88TYPED_TEST(stdlib_field_conversion, FieldConversionBN254AffineElement)
89{
90 using Builder = TypeParam;
91 { // Serialize and deserialize the bn254 generator
93
94 bn254_element<Builder> group_element =
95 bn254_element<Builder>::from_witness(&builder, curve::BN254::AffineElement::one());
96 this->check_conversion(group_element);
97 }
98 { // Serialize and deserialize a valid bn254 point
100
102 bn254_element<Builder> group_element = bn254_element<Builder>::from_witness(&builder, group_element_val);
103 this->check_conversion(group_element);
104 }
105
106 { // Serialize and deserialize random Grumpkin points
108 const size_t num_points = 50;
109 const curve::BN254::AffineElement native_generator = curve::BN254::AffineElement::one();
110
111 for (size_t i = 0; i < num_points; i++) {
112 bb::fr random_scalar = bb::fr::random_element();
113 bn254_element<Builder> group_element =
114 bn254_element<Builder>::from_witness(&builder, native_generator * random_scalar);
115 this->check_conversion(group_element);
116 }
117 }
118 // TODO(https://github.com/AztecProtocol/barretenberg/issues/1527): Remove `point_at_infinity` flag when point at
119 // infinity is consistently represented.
120 { // Serialize and deserialize the point at infinity
122
123 bn254_element<Builder> group_element =
124 bn254_element<Builder>::from_witness(&builder, curve::BN254::AffineElement::infinity());
125 // The circuit is valid, because the point at infinity is set to `one`.
126 this->check_conversion(group_element, /* valid circuit */ true, /* point at infinity */ true);
127 }
128
129 { // Serialize and deserialize "coordinates" that do not correspond to any point on the curve
131
132 curve::BN254::AffineElement group_element_val(1, 4);
133 bn254_element<Builder> group_element;
135 EXPECT_THROW_OR_ABORT(group_element = bn254_element<Builder>::from_witness(&builder, group_element_val),
136 "");
137 } else {
138 group_element = bn254_element<Builder>::from_witness(&builder, group_element_val);
139 this->check_conversion(group_element);
140 }
141 }
142}
143
148TYPED_TEST(stdlib_field_conversion, FieldConversionGrumpkinAffineElement)
149{
150 using Builder = TypeParam;
151
152 { // Serialize and deserialize the Grumpkin generator
154 grumpkin_element<Builder> group_element =
155 grumpkin_element<Builder>::from_witness(&builder, curve::Grumpkin::AffineElement::one());
156 this->check_conversion(group_element);
157 }
158 { // Serialize and deserialize random Grumpkin points
160 const size_t num_points = 50;
161 const curve::Grumpkin::AffineElement native_generator = curve::Grumpkin::AffineElement::one();
162
163 for (size_t i = 0; i < num_points; i++) {
164 bb::fq random_scalar = bb::fq::random_element();
165 grumpkin_element<Builder> group_element =
166 grumpkin_element<Builder>::from_witness(&builder, native_generator * random_scalar);
167 this->check_conversion(group_element);
168 }
169 }
170
171 { // Serialize and deserialize "coordinates" that do not correspond to any point on the curve
172 BB_DISABLE_ASSERTS(); // Avoid on_curve assertion failure in cycle_group constructor
174
175 curve::Grumpkin::AffineElement group_element_val(12, 100);
177 this->check_conversion(group_element, /* valid circuit */ false);
178 }
179
180 { // Serialize and deserialize the point at infinity
182
183 grumpkin_element<Builder> group_element =
184 grumpkin_element<Builder>::from_witness(&builder, curve::Grumpkin::AffineElement::infinity());
185 this->check_conversion(group_element);
186 }
187}
188
189TYPED_TEST(stdlib_field_conversion, DeserializePointAtInfinity)
190{
191 using Builder = TypeParam;
192 using Codec = StdlibCodec<field_t<Builder>>;
195
196 {
197 std::vector<fr<Builder>> zeros(4, zero);
198
199 bn254_element<Builder> point_at_infinity =
200 Codec::template deserialize_from_fields<bn254_element<Builder>>(zeros);
201
202 EXPECT_TRUE(point_at_infinity.is_point_at_infinity().get_value());
203 EXPECT_TRUE(CircuitChecker::check(builder));
204 }
205 {
206 std::vector<fr<Builder>> zeros(2, zero);
207
208 grumpkin_element<Builder> point_at_infinity =
209 Codec::template deserialize_from_fields<grumpkin_element<Builder>>(zeros);
210
211 EXPECT_TRUE(point_at_infinity.is_point_at_infinity().get_value());
212 EXPECT_TRUE(CircuitChecker::check(builder));
213 }
214}
215
219TYPED_TEST(stdlib_field_conversion, FieldConversionArrayBn254Fr)
220{
221 using Builder = TypeParam;
223
224 // Constructing std::array objects with fr<Builder> values
225 std::array<fr<Builder>, 4> array_of_frs_4{
227 };
228 this->check_conversion_iterable(array_of_frs_4);
229
232 fr<Builder>(&builder, 215215125),
233 fr<Builder>(&builder, 102701750),
234 fr<Builder>(&builder, 367032),
235 fr<Builder>(&builder, 12985028),
237 this->check_conversion_iterable(array_of_frs_7);
238}
239
243TYPED_TEST(stdlib_field_conversion, FieldConversionArrayGrumpkinFr)
244{
245 using Builder = TypeParam;
247
248 // Constructing std::array objects with fq<Builder> values
249 std::array<fq<Builder>, 4> array_of_fqs_4{
251 &builder,
252 static_cast<bb::fq>(std::string("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"))),
254 &builder,
255 static_cast<bb::fq>(std::string("2bf1eaf87f7d27e8dc4056e9af975985bccc89077a21891d6c7b6ccce0631f95"))),
257 &builder,
258 static_cast<bb::fq>(std::string("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"))),
260 &builder,
261 static_cast<bb::fq>(std::string("018555a8eb50cf07f64b019ebaf3af3c925c93e631f3ecd455db07bbb52bbdd3"))),
262 };
263 this->check_conversion_iterable(array_of_fqs_4);
264}
265
269TYPED_TEST(stdlib_field_conversion, FieldConversionUnivariateBn254Fr)
270{
271 using Builder = TypeParam;
273
274 // Constructing Univariate objects with fr<Builder> values
275 Univariate<fr<Builder>, 4> univariate{
277 };
278 this->check_conversion_iterable(univariate);
279}
280
284TYPED_TEST(stdlib_field_conversion, FieldConversionUnivariateGrumpkinFr)
285{
286 using Builder = TypeParam;
288
289 // Constructing std::array objects with fq<Builder> values
290 Univariate<fq<Builder>, 4> univariate{
292 &builder,
293 static_cast<bb::fq>(std::string("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"))),
295 &builder,
296 static_cast<bb::fq>(std::string("2bf1eaf87f7d27e8dc4056e9af975985bccc89077a21891d6c7b6ccce0631f95"))),
298 &builder,
299 static_cast<bb::fq>(std::string("018555a8eb50cf07f64b019ebaf3af3c925c93e631f3ecd455db07bbb52bbdd3"))),
301 &builder,
302 static_cast<bb::fq>(std::string("2bf1eaf87f7d27e8dc4056e9af975985bccc89077a21891d6c7b6ccce0631f95"))) }
303 };
304 this->check_conversion_iterable(univariate);
305}
306
307} // namespace bb::stdlib::field_conversion_tests
#define EXPECT_THROW_OR_ABORT(statement, matcher)
Definition assert.hpp:185
#define BB_DISABLE_ASSERTS()
Definition assert.hpp:32
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
A univariate polynomial represented by its values on {domain_start, domain_start + 1,...
typename bb::g1 Group
Definition bn254.hpp:20
typename Group::affine_element AffineElement
Definition bn254.hpp:22
typename Group::affine_element AffineElement
Definition grumpkin.hpp:56
static std::vector< fr > serialize_to_fields(const T &val)
Core stdlib Transcript serialization method.
bool get_value() const
Definition bool.hpp:111
cycle_group represents a group Element of the proving system's embedded curve, i.e....
bool_t is_point_at_infinity() const
void check_conversion(T in, bool valid_circuit=true, bool point_at_infinity=false)
AluTraceBuilder builder
Definition alu.test.cpp:123
testing::Types< UltraCircuitBuilder, MegaCircuitBuilder > BuilderTypes
element< Builder, fq< Builder >, fr< Builder >, curve::BN254::Group > bn254_element
std::conditional_t< IsGoblinBigGroup< C, Fq, Fr, G >, element_goblin::goblin_element< C, goblin_field< C >, Fr, G >, element_default::element< C, Fq, Fr, G > > element
element wraps either element_default::element or element_goblin::goblin_element depending on parametr...
TYPED_TEST_SUITE(ShpleminiTest, TestSettings)
field< Bn254FrParams > fr
Definition fr.hpp:174
TYPED_TEST(ShpleminiTest, CorrectnessOfMultivariateClaimBatching)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
uint8_t len
static field random_element(numeric::RNG *engine=nullptr) noexcept
static constexpr uint256_t modulus_minus_two