algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective_with_a4_minus_3/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 // Copyright (c) 2022 Ekaterina Chukavina <kate@nil.foundation>
6 //
7 // MIT License
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to deal
11 // in the Software without restriction, including without limitation the rights
12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 // copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
15 //
16 // The above copyright notice and this permission notice shall be included in all
17 // copies or substantial portions of the Software.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 // SOFTWARE.
26 //---------------------------------------------------------------------------//
27 
28 #ifndef CRYPTO3_ALGEBRA_CURVES_SHORT_WEIERSTRASS_G1_ELEMENT_PROJECTIVE_WITH_A4_MINUS_3_HPP
29 #define CRYPTO3_ALGEBRA_CURVES_SHORT_WEIERSTRASS_G1_ELEMENT_PROJECTIVE_WITH_A4_MINUS_3_HPP
30 
33 
38 
39 namespace nil {
40  namespace crypto3 {
41  namespace algebra {
42  namespace curves {
43  namespace detail {
49  template<typename CurveParams, typename Form, typename Coordinates>
50  struct curve_element;
51 
57  template<typename CurveParams>
58  struct curve_element<CurveParams, forms::short_weierstrass, coordinates::projective_with_a4_minus_3> {
59 
60  using params_type = CurveParams;
61  using field_type = typename params_type::field_type;
62 
63  private:
64  using field_value_type = typename field_type::value_type;
65 
68 
69  public:
71  using coordinates = coordinates::projective_with_a4_minus_3;
72 
73  using group_type = typename params_type::template group_type<coordinates>;
74 
75  field_value_type X;
76  field_value_type Y;
77  field_value_type Z;
78 
79  /************************* Constructors and zero/one ***********************************/
80 
85  constexpr curve_element() :
86  curve_element(params_type::zero_fill[0],
87  params_type::zero_fill[1],
88  field_value_type::zero()) {};
89 
94  constexpr curve_element(field_value_type X, field_value_type Y, field_value_type Z) {
95  this->X = X;
96  this->Y = Y;
97  this->Z = Z;
98  };
99 
103  constexpr static curve_element zero() {
104  return curve_element();
105  }
106 
110  constexpr static curve_element one() {
111  return curve_element(params_type::one_fill[0], params_type::one_fill[1],
112  field_value_type::one());
113  }
114 
115  /************************* Comparison operations ***********************************/
116 
117  constexpr bool operator==(const curve_element &other) const {
118  if (this->is_zero()) {
119  return other.is_zero();
120  }
121 
122  if (other.is_zero()) {
123  return false;
124  }
125 
126  /* now neither is O */
127 
128  // X1/Z1 = X2/Z2 <=> X1*Z2 = X2*Z1
129  if ((this->X * other.Z) != (other.X * this->Z)) {
130  return false;
131  }
132 
133  // Y1/Z1 = Y2/Z2 <=> Y1*Z2 = Y2*Z1
134  if ((this->Y * other.Z) != (other.Y * this->Z)) {
135  return false;
136  }
137 
138  return true;
139  }
140 
141  constexpr bool operator!=(const curve_element &other) const {
142  return !(operator==(other));
143  }
148  constexpr bool is_zero() const {
149  return (this->X.is_zero() && this->Z.is_zero());
150  }
151 
156  constexpr bool is_well_formed() const {
157  if (this->is_zero()) {
158  return true;
159  } else {
160  /*
161  y^2 = x^3 + ax + b
162 
163  We are using projective_with_a4_minus_3, so equation we need to check is actually
164 
165  (y/z)^2 = (x/z)^3 + a (x/z) + b
166  z y^2 = x^3 + a z^2 x + b z^3
167  z (y^2 - b z^2) = x ( x^2 + a z^2)
168 
169  z (y^2 - b z^2) = x ( x^2 - z^2)
170  */
171  const field_value_type X2 = this->X.squared();
172  const field_value_type Y2 = this->Y.squared();
173  const field_value_type Z2 = this->Z.squared();
174 
175  return (this->Z * (Y2 - params_type::b * Z2) == this->X * (X2 - Z2));
176  }
177  }
178 
179  /************************* Reducing operations ***********************************/
180 
187  to_affine() const {
188 
190 
191  if (is_zero()) {
192  return result_type::zero();
193  }
194 
195  return result_type(X * Z.inversed(), Y * Z.inversed()); // x=X/Z, y=Y/Z
196  }
197 
198  /************************* Arithmetic operations ***********************************/
199 
200  constexpr curve_element operator=(const curve_element &other) {
201  // handle special cases having to do with O
202  this->X = other.X;
203  this->Y = other.Y;
204  this->Z = other.Z;
205 
206  return *this;
207  }
208 
209  constexpr curve_element operator+(const curve_element &other) const {
210  // handle special cases having to do with O
211  if (this->is_zero()) {
212  return other;
213  }
214 
215  if (other.is_zero()) {
216  return (*this);
217  }
218 
219  if (*this == other) {
220  return this->doubled();
221  }
222 
223  return common_addition_processor::process(*this, other);
224  }
225 
226  constexpr curve_element operator-() const {
227  return curve_element(this->X, -this->Y, this->Z);
228  }
229 
230  constexpr curve_element operator-(const curve_element &other) const {
231  return (*this) + (-other);
232  }
233 
238  constexpr curve_element doubled() const {
239  return common_doubling_processor::process(*this);
240  }
241 
247  constexpr curve_element mixed_add(const curve_element &other) const {
248 
249  // NOTE: does not handle O and pts of order 2,4
250  // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-projective_with_a4_minus_3.html#addition-add-1998-cmo-2
251 
252  if (this->is_zero()) {
253  return other;
254  }
255 
256  if (other.is_zero()) {
257  return (*this);
258  }
259 
260  // Because for some reasons it's not so
261  // assert(other.Z == field_value_type::one());
262 
263  const field_value_type &X1Z2 =
264  (this->X); // X1Z2 = X1*Z2 (but other is special and not zero)
265  const field_value_type X2Z1 = (this->Z) * (other.X); // X2Z1 = X2*Z1
266 
267  // (used both in add and double checks)
268 
269  const field_value_type &Y1Z2 =
270  (this->Y); // Y1Z2 = Y1*Z2 (but other is special and not zero)
271  const field_value_type Y2Z1 = (this->Z) * (other.Y); // Y2Z1 = Y2*Z1
272 
273  if (X1Z2 == X2Z1 && Y1Z2 == Y2Z1) {
274  return this->doubled();
275  }
276 
277  const field_value_type u = Y2Z1 - this->Y; // u = Y2*Z1-Y1
278  const field_value_type uu = u.squared(); // uu = u2
279  const field_value_type v = X2Z1 - this->X; // v = X2*Z1-X1
280  const field_value_type vv = v.squared(); // vv = v2
281  const field_value_type vvv = v * vv; // vvv = v*vv
282  const field_value_type R = vv * this->X; // R = vv*X1
283  const field_value_type A = uu * this->Z - vvv - R - R; // A = uu*Z1-vvv-2*R
284  const field_value_type X3 = v * A; // X3 = v*A
285  const field_value_type Y3 = u * (R - A) - vvv * this->Y; // Y3 = u*(R-A)-vvv*Y1
286  const field_value_type Z3 = vvv * this->Z; // Z3 = vvv*Z1
287 
288  return curve_element(X3, Y3, Z3);
289  }
290  };
291 
292  } // namespace detail
293  } // namespace curves
294  } // namespace algebra
295  } // namespace crypto3
296 } // namespace nil
297 #endif // CRYPTO3_ALGEBRA_CURVES_SHORT_WEIERSTRASS_G1_ELEMENT_PROJECTIVE_WITH_A4_MINUS_3_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
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_with_a4_minus_3/element_g1.hpp:247
field_value_type Z
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective_with_a4_minus_3/element_g1.hpp:77
constexpr curve_element()
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective_with_a4_minus_3/element_g1.hpp:85
CurveParams params_type
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective_with_a4_minus_3/element_g1.hpp:60
typename params_type::template group_type< coordinates > group_type
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective_with_a4_minus_3/element_g1.hpp:73
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_with_a4_minus_3/element_g1.hpp:94
coordinates::projective_with_a4_minus_3 coordinates
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective_with_a4_minus_3/element_g1.hpp:71
constexpr curve_element operator+(const curve_element &other) const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective_with_a4_minus_3/element_g1.hpp:209
constexpr curve_element operator-() const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective_with_a4_minus_3/element_g1.hpp:226
field_value_type X
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective_with_a4_minus_3/element_g1.hpp:75
constexpr bool is_well_formed() const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective_with_a4_minus_3/element_g1.hpp:156
constexpr bool operator!=(const curve_element &other) const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective_with_a4_minus_3/element_g1.hpp:141
constexpr curve_element operator=(const curve_element &other)
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective_with_a4_minus_3/element_g1.hpp:200
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_with_a4_minus_3/element_g1.hpp:187
constexpr curve_element doubled() const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective_with_a4_minus_3/element_g1.hpp:238
constexpr bool operator==(const curve_element &other) const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective_with_a4_minus_3/element_g1.hpp:117
field_value_type Y
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective_with_a4_minus_3/element_g1.hpp:76
constexpr static curve_element one()
Get the generator of group G1.
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective_with_a4_minus_3/element_g1.hpp:110
constexpr curve_element operator-(const curve_element &other) const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective_with_a4_minus_3/element_g1.hpp:230
constexpr bool is_zero() const
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective_with_a4_minus_3/element_g1.hpp:148
constexpr static curve_element zero()
Get the point at infinity.
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective_with_a4_minus_3/element_g1.hpp:103
typename params_type::field_type field_type
Definition: algebra/include/nil/crypto3/algebra/curves/detail/forms/short_weierstrass/projective_with_a4_minus_3/element_g1.hpp:61
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_wi...
Definition: projective_with_a4_minus_3/add_1998_cmo_2.hpp:42
A struct representing element doubling from the group G1 of short Weierstrass curve for projective_wi...
Definition: short_weierstrass/projective_with_a4_minus_3/dbl_2007_bl.hpp:41
Definition: forms.hpp:34