Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
libff::edwards_G2 Class Reference

#include <edwards_g2.hpp>

Collaboration diagram for libff::edwards_G2:

Public Types

typedef edwards_Fq base_field
 
typedef edwards_Fq3 twist_field
 
typedef edwards_Fr scalar_field
 

Public Member Functions

 edwards_G2 ()
 
 edwards_G2 (const edwards_Fq3 &X, const edwards_Fq3 &Y)
 
void print () const
 
void print_coordinates () const
 
void to_affine_coordinates ()
 
void to_special ()
 
bool is_special () const
 
bool is_zero () const
 
bool operator== (const edwards_G2 &other) const
 
bool operator!= (const edwards_G2 &other) const
 
edwards_G2 operator+ (const edwards_G2 &other) const
 
edwards_G2 operator- () const
 
edwards_G2 operator- (const edwards_G2 &other) const
 
edwards_G2 add (const edwards_G2 &other) const
 
edwards_G2 mixed_add (const edwards_G2 &other) const
 
edwards_G2 dbl () const
 
edwards_G2 mul_by_q () const
 
bool is_well_formed () const
 

Static Public Member Functions

static edwards_Fq3 mul_by_a (const edwards_Fq3 &elt)
 
static edwards_Fq3 mul_by_d (const edwards_Fq3 &elt)
 
static edwards_G2 zero ()
 
static edwards_G2 one ()
 
static edwards_G2 random_element ()
 
static size_t size_in_bits ()
 
static bigint< base_field::num_limbsbase_field_char ()
 
static bigint< scalar_field::num_limbsorder ()
 
static void batch_to_special_all_non_zeros (std::vector< edwards_G2 > &vec)
 

Public Attributes

edwards_Fq3 X
 
edwards_Fq3 Y
 
edwards_Fq3 Z
 

Static Public Attributes

static std::vector< size_t > wnaf_window_table
 
static std::vector< size_t > fixed_base_exp_window_table
 
static edwards_G2 G2_zero = {}
 
static edwards_G2 G2_one = {}
 
static bool initialized = false
 

Friends

std::ostream & operator<< (std::ostream &out, const edwards_G2 &g)
 
std::istream & operator>> (std::istream &in, edwards_G2 &g)
 

Detailed Description

Definition at line 22 of file edwards_g2.hpp.

Member Typedef Documentation

◆ base_field

◆ scalar_field

◆ twist_field

Constructor & Destructor Documentation

◆ edwards_G2() [1/2]

libff::edwards_G2::edwards_G2 ( )

Definition at line 24 of file edwards_g2.cpp.

25{
26 if (initialized)
27 {
28 this->X = G2_zero.X;
29 this->Y = G2_zero.Y;
30 this->Z = G2_zero.Z;
31 }
32}
static bool initialized
static edwards_G2 G2_zero
Definition lib.h:43
Here is the caller graph for this function:

◆ edwards_G2() [2/2]

libff::edwards_G2::edwards_G2 ( const edwards_Fq3 & X,
const edwards_Fq3 & Y )
inline

Definition at line 47 of file edwards_g2.hpp.

47: X(Y), Y(X), Z(X*Y) {};

Member Function Documentation

◆ add()

edwards_G2 libff::edwards_G2::add ( const edwards_G2 & other) const

Definition at line 202 of file edwards_g2.cpp.

203{
204#ifdef PROFILE_OP_COUNTS
205 this->add_cnt++;
206#endif
207 // NOTE: does not handle O and pts of order 2,4
208 // http://www.hyperelliptic.org/EFD/g1p/auto-twisted-inverted.html#addition-add-2008-bbjlp
209
210 const edwards_Fq3 A = (this->Z) * (other.Z); // A = Z1*Z2
211 const edwards_Fq3 B = edwards_G2::mul_by_d(A.squared()); // B = d*A^2
212 const edwards_Fq3 C = (this->X) * (other.X); // C = X1*X2
213 const edwards_Fq3 D = (this->Y) * (other.Y); // D = Y1*Y2
214 const edwards_Fq3 E = C*D; // E = C*D
215 const edwards_Fq3 H = C - edwards_G2::mul_by_a(D); // H = C-a*D
216 const edwards_Fq3 I = (this->X+this->Y)*(other.X+other.Y)-C-D; // I = (X1+Y1)*(X2+Y2)-C-D
217 const edwards_Fq3 X3 = (E+B)*H; // X3 = (E+B)*H
218 const edwards_Fq3 Y3 = (E-B)*I; // Y3 = (E-B)*I
219 const edwards_Fq3 Z3 = A*H*I; // Z3 = A*H*I
220
221 return edwards_G2(X3, Y3, Z3);
222}
static edwards_Fq3 mul_by_a(const edwards_Fq3 &elt)
static edwards_Fq3 mul_by_d(const edwards_Fq3 &elt)
#define D(var, file, col, who, lev,...)
Definition debug.h:44
Fp3_model< edwards_q_limbs, edwards_modulus_q > edwards_Fq3
Here is the call graph for this function:
Here is the caller graph for this function:

◆ base_field_char()

static bigint< base_field::num_limbs > libff::edwards_G2::base_field_char ( )
inlinestatic

Definition at line 77 of file edwards_g2.hpp.

Here is the call graph for this function:

◆ batch_to_special_all_non_zeros()

void libff::edwards_G2::batch_to_special_all_non_zeros ( std::vector< edwards_G2 > & vec)
static

Definition at line 396 of file edwards_g2.cpp.

397{
398 std::vector<edwards_Fq3> Z_vec;
399 Z_vec.reserve(vec.size());
400
401 for (auto &el: vec)
402 {
403 Z_vec.emplace_back(el.Z);
404 }
406
408
409 for (size_t i = 0; i < vec.size(); ++i)
410 {
411 vec[i].X = vec[i].X * Z_vec[i];
412 vec[i].Y = vec[i].Y * Z_vec[i];
413 vec[i].Z = one;
414 }
415}
static edwards_G2 one()
void batch_invert(std::vector< FieldT > &vec)
Here is the call graph for this function:

◆ dbl()

edwards_G2 libff::edwards_G2::dbl ( ) const

Definition at line 261 of file edwards_g2.cpp.

262{
263#ifdef PROFILE_OP_COUNTS
264 this->dbl_cnt++;
265#endif
266 if (this->is_zero())
267 {
268 return (*this);
269 }
270 else
271 {
272 // NOTE: does not handle O and pts of order 2,4
273 // http://www.hyperelliptic.org/EFD/g1p/auto-twisted-inverted.html#doubling-dbl-2008-bbjlp
274
275 const edwards_Fq3 A = (this->X).squared(); // A = X1^2
276 const edwards_Fq3 B = (this->Y).squared(); // B = Y1^2
277 const edwards_Fq3 U = edwards_G2::mul_by_a(B); // U = a*B
278 const edwards_Fq3 C = A+U; // C = A+U
279 const edwards_Fq3 D = A-U; // D = A-U
280 const edwards_Fq3 E = (this->X+this->Y).squared()-A-B; // E = (X1+Y1)^2-A-B
281 const edwards_Fq3 X3 = C*D; // X3 = C*D
282 const edwards_Fq3 dZZ = edwards_G2::mul_by_d(this->Z.squared());
283 const edwards_Fq3 Y3 = E*(C-dZZ-dZZ); // Y3 = E*(C-2*d*Z1^2)
284 const edwards_Fq3 Z3 = D*E; // Z3 = D*E
285
286 return edwards_G2(X3, Y3, Z3);
287 }
288}
Fp3_model squared() const
bool is_zero() const
Definition dtoa.c:306
Here is the call graph for this function:

◆ is_special()

bool libff::edwards_G2::is_special ( ) const

Definition at line 131 of file edwards_g2.cpp.

132{
133 return (this->is_zero() || this->Z == edwards_Fq3::one());
134}
Here is the call graph for this function:

◆ is_well_formed()

bool libff::edwards_G2::is_well_formed ( ) const

Definition at line 297 of file edwards_g2.cpp.

298{
299 /* Note that point at infinity is the only special case we must check as
300 inverted representation does no cover points (0, +-c) and (+-c, 0). */
301 if (this->is_zero())
302 {
303 return true;
304 }
305 else
306 {
307 /*
308 a x^2 + y^2 = 1 + d x^2 y^2
309
310 We are using inverted, so equation we need to check is actually
311
312 a (z/x)^2 + (z/y)^2 = 1 + d z^4 / (x^2 * y^2)
313 z^2 (a y^2 + x^2 - dz^2) = x^2 y^2
314 */
315 edwards_Fq3 X2 = this->X.squared();
316 edwards_Fq3 Y2 = this->Y.squared();
317 edwards_Fq3 Z2 = this->Z.squared();
320 return (Z2 * (aY2 + X2 - dZ2) == X2 * Y2);
321 }
322}
Here is the call graph for this function:

◆ is_zero()

bool libff::edwards_G2::is_zero ( ) const

Definition at line 136 of file edwards_g2.cpp.

137{
138 return (this->Y.is_zero() && this->Z.is_zero());
139}
bool is_zero() const
Definition fp3.hpp:61
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mixed_add()

edwards_G2 libff::edwards_G2::mixed_add ( const edwards_G2 & other) const

Definition at line 224 of file edwards_g2.cpp.

225{
226#ifdef PROFILE_OP_COUNTS
227 this->add_cnt++;
228#endif
229 // handle special cases having to do with O
230 if (this->is_zero())
231 {
232 return other;
233 }
234
235 if (other.is_zero())
236 {
237 return *this;
238 }
239
240#ifdef DEBUG
241 assert(other.is_special());
242#endif
243
244 // NOTE: does not handle O and pts of order 2,4
245 // http://www.hyperelliptic.org/EFD/g1p/auto-edwards-inverted.html#addition-madd-2007-lb
246
247 const edwards_Fq3 A = this->Z; // A = Z1*Z2
248 const edwards_Fq3 B = edwards_G2::mul_by_d(A.squared()); // B = d*A^2
249 const edwards_Fq3 C = (this->X) * (other.X); // C = X1*X2
250 const edwards_Fq3 D = (this->Y) * (other.Y); // D = Y1*Y2
251 const edwards_Fq3 E = C*D; // E = C*D
252 const edwards_Fq3 H = C - edwards_G2::mul_by_a(D); // H = C-a*D
253 const edwards_Fq3 I = (this->X+this->Y)*(other.X+other.Y)-C-D; // I = (X1+Y1)*(X2+Y2)-C-D
254 const edwards_Fq3 X3 = (E+B)*H; // X3 = (E+B)*H
255 const edwards_Fq3 Y3 = (E-B)*I; // Y3 = (E-B)*I
256 const edwards_Fq3 Z3 = A*H*I; // Z3 = A*H*I
257
258 return edwards_G2(X3, Y3, Z3);
259}
Here is the call graph for this function:

◆ mul_by_a()

edwards_Fq3 libff::edwards_G2::mul_by_a ( const edwards_Fq3 & elt)
static

Definition at line 34 of file edwards_g2.cpp.

35{
36 // should be
37 // edwards_Fq3(edwards_twist_mul_by_a_c0 * elt.c2, edwards_twist_mul_by_a_c1 * elt.c0, edwards_twist_mul_by_a_c2 * elt.c1)
38 // but optimizing the fact that edwards_twist_mul_by_a_c1 = edwards_twist_mul_by_a_c2 = 1
39 return edwards_Fq3(edwards_twist_mul_by_a_c0 * elt.c2, elt.c0, elt.c1);
40}
edwards_Fq edwards_twist_mul_by_a_c0
Here is the caller graph for this function:

◆ mul_by_d()

edwards_Fq3 libff::edwards_G2::mul_by_d ( const edwards_Fq3 & elt)
static

Definition at line 42 of file edwards_g2.cpp.

43{
45}
edwards_Fq edwards_twist_mul_by_d_c1
edwards_Fq edwards_twist_mul_by_d_c2
edwards_Fq edwards_twist_mul_by_d_c0
Here is the caller graph for this function:

◆ mul_by_q()

edwards_G2 libff::edwards_G2::mul_by_q ( ) const

Definition at line 290 of file edwards_g2.cpp.

291{
292 return edwards_G2((this->X).Frobenius_map(1),
293 edwards_twist_mul_by_q_Y * (this->Y).Frobenius_map(1),
294 edwards_twist_mul_by_q_Z * (this->Z).Frobenius_map(1));
295}
edwards_Fq edwards_twist_mul_by_q_Y
edwards_Fq edwards_twist_mul_by_q_Z
Here is the call graph for this function:

◆ one()

edwards_G2 libff::edwards_G2::one ( )
static

Definition at line 329 of file edwards_g2.cpp.

330{
331 return G2_one;
332}
static edwards_G2 G2_one
Here is the caller graph for this function:

◆ operator!=()

bool libff::edwards_G2::operator!= ( const edwards_G2 & other) const

Definition at line 170 of file edwards_g2.cpp.

171{
172 return !(operator==(other));
173}
bool operator==(const edwards_G2 &other) const
Here is the call graph for this function:

◆ operator+()

edwards_G2 libff::edwards_G2::operator+ ( const edwards_G2 & other) const

Definition at line 175 of file edwards_g2.cpp.

176{
177 // handle special cases having to do with O
178 if (this->is_zero())
179 {
180 return other;
181 }
182
183 if (other.is_zero())
184 {
185 return (*this);
186 }
187
188 return this->add(other);
189}
edwards_G2 add(const edwards_G2 &other) const
Here is the call graph for this function:

◆ operator-() [1/2]

edwards_G2 libff::edwards_G2::operator- ( ) const

Definition at line 191 of file edwards_g2.cpp.

192{
193 return edwards_G2(-(this->X), this->Y, this->Z);
194}
Here is the call graph for this function:

◆ operator-() [2/2]

edwards_G2 libff::edwards_G2::operator- ( const edwards_G2 & other) const

Definition at line 197 of file edwards_g2.cpp.

198{
199 return (*this) + (-other);
200}

◆ operator==()

bool libff::edwards_G2::operator== ( const edwards_G2 & other) const

Definition at line 141 of file edwards_g2.cpp.

142{
143 if (this->is_zero())
144 {
145 return other.is_zero();
146 }
147
148 if (other.is_zero())
149 {
150 return false;
151 }
152
153 /* now neither is O */
154
155 // X1/Z1 = X2/Z2 <=> X1*Z2 = X2*Z1
156 if ((this->X * other.Z) != (other.X * this->Z))
157 {
158 return false;
159 }
160
161 // Y1/Z1 = Y2/Z2 <=> Y1*Z2 = Y2*Z1
162 if ((this->Y * other.Z) != (other.Y * this->Z))
163 {
164 return false;
165 }
166
167 return true;
168}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ order()

static bigint< scalar_field::num_limbs > libff::edwards_G2::order ( )
inlinestatic

Definition at line 78 of file edwards_g2.hpp.

78{ return scalar_field::field_char(); }
Here is the call graph for this function:

◆ print()

void libff::edwards_G2::print ( ) const

Definition at line 47 of file edwards_g2.cpp.

48{
49 if (this->is_zero())
50 {
51 printf("O\n");
52 }
53 else
54 {
55 edwards_G2 copy(*this);
56 copy.to_affine_coordinates();
57 gmp_printf("(%Nd*z^2 + %Nd*z + %Nd , %Nd*z^2 + %Nd*z + %Nd)\n",
58 copy.X.c2.as_bigint().data, edwards_Fq::num_limbs,
59 copy.X.c1.as_bigint().data, edwards_Fq::num_limbs,
60 copy.X.c0.as_bigint().data, edwards_Fq::num_limbs,
61 copy.Y.c2.as_bigint().data, edwards_Fq::num_limbs,
62 copy.Y.c1.as_bigint().data, edwards_Fq::num_limbs,
63 copy.Y.c0.as_bigint().data, edwards_Fq::num_limbs);
64 }
65}
LOGGING_API void printf(Category category, const char *format,...)
Definition Logging.cpp:30
void copy(const path &from, const path &to)
Here is the call graph for this function:

◆ print_coordinates()

void libff::edwards_G2::print_coordinates ( ) const

Definition at line 67 of file edwards_g2.cpp.

68{
69 if (this->is_zero())
70 {
71 printf("O\n");
72 }
73 else
74 {
75 gmp_printf("(%Nd*z^2 + %Nd*z + %Nd : %Nd*z^2 + %Nd*z + %Nd : %Nd*z^2 + %Nd*z + %Nd)\n",
76 this->X.c2.as_bigint().data, edwards_Fq::num_limbs,
77 this->X.c1.as_bigint().data, edwards_Fq::num_limbs,
78 this->X.c0.as_bigint().data, edwards_Fq::num_limbs,
79 this->Y.c2.as_bigint().data, edwards_Fq::num_limbs,
80 this->Y.c1.as_bigint().data, edwards_Fq::num_limbs,
81 this->Y.c0.as_bigint().data, edwards_Fq::num_limbs,
82 this->Z.c2.as_bigint().data, edwards_Fq::num_limbs,
83 this->Z.c1.as_bigint().data, edwards_Fq::num_limbs,
84 this->Z.c0.as_bigint().data, edwards_Fq::num_limbs);
85 }
86}
Here is the call graph for this function:

◆ random_element()

edwards_G2 libff::edwards_G2::random_element ( )
static

Definition at line 334 of file edwards_g2.cpp.

335{
336 return edwards_Fr::random_element().as_bigint() * G2_one;
337}
static Fp_model< n, modulus > random_element()
Here is the call graph for this function:

◆ size_in_bits()

static size_t libff::edwards_G2::size_in_bits ( )
inlinestatic

Definition at line 76 of file edwards_g2.hpp.

Here is the call graph for this function:

◆ to_affine_coordinates()

void libff::edwards_G2::to_affine_coordinates ( )

Definition at line 88 of file edwards_g2.cpp.

89{
90 if (this->is_zero())
91 {
92 this->X = edwards_Fq3::zero();
93 this->Y = edwards_Fq3::one();
94 this->Z = edwards_Fq3::one();
95 }
96 else
97 {
98 // go from inverted coordinates to projective coordinates
99 edwards_Fq3 tX = this->Y * this->Z;
100 edwards_Fq3 tY = this->X * this->Z;
101 edwards_Fq3 tZ = this->X * this->Y;
102 // go from projective coordinates to affine coordinates
103 edwards_Fq3 tZ_inv = tZ.inverse();
104 this->X = tX * tZ_inv;
105 this->Y = tY * tZ_inv;
106 this->Z = edwards_Fq3::one();
107 }
108}
Fp3_model inverse() const
Here is the call graph for this function:
Here is the caller graph for this function:

◆ to_special()

void libff::edwards_G2::to_special ( )

Definition at line 110 of file edwards_g2.cpp.

111{
112 if (this->Z.is_zero())
113 {
114 return;
115 }
116
117#ifdef DEBUG
118 const edwards_G2 copy(*this);
119#endif
120
121 edwards_Fq3 Z_inv = this->Z.inverse();
122 this->X = this->X * Z_inv;
123 this->Y = this->Y * Z_inv;
124 this->Z = edwards_Fq3::one();
125
126#ifdef DEBUG
127 assert((*this) == copy);
128#endif
129}
Here is the call graph for this function:

◆ zero()

edwards_G2 libff::edwards_G2::zero ( )
static

Definition at line 324 of file edwards_g2.cpp.

325{
326 return G2_zero;
327}

Friends And Related Symbol Documentation

◆ operator<<

std::ostream & operator<< ( std::ostream & out,
const edwards_G2 & g )
friend

Definition at line 339 of file edwards_g2.cpp.

340{
341 edwards_G2 copy(g);
342 copy.to_affine_coordinates();
343#ifdef NO_PT_COMPRESSION
344 out << copy.X << OUTPUT_SEPARATOR << copy.Y;
345#else
346 /* storing LSB of Y */
347 out << copy.X << OUTPUT_SEPARATOR << (copy.Y.c0.as_bigint().data[0] & 1);
348#endif
349 return out;
350}
#define OUTPUT_SEPARATOR

◆ operator>>

std::istream & operator>> ( std::istream & in,
edwards_G2 & g )
friend

Definition at line 352 of file edwards_g2.cpp.

353{
354 edwards_Fq3 tX, tY;
355
356#ifdef NO_PT_COMPRESSION
357 in >> tX;
359 in >> tY;
360#else
361 /*
362 a x^2 + y^2 = 1 + d x^2 y^2
363 y = sqrt((1-ax^2)/(1-dx^2))
364 */
365 unsigned char Y_lsb;
366 in >> tX;
368
369 in.read((char*)&Y_lsb, 1);
370 Y_lsb -= '0';
371
372 edwards_Fq3 tX2 = tX.squared();
373 const edwards_Fq3 tY2 =
376 tY = tY2.sqrt();
377
378 if ((tY.c0.as_bigint().data[0] & 1) != Y_lsb)
379 {
380 tY = -tY;
381 }
382#endif
383
384 // using inverted coordinates
385 g.X = tY;
386 g.Y = tX;
387 g.Z = tX * tY;
388
389#ifdef USE_MIXED_ADDITION
390 g.to_special();
391#endif
392
393 return in;
394}
Fp3_model sqrt() const
void consume_OUTPUT_SEPARATOR(std::istream &in)

Member Data Documentation

◆ fixed_base_exp_window_table

std::vector< size_t > libff::edwards_G2::fixed_base_exp_window_table
static

Definition at line 29 of file edwards_g2.hpp.

◆ G2_one

edwards_G2 libff::edwards_G2::G2_one = {}
static

Definition at line 32 of file edwards_g2.hpp.

◆ G2_zero

edwards_G2 libff::edwards_G2::G2_zero = {}
static

Definition at line 31 of file edwards_g2.hpp.

◆ initialized

bool libff::edwards_G2::initialized = false
static

Definition at line 33 of file edwards_g2.hpp.

◆ wnaf_window_table

std::vector< size_t > libff::edwards_G2::wnaf_window_table
static

Definition at line 28 of file edwards_g2.hpp.

◆ X

edwards_Fq3 libff::edwards_G2::X

Definition at line 35 of file edwards_g2.hpp.

◆ Y

edwards_Fq3 libff::edwards_G2::Y

Definition at line 35 of file edwards_g2.hpp.

◆ Z

edwards_Fq3 libff::edwards_G2::Z

Definition at line 35 of file edwards_g2.hpp.


The documentation for this class was generated from the following files: