montgomery/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_MONTGOMERY_G1_ELEMENT_AFFINE_HPP
28 #define CRYPTO3_ALGEBRA_CURVES_MONTGOMERY_G1_ELEMENT_AFFINE_HPP
29 
34 
35 namespace nil {
36  namespace crypto3 {
37  namespace algebra {
38  namespace curves {
39  namespace detail {
46  template<typename CurveParams, typename Form, typename Coordinates>
47  struct curve_element;
48 
55  template<typename CurveParams>
56  struct curve_element<CurveParams, forms::montgomery, coordinates::affine> {
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  bool is_inf_point;
64 
65  public:
68 
69  using group_type = typename params_type::template group_type<coordinates>;
70 
71  field_value_type X;
72  field_value_type Y;
73 
74  /************************* Constructors and zero/one ***********************************/
80  constexpr curve_element() : is_inf_point(true) {};
81 
86  constexpr curve_element(const field_value_type &in_X, const field_value_type &in_Y) :
87  is_inf_point(false), X(in_X), Y(in_Y) {};
88 
92  static curve_element zero() {
93  return curve_element();
94  }
95 
99  static curve_element one() {
100  return curve_element(params_type::one_fill[0], params_type::one_fill[1]);
101  }
102 
103  /************************* Comparison operations ***********************************/
104 
105  constexpr bool operator==(const curve_element &other) const {
106  if (this->is_zero()) {
107  return other.is_zero();
108  }
109 
110  if (other.is_zero()) {
111  return false;
112  }
113 
114  /* now neither is O */
115 
116  if (this->X != other.X) {
117  return false;
118  }
119 
120  if (this->Y != other.Y) {
121  return false;
122  }
123 
124  return true;
125  }
126 
127  constexpr bool operator!=(const curve_element &other) const {
128  return !(operator==(other));
129  }
130 
136  constexpr bool is_zero() const {
137  return this->is_inf_point;
138  }
139 
145  constexpr bool is_well_formed() const {
146  if (this->is_zero()) {
147  return true;
148  } else {
149  field_value_type XX = this->X.squared();
150  field_value_type YY = this->Y.squared();
151 
152  return (field_value_type(params_type::B) * YY) ==
153  (XX * this->X + field_value_type(params_type::A) * XX + this->X);
154  }
155  }
156 
157  /************************* Reducing operations ***********************************/
158 
159  // /** @brief
160  // *
161  // * See https://eprint.iacr.org/2017/212.pdf, p. 7, par. 3.
162  // *
163  // * @return return the corresponding element from affine coordinates to
164  // xz coordinates
165  // */
166  // constexpr curve_element<params_type, form, typename curves::coordinates::xz> to_xz() const {
167  // using result_type = curve_element<params_type, form, typename curves::coordinates::xz>;
168  //
169  // return this->is_zero() ? result_type(result_type::field_type::value_type::one(),
170  // result_type::field_type::value_type::zero()) :
171  // result_type(this->X,
172  // result_type::field_type::value_type::one());
173  // }
174 
181  constexpr curve_element to_affine() const {
182  return *this;
183  }
184 
185  /************************* Arithmetic operations ***********************************/
186 
187  constexpr curve_element operator=(const curve_element &other) {
188  this->is_inf_point = other.is_inf_point;
189 
190  if (!other.is_zero()) {
191  this->X = other.X;
192  this->Y = other.Y;
193  }
194 
195  return *this;
196  }
197 
198  constexpr curve_element operator+(const curve_element &other) const {
199  if (this->is_zero()) {
200  return other;
201  }
202 
203  if (other.is_zero()) {
204  return (*this);
205  }
206 
207  if (*this == other) {
208  return this->doubled();
209  }
210 
211  return this->add(other);
212  }
213 
219  constexpr curve_element operator-() const {
220  return curve_element(this->X, -(this->Y));
221  }
222 
223  constexpr curve_element operator-(const curve_element &other) const {
224  return (*this) + (-other);
225  }
226 
237  constexpr curve_element doubled() const {
238  if (this->is_zero()) {
239  return (*this);
240  } else {
241  const field_value_type two(2);
242  const field_value_type three(3);
243  const field_value_type A(params_type::A);
244  const field_value_type B(params_type::B);
245 
246  const field_value_type temp1 = two * B * this->Y;
247  const field_value_type temp2 =
248  three * this->X.squared() + two * A * this->X + field_value_type::one();
249  const field_value_type temp1_sqr = temp1.squared();
250  const field_value_type temp2_sqr = temp2.squared();
251 
252  return curve_element((B * temp2_sqr) / temp1_sqr - A - this->X - this->X,
253  ((three * this->X + A) * temp2) / temp1 -
254  (B * temp2 * temp2_sqr) / (temp1 * temp1_sqr) - this->Y);
255  }
256  }
257 
258  private:
269  constexpr curve_element add(const curve_element &other) const {
270  const field_value_type two(2);
271  const field_value_type A(params_type::A);
272  const field_value_type B(params_type::B);
273 
274  const field_value_type temp1 = (other.Y) - (this->Y);
275  const field_value_type temp2 = (other.X) - (this->X);
276  const field_value_type temp1_sqr = temp1.squared();
277  const field_value_type temp2_sqr = temp2.squared();
278 
279  return curve_element((B * temp1_sqr) / temp2_sqr - A - this->X - other.X,
280  ((two * this->X + other.X + A) * temp1) / temp2 -
281  (B * temp1 * temp1_sqr) / (temp2 * temp2_sqr) - this->Y);
282  }
283 
284  public:
285  /************************* Reducing operations ***********************************/
286 
322  constexpr auto to_twisted_edwards() const {
323  using result_params =
324  typename group_type::curve_type::template g1_type<curves::coordinates::affine,
325  forms::twisted_edwards>::params_type;
326  using result_type =
327  typename group_type::curve_type::template g1_type<curves::coordinates::affine,
328  forms::twisted_edwards>::value_type;
329 
330  if (this->is_zero()) {
331  return result_type();
332  }
333 
334  assert(static_cast<field_value_type>(params_type::A) ==
335  static_cast<field_value_type>(2) *
336  (static_cast<field_value_type>(result_params::a) +
337  static_cast<field_value_type>(result_params::d)) /
338  (static_cast<field_value_type>(result_params::a) -
339  static_cast<field_value_type>(result_params::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>(result_params::a) -
344  static_cast<field_value_type>(result_params::d));
345  if (static_cast<field_value_type>(params_type::B) != B_) {
346  s_inv = (B_ / static_cast<field_value_type>(params_type::B)).sqrt();
347  }
348 
349  return result_type(s_inv * this->X / this->Y,
350  (this->X - field_value_type::one()) /
351  (this->X + field_value_type::one()));
352  }
353  };
354  } // namespace detail
355  } // namespace curves
356  } // namespace algebra
357  } // namespace crypto3
358 } // namespace nil
359 #endif // CRYPTO3_ALGEBRA_CURVES_MONTGOMERY_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 operator-() const
Affine negation formulas: -(x1,y1)=(x1,-y1).
Definition: montgomery/element_g1_affine.hpp:219
constexpr curve_element doubled() const
Affine doubling formulas: 2(x1,y1)=(x3,y3) where.
Definition: montgomery/element_g1_affine.hpp:237
constexpr bool is_zero() const
Definition: montgomery/element_g1_affine.hpp:136
typename params_type::template group_type< coordinates > group_type
Definition: montgomery/element_g1_affine.hpp:69
constexpr auto to_twisted_edwards() const
Convert point coordinates into twisted Edwards form according to birational equivalence map:
Definition: montgomery/element_g1_affine.hpp:322
constexpr curve_element operator-(const curve_element &other) const
Definition: montgomery/element_g1_affine.hpp:223
constexpr bool operator==(const curve_element &other) const
Definition: montgomery/element_g1_affine.hpp:105
static curve_element one()
Get the generator of group G1.
Definition: montgomery/element_g1_affine.hpp:99
constexpr curve_element operator+(const curve_element &other) const
Definition: montgomery/element_g1_affine.hpp:198
constexpr curve_element(const field_value_type &in_X, const field_value_type &in_Y)
Definition: montgomery/element_g1_affine.hpp:86
constexpr curve_element to_affine() const
Definition: montgomery/element_g1_affine.hpp:181
constexpr curve_element operator=(const curve_element &other)
Definition: montgomery/element_g1_affine.hpp:187
constexpr bool is_well_formed() const
Check that point coordinates satisfy curve equitation: b*y^2 = x^3 + a*x^2 + x.
Definition: montgomery/element_g1_affine.hpp:145
typename CurveParams::field_type field_type
Definition: montgomery/element_g1_affine.hpp:57
static curve_element zero()
Get the point at infinity.
Definition: montgomery/element_g1_affine.hpp:92
constexpr bool operator!=(const curve_element &other) const
Definition: montgomery/element_g1_affine.hpp:127
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