Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
g1.test.cpp
Go to the documentation of this file.
1#include "g1.hpp"
4#include <gtest/gtest.h>
5
6using namespace bb;
7
8TEST(g1, RandomElement)
9{
10 g1::element result = g1::element::random_element();
11 EXPECT_EQ(result.on_curve(), true);
12}
13
14TEST(g1, RandomAffineElement)
15{
16 g1::affine_element result = g1::element::random_element();
17 EXPECT_EQ(result.on_curve(), true);
18}
19
20TEST(g1, Eq)
21{
22 g1::element a = g1::element::random_element();
24
25 EXPECT_EQ(a == b, true);
26 EXPECT_EQ(a == a, true);
27
28 b.self_set_infinity();
29
30 EXPECT_EQ(a == b, false);
31 g1::element c = g1::element::random_element();
32
33 EXPECT_EQ(a == c, false);
34
35 a.self_set_infinity();
36
37 EXPECT_EQ(a == b, true);
38}
39
40TEST(g1, MixedAddCheckAgainstConstants)
41{
42 fq a_x{ 0x92716caa6cac6d26, 0x1e6e234136736544, 0x1bb04588cde00af0, 0x9a2ac922d97e6f5 };
43 fq a_y{ 0x9e693aeb52d79d2d, 0xf0c1895a61e5e975, 0x18cd7f5310ced70f, 0xac67920a22939ad };
44 fq a_z{ 0xfef593c9ce1df132, 0xe0486f801303c27d, 0x9bbd01ab881dc08e, 0x2a589badf38ec0f9 };
45 fq b_x{ 0xa1ec5d1398660db8, 0x6be3e1f6fd5d8ab1, 0x69173397dd272e11, 0x12575bbfe1198886 };
46 fq b_y{ 0xcfbfd4441138823e, 0xb5f817e28a1ef904, 0xefb7c5629dcc1c42, 0x1a9ed3d6f846230e };
47 fq expected_x{ 0x2a9d0201fccca20, 0x36f969b294f31776, 0xee5534422a6f646, 0x911dbc6b02310b6 };
48 fq expected_y{ 0x14c30aaeb4f135ef, 0x9c27c128ea2017a1, 0xf9b7d80c8315eabf, 0x35e628df8add760 };
49 fq expected_z{ 0xa43fe96673d10eb3, 0x88fbe6351753d410, 0x45c21cc9d99cb7d, 0x3018020aa6e9ede5 };
50 g1::element lhs;
52 g1::element result;
53 g1::element expected;
54 lhs.x = a_x.to_montgomery_form();
55 lhs.y = a_y.to_montgomery_form();
56 lhs.z = a_z.to_montgomery_form();
57 rhs.x = b_x.to_montgomery_form();
58 rhs.y = b_y.to_montgomery_form();
59 expected.x = expected_x.to_montgomery_form();
60 expected.y = expected_y.to_montgomery_form();
61 expected.z = expected_z.to_montgomery_form();
62 result = lhs + rhs;
63
64 EXPECT_EQ(result == expected, true);
65}
66
67TEST(g1, DblCheckAgainstConstants)
68{
69 fq a_x{ 0x8d1703aa518d827f, 0xd19cc40779f54f63, 0xabc11ce30d02728c, 0x10938940de3cbeec };
70 fq a_y{ 0xcf1798994f1258b4, 0x36307a354ad90a25, 0xcd84adb348c63007, 0x6266b85241aff3f };
71 fq a_z{ 0xe213e18fd2df7044, 0xb2f42355982c5bc8, 0xf65cf5150a3a9da1, 0xc43bde08b03aca2 };
72 fq expected_x{ 0xd5c6473044b2e67c, 0x89b185ea20951f3a, 0x4ac597219cf47467, 0x2d00482f63b12c86 };
73 fq expected_y{ 0x4e7e6c06a87e4314, 0x906a877a71735161, 0xaa7b9893cc370d39, 0x62f206bef795a05 };
74 fq expected_z{ 0x8813bdca7b0b115a, 0x929104dffdfabd22, 0x3fff575136879112, 0x18a299c1f683bdca };
75 g1::element lhs;
76 g1::element result;
77 g1::element expected;
78 lhs.x = a_x.to_montgomery_form();
79 lhs.y = a_y.to_montgomery_form();
80 lhs.z = a_z.to_montgomery_form();
81 expected.x = expected_x.to_montgomery_form();
82 expected.y = expected_y.to_montgomery_form();
83 expected.z = expected_z.to_montgomery_form();
84
85 result = lhs.dbl();
86 result.self_dbl();
87 result.self_dbl();
88
89 EXPECT_EQ(result == expected, true);
90}
91
92TEST(g1, AddCheckAgainstConstants)
93{
94 fq a_x{ 0x184b38afc6e2e09a, 0x4965cd1c3687f635, 0x334da8e7539e71c4, 0xf708d16cfe6e14 };
95 fq a_y{ 0x2a6ff6ffc739b3b6, 0x70761d618b513b9, 0xbf1645401de26ba1, 0x114a1616c164b980 };
96 fq a_z{ 0x10143ade26bbd57a, 0x98cf4e1f6c214053, 0x6bfdc534f6b00006, 0x1875e5068ababf2c };
97 fq b_x{ 0xafdb8a15c98bf74c, 0xac54df622a8d991a, 0xc6e5ae1f3dad4ec8, 0x1bd3fb4a59e19b52 };
98 fq b_y{ 0x21b3bb529bec20c0, 0xaabd496406ffb8c1, 0xcd3526c26ac5bdcb, 0x187ada6b8693c184 };
99 fq b_z{ 0xffcd440a228ed652, 0x8a795c8f234145f1, 0xd5279cdbabb05b95, 0xbdf19ba16fc607a };
100 fq expected_x{ 0x18764da36aa4cd81, 0xd15388d1fea9f3d3, 0xeb7c437de4bbd748, 0x2f09b712adf6f18f };
101 fq expected_y{ 0x50c5f3cab191498c, 0xe50aa3ce802ea3b5, 0xd9d6125b82ebeff8, 0x27e91ba0686e54fe };
102 fq expected_z{ 0xe4b81ef75fedf95, 0xf608edef14913c75, 0xfd9e178143224c96, 0xa8ae44990c8accd };
103 g1::element lhs;
104 g1::element rhs;
105 g1::element result;
106 g1::element expected;
107
108 lhs.x = a_x.to_montgomery_form();
109 lhs.y = a_y.to_montgomery_form();
110 lhs.z = a_z.to_montgomery_form();
111 rhs.x = b_x.to_montgomery_form();
112 rhs.y = b_y.to_montgomery_form();
113 rhs.z = b_z.to_montgomery_form();
114 expected.x = expected_x.to_montgomery_form();
115 expected.y = expected_y.to_montgomery_form();
116 expected.z = expected_z.to_montgomery_form();
117
118 result = lhs + rhs;
119
120 EXPECT_EQ(result == expected, true);
121}
122
123TEST(g1, AddExceptionTestInfinity)
124{
125 g1::element lhs = g1::element::random_element();
126 g1::element rhs;
127 g1::element result;
128
129 rhs = -lhs;
130
131 result = lhs + rhs;
132
133 EXPECT_EQ(result.is_point_at_infinity(), true);
134
135 g1::element rhs_b;
136 rhs_b = rhs;
137 rhs_b.self_set_infinity();
138
139 result = lhs + rhs_b;
140
141 EXPECT_EQ(lhs == result, true);
142
143 lhs.self_set_infinity();
144 result = lhs + rhs;
145
146 EXPECT_EQ(rhs == result, true);
147}
148
149TEST(g1, TestInfinity)
150{
151 g1::affine_element inf_affine = g1::affine_element::infinity();
152 EXPECT_EQ(inf_affine.is_point_at_infinity(), true);
153
154 g1::element inf_element = g1::element::infinity();
155 EXPECT_EQ(inf_element.is_point_at_infinity(), true);
156}
157
158TEST(g1, AddExceptionTestDbl)
159{
160 g1::element lhs = g1::element::random_element();
161 g1::element rhs;
162 rhs = lhs;
163
164 g1::element result;
165 g1::element expected;
166
167 result = lhs + rhs;
168 expected = lhs.dbl();
169
170 EXPECT_EQ(result == expected, true);
171}
172
173TEST(g1, AddAffineTest)
174{
175 g1::element lhs = g1::element::random_element();
176 g1::affine_element lhs_affine(lhs);
177
178 g1::element rhs = g1::element::random_element();
179 g1::affine_element rhs_affine(rhs);
180
181 g1::element expected = lhs + rhs;
182 g1::affine_element result = lhs_affine + rhs_affine;
183 EXPECT_EQ(g1::element(result) == expected, true);
184}
185
186TEST(g1, AddDblConsistency)
187{
188 g1::element a = g1::element::random_element();
189 g1::element b = g1::element::random_element();
190
191 g1::element c;
192 g1::element d;
193 g1::element add_result;
194 g1::element dbl_result;
195
196 c = a + b;
197 b = -b;
198 d = a + b;
199
200 add_result = c + d;
201 dbl_result = a.dbl();
202
203 EXPECT_EQ(add_result == dbl_result, true);
204}
205
206TEST(g1, AddDblConsistencyRepeated)
207{
208 g1::element a = g1::element::random_element();
210 g1::element c;
211 g1::element d;
212 g1::element e;
213
214 g1::element result;
215 g1::element expected;
216
217 b = a.dbl(); // b = 2a
218 c = b.dbl(); // c = 4a
219
220 d = a + b; // d = 3a
221 e = a + c; // e = 5a
222 result = d + e; // result = 8a
223
224 expected = c.dbl(); // expected = 8a
225
226 EXPECT_EQ(result == expected, true);
227}
228
229TEST(g1, MixedAddExceptionTestInfinity)
230{
231 g1::element lhs = g1::one;
232 g1::affine_element rhs = g1::element::random_element();
233 fq::__copy(rhs.x, lhs.x);
234 lhs.y = -rhs.y;
235
236 g1::element result;
237 result = lhs + rhs;
238
239 EXPECT_EQ(result.is_point_at_infinity(), true);
240
241 lhs.self_set_infinity();
242 result = lhs + rhs;
243 g1::element rhs_c;
244 rhs_c = g1::element(rhs);
245
246 EXPECT_EQ(rhs_c == result, true);
247}
248
249TEST(g1, MixedAddExceptionTestDbl)
250{
251 g1::affine_element rhs = g1::element::random_element();
252 g1::element lhs;
253 lhs = g1::element(rhs);
254
255 g1::element result;
256 g1::element expected;
257 result = lhs + rhs;
258
259 expected = lhs.dbl();
260
261 EXPECT_EQ(result == expected, true);
262}
263
264TEST(g1, AddMixedAddConsistencyCheck)
265{
266 g1::affine_element rhs = g1::element::random_element();
267 g1::element lhs = g1::element::random_element();
268 g1::element rhs_b;
269 rhs_b = g1::element(rhs);
270
271 g1::element add_result;
272 g1::element mixed_add_result;
273 add_result = lhs + rhs_b;
274 mixed_add_result = lhs + rhs;
275
276 EXPECT_EQ(add_result == mixed_add_result, true);
277}
278
279TEST(g1, BatchNormalize)
280{
281 size_t num_points = 2;
282 std::vector<g1::element> points(num_points);
283 std::vector<g1::element> normalized(num_points);
284 for (size_t i = 0; i < num_points; ++i) {
285 g1::element a = g1::element::random_element();
286 g1::element b = g1::element::random_element();
287 points[i] = a + b;
288 normalized[i] = points[i];
289 }
290 g1::element::batch_normalize(&normalized[0], num_points);
291
292 for (size_t i = 0; i < num_points; ++i) {
293 fq zz;
294 fq zzz;
295 fq result_x;
296 fq result_y;
297 zz = points[i].z.sqr();
298 zzz = points[i].z * zz;
299 result_x = normalized[i].x * zz;
300 result_y = normalized[i].y * zzz;
301
302 EXPECT_EQ((result_x == points[i].x), true);
303 EXPECT_EQ((result_y == points[i].y), true);
304 }
305}
306
307TEST(g1, GroupExponentiationCheckAgainstConstants)
308{
309 fr a{ 0xb67299b792199cf0, 0xc1da7df1e7e12768, 0x692e427911532edf, 0x13dd85e87dc89978 };
311
312 fq expected_x{ 0x9bf840faf1b4ba00, 0xe81b7260d068e663, 0x7610c9a658d2c443, 0x278307cd3d0cddb0 };
313 fq expected_y{ 0xf6ed5fb779ebecb, 0x414ca771acbe183c, 0xe3692cb56dfbdb67, 0x3d3c5ed19b080a3 };
314
315 g1::affine_element expected;
316 expected.x = expected_x.to_montgomery_form();
317 expected.y = expected_y.to_montgomery_form();
318
319 g1::affine_element result(g1::one * a);
320
321 EXPECT_EQ(result == expected, true);
322}
323
324TEST(g1, OperatorOrdering)
325{
326 // fq a_x{ 0x92716caa6cac6d26, 0x1e6e234136736544, 0x1bb04588cde00af0, 0x9a2ac922d97e6f5 };
327 // fq a_y{ 0x9e693aeb52d79d2d, 0xf0c1895a61e5e975, 0x18cd7f5310ced70f, 0xac67920a22939ad };
328 // fq a_z{ 0xfef593c9ce1df132, 0xe0486f801303c27d, 0x9bbd01ab881dc08e, 0x2a589badf38ec0f9 };
329 fr scalar{ 0xcfbfd4441138823e, 0xb5f817e28a1ef904, 0xefb7c5629dcc1c42, 0x1a9ed3d6f846230e };
330 // fq expected_x{ 0x2a9d0201fccca20, 0x36f969b294f31776, 0xee5534422a6f646, 0x911dbc6b02310b6 };
331 // fq expected_y{ 0x14c30aaeb4f135ef, 0x9c27c128ea2017a1, 0xf9b7d80c8315eabf, 0x35e628df8add760 };
332 // fq expected_z{ 0xa43fe96673d10eb3, 0x88fbe6351753d410, 0x45c21cc9d99cb7d, 0x3018020aa6e9ede5 };
333
336
337 g1::element c = a + b;
338 g1::element d = b + a;
339 EXPECT_EQ(c, d);
340
341 g1::element e = a * scalar;
342 g1::element f = b * scalar;
343 g1::affine_element g = b * scalar;
344 g1::affine_element h = a * scalar;
345 EXPECT_EQ(e, f);
346 EXPECT_EQ(g, h);
347}
348
349TEST(g1, GroupExponentiationZeroAndOne)
350{
352
353 EXPECT_EQ(result.is_point_at_infinity(), true);
354
355 result = g1::one * fr::one();
356
357 EXPECT_EQ(result == g1::affine_one, true);
358}
359
360TEST(g1, GroupExponentiationConsistencyCheck)
361{
364
365 fr c;
366 c = a * b;
367
369 g1::affine_element result(g1::element(input) * a);
370 result = g1::affine_element(g1::element(result) * b);
371
373
374 EXPECT_EQ(result == expected, true);
375}
376
377TEST(g1, DeriveGenerators)
378{
379 constexpr size_t num_generators = 128;
380 auto result = g1::derive_generators("test domain", 128);
381
382 const auto is_unique = [&result](const g1::affine_element& y, const size_t j) {
383 for (size_t i = 0; i < result.size(); ++i) {
384 if ((i != j) && result[i] == y) {
385 return false;
386 }
387 }
388 return true;
389 };
390
391 for (size_t k = 0; k < num_generators; ++k) {
392 EXPECT_EQ(is_unique(result[k], k), true);
393 EXPECT_EQ(result[k].on_curve(), true);
394 }
395}
396
397TEST(g1, Serialize)
398{
399 g1::affine_element expected = g1::element::random_element();
400
401 std::vector<uint8_t> buffer(sizeof(g1::affine_element));
402
403 g1::affine_element::serialize_to_buffer(expected, &buffer[0]);
404
405 g1::affine_element result = g1::affine_element::serialize_from_buffer(&buffer[0]);
406
407 EXPECT_EQ(result == expected, true);
408}
409template <class T> void write(const T t)
410{
411 FILE* fp = fopen("/dev/null", "wb");
412 static_cast<void>(fwrite(&t, sizeof(t), 1, fp));
413 static_cast<void>(fclose(fp));
414}
415
416#if !defined(__wasm__)
417TEST(g1, InitializationCheck)
418{
419 // NOLINTNEXTLINE not our fault googletest uses `goto`!
420 EXPECT_NO_THROW(write<g1::affine_element>({}));
421}
422#endif
423
424TEST(g1, CheckPrecomputedGenerators)
425{
426 ASSERT_TRUE((bb::check_precomputed_generators<g1, "biggroup table offset generator", 1UL>()));
427 ASSERT_TRUE((bb::check_precomputed_generators<g1, "biggroup offset generator", 1UL>()));
428 ASSERT_TRUE((bb::check_precomputed_generators<g1, "ECCVM_OFFSET_GENERATOR", 1UL>()));
429 ASSERT_TRUE((bb::check_precomputed_generators<g1, "test generators", 2UL>()));
430}
constexpr bool is_point_at_infinity() const 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
constexpr void self_dbl() 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
static std::vector< affine_element > derive_generators(const std::vector< uint8_t > &domain_separator_bytes, const size_t num_generators, const size_t starting_index=0)
Derives generator points via hash-to-curve.
Definition group.hpp:87
FF a
FF b
uint8_t buffer[RANDOM_BUFFER_SIZE]
Definition engine.cpp:34
void write(const T t)
Definition g1.test.cpp:409
Entry point for Barretenberg command-line interface.
TEST(MegaCircuitBuilder, CopyConstructor)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
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 field sqr() const noexcept
static BB_INLINE void __copy(const field &a, field &r) noexcept
BB_INLINE constexpr void self_to_montgomery_form() &noexcept
static constexpr field zero()