algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.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_SHORT_WEIERSTRASS_G1_ELEMENT_PROJECTIVE_HPP
28 #define CRYPTO3_ALGEBRA_CURVES_SHORT_WEIERSTRASS_G1_ELEMENT_PROJECTIVE_HPP
29 
32 
37 
38 namespace nil {
39  namespace crypto3 {
40  namespace algebra {
41  namespace curves {
42  namespace detail {
48  template<typename CurveParams, typename Form, typename Coordinates>
49  struct curve_element;
50 
56  template<typename CurveParams>
57  struct curve_element<CurveParams, forms::short_weierstrass, coordinates::projective> {
58 
59  using params_type = CurveParams;
60  using field_type = typename params_type::field_type;
61 
62  private:
63  using field_value_type = typename field_type::value_type;
64 
67 
68  public:
70  using coordinates = coordinates::projective;
71 
72  using group_type = typename params_type::template group_type<coordinates>;
73 
74  field_value_type X;
75  field_value_type Y;
76  field_value_type Z;
77 
78  /************************* Constructors and zero/one ***********************************/
79 
84  constexpr curve_element() :
85  curve_element(params_type::zero_fill[0],
86  params_type::zero_fill[1],
87  field_value_type::zero()) {};
88 
93  constexpr curve_element(field_value_type X, field_value_type Y, field_value_type Z) {
94  this->X = X;
95  this->Y = Y;
96  this->Z = Z;
97  };
98 
102  constexpr static curve_element zero() {
103  return curve_element();
104  }
105 
109  constexpr static curve_element one() {
110  return curve_element(params_type::one_fill[0], params_type::one_fill[1],
111  field_value_type::one());
112  }
113 
114  /************************* Comparison operations ***********************************/
115 
116  constexpr bool operator==(const curve_element &other) const {
117  if (this->is_zero()) {
118  return other.is_zero();
119  }
120 
121  if (other.is_zero()) {
122  return false;
123  }
124 
125  /* now neither is O */
126 
127  // X1/Z1 = X2/Z2 <=> X1*Z2 = X2*Z1
128  if ((this->X * other.Z) != (other.X * this->Z)) {
129  return false;
130  }
131 
132  // Y1/Z1 = Y2/Z2 <=> Y1*Z2 = Y2*Z1
133  if ((this->Y * other.Z) != (other.Y * this->Z)) {
134  return false;
135  }
136 
137  return true;
138  }
139 
140  constexpr bool operator!=(const curve_element &other) const {
141  return !(operator==(other));
142  }
147  constexpr bool is_zero() const {
148  return (this->X.is_zero() && this->Z.is_zero());
149  }
150 
155  constexpr bool is_well_formed() const {
156  if (this->is_zero()) {
157  return true;
158  } else {
159  /*
160  y^2 = x^3 + ax + b
161 
162  We are using projective, so equation we need to check is actually
163 
164  (y/z)^2 = (x/z)^3 + a (x/z) + b
165  z y^2 = x^3 + a z^2 x + b z^3
166 
167  z (y^2 - b z^2) = x ( x^2 + a z^2)
168  */
169  const field_value_type X2 = this->X.squared();
170  const field_value_type Y2 = this->Y.squared();
171  const field_value_type Z2 = this->Z.squared();
172 
173  return (this->Z * (Y2 - params_type::b * Z2) == this->X * (X2 + params_type::a * Z2));
174  }
175  }
176 
177  /************************* Reducing operations ***********************************/
178 
185  to_affine() const {
186 
188 
189  if (is_zero()) {
190  return result_type::zero();
191  }
192 
193  return result_type(X * Z.inversed(), Y * Z.inversed()); // x=X/Z, y=Y/Z
194  }
195 
196  /************************* Arithmetic operations ***********************************/
197 
198  constexpr curve_element operator=(const curve_element &other) {
199  // handle special cases having to do with O
200  this->X = other.X;
201  this->Y = other.Y;
202  this->Z = other.Z;
203 
204  return *this;
205  }
206 
207  constexpr curve_element operator+(const curve_element &other) const {
208  // handle special cases having to do with O
209  if (this->is_zero()) {
210  return other;
211  }
212 
213  if (other.is_zero()) {
214  return (*this);
215  }
216 
217  if (*this == other) {
218  return this->doubled();
219  }
220 
221  return common_addition_processor::process(*this, other);
222  }
223 
224  constexpr curve_element operator-() const {
225  return curve_element(this->X, -this->Y, this->Z);
226  }
227 
228  constexpr curve_element operator-(const curve_element &other) const {
229  return (*this) + (-other);
230  }
231 
236  constexpr curve_element doubled() const {
237  return common_doubling_processor::process(*this);
238  }
239 
245  constexpr curve_element mixed_add(const curve_element &other) const {
246 
247  // NOTE: does not handle O and pts of order 2,4
248  // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-projective.html#addition-add-1998-cmo-2
249 
250  if (this->is_zero()) {
251  return other;
252  }
253 
254  if (other.is_zero()) {
255  return (*this);
256  }
257 
258  // Because for some reasons it's not so
259  // assert(other.Z == field_value_type::one());
260 
261  const field_value_type &X1Z2 =
262  (this->X); // X1Z2 = X1*Z2 (but other is special and not zero)
263  const field_value_type X2Z1 = (this->Z) * (other.X); // X2Z1 = X2*Z1
264 
265  // (used both in add and double checks)
266 
267  const field_value_type &Y1Z2 =
268  (this->Y); // Y1Z2 = Y1*Z2 (but other is special and not zero)
269  const field_value_type Y2Z1 = (this->Z) * (other.Y); // Y2Z1 = Y2*Z1
270 
271  if (X1Z2 == X2Z1 && Y1Z2 == Y2Z1) {
272  return this->doubled();
273  }
274 
275  const field_value_type u = Y2Z1 - this->Y; // u = Y2*Z1-Y1
276  const field_value_type uu = u.squared(); // uu = u2
277  const field_value_type v = X2Z1 - this->X; // v = X2*Z1-X1
278  const field_value_type vv = v.squared(); // vv = v2
279  const field_value_type vvv = v * vv; // vvv = v*vv
280  const field_value_type R = vv * this->X; // R = vv*X1
281  const field_value_type A = uu * this->Z - vvv - R - R; // A = uu*Z1-vvv-2*R
282  const field_value_type X3 = v * A; // X3 = v*A
283  const field_value_type Y3 = u * (R - A) - vvv * this->Y; // Y3 = u*(R-A)-vvv*Y1
284  const field_value_type Z3 = vvv * this->Z; // Z3 = vvv*Z1
285 
286  return curve_element(X3, Y3, Z3);
287  }
288  };
289 
290  } // namespace detail
291  } // namespace curves
292  } // namespace algebra
293  } // namespace crypto3
294 } // namespace nil
295 #endif // CRYPTO3_ALGEBRA_CURVES_SHORT_WEIERSTRASS_G1_ELEMENT_PROJECTIVE_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
field_value_type X
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.hpp:74
constexpr curve_element operator-() const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.hpp:224
constexpr curve_element()
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.hpp:84
constexpr bool operator==(const curve_element &other) const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.hpp:116
constexpr curve_element< params_type, form, typename curves::coordinates::affine > to_affine() const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.hpp:185
constexpr curve_element doubled() const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.hpp:236
coordinates::projective coordinates
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.hpp:70
constexpr bool operator!=(const curve_element &other) const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.hpp:140
typename params_type::template group_type< coordinates > group_type
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.hpp:72
constexpr static curve_element zero()
Get the point at infinity.
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.hpp:102
field_value_type Y
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.hpp:75
constexpr bool is_zero() const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.hpp:147
constexpr curve_element mixed_add(const curve_element &other) const
“Mixed addition” refers to the case Z2 known to be 1.
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.hpp:245
CurveParams params_type
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.hpp:59
constexpr curve_element(field_value_type X, field_value_type Y, field_value_type Z)
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.hpp:93
constexpr curve_element operator=(const curve_element &other)
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.hpp:198
constexpr static curve_element one()
Get the generator of group G1.
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.hpp:109
constexpr curve_element operator+(const curve_element &other) const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.hpp:207
constexpr bool is_well_formed() const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.hpp:155
field_value_type Z
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.hpp:76
typename params_type::field_type field_type
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.hpp:60
constexpr curve_element operator-(const curve_element &other) const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective/element_g1.hpp:228
A struct representing a group G1 of elliptic curve.
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/edwards/inverted/element_g1.hpp:50
A struct representing element addition from the group G1 of short Weierstrass curve for projective co...
Definition: projective/add_1998_cmo_2.hpp:41
A struct representing element doubling from the group G1 of short Weierstrass curve for projective co...
Definition: short_weierstrass/projective/dbl_2007_bl.hpp:40
Definition: forms.hpp:34