twisted_edwards/element_g1_affine.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2021 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 2021 Nikita Kaskov <nbering@nil.foundation>
4 // Copyright (c) 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_TWISTED_EDWARDS_G1_ELEMENT_AFFINE_HPP
28 #define CRYPTO3_ALGEBRA_CURVES_TWISTED_EDWARDS_G1_ELEMENT_AFFINE_HPP
29 
34 
35 namespace nil {
36  namespace crypto3 {
37  namespace algebra {
38  namespace curves {
39  namespace detail {
45  template<typename CurveParams, typename Form, typename Coordinates>
46  struct curve_element;
47 
54  template<typename CurveParams>
55  struct curve_element<CurveParams, forms::twisted_edwards, coordinates::affine> {
56 
57  using field_type = typename CurveParams::field_type;
58 
59  private:
60  using params_type = CurveParams;
61  using field_value_type = typename field_type::value_type;
62 
63  public:
66 
67  using group_type = typename params_type::template group_type<coordinates>;
68 
69  field_value_type X;
70  field_value_type Y;
71 
72  /************************* Constructors and zero/one ***********************************/
77  constexpr curve_element() :
78  curve_element(params_type::zero_fill[0], params_type::zero_fill[1]) {};
79 
84  constexpr curve_element(field_value_type in_X, field_value_type in_Y) {
85  this->X = in_X;
86  this->Y = in_Y;
87  };
88 
92  static curve_element zero() {
93  return curve_element();
94  }
98  static curve_element one() {
99  return curve_element(params_type::one_fill[0], params_type::one_fill[1]);
100  }
101 
102  /************************* Comparison operations ***********************************/
103 
104  constexpr bool operator==(const curve_element &other) const {
105  if (this->is_zero()) {
106  return other.is_zero();
107  }
108 
109  if (other.is_zero()) {
110  return false;
111  }
112 
113  /* now neither is O */
114 
115  if (this->X != other.X) {
116  return false;
117  }
118 
119  if (this->Y != other.Y) {
120  return false;
121  }
122 
123  return true;
124  }
125 
126  constexpr bool operator!=(const curve_element &other) const {
127  return !(operator==(other));
128  }
133  constexpr bool is_zero() const {
134  return X == params_type::zero_fill[0] && Y == params_type::zero_fill[1];
135  }
136 
143  constexpr bool is_well_formed() const {
144  if (this->is_zero()) {
145  return true;
146  } else {
147 
148  field_value_type XX = this->X.squared();
149  field_value_type YY = this->Y.squared();
150 
151  return (field_value_type(params_type::a) * XX + YY ==
152  field_value_type::one() + field_value_type(params_type::d) * XX * YY);
153  }
154  }
155 
156  /************************* Reducing operations ***********************************/
157 
158  // /** @brief
159  // *
160  // * @return return the corresponding element from affine coordinates to
161  // * projective coordinates
162  // */
163  // constexpr curve_element<
164  // params_type,
165  // form,
166  // typename curves::coordinates::projective> to_projective () const {
167 
168  // using result_type = curve_element<params_type,
169  // form, typename curves::coordinates::projective>;
170 
171  // return result_type(X, Y, result_type::field_type::value_type::one()); // X = x, Y = y, Z
172  // = 1
173  // }
174 
181  to_inverted() const {
182 
183  using result_type =
185 
186  return result_type(
187  X.inversed(), Y.inversed(),
188  result_type::field_type::value_type::one()); // X = x^(-1), Y = y^(-1), Z = 1
189  }
190 
196  constexpr curve_element<params_type, form,
197  typename curves::coordinates::extended_with_a_minus_1>
199 
200  using result_type =
202 
203  return result_type(X, Y, X * Y,
204  result_type::field_type::value_type::one()); // x=X/Z, y=Y/Z, x*y=T/Z
205  }
206 
212  constexpr curve_element to_affine() const {
213  return *this;
214  }
215 
216  /************************* Arithmetic operations ***********************************/
217 
218  constexpr curve_element operator=(const curve_element &other) {
219  // handle special cases having to do with O
220  this->X = other.X;
221  this->Y = other.Y;
222 
223  return *this;
224  }
225 
226  constexpr curve_element operator+(const curve_element &other) const {
227  // handle special cases having to do with O
228  if (this->is_zero()) {
229  return other;
230  }
231 
232  if (other.is_zero()) {
233  return (*this);
234  }
235 
236  if (*this == other) {
237  return this->doubled();
238  }
239 
240  return this->add(other);
241  }
242 
243  constexpr curve_element operator-() const {
244  return curve_element(-(this->X), this->Y);
245  }
246 
247  constexpr curve_element operator-(const curve_element &B) const {
248  return (*this) + (-B);
249  }
254  constexpr curve_element doubled() const {
255 
256  if (this->is_zero()) {
257  return (*this);
258  } else {
259 
260  return this->add(*this); // Temporary intil we find something more efficient
261  }
262  }
263 
264  private:
270  curve_element add(const curve_element &other) const {
271  field_value_type XX = (this->X) * (other.X);
272  field_value_type YY = (this->Y) * (other.Y);
273  field_value_type XY = (this->X) * (other.Y);
274  field_value_type YX = (this->Y) * (other.X);
275 
276  field_value_type lambda = params_type::d * XX * YY;
277  field_value_type X3 = (XY + YX) * (field_value_type::one() + lambda).inversed();
278  field_value_type Y3 =
279  (YY - params_type::a * XX) * (field_value_type::one() - lambda).inversed();
280 
281  return curve_element(X3, Y3);
282  }
283 
284  public:
285  /************************* Reducing operations ***********************************/
286 
322  constexpr auto to_montgomery() const {
323  using result_params =
324  typename group_type::curve_type::template g1_type<curves::coordinates::affine,
325  forms::montgomery>::params_type;
326  using result_type =
327  typename group_type::curve_type::template g1_type<curves::coordinates::affine,
328  forms::montgomery>::value_type;
329 
330  if (this->is_zero()) {
331  return result_type();
332  }
333 
334  assert(static_cast<field_value_type>(result_params::A) ==
335  static_cast<field_value_type>(2) *
336  (static_cast<field_value_type>(params_type::a) +
337  static_cast<field_value_type>(params_type::d)) /
338  (static_cast<field_value_type>(params_type::a) -
339  static_cast<field_value_type>(params_type::d)));
340 
341  field_value_type s_inv = field_value_type::one();
342  field_value_type B_ =
343  static_cast<field_value_type>(4) / (static_cast<field_value_type>(params_type::a) -
344  static_cast<field_value_type>(params_type::d));
345  if (static_cast<field_value_type>(result_params::B) != B_) {
346  s_inv = (B_ / static_cast<field_value_type>(result_params::B)).sqrt();
347  }
348 
349  return result_type((field_value_type::one() + this->Y) /
350  (field_value_type::one() - this->Y),
351  s_inv * ((field_value_type::one() + this->Y) /
352  (this->X * (field_value_type::one() - this->Y))));
353  }
354  };
355 
356  } // namespace detail
357  } // namespace curves
358  } // namespace algebra
359  } // namespace crypto3
360 } // namespace nil
361 #endif // CRYPTO3_ALGEBRA_CURVES_TWISTED_EDWARDS_G1_ELEMENT_AFFINE_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
Jacobi quatrics curve group element coordinates representation. Description: https://hyperelliptic....
Definition: jacobi_quartics/coordinates.hpp:40
constexpr curve_element doubled() const
Definition: twisted_edwards/element_g1_affine.hpp:254
constexpr bool is_zero() const
Definition: twisted_edwards/element_g1_affine.hpp:133
constexpr bool operator!=(const curve_element &other) const
Definition: twisted_edwards/element_g1_affine.hpp:126
constexpr curve_element operator-(const curve_element &B) const
Definition: twisted_edwards/element_g1_affine.hpp:247
constexpr bool operator==(const curve_element &other) const
Definition: twisted_edwards/element_g1_affine.hpp:104
constexpr curve_element to_affine() const
Definition: twisted_edwards/element_g1_affine.hpp:212
constexpr curve_element operator-() const
Definition: twisted_edwards/element_g1_affine.hpp:243
constexpr curve_element< params_type, form, typename curves::coordinates::inverted > to_inverted() const
Definition: twisted_edwards/element_g1_affine.hpp:181
static curve_element zero()
Get the point at infinity.
Definition: twisted_edwards/element_g1_affine.hpp:92
constexpr curve_element(field_value_type in_X, field_value_type in_Y)
Definition: twisted_edwards/element_g1_affine.hpp:84
typename params_type::template group_type< coordinates > group_type
Definition: twisted_edwards/element_g1_affine.hpp:67
constexpr auto to_montgomery() const
Convert point coordinates into Montgomery form according to birational equivalence map:
Definition: twisted_edwards/element_g1_affine.hpp:322
constexpr curve_element operator=(const curve_element &other)
Definition: twisted_edwards/element_g1_affine.hpp:218
constexpr curve_element operator+(const curve_element &other) const
Definition: twisted_edwards/element_g1_affine.hpp:226
static curve_element one()
Get the generator of group G1.
Definition: twisted_edwards/element_g1_affine.hpp:98
constexpr bool is_well_formed() const
Definition: twisted_edwards/element_g1_affine.hpp:143
typename CurveParams::field_type field_type
Definition: twisted_edwards/element_g1_affine.hpp:57
constexpr curve_element< params_type, form, typename curves::coordinates::extended_with_a_minus_1 > to_extended_with_a_minus_1() const
Definition: twisted_edwards/element_g1_affine.hpp:198
A struct representing a group G1 of elliptic curve.
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/edwards/inverted/element_g1.hpp:50
Definition: forms.hpp:34