Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
g2.test.cpp
Go to the documentation of this file.
1#include "g2.hpp"
2#include <gtest/gtest.h>
3
4using namespace bb;
5
6TEST(g2, RandomElement)
7{
8 g2::element result = g2::element::random_element();
9 EXPECT_EQ(result.on_curve(), true);
10}
11
12TEST(g2, RandomAffineElement)
13{
14 g2::affine_element result = g2::element::random_element();
15 EXPECT_EQ(result.on_curve(), true);
16}
17
18TEST(g2, Eq)
19{
20 g2::element a = g2::element::random_element();
22
23 EXPECT_EQ(a == b, true);
24 EXPECT_EQ(a == a, true);
25
26 b.self_set_infinity();
27
28 EXPECT_EQ(a == b, false);
29 g2::element c = g2::element::random_element();
30
31 EXPECT_EQ(a == c, false);
32
33 a.self_set_infinity();
34
35 EXPECT_EQ(a == b, true);
36}
37
38TEST(g2, DblCheckAgainstConstants)
39{
40 g2::element lhs = { { { 0x46debd5cd992f6ed, 0x674322d4f75edadd, 0x426a00665e5c4479, 0x1800deef121f1e76 },
41 { 0x97e485b7aef312c2, 0xf1aa493335a9e712, 0x7260bfb731fb5d25, 0x198e9393920d483a } },
42 { { 0x4ce6cc0166fa7daa, 0xe3d1e7690c43d37b, 0x4aab71808dcb408f, 0x12c85ea5db8c6deb },
43 { 0x55acdadcd122975b, 0xbc4b313370b38ef3, 0xec9e99ad690c3395, 0x90689d0585ff075 } },
44 { { 0x1, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0 } } };
45 g2::element expected = { { { 0x8fcae74c62173d99, 0xadb8624eb3bce1ad, 0x7b95c05d3e9c3c98, 0x11d65cded12c8731 },
46 { 0x913fa47117bd9d56, 0x17eb5f9e60297b13, 0x132207965bf363ee, 0x168dfeb5f21b6dc0 } },
47 { { 0x1c10da5c8693bc8, 0x152ff094bd258271, 0xeb12d62e95fef138, 0x2891f38f6935fd84 },
48 { 0x9f5265a7b4e4ae19, 0xfb6348cb8fdefd6c, 0x6259df5c8932f6b1, 0x53858cc3dba708f } },
49 { { 0x99cd9802cdf4fb54, 0xc7a3ced21887a6f6, 0x9556e3011b96811f, 0x2590bd4bb718dbd6 },
50 { 0xab59b5b9a2452eb6, 0x78966266e1671de6, 0xd93d335ad218672b, 0x120d13a0b0bfe0eb } } };
51
52 lhs.x = lhs.x.to_montgomery_form();
53 lhs.y = lhs.y.to_montgomery_form();
54 lhs.z = lhs.z.to_montgomery_form();
55 expected.x = expected.x.to_montgomery_form();
56 expected.y = expected.y.to_montgomery_form();
57 expected.z = expected.z.to_montgomery_form();
58
59 g2::element result;
60 result = lhs.dbl();
61 EXPECT_EQ(result == expected, true);
62}
63
64TEST(g2, MixedAddCheckAgainstConstants)
65{
66 g2::element lhs = { { { 0xfe0ee11d88ef9c7c, 0xa50b3642c93787df, 0x5c4925f0812249a3, 0x13360054113b26e5 },
67 { 0x85a786ba7563664d, 0xebb6adaab3da2d35, 0x2e5c4b3e8bfae51d, 0x860451c5f3cb08 } },
68 { { 0x1336c5c955c13e31, 0x99acf7e0bf631edd, 0x7544255d031dcb7c, 0x170f93b2ac0d088d },
69 { 0xd27a61c30f2f9b75, 0x27abf783f3139bb9, 0x84ee0a9379a3c860, 0x23df8ba46e8f6ea7 } },
70 { { 0x3b2009df97845379, 0x3262a4c15a3ad056, 0xc5852fece05e2563, 0x1bb45a345c7765a9 },
71 { 0xaeb423ce4f95d63, 0xa9dee5d2983c1985, 0x8120e98ba5901fdb, 0x181589d4f3580f3a } } };
72 g2::affine_element affine_rhs = {
73 { { 0x46debd5cd992f6ed, 0x674322d4f75edadd, 0x426a00665e5c4479, 0x1800deef121f1e76 },
74 { 0x97e485b7aef312c2, 0xf1aa493335a9e712, 0x7260bfb731fb5d25, 0x198e9393920d483a } },
75 { { 0x4ce6cc0166fa7daa, 0xe3d1e7690c43d37b, 0x4aab71808dcb408f, 0x12c85ea5db8c6deb },
76 { 0x55acdadcd122975b, 0xbc4b313370b38ef3, 0xec9e99ad690c3395, 0x90689d0585ff075 } }
77 };
78 g2::element expected = { { { 0x98399c68dd927f5, 0x585e18855b30df06, 0x9874333b9a1bab34, 0x2bb4f72523c319bf },
79 { 0x29e78f88e1516115, 0x9240c8e9ab1546d5, 0x8d350dc8b1c3b2b8, 0x17688e3c6ab5e4d2 } },
80 { { 0x1e57dc45f291a09e, 0xe54bbdd2e4e99866, 0x653c8c883714add1, 0xe71bea84e3257e6 },
81 { 0x75c1f2d7c18946a6, 0x315f562c7349c2e8, 0x686aea0f0df36a52, 0x9bfa6ed372f6a0e } },
82 { { 0xf5b3de9258529bb0, 0x532ab749f5abddd7, 0x448d9ba9d7eee9c0, 0x3053d1c7326c11a8 },
83 { 0x18457bf2457b178d, 0x8d9a26e09db091c1, 0xce0fce46e53efa63, 0x2594360eb4eaf8e4 } } };
84
85 lhs.x = lhs.x.to_montgomery_form();
86 lhs.y = lhs.y.to_montgomery_form();
87 lhs.z = lhs.z.to_montgomery_form();
88 affine_rhs.x = affine_rhs.x.to_montgomery_form();
89 affine_rhs.y = affine_rhs.y.to_montgomery_form();
90 expected.x = expected.x.to_montgomery_form();
91 expected.y = expected.y.to_montgomery_form();
92 expected.z = expected.z.to_montgomery_form();
93
94 g2::element result;
95
96 result = lhs + affine_rhs;
97 EXPECT_EQ(result == expected, true);
98}
99
100TEST(g2, AddCheckAgainstConstants)
101{
102 g2::element lhs = { { { 0xfe0ee11d88ef9c7c, 0xa50b3642c93787df, 0x5c4925f0812249a3, 0x13360054113b26e5 },
103 { 0x85a786ba7563664d, 0xebb6adaab3da2d35, 0x2e5c4b3e8bfae51d, 0x860451c5f3cb08 } },
104 { { 0x1336c5c955c13e31, 0x99acf7e0bf631edd, 0x7544255d031dcb7c, 0x170f93b2ac0d088d },
105 { 0xd27a61c30f2f9b75, 0x27abf783f3139bb9, 0x84ee0a9379a3c860, 0x23df8ba46e8f6ea7 } },
106 { { 0x3b2009df97845379, 0x3262a4c15a3ad056, 0xc5852fece05e2563, 0x1bb45a345c7765a9 },
107 { 0xaeb423ce4f95d63, 0xa9dee5d2983c1985, 0x8120e98ba5901fdb, 0x181589d4f3580f3a } } };
108 g2::element rhs = { { { 0x46debd5cd992f6ed, 0x674322d4f75edadd, 0x426a00665e5c4479, 0x1800deef121f1e76 },
109 { 0x97e485b7aef312c2, 0xf1aa493335a9e712, 0x7260bfb731fb5d25, 0x198e9393920d483a } },
110 { { 0x4ce6cc0166fa7daa, 0xe3d1e7690c43d37b, 0x4aab71808dcb408f, 0x12c85ea5db8c6deb },
111 { 0x55acdadcd122975b, 0xbc4b313370b38ef3, 0xec9e99ad690c3395, 0x90689d0585ff075 } },
112 { { 0x1, 0x0, 0x0, 0x0 }, { 0x0, 0x0, 0x0, 0x0 } } };
113 g2::element expected = { { { 0x98399c68dd927f5, 0x585e18855b30df06, 0x9874333b9a1bab34, 0x2bb4f72523c319bf },
114 { 0x29e78f88e1516115, 0x9240c8e9ab1546d5, 0x8d350dc8b1c3b2b8, 0x17688e3c6ab5e4d2 } },
115 { { 0x1e57dc45f291a09e, 0xe54bbdd2e4e99866, 0x653c8c883714add1, 0xe71bea84e3257e6 },
116 { 0x75c1f2d7c18946a6, 0x315f562c7349c2e8, 0x686aea0f0df36a52, 0x9bfa6ed372f6a0e } },
117 { { 0xf5b3de9258529bb0, 0x532ab749f5abddd7, 0x448d9ba9d7eee9c0, 0x3053d1c7326c11a8 },
118 { 0x18457bf2457b178d, 0x8d9a26e09db091c1, 0xce0fce46e53efa63, 0x2594360eb4eaf8e4 } } };
119
120 lhs.x = lhs.x.to_montgomery_form();
121 lhs.y = lhs.y.to_montgomery_form();
122 lhs.z = lhs.z.to_montgomery_form();
123 rhs.x = rhs.x.to_montgomery_form();
124 rhs.y = rhs.y.to_montgomery_form();
125 rhs.z = rhs.z.to_montgomery_form();
126
127 expected.x = expected.x.to_montgomery_form();
128 expected.y = expected.y.to_montgomery_form();
129 expected.z = expected.z.to_montgomery_form();
130
131 g2::element result;
132 result = lhs + rhs;
133 EXPECT_EQ(result == expected, true);
134}
135
136TEST(g2, AddExceptionTestInfinity)
137{
138 g2::element lhs = g2::element::random_element();
139 g2::element rhs;
140 g2::element result;
141
142 rhs = -lhs;
143
144 result = lhs + rhs;
145
146 EXPECT_EQ(result.is_point_at_infinity(), true);
147
148 g2::element rhs_b;
149 rhs_b = rhs;
150 rhs_b.self_set_infinity();
151
152 result = lhs + rhs_b;
153
154 EXPECT_EQ(lhs == result, true);
155
156 lhs.self_set_infinity();
157 result = lhs + rhs;
158
159 EXPECT_EQ(rhs == result, true);
160}
161
162TEST(g2, AddExceptionTestDbl)
163{
164 g2::element lhs = g2::element::random_element();
165 g2::element rhs;
166 rhs = lhs;
167
168 g2::element result;
169 g2::element expected;
170
171 result = lhs + rhs;
172 expected = lhs.dbl();
173
174 EXPECT_EQ(result == expected, true);
175}
176
177TEST(g2, AddDblConsistency)
178{
179 g2::element a = g2::element::random_element();
180 g2::element b = g2::element::random_element();
181
182 g2::element c;
183 g2::element d;
184 g2::element add_result;
185 g2::element dbl_result;
186
187 c = a + b;
188 b = -b;
189 d = a + b;
190
191 add_result = c + d;
192 dbl_result = a.dbl();
193
194 EXPECT_EQ(add_result == dbl_result, true);
195}
196
197TEST(g2, AddDblConsistencyRepeated)
198{
199 g2::element a = g2::element::random_element();
201 g2::element c;
202 g2::element d;
203 g2::element e;
204
205 g2::element result;
206 g2::element expected;
207
208 b = a.dbl(); // b = 2a
209 c = b.dbl(); // c = 4a
210
211 d = a + b; // d = 3a
212 e = a + c; // e = 5a
213 result = d + e; // result = 8a
214
215 expected = c.dbl(); // expected = 8a
216
217 EXPECT_EQ(result == expected, true);
218}
219
220TEST(g2, MixedAddExceptionTestInfinity)
221{
222 g2::element lhs = g2::one;
223 g2::affine_element rhs = g2::element::random_element();
224 lhs = { rhs.x, -rhs.y, fq2::one() };
225
226 g2::element result;
227 result = lhs + rhs;
228
229 EXPECT_EQ(result.is_point_at_infinity(), true);
230
231 lhs.self_set_infinity();
232 result = lhs + rhs;
233 g2::element rhs_c;
234 rhs_c = g2::element(rhs);
235
236 EXPECT_EQ(rhs_c == result, true);
237}
238
239TEST(g2, MixedAddExceptionTestDbl)
240{
241 g2::affine_element rhs = g2::element::random_element();
242 g2::element lhs;
243 lhs = g2::element(rhs);
244
245 g2::element result;
246 g2::element expected;
247 result = lhs + rhs;
248
249 expected = lhs.dbl();
250
251 EXPECT_EQ(result == expected, true);
252}
253
254TEST(g2, AddMixedAddConsistencyCheck)
255{
256 g2::affine_element rhs = g2::element::random_element();
257 g2::element lhs = g2::element::random_element();
258 g2::element rhs_b;
259 rhs_b = g2::element(rhs);
260
261 g2::element add_result;
262 g2::element mixed_add_result;
263 add_result = lhs + rhs_b;
264 mixed_add_result = lhs + rhs;
265
266 EXPECT_EQ(add_result == mixed_add_result, true);
267}
268
269TEST(g2, BatchNormalize)
270{
271 size_t num_points = 2;
272 std::vector<g2::element> points(num_points);
273 std::vector<g2::element> normalized(num_points);
274
275 for (size_t i = 0; i < num_points; ++i) {
276 g2::element a = g2::element::random_element();
277 g2::element b = g2::element::random_element();
278 points[i] = a + b;
279 normalized[i] = points[i];
280 }
281 g2::element::batch_normalize(&normalized[0], num_points);
282
283 for (size_t i = 0; i < num_points; ++i) {
284 fq2 zz = points[i].z.sqr();
285 fq2 zzz = zz * points[i].z;
286 fq2 result_x = normalized[i].x * zz;
287 fq2 result_y = normalized[i].y * zzz;
288
289 EXPECT_EQ(result_x, points[i].x);
290 EXPECT_EQ(result_y, points[i].y);
291 }
292}
293
294TEST(g2, GroupExponentiationCheckAgainstConstants)
295{
296 fr scalar = { 0xc4199e4b971f705, 0xc8d89c916a23ab3d, 0x7ea3cd7c05c7af82, 0x2fdafbf994a8d400 };
297 g2::affine_element lhs = { { { 0x46debd5cd992f6ed, 0x674322d4f75edadd, 0x426a00665e5c4479, 0x1800deef121f1e76 },
298 { 0x97e485b7aef312c2, 0xf1aa493335a9e712, 0x7260bfb731fb5d25, 0x198e9393920d483a } },
299 { { 0x4ce6cc0166fa7daa, 0xe3d1e7690c43d37b, 0x4aab71808dcb408f, 0x12c85ea5db8c6deb },
300 { 0x55acdadcd122975b, 0xbc4b313370b38ef3, 0xec9e99ad690c3395, 0x90689d0585ff075 } } };
301 g2::affine_element expected = {
302 { { 0x3363a6e8193817c0, 0x5edb295efcf8a8f0, 0xe33df179b9821b84, 0xaa0f7e7c00600d3 },
303 { 0x91b09f192f2b3eb2, 0x3a27767998031cd5, 0xa44abe0ef5ba1c0f, 0x10bbc579ca6f412f } },
304 { { 0xa8850d9c027ba4db, 0xae6147163c4068a6, 0x5f73bedc2cd52fab, 0x159dfbb82478b51b },
305 { 0x33cccf11dd7d7fb2, 0xcbb3c7c098cbb079, 0x2e83153ab90a931d, 0x26d19735b36c2d08 } }
306 };
307
309 lhs.x = lhs.x.to_montgomery_form();
310 lhs.y = lhs.y.to_montgomery_form();
311 expected.x = expected.x.to_montgomery_form();
312 expected.y = expected.y.to_montgomery_form();
313
314 g2::affine_element result(g2::element(lhs) * scalar);
315
316 EXPECT_EQ(result == expected, true);
317}
318
319TEST(g2, GroupExponentiationZeroAndOne)
320{
322
323 EXPECT_EQ(result.is_point_at_infinity(), true);
324
325 result = g2::one * fr::one();
326 EXPECT_EQ(result == g2::affine_one, true);
327}
328
329TEST(g2, GroupExponentiationConsistencyCheck)
330{
333
334 fr c;
335 c = a * b;
336
338 g2::affine_element result(g2::element(input) * a);
339 result = g2::affine_element(g2::element(result) * b);
340
341 g2::affine_element expected = input * c;
342
343 EXPECT_EQ(result == expected, true);
344}
345
346TEST(g2, Serialize)
347{
348 // test serializing random points
349 size_t num_repetitions(1);
350 for (size_t i = 0; i < num_repetitions; i++) {
351 g2::affine_element expected = g2::element::random_element();
352
353 std::array<uint8_t, sizeof(g2::affine_element)> buffer;
354
355 g2::affine_element::serialize_to_buffer(expected, &buffer[0]);
356
357 g2::affine_element result = g2::affine_element::serialize_from_buffer(&buffer[0]);
358
359 EXPECT_EQ(result == expected, true);
360 }
361
362 // test serializing the point at infinity
363 {
364 g2::affine_element expected = g2::element::random_element();
365 expected.self_set_infinity();
366 std::array<uint8_t, sizeof(g2::affine_element)> buffer;
367
368 g2::affine_element::serialize_to_buffer(expected, &buffer[0]);
369
370 g2::affine_element result = g2::affine_element::serialize_from_buffer(&buffer[0]);
371
372 ASSERT_TRUE(result.is_point_at_infinity());
373 EXPECT_EQ(result == expected, true);
374 }
375}
376
377template <class T> void write(const T t)
378{
379 FILE* fp = fopen("/dev/null", "wb");
380 static_cast<void>(fwrite(&t, sizeof(t), 1, fp));
381 static_cast<void>(fclose(fp));
382}
383
384#if !defined(__wasm__)
385TEST(g2, InitializationCheck)
386{
387 // NOLINTNEXTLINE not our fault googletest uses `goto`!
388 EXPECT_NO_THROW(write<g2::affine_element>({}));
389}
390#endif
constexpr bool is_point_at_infinity() const noexcept
constexpr void self_set_infinity() noexcept
constexpr bool on_curve() const noexcept
element class. Implements ecc group arithmetic using Jacobian coordinates See https://hyperelliptic....
Definition element.hpp:33
constexpr element dbl() const noexcept
constexpr element normalize() const noexcept
BB_INLINE constexpr bool on_curve() const noexcept
BB_INLINE constexpr void self_set_infinity() noexcept
BB_INLINE constexpr bool is_point_at_infinity() const noexcept
group class. Represents an elliptic curve group element. Group is parametrised by Fq and Fr
Definition group.hpp:36
group_elements::affine_element< Fq, Fr, Params > affine_element
Definition group.hpp:42
static constexpr element one
Definition group.hpp:46
static constexpr affine_element affine_one
Definition group.hpp:48
group_elements::element< Fq, Fr, Params > element
Definition group.hpp:41
FF a
FF b
uint8_t buffer[RANDOM_BUFFER_SIZE]
Definition engine.cpp:34
void write(const T t)
Definition g2.test.cpp:377
Entry point for Barretenberg command-line interface.
TEST(MegaCircuitBuilder, CopyConstructor)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
constexpr field2 sqr() const noexcept
Definition field2.hpp:74
static constexpr field2 one()
static constexpr field one()
BB_INLINE constexpr field to_montgomery_form() const noexcept
static field random_element(numeric::RNG *engine=nullptr) noexcept
BB_INLINE constexpr void self_to_montgomery_form() &noexcept
static constexpr field zero()