algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2020-2021 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 2020-2021 Nikita Kaskov <nbering@nil.foundation>
4 // Copyright (c) 2020-2021 Ilias Khairullin <ilias@nil.foundation>
5 //
6 // MIT License
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be included in all
16 // copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 // SOFTWARE.
25 //---------------------------------------------------------------------------//
26 
27 #ifndef CRYPTO3_ALGEBRA_CURVES_EDWARDS_G2_ELEMENT_HPP
28 #define CRYPTO3_ALGEBRA_CURVES_EDWARDS_G2_ELEMENT_HPP
29 
31 
33 
34 namespace nil {
35  namespace crypto3 {
36  namespace algebra {
37  namespace curves {
38  namespace detail {
43  template<std::size_t Version, typename Form, typename Coordinates>
44  struct edwards_g2;
49  template<std::size_t Version>
50  struct element_edwards_g2 { };
54  template<>
55  struct element_edwards_g2<183> {
56 
58 
60  typedef typename policy_type::g1_field_type::value_type g1_field_type_value;
61  typedef typename policy_type::g2_field_type::value_type g2_field_type_value;
62 
64 
68 
69  /************************* Constructors and zero/one ***********************************/
74  constexpr element_edwards_g2() :
75  element_edwards_g2(policy_type::g2_zero_fill[0], policy_type::g2_zero_fill[1],
76  policy_type::g2_zero_fill[2]) {};
77 
84  this->X = in_X;
85  this->Y = in_Y;
86  this->Z = in_Z;
87  };
93  element_edwards_g2(X, Y, X * Y) {};
97  constexpr static element_edwards_g2 zero() {
98  return element_edwards_g2(policy_type::g2_zero_fill[0], policy_type::g2_zero_fill[1],
99  policy_type::g2_zero_fill[2]);
100  }
104  constexpr static element_edwards_g2 one() {
105  return element_edwards_g2(policy_type::g2_one_fill[0],
106  policy_type::g2_one_fill[1]); // it's better to precompute also
107  // policy_type::g2_one_fill[2]
108  }
109 
110  /************************* Comparison operations ***********************************/
111 
112  constexpr bool operator==(const element_edwards_g2 &other) const {
113  if (this->is_zero()) {
114  return other.is_zero();
115  }
116 
117  if (other.is_zero()) {
118  return false;
119  }
120 
121  /* now neither is O */
122 
123  // X1/Z1 = X2/Z2 <=> X1*Z2 = X2*Z1
124  if ((this->X * other.Z) != (other.X * this->Z)) {
125  return false;
126  }
127 
128  // Y1/Z1 = Y2/Z2 <=> Y1*Z2 = Y2*Z1
129  if ((this->Y * other.Z) != (other.Y * this->Z)) {
130  return false;
131  }
132 
133  return true;
134  }
135 
136  constexpr bool operator!=(const element_edwards_g2 &other) const {
137  return !(operator==(other));
138  }
143  constexpr bool is_zero() const {
144  return (this->Y.is_zero() && this->Z.is_zero());
145  }
150  constexpr bool is_special() const {
151  return (this->is_zero() || this->Z == underlying_field_value_type::one());
152  }
153 
154  /************************* Arithmetic operations ***********************************/
155 
157  // handle special cases having to do with O
158  this->X = other.X;
159  this->Y = other.Y;
160  this->Z = other.Z;
161 
162  return *this;
163  }
164 
165  constexpr element_edwards_g2 operator+(const element_edwards_g2 &other) const {
166  // handle special cases having to do with O
167  if (this->is_zero()) {
168  return other;
169  }
170 
171  if (other.is_zero()) {
172  return (*this);
173  }
174 
175  if (*this == other) {
176  return this->doubled();
177  }
178 
179  return this->add(other);
180  }
181 
182  constexpr element_edwards_g2 operator-() const {
183  return element_edwards_g2(-(this->X), this->Y, this->Z);
184  }
185 
186  constexpr element_edwards_g2 operator-(const element_edwards_g2 &other) const {
187  return (*this) + (-other);
188  }
193  constexpr element_edwards_g2 doubled() const {
194 
195  if (this->is_zero()) {
196  return (*this);
197  } else {
198  // NOTE: does not handle O and pts of order 2,4
199  // http://www.hyperelliptic.org/EFD/g1p/auto-twisted-inverted.html#doubling-dbl-2008-bbjlp
200 
201  const underlying_field_value_type A = (this->X).squared(); // A = X1^2
202  const underlying_field_value_type B = (this->Y).squared(); // B = Y1^2
203  const underlying_field_value_type U = mul_by_a(B); // U = a*B
204  const underlying_field_value_type C = A + U; // C = A+U
205  const underlying_field_value_type D = A - U; // D = A-U
207  (this->X + this->Y).squared() - A - B; // E = (X1+Y1)^2-A-B
208  const underlying_field_value_type X3 = C * D; // X3 = C*D
209  const underlying_field_value_type dZZ = mul_by_d(this->Z.squared());
210  const underlying_field_value_type Y3 = E * (C - dZZ - dZZ); // Y3 = E*(C-2*d*Z1^2)
211  const underlying_field_value_type Z3 = D * E; // Z3 = D*E
212 
213  return element_edwards_g2(X3, Y3, Z3);
214  }
215  }
221  constexpr element_edwards_g2 mixed_add(const element_edwards_g2 &other) const {
222 
223  // handle special cases having to do with O
224  if (this->is_zero()) {
225  return other;
226  }
227 
228  if (other.is_zero()) {
229  return *this;
230  }
231 
232  // NOTE: does not handle O and pts of order 2,4
233  // http://www.hyperelliptic.org/EFD/g1p/auto-edwards-inverted.html#addition-madd-2007-lb
234 
235  const underlying_field_value_type A = this->Z; // A = Z1*Z2
236  const underlying_field_value_type B = mul_by_d(A.squared()); // B = d*A^2
237  const underlying_field_value_type C = (this->X) * (other.X); // C = X1*X2
238  const underlying_field_value_type D = (this->Y) * (other.Y); // D = Y1*Y2
239  const underlying_field_value_type E = C * D; // E = C*D
240  const underlying_field_value_type H = C - mul_by_a(D); // H = C-a*D
242  (this->X + this->Y) * (other.X + other.Y) - C - D; // I = (X1+Y1)*(X2+Y2)-C-D
243  const underlying_field_value_type X3 = (E + B) * H; // X3 = (E+B)*H
244  const underlying_field_value_type Y3 = (E - B) * I; // Y3 = (E-B)*I
245  const underlying_field_value_type Z3 = A * H * I; // Z3 = A*H*I
246 
247  return element_edwards_g2(X3, Y3, Z3);
248  }
249 
250  private:
251  constexpr element_edwards_g2 add(const element_edwards_g2 &other) const {
252  // NOTE: does not handle O and pts of order 2,4
253  // http://www.hyperelliptic.org/EFD/g1p/auto-twisted-inverted.html#addition-add-2008-bbjlp
254 
255  const underlying_field_value_type A = (this->Z) * (other.Z); // A = Z1*Z2
256  const underlying_field_value_type B = this->mul_by_d(A.squared()); // B = d*A^2
257  const underlying_field_value_type C = (this->X) * (other.X); // C = X1*X2
258  const underlying_field_value_type D = (this->Y) * (other.Y); // D = Y1*Y2
259  const underlying_field_value_type E = C * D; // E = C*D
260  const underlying_field_value_type H = C - this->mul_by_a(D); // H = C-a*D
261  const underlying_field_value_type I =
262  (this->X + this->Y) * (other.X + other.Y) - C - D; // I = (X1+Y1)*(X2+Y2)-C-D
263  const underlying_field_value_type X3 = (E + B) * H; // X3 = (E+B)*H
264  const underlying_field_value_type Y3 = (E - B) * I; // Y3 = (E-B)*I
265  const underlying_field_value_type Z3 = A * H * I; // Z3 = A*H*I
266 
267  return element_edwards_g2(X3, Y3, Z3);
268  }
269 
270  public:
271  /************************* Extra arithmetic operations ***********************************/
272 
273  constexpr inline static underlying_field_value_type
275  return underlying_field_value_type(twist_mul_by_a_c0 * elt.data[2], elt.data[0],
276  elt.data[1]);
277  }
278 
279  constexpr inline static underlying_field_value_type
281  return underlying_field_value_type(twist_mul_by_d_c0 * elt.data[2],
282  twist_mul_by_d_c1 * elt.data[0],
283  twist_mul_by_d_c2 * elt.data[1]);
284  }
285 
286  /************************* Reducing operations ***********************************/
291  constexpr element_edwards_g2 to_affine() const {
293 
294  if (this->is_zero()) {
295  p_out[0] = underlying_field_value_type::zero();
296  p_out[1] = underlying_field_value_type::one();
297  p_out[2] = underlying_field_value_type::one();
298  } else {
299  // go from inverted coordinates to projective coordinates
300  underlying_field_value_type tX = this->Y * this->Z;
301  underlying_field_value_type tY = this->X * this->Z;
302  underlying_field_value_type tZ = this->X * this->Y;
303  // go from projective coordinates to affine coordinates
304  underlying_field_value_type tZ_inv = tZ.inversed();
305  p_out[0] = tX * tZ_inv;
306  p_out[1] = tY * tZ_inv;
307  p_out[2] = underlying_field_value_type::one();
308  }
309 
310  return element_edwards_g2(p_out[0], p_out[1], p_out[2]);
311  }
312 
317  constexpr element_edwards_g2 to_projective() const {
319 
320  if (this->Z.is_zero()) {
321  return *this;
322  }
323 
324  underlying_field_value_type Z_inv = this->Z.inversed();
325  p_out[0] = this->X * Z_inv;
326  p_out[1] = this->Y * Z_inv;
327  p_out[2] = underlying_field_value_type::one();
328 
329  return element_edwards_g2(p_out[0], p_out[1], p_out[2]);
330  }
331 
332  constexpr static const g2_field_type_value twist = g2_field_type_value(
333  g2_field_type_value::underlying_type::zero(), g2_field_type_value::underlying_type::one(),
334  g2_field_type_value::underlying_type::zero());
335 
336  private:
337  constexpr static const g1_field_type_value a = policy_type::a;
338  constexpr static const g1_field_type_value d = policy_type::d;
339 
340  constexpr static const g2_field_type_value twist_coeff_a = a * twist;
341  constexpr static const g2_field_type_value twist_coeff_d = d * twist;
342 
343  constexpr static g1_field_type_value twist_mul_by_a_c0 = a * g2_field_type_value::non_residue;
344  constexpr static const g1_field_type_value twist_mul_by_a_c1 = a;
345  constexpr static const g1_field_type_value twist_mul_by_a_c2 = a;
346  constexpr static g1_field_type_value twist_mul_by_d_c0 = d * g2_field_type_value::non_residue;
347  constexpr static const g1_field_type_value twist_mul_by_d_c1 = d;
348  constexpr static const g1_field_type_value twist_mul_by_d_c2 = d;
349  constexpr static const g1_field_type_value twist_mul_by_q_Y =
350  g1_field_type_value(0xB35E3665A18365954D018902935D4419423F84321BC3E_cppui180);
351  constexpr static const g1_field_type_value twist_mul_by_q_Z =
352  g1_field_type_value(0xB35E3665A18365954D018902935D4419423F84321BC3E_cppui180);
353  };
354 
357 
358  constexpr typename element_edwards_g2<183>::g2_field_type_value const
360  constexpr typename element_edwards_g2<183>::g2_field_type_value const
362 
363  constexpr typename element_edwards_g2<183>::g1_field_type_value const
365  constexpr typename element_edwards_g2<183>::g1_field_type_value const
367 
368  constexpr typename element_edwards_g2<183>::g1_field_type_value const
370  constexpr typename element_edwards_g2<183>::g1_field_type_value const
372 
373  constexpr typename element_edwards_g2<183>::g1_field_type_value const
375  constexpr typename element_edwards_g2<183>::g1_field_type_value const
377 
382  } // namespace detail
383  } // namespace curves
384  } // namespace algebra
385  } // namespace crypto3
386 } // namespace nil
387 #endif // CRYPTO3_ALGEBRA_CURVES_EDWARDS_G1_ELEMENT_HPP
constexpr bool operator==(const matrix< T, N, M > &a, const matrix< T, N, M > &b)
checks equality of two matrices
Definition: matrix/operators.hpp:48
bool is_zero(const Range &a)
Definition: basic_operations.hpp:43
Definition: pair.hpp:31
A struct representing details about base and scalar fields of the size 183 bits and 181 bits respecti...
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/basic_policy.hpp:55
A struct representing a group G2 of Edwards curve.
Definition: edwards/g2.hpp:47
underlying_field_value_type X
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:65
constexpr element_edwards_g2 doubled() const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:193
constexpr element_edwards_g2 operator-() const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:182
constexpr element_edwards_g2 to_projective() const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:317
constexpr element_edwards_g2 to_affine() const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:291
constexpr element_edwards_g2()
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:74
constexpr element_edwards_g2(underlying_field_value_type X, underlying_field_value_type Y)
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:92
constexpr element_edwards_g2 operator+(const element_edwards_g2 &other) const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:165
constexpr bool operator==(const element_edwards_g2 &other) const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:112
constexpr static underlying_field_value_type mul_by_d(const underlying_field_value_type &elt)
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:280
g2_field_type_value underlying_field_value_type
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:63
constexpr static element_edwards_g2 zero()
Get the point at infinity.
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:97
constexpr static element_edwards_g2 one()
Get the generator of group G2.
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:104
constexpr element_edwards_g2 operator=(const element_edwards_g2 &other)
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:156
constexpr element_edwards_g2 mixed_add(const element_edwards_g2 &other) const
“Mixed addition” refers to the case Z2 known to be 1.
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:221
constexpr element_edwards_g2 operator-(const element_edwards_g2 &other) const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:186
constexpr bool operator!=(const element_edwards_g2 &other) const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:136
underlying_field_value_type Z
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:67
policy_type::g1_field_type::value_type g1_field_type_value
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:60
policy_type::g2_field_type::value_type g2_field_type_value
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:61
constexpr element_edwards_g2(underlying_field_value_type in_X, underlying_field_value_type in_Y, underlying_field_value_type in_Z)
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:82
constexpr bool is_special() const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:150
constexpr static underlying_field_value_type mul_by_a(const underlying_field_value_type &elt)
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:274
constexpr bool is_zero() const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:143
underlying_field_value_type Y
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:66
A struct representing an element from the group G2 of Edwards curve.
Definition: algebra/include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp:50