14 #ifdef PROFILE_OP_COUNTS
15 long long bn128_G1::add_cnt = 0;
16 long long bn128_G1::dbl_cnt = 0;
25 bn::Fp bn128_G1::sqrt(
const bn::Fp &el)
36 for (
size_t i = 0; i < v - 1; ++i) {
37 bn::Fp::square(check, check);
40 assert(check == bn::Fp(1));
46 while (b != bn::Fp(1)) {
49 while (b2m != bn::Fp(1)) {
51 bn::Fp::square(b2m, b2m);
86 std::cout <<
"(" << copy.
X.toString(10) <<
" : " << copy.
Y.toString(10)
87 <<
" : " << copy.
Z.toString(10) <<
")\n";
96 std::cout <<
"(" <<
X.toString(10) <<
" : " <<
Y.toString(10) <<
" : "
97 <<
Z.toString(10) <<
")\n";
111 bn::Fp::square(
Z, r);
137 bn::Fp Z1sq, Z2sq, lhs, rhs;
138 bn::Fp::square(Z1sq, this->
Z);
139 bn::Fp::square(Z2sq, other.
Z);
140 bn::Fp::mul(lhs, Z2sq, this->
X);
141 bn::Fp::mul(rhs, Z1sq, other.
X);
147 bn::Fp Z1cubed, Z2cubed;
148 bn::Fp::mul(Z1cubed, Z1sq, this->
Z);
149 bn::Fp::mul(Z2cubed, Z2sq, other.
Z);
150 bn::Fp::mul(lhs, Z2cubed, this->
Y);
151 bn::Fp::mul(rhs, Z1cubed, other.
Y);
176 if (this->
operator==(other)) {
179 return this->
add(other);
186 bn::Fp::neg(result.
Y, result.
Y);
192 return (*
this) + (-other);
197 #ifdef PROFILE_OP_COUNTS
201 bn::Fp this_coord[3], other_coord[3], result_coord[3];
204 bn::ecop::ECAdd(result_coord, this_coord, other_coord);
239 bn::Fp::square(Z1Z1, this->
Z);
240 const bn::Fp &U1 = this->
X;
242 bn::Fp::mul(U2, other.
X, Z1Z1);
244 bn::Fp::mul(Z1_cubed, this->
Z, Z1Z1);
246 const bn::Fp &S1 = this->
Y;
248 bn::Fp::mul(S2, other.
Y, Z1_cubed);
250 if (U1 == U2 && S1 == S2) {
255 #ifdef PROFILE_OP_COUNTS
260 bn::Fp H, HH, I, J, r, V, tmp;
262 bn::Fp::sub(H, U2, this->
X);
264 bn::Fp::square(HH, H);
266 bn::Fp::add(tmp, HH, HH);
267 bn::Fp::add(I, tmp, tmp);
269 bn::Fp::mul(J, H, I);
271 bn::Fp::sub(tmp, S2, this->
Y);
272 bn::Fp::add(r, tmp, tmp);
274 bn::Fp::mul(V, this->
X, I);
276 bn::Fp::square(result.
X, r);
277 bn::Fp::sub(result.
X, result.
X, J);
278 bn::Fp::sub(result.
X, result.
X, V);
279 bn::Fp::sub(result.
X, result.
X, V);
281 bn::Fp::sub(tmp, V, result.
X);
282 bn::Fp::mul(result.
Y, r, tmp);
283 bn::Fp::mul(tmp, this->
Y, J);
284 bn::Fp::sub(result.
Y, result.
Y, tmp);
285 bn::Fp::sub(result.
Y, result.
Y, tmp);
287 bn::Fp::add(tmp, this->
Z, H);
288 bn::Fp::square(result.
Z, tmp);
289 bn::Fp::sub(result.
Z, result.
Z, Z1Z1);
290 bn::Fp::sub(result.
Z, result.
Z, HH);
296 #ifdef PROFILE_OP_COUNTS
300 bn::Fp this_coord[3], result_coord[3];
302 bn::ecop::ECDouble(result_coord, this_coord);
339 bn::Fp::square(X2, this->
X);
340 bn::Fp::square(Y2, this->
Y);
341 bn::Fp::square(Z2, this->
Z);
344 bn::Fp::mul(X3, X2, this->
X);
345 bn::Fp::mul(Z3, Z2, this->
Z);
346 bn::Fp::square(Z6, Z3);
361 #ifndef BINARY_OUTPUT
364 out.write((
char *)&gcopy.
X,
sizeof(gcopy.
X));
365 out.write((
char *)&gcopy.
Y,
sizeof(gcopy.
Y));
376 #ifndef BINARY_OUTPUT
379 out.write((
char *)&gcopy.
X,
sizeof(gcopy.
X));
391 #ifndef BINARY_OUTPUT
396 in.read((
char *)&g.
X,
sizeof(g.
X));
397 in.read((
char *)&g.
Y,
sizeof(g.
Y));
417 #ifndef BINARY_OUTPUT
420 in.read((
char *)&tX,
sizeof(tX));
424 in.read((
char *)&Y_lsb, 1);
431 bn::Fp::square(tX2, tX);
432 bn::Fp::mul(tY2, tX2, tX);
435 g.
Y = bn128_G1::sqrt(tY2);
436 if ((((
unsigned char *)&g.
Y)[0] & 1) != Y_lsb) {
437 bn::Fp::neg(g.
Y, g.
Y);
451 #ifdef NO_PT_COMPRESSION
461 #ifdef NO_PT_COMPRESSION
471 std::vector<bn::Fp> Z_vec;
472 Z_vec.reserve(vec.size());
474 for (
auto &el : vec) {
475 Z_vec.emplace_back(el.Z);
477 bn_batch_invert<bn::Fp>(Z_vec);
479 const bn::Fp
one = 1;
481 for (
size_t i = 0; i < vec.size(); ++i) {
483 bn::Fp::square(Z2, Z_vec[i]);
484 bn::Fp::mul(Z3, Z2, Z_vec[i]);
486 bn::Fp::mul(vec[i].
X, vec[i].
X, Z2);
487 bn::Fp::mul(vec[i].
Y, vec[i].
Y, Z3);