Clearmatics Libff  0.1
C++ library for Finite Fields and Elliptic Curves
mnt4_g2.cpp
Go to the documentation of this file.
1 
15 
16 namespace libff
17 {
18 
19 #ifdef PROFILE_OP_COUNTS
20 long long mnt4_G2::add_cnt = 0;
21 long long mnt4_G2::dbl_cnt = 0;
22 #endif
23 
24 std::vector<size_t> mnt4_G2::wnaf_window_table;
25 std::vector<size_t> mnt4_G2::fixed_base_exp_window_table;
29 mnt4_G2 mnt4_G2::G2_zero;
30 mnt4_G2 mnt4_G2::G2_one;
31 bigint<mnt4_G2::h_limbs> mnt4_G2::h;
32 
34 {
35  return mnt4_Fq2(
38 }
39 
41 {
42  return mnt4_Fq2(
45 }
46 
48 {
49  this->X = G2_zero.X;
50  this->Y = G2_zero.Y;
51  this->Z = G2_zero.Z;
52 }
53 
54 void mnt4_G2::print() const
55 {
56  if (this->is_zero()) {
57  printf("O\n");
58  } else {
59  mnt4_G2 copy(*this);
60  copy.to_affine_coordinates();
61  gmp_printf(
62  "(%Nd*z + %Nd , %Nd*z + %Nd)\n",
63  copy.X.coeffs[1].as_bigint().data,
65  copy.X.coeffs[0].as_bigint().data,
67  copy.Y.coeffs[1].as_bigint().data,
69  copy.Y.coeffs[0].as_bigint().data,
71  }
72 }
73 
75 {
76  if (this->is_zero()) {
77  printf("O\n");
78  } else {
79  gmp_printf(
80  "(%Nd*z + %Nd : %Nd*z + %Nd : %Nd*z + %Nd)\n",
81  this->X.coeffs[1].as_bigint().data,
83  this->X.coeffs[0].as_bigint().data,
85  this->Y.coeffs[1].as_bigint().data,
87  this->Y.coeffs[0].as_bigint().data,
89  this->Z.coeffs[1].as_bigint().data,
91  this->Z.coeffs[0].as_bigint().data,
93  }
94 }
95 
97 {
98  if (this->is_zero()) {
99  this->X = mnt4_Fq2::zero();
100  this->Y = mnt4_Fq2::one();
101  this->Z = mnt4_Fq2::zero();
102  } else {
103  const mnt4_Fq2 Z_inv = Z.inverse();
104  X = X * Z_inv;
105  Y = Y * Z_inv;
106  Z = mnt4_Fq2::one();
107  }
108 }
109 
111 
113 {
114  return (this->is_zero() || this->Z == mnt4_Fq2::one());
115 }
116 
117 bool mnt4_G2::is_zero() const
118 {
119  return (this->X.is_zero() && this->Z.is_zero());
120 }
121 
122 bool mnt4_G2::operator==(const mnt4_G2 &other) const
123 {
124  if (this->is_zero()) {
125  return other.is_zero();
126  }
127 
128  if (other.is_zero()) {
129  return false;
130  }
131 
132  /* now neither is O */
133 
134  // X1/Z1 = X2/Z2 <=> X1*Z2 = X2*Z1
135  if ((this->X * other.Z) != (other.X * this->Z)) {
136  return false;
137  }
138 
139  // Y1/Z1 = Y2/Z2 <=> Y1*Z2 = Y2*Z1
140  if ((this->Y * other.Z) != (other.Y * this->Z)) {
141  return false;
142  }
143 
144  return true;
145 }
146 
147 bool mnt4_G2::operator!=(const mnt4_G2 &other) const
148 {
149  return !(operator==(other));
150 }
151 
152 mnt4_G2 mnt4_G2::operator+(const mnt4_G2 &other) const
153 {
154  // handle special cases having to do with O
155  if (this->is_zero()) {
156  return other;
157  }
158 
159  if (other.is_zero()) {
160  return *this;
161  }
162 
163  // no need to handle points of order 2,4
164  // (they cannot exist in a prime-order subgroup)
165 
166  // handle double case, and then all the rest
167  /*
168  The code below is equivalent to (but faster than) the snippet below:
169 
170  if (this->operator==(other))
171  {
172  return this->dbl();
173  }
174  else
175  {
176  return this->add(other);
177  }
178  */
179 
180  // X1Z2 = X1*Z2
181  const mnt4_Fq2 X1Z2 = (this->X) * (other.Z);
182  // X2Z1 = X2*Z1
183  const mnt4_Fq2 X2Z1 = (this->Z) * (other.X);
184 
185  // (used both in add and double checks)
186 
187  // Y1Z2 = Y1*Z2
188  const mnt4_Fq2 Y1Z2 = (this->Y) * (other.Z);
189  // Y2Z1 = Y2*Z1
190  const mnt4_Fq2 Y2Z1 = (this->Z) * (other.Y);
191 
192  if (X1Z2 == X2Z1 && Y1Z2 == Y2Z1) {
193  // perform dbl case
194  // XX = X1^2
195  const mnt4_Fq2 XX = (this->X).squared();
196  // ZZ = Z1^2
197  const mnt4_Fq2 ZZ = (this->Z).squared();
198  // w = a*ZZ + 3*XX
199  const mnt4_Fq2 w = mnt4_G2::mul_by_a(ZZ) + (XX + XX + XX);
200  const mnt4_Fq2 Y1Z1 = (this->Y) * (this->Z);
201  // s = 2*Y1*Z1
202  const mnt4_Fq2 s = Y1Z1 + Y1Z1;
203  // ss = s^2
204  const mnt4_Fq2 ss = s.squared();
205  // sss = s*ss
206  const mnt4_Fq2 sss = s * ss;
207  // R = Y1*s
208  const mnt4_Fq2 R = (this->Y) * s;
209  // RR = R^2
210  const mnt4_Fq2 RR = R.squared();
211  // B = (X1+R)^2 - XX - RR
212  const mnt4_Fq2 B = ((this->X) + R).squared() - XX - RR;
213  // h = w^2 - 2*B
214  const mnt4_Fq2 h = w.squared() - (B + B);
215  // X3 = h*s
216  const mnt4_Fq2 X3 = h * s;
217  // Y3 = w*(B-h) - 2*RR
218  const mnt4_Fq2 Y3 = w * (B - h) - (RR + RR);
219  // Z3 = sss
220  const mnt4_Fq2 Z3 = sss;
221 
222  return mnt4_G2(X3, Y3, Z3);
223  }
224 
225  // if we have arrived here we are in the add case
226  // Z1Z2 = Z1*Z2
227  const mnt4_Fq2 Z1Z2 = (this->Z) * (other.Z);
228  // u = Y2*Z1-Y1Z2
229  const mnt4_Fq2 u = Y2Z1 - Y1Z2;
230  // uu = u^2
231  const mnt4_Fq2 uu = u.squared();
232  // v = X2*Z1-X1Z2
233  const mnt4_Fq2 v = X2Z1 - X1Z2;
234  // vv = v^2
235  const mnt4_Fq2 vv = v.squared();
236  // vvv = v*vv
237  const mnt4_Fq2 vvv = v * vv;
238  // R = vv*X1Z2
239  const mnt4_Fq2 R = vv * X1Z2;
240  // A = uu*Z1Z2 - vvv - 2*R
241  const mnt4_Fq2 A = uu * Z1Z2 - (vvv + R + R);
242  // X3 = v*A
243  const mnt4_Fq2 X3 = v * A;
244  // Y3 = u*(R-A) - vvv*Y1Z2
245  const mnt4_Fq2 Y3 = u * (R - A) - vvv * Y1Z2;
246  // Z3 = vvv*Z1Z2
247  const mnt4_Fq2 Z3 = vvv * Z1Z2;
248 
249  return mnt4_G2(X3, Y3, Z3);
250 }
251 
253 {
254  return mnt4_G2(this->X, -(this->Y), this->Z);
255 }
256 
257 mnt4_G2 mnt4_G2::operator-(const mnt4_G2 &other) const
258 {
259  return (*this) + (-other);
260 }
261 
262 mnt4_G2 mnt4_G2::add(const mnt4_G2 &other) const
263 {
264  // handle special cases having to do with O
265  if (this->is_zero()) {
266  return other;
267  }
268 
269  if (other.is_zero()) {
270  return (*this);
271  }
272 
273  // no need to handle points of order 2,4
274  // (they cannot exist in a prime-order subgroup)
275 
276  // handle double case
277  if (this->operator==(other)) {
278  return this->dbl();
279  }
280 
281 #ifdef PROFILE_OP_COUNTS
282  this->add_cnt++;
283 #endif
284  // NOTE: does not handle O and pts of order 2,4
285  // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-projective.html#addition-add-1998-cmo-2
286 
287  // Y1Z2 = Y1*Z2
288  const mnt4_Fq2 Y1Z2 = (this->Y) * (other.Z);
289  // X1Z2 = X1*Z2
290  const mnt4_Fq2 X1Z2 = (this->X) * (other.Z);
291  // Z1Z2 = Z1*Z2
292  const mnt4_Fq2 Z1Z2 = (this->Z) * (other.Z);
293  // u = Y2*Z1-Y1Z2
294  const mnt4_Fq2 u = (other.Y) * (this->Z) - Y1Z2;
295  // uu = u^2
296  const mnt4_Fq2 uu = u.squared();
297  // v = X2*Z1-X1Z2
298  const mnt4_Fq2 v = (other.X) * (this->Z) - X1Z2;
299  // vv = v^2
300  const mnt4_Fq2 vv = v.squared();
301  // vvv = v*vv
302  const mnt4_Fq2 vvv = v * vv;
303  // R = vv*X1Z2
304  const mnt4_Fq2 R = vv * X1Z2;
305  // A = uu*Z1Z2 - vvv - 2*R
306  const mnt4_Fq2 A = uu * Z1Z2 - (vvv + R + R);
307  // X3 = v*A
308  const mnt4_Fq2 X3 = v * A;
309  // Y3 = u*(R-A) - vvv*Y1Z2
310  const mnt4_Fq2 Y3 = u * (R - A) - vvv * Y1Z2;
311  // Z3 = vvv*Z1Z2
312  const mnt4_Fq2 Z3 = vvv * Z1Z2;
313 
314  return mnt4_G2(X3, Y3, Z3);
315 }
316 
317 mnt4_G2 mnt4_G2::mixed_add(const mnt4_G2 &other) const
318 {
319 #ifdef PROFILE_OP_COUNTS
320  this->add_cnt++;
321 #endif
322  // NOTE: does not handle O and pts of order 2,4
323  // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-projective.html#addition-add-1998-cmo-2
324  // assert(other.Z == mnt4_Fq2::one());
325 
326  if (this->is_zero()) {
327  return other;
328  }
329 
330  if (other.is_zero()) {
331  return (*this);
332  }
333 
334 #ifdef DEBUG
335  assert(other.is_special());
336 #endif
337 
338  // X1Z2 = X1*Z2 (but other is special and not zero)
339  const mnt4_Fq2 &X1Z2 = (this->X);
340  // X2Z1 = X2*Z1
341  const mnt4_Fq2 X2Z1 = (this->Z) * (other.X);
342 
343  // (used both in add and double checks)
344 
345  // Y1Z2 = Y1*Z2 (but other is special and not zero)
346  const mnt4_Fq2 &Y1Z2 = (this->Y);
347  // Y2Z1 = Y2*Z1
348  const mnt4_Fq2 Y2Z1 = (this->Z) * (other.Y);
349 
350  if (X1Z2 == X2Z1 && Y1Z2 == Y2Z1) {
351  return this->dbl();
352  }
353 
354  // u = Y2*Z1-Y1
355  const mnt4_Fq2 u = Y2Z1 - this->Y;
356  // uu = u2
357  const mnt4_Fq2 uu = u.squared();
358  // v = X2*Z1-X1
359  const mnt4_Fq2 v = X2Z1 - this->X;
360  // vv = v2
361  const mnt4_Fq2 vv = v.squared();
362  // vvv = v*vv
363  const mnt4_Fq2 vvv = v * vv;
364  // R = vv*X1
365  const mnt4_Fq2 R = vv * this->X;
366  // A = uu*Z1-vvv-2*R
367  const mnt4_Fq2 A = uu * this->Z - vvv - R - R;
368  // X3 = v*A
369  const mnt4_Fq2 X3 = v * A;
370  // Y3 = u*(R-A)-vvv*Y1
371  const mnt4_Fq2 Y3 = u * (R - A) - vvv * this->Y;
372  // Z3 = vvv*Z1
373  const mnt4_Fq2 Z3 = vvv * this->Z;
374 
375  return mnt4_G2(X3, Y3, Z3);
376 }
377 
379 {
380 #ifdef PROFILE_OP_COUNTS
381  this->dbl_cnt++;
382 #endif
383  if (this->is_zero()) {
384  return (*this);
385  } else {
386  // NOTE: does not handle O and pts of order 2,4
387  // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-projective.html#doubling-dbl-2007-bl
388 
389  // XX = X1^2
390  const mnt4_Fq2 XX = (this->X).squared();
391  // ZZ = Z1^2
392  const mnt4_Fq2 ZZ = (this->Z).squared();
393  // w = a*ZZ + 3*XX
394  const mnt4_Fq2 w = mnt4_G2::mul_by_a(ZZ) + (XX + XX + XX);
395  const mnt4_Fq2 Y1Z1 = (this->Y) * (this->Z);
396  // s = 2*Y1*Z1
397  const mnt4_Fq2 s = Y1Z1 + Y1Z1;
398  // ss = s^2
399  const mnt4_Fq2 ss = s.squared();
400  // sss = s*ss
401  const mnt4_Fq2 sss = s * ss;
402  // R = Y1*s
403  const mnt4_Fq2 R = (this->Y) * s;
404  // RR = R^2
405  const mnt4_Fq2 RR = R.squared();
406  // B = (X1+R)^2 - XX - RR
407  const mnt4_Fq2 B = ((this->X) + R).squared() - XX - RR;
408  // h = w^2-2*B
409  const mnt4_Fq2 h = w.squared() - (B + B);
410  // X3 = h*s
411  const mnt4_Fq2 X3 = h * s;
412  // Y3 = w*(B-h) - 2*RR
413  const mnt4_Fq2 Y3 = w * (B - h) - (RR + RR);
414  // Z3 = sss
415  const mnt4_Fq2 Z3 = sss;
416 
417  return mnt4_G2(X3, Y3, Z3);
418  }
419 }
420 
422 {
423  return mnt4_G2(
424  mnt4_twist_mul_by_q_X * (this->X).Frobenius_map(1),
425  mnt4_twist_mul_by_q_Y * (this->Y).Frobenius_map(1),
426  (this->Z).Frobenius_map(1));
427 }
428 
429 mnt4_G2 mnt4_G2::mul_by_cofactor() const { return mnt4_G2::h * (*this); }
430 
432 {
433  if (this->is_zero()) {
434  return true;
435  } else {
436  // y^2 = x^3 + ax + b
437  //
438  // We are using projective, so equation we need to check is actually
439  //
440  // (y/z)^2 = (x/z)^3 + a (x/z) + b
441  // z y^2 = x^3 + a z^2 x + b z^3
442  //
443  // z (y^2 - b z^2) = x ( x^2 + a z^2)
444  const mnt4_Fq2 X2 = this->X.squared();
445  const mnt4_Fq2 Y2 = this->Y.squared();
446  const mnt4_Fq2 Z2 = this->Z.squared();
447  const mnt4_Fq2 aZ2 = mnt4_twist_coeff_a * Z2;
448 
449  return (
450  this->Z * (Y2 - mnt4_twist_coeff_b * Z2) == this->X * (X2 + aZ2));
451  }
452 }
453 
455 {
456  return zero() == scalar_field::mod * (*this);
457 }
458 
459 const mnt4_G2 &mnt4_G2::zero() { return G2_zero; }
460 
461 const mnt4_G2 &mnt4_G2::one() { return G2_one; }
462 
464 {
465  return (mnt4_Fr::random_element().as_bigint()) * G2_one;
466 }
467 
468 void mnt4_G2::write_uncompressed(std::ostream &out) const
469 {
470  mnt4_G2 copy(*this);
471  copy.to_affine_coordinates();
472 
473  out << (copy.is_zero() ? 1 : 0) << OUTPUT_SEPARATOR;
474  out << copy.X << OUTPUT_SEPARATOR << copy.Y;
475 }
476 
477 void mnt4_G2::write_compressed(std::ostream &out) const
478 {
479  mnt4_G2 copy(*this);
480  copy.to_affine_coordinates();
481 
482  out << (copy.is_zero() ? 1 : 0) << OUTPUT_SEPARATOR;
483  /* storing LSB of Y */
484  out << copy.X << OUTPUT_SEPARATOR
485  << (copy.Y.coeffs[0].as_bigint().data[0] & 1);
486 }
487 
488 void mnt4_G2::read_uncompressed(std::istream &in, mnt4_G2 &g)
489 {
490  char is_zero;
491  mnt4_Fq2 tX, tY;
492  in >> is_zero >> tX >> tY;
493  is_zero -= '0';
494 
495  // using projective coordinates
496  if (!is_zero) {
497  g.X = tX;
498  g.Y = tY;
499  g.Z = mnt4_Fq2::one();
500  } else {
501  g = mnt4_G2::zero();
502  }
503 }
504 
505 void mnt4_G2::read_compressed(std::istream &in, mnt4_G2 &g)
506 {
507  char is_zero;
508  mnt4_Fq2 tX, tY;
509  // this reads is_zero;
510  in.read((char *)&is_zero, 1);
511  is_zero -= '0';
513 
514  unsigned char Y_lsb;
515  in >> tX;
517  in.read((char *)&Y_lsb, 1);
518  Y_lsb -= '0';
519 
520  // y = +/- sqrt(x^3 + a*x + b)
521  if (!is_zero) {
522  mnt4_Fq2 tX2 = tX.squared();
523  mnt4_Fq2 tY2 = (tX2 + mnt4_twist_coeff_a) * tX + mnt4_twist_coeff_b;
524  tY = tY2.sqrt();
525 
526  if ((tY.coeffs[0].as_bigint().data[0] & 1) != Y_lsb) {
527  tY = -tY;
528  }
529  }
530 
531  // using projective coordinates
532  if (!is_zero) {
533  g.X = tX;
534  g.Y = tY;
535  g.Z = mnt4_Fq2::one();
536  } else {
537  g = mnt4_G2::zero();
538  }
539 }
540 
541 void mnt4_G2::batch_to_special_all_non_zeros(std::vector<mnt4_G2> &vec)
542 {
543  std::vector<mnt4_Fq2> Z_vec;
544  Z_vec.reserve(vec.size());
545 
546  for (auto &el : vec) {
547  Z_vec.emplace_back(el.Z);
548  }
549  batch_invert<mnt4_Fq2>(Z_vec);
550 
551  const mnt4_Fq2 one = mnt4_Fq2::one();
552 
553  for (size_t i = 0; i < vec.size(); ++i) {
554  vec[i] = mnt4_G2(vec[i].X * Z_vec[i], vec[i].Y * Z_vec[i], one);
555  }
556 }
557 
558 std::ostream &operator<<(std::ostream &out, const mnt4_G2 &g)
559 {
560 #ifdef NO_PT_COMPRESSION
561  g.write_uncompressed(out);
562 #else
563  g.write_compressed(out);
564 #endif
565  return out;
566 }
567 
568 std::istream &operator>>(std::istream &in, mnt4_G2 &g)
569 {
570 #ifdef NO_PT_COMPRESSION
572 #else
574 #endif
575  return in;
576 }
577 
578 } // namespace libff
libff::Fp2_model::coeffs
my_Fp coeffs[2]
Definition: fp2.hpp:63
libff::mnt4_twist_mul_by_b_c1
mnt4_Fq mnt4_twist_mul_by_b_c1
Definition: mnt4_init.cpp:30
libff::mnt4_twist_coeff_b
mnt4_Fq2 mnt4_twist_coeff_b
Definition: mnt4_init.cpp:26
libff::mnt4_twist_mul_by_a_c1
mnt4_Fq mnt4_twist_mul_by_a_c1
Definition: mnt4_init.cpp:28
libff::mnt4_G2
Definition: mnt4_g2.hpp:26
libff::mnt4_G2::write_compressed
void write_compressed(std::ostream &) const
Definition: mnt4_g2.cpp:477
libff::mnt4_G2::print_coordinates
void print_coordinates() const
Definition: mnt4_g2.cpp:74
libff::Fp_model::random_element
static Fp_model< n, modulus > random_element()
returns random element of Fp_model
libff::mnt4_G2::add
mnt4_G2 add(const mnt4_G2 &other) const
Definition: mnt4_g2.cpp:262
libff::mnt4_G2::G2_one
static mnt4_G2 G2_one
Definition: mnt4_g2.hpp:36
libff::mnt4_G2::X
mnt4_Fq2 X
Definition: mnt4_g2.hpp:51
libff
Definition: ffi.cpp:8
libff::Fp2_model< mnt4_q_limbs, mnt4_modulus_q >::one
static const Fp2_model< n, modulus > & one()
libff::mnt4_G2::h
static bigint< h_limbs > h
Definition: mnt4_g2.hpp:49
libff::mnt4_twist_coeff_a
mnt4_Fq2 mnt4_twist_coeff_a
Definition: mnt4_init.cpp:25
libff::mnt4_G2::read_compressed
static void read_compressed(std::istream &, mnt4_G2 &)
Definition: mnt4_g2.cpp:505
libff::mnt4_G2::coeff_b
static mnt4_Fq2 coeff_b
Definition: mnt4_g2.hpp:39
libff::operator>>
std::istream & operator>>(std::istream &in, alt_bn128_G1 &g)
Definition: alt_bn128_g1.cpp:446
libff::mnt4_G2::twist
static mnt4_Fq2 twist
Definition: mnt4_g2.hpp:37
libff::mnt4_G2::operator!=
bool operator!=(const mnt4_G2 &other) const
Definition: mnt4_g2.cpp:147
libff::mnt4_G2::is_well_formed
bool is_well_formed() const
Definition: mnt4_g2.cpp:431
libff::mnt4_twist_mul_by_q_X
mnt4_Fq mnt4_twist_mul_by_q_X
Definition: mnt4_init.cpp:31
libff::mnt4_G2::operator+
mnt4_G2 operator+(const mnt4_G2 &other) const
Definition: mnt4_g2.cpp:152
libff::mnt4_G2::write_uncompressed
void write_uncompressed(std::ostream &) const
Definition: mnt4_g2.cpp:468
libff::Fp2_model::inverse
Fp2_model inverse() const
OUTPUT_SEPARATOR
#define OUTPUT_SEPARATOR
Definition: serialization.hpp:69
libff::Fp2_model::is_zero
bool is_zero() const
Definition: fp2.hpp:89
libff::mnt4_G2::to_affine_coordinates
void to_affine_coordinates()
Definition: mnt4_g2.cpp:96
libff::mnt4_G2::Z
mnt4_Fq2 Z
Definition: mnt4_g2.hpp:51
libff::mnt4_G2::mnt4_G2
mnt4_G2()
Definition: mnt4_g2.cpp:47
libff::mnt4_G2::batch_to_special_all_non_zeros
static void batch_to_special_all_non_zeros(std::vector< mnt4_G2 > &vec)
Definition: mnt4_g2.cpp:541
libff::mnt4_G2::is_special
bool is_special() const
Definition: mnt4_g2.cpp:112
libff::mnt4_G2::random_element
static mnt4_G2 random_element()
Definition: mnt4_g2.cpp:463
libff::mnt4_G2::fixed_base_exp_window_table
static std::vector< size_t > fixed_base_exp_window_table
Definition: mnt4_g2.hpp:34
libff::consume_OUTPUT_SEPARATOR
void consume_OUTPUT_SEPARATOR(std::istream &in)
libff::Fp_model< mnt4_q_limbs, mnt4_modulus_q >::num_limbs
static const mp_size_t num_limbs
Definition: fp.hpp:47
libff::mnt4_G2::G2_zero
static mnt4_G2 G2_zero
Definition: mnt4_g2.hpp:35
libff::mnt4_Fq2
Fp2_model< mnt4_q_limbs, mnt4_modulus_q > mnt4_Fq2
Definition: mnt4_init.hpp:38
libff::mnt4_G2::print
void print() const
Definition: mnt4_g2.cpp:54
libff::Fp_model::as_bigint
bigint< n > as_bigint() const
mnt4_g2.hpp
libff::mnt4_G2::coeff_a
static mnt4_Fq2 coeff_a
Definition: mnt4_g2.hpp:38
libff::mnt4_twist_mul_by_b_c0
mnt4_Fq mnt4_twist_mul_by_b_c0
Definition: mnt4_init.cpp:29
libff::mnt4_G2::read_uncompressed
static void read_uncompressed(std::istream &, mnt4_G2 &)
Definition: mnt4_g2.cpp:488
libff::operator<<
std::ostream & operator<<(std::ostream &out, const alt_bn128_G1 &g)
Definition: alt_bn128_g1.cpp:436
libff::mnt4_G2::one
static const mnt4_G2 & one()
Definition: mnt4_g2.cpp:461
libff::mnt4_twist_mul_by_q_Y
mnt4_Fq mnt4_twist_mul_by_q_Y
Definition: mnt4_init.cpp:32
libff::mnt4_G2::mixed_add
mnt4_G2 mixed_add(const mnt4_G2 &other) const
Definition: mnt4_g2.cpp:317
libff::Fp2_model::squared
Fp2_model squared() const
default is squared_complex
libff::Fp2_model
Definition: fp2.hpp:18
libff::mnt4_G2::mul_by_a
static mnt4_Fq2 mul_by_a(const mnt4_Fq2 &elt)
Definition: mnt4_g2.cpp:33
libff::mnt4_G2::dbl
mnt4_G2 dbl() const
Definition: mnt4_g2.cpp:378
libff::mnt4_G2::to_special
void to_special()
Definition: mnt4_g2.cpp:110
libff::mnt4_G2::Y
mnt4_Fq2 Y
Definition: mnt4_g2.hpp:51
libff::mnt4_G2::operator-
mnt4_G2 operator-() const
Definition: mnt4_g2.cpp:252
libff::Fp_model::mod
static const constexpr bigint< n > & mod
Definition: fp.hpp:48
libff::mnt4_G2::operator==
bool operator==(const mnt4_G2 &other) const
Definition: mnt4_g2.cpp:122
libff::mnt4_G2::wnaf_window_table
static std::vector< size_t > wnaf_window_table
Definition: mnt4_g2.hpp:33
libff::Fp2_model::sqrt
Fp2_model sqrt() const
HAS TO BE A SQUARE (else does not terminate)
libff::mnt4_twist_mul_by_a_c0
mnt4_Fq mnt4_twist_mul_by_a_c0
Definition: mnt4_init.cpp:27
libff::Fp2_model< mnt4_q_limbs, mnt4_modulus_q >::zero
static const Fp2_model< n, modulus > & zero()
libff::mnt4_G2::mul_by_cofactor
mnt4_G2 mul_by_cofactor() const
Definition: mnt4_g2.cpp:429
libff::mnt4_G2::is_in_safe_subgroup
bool is_in_safe_subgroup() const
Definition: mnt4_g2.cpp:454
libff::mnt4_G2::mul_by_q
mnt4_G2 mul_by_q() const
Definition: mnt4_g2.cpp:421
libff::mnt4_G2::mul_by_b
static mnt4_Fq2 mul_by_b(const mnt4_Fq2 &elt)
Definition: mnt4_g2.cpp:40
libff::mnt4_G2::is_zero
bool is_zero() const
Definition: mnt4_g2.cpp:117
libff::mnt4_G2::zero
static const mnt4_G2 & zero()
Definition: mnt4_g2.cpp:459