edwards/183/ate_precompute_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 //
5 // MIT License
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy
8 // of this software and associated documentation files (the "Software"), to deal
9 // in the Software without restriction, including without limitation the rights
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 // copies of the Software, and to permit persons to whom the Software is
12 // furnished to do so, subject to the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be included in all
15 // copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 // SOFTWARE.
24 //---------------------------------------------------------------------------//
25 
26 #ifndef CRYPTO3_ALGEBRA_PAIRING_BLS12_ATE_PRECOMPUTE_G2_HPP
27 #define CRYPTO3_ALGEBRA_PAIRING_BLS12_ATE_PRECOMPUTE_G2_HPP
28 
29 #include <nil/crypto3/multiprecision/number.hpp>
30 #include <nil/crypto3/multiprecision/cpp_int.hpp>
31 
35 
36 namespace nil {
37  namespace crypto3 {
38  namespace algebra {
39  namespace pairing {
40 
41  template<std::size_t Version = 183>
43 
44  template<>
47 
50 
51  using base_field_type = typename curve_type::base_field_type;
52  using g2_type = typename curve_type::template g2_type<>;
53  using g2_affine_type = typename curve_type::template g2_type<curves::coordinates::affine>;
54 
55  using g2_field_type_value = typename g2_type::field_type::value_type;
56 
57  struct extended_g2_projective {
58  g2_field_type_value X;
59  g2_field_type_value Y;
60  g2_field_type_value Z;
61  g2_field_type_value T;
62  };
63 
64  static void
65  doubling_step_for_flipped_miller_loop(extended_g2_projective &current,
66  typename policy_type::Fq3_conic_coefficients &cc) {
67 
68  const g2_field_type_value &X = current.X, &Y = current.Y, &Z = current.Z, &T = current.T;
69  const g2_field_type_value A = X.squared(); // A = X1^2
70  const g2_field_type_value B = Y.squared(); // B = Y1^2
71  const g2_field_type_value C = Z.squared(); // C = Z1^2
72  const g2_field_type_value D = (X + Y).squared(); // D = (X1+Y1)^2
73  const g2_field_type_value E = (Y + Z).squared(); // E = (Y1+Z1)^2
74  const g2_field_type_value F = D - (A + B); // F = D-(A+B)
75  const g2_field_type_value G = E - (B + C); // G = E-(B+C)
76  const g2_field_type_value H =
77  g2_type::value_type::mul_by_a(A); // param_twist_coeff_a is 1 * X for us
78  // H = twisted_a * A
79  const g2_field_type_value I = H + B; // I = H+B
80  const g2_field_type_value J = C - I; // J = C-I
81  const g2_field_type_value K = J + C; // K = J+C
82 
83  cc.c_ZZ = Y * (T - X); // c_ZZ = 2*Y1*(T1-X1)
84  cc.c_ZZ = cc.c_ZZ + cc.c_ZZ;
85  // c_XY = 2*(C-a * A * delta_3-B)+G (a = 1 for us)
86  cc.c_XY = C - g2_type::value_type::mul_by_a(A) - B; // param_twist_coeff_a is 1 * X for us
87  cc.c_XY = cc.c_XY + cc.c_XY + G;
88  // c_XZ = 2*(a*X1*T1*delta_3-B) (a = 1 for us)
89  cc.c_XZ = g2_type::value_type::mul_by_a(X * T) - B; // param_twist_coeff_a is 1 * X for us
90  cc.c_XZ = cc.c_XZ + cc.c_XZ;
91 
92  current.X = F * K; // X3 = F*K
93  current.Y = I * (B - H); // Y3 = I*(B-H)
94  current.Z = I * K; // Z3 = I*K
95  current.T = F * (B - H); // T3 = F*(B-H)
96  }
97 
98  static void
99  full_addition_step_for_flipped_miller_loop(const extended_g2_projective &base,
100  extended_g2_projective &current,
101  typename policy_type::Fq3_conic_coefficients &cc) {
102 
103  const g2_field_type_value &X1 = current.X, &Y1 = current.Y, &Z1 = current.Z, &T1 = current.T;
104  const g2_field_type_value &X2 = base.X, &Y2 = base.Y, &Z2 = base.Z, &T2 = base.T;
105 
106  const g2_field_type_value A = X1 * X2; // A = X1*X2
107  const g2_field_type_value B = Y1 * Y2; // B = Y1*Y2
108  const g2_field_type_value C = Z1 * T2; // C = Z1*T2
109  const g2_field_type_value D = T1 * Z2; // D = T1*Z2
110  const g2_field_type_value E = D + C; // E = D+C
111  const g2_field_type_value F = (X1 - Y1) * (X2 + Y2) + B - A; // F = (X1-Y1)*(X2+Y2)+B-A
112  // G = B + twisted_a * A
113  const g2_field_type_value G =
114  B + g2_type::value_type::mul_by_a(A); // param_twist_coeff_a is 1*X for us
115 
116  const g2_field_type_value H = D - C; // H = D-C
117  const g2_field_type_value I = T1 * T2; // I = T1*T2
118 
119  // c_ZZ = delta_3* ((T1-X1)*(T2+X2)-I+A)
120  cc.c_ZZ = g2_type::value_type::mul_by_a((T1 - X1) * (T2 + X2) - I +
121  A); // param_twist_coeff_a is 1*X for us
122 
123  cc.c_XY = X1 * Z2 - X2 * Z1 + F; // c_XY = X1*Z2-X2*Z1+F
124  cc.c_XZ = (Y1 - T1) * (Y2 + T2) - B + I - H; // c_XZ = (Y1-T1)*(Y2+T2)-B+I-H
125  current.X = E * F; // X3 = E*F
126  current.Y = G * H; // Y3 = G*H
127  current.Z = F * G; // Z3 = F*G
128  current.T = E * H; // T3 = E*H
129  }
130 
131  static void
132  mixed_addition_step_for_flipped_miller_loop(const extended_g2_projective &base,
133  extended_g2_projective &current,
134  typename policy_type::Fq3_conic_coefficients &cc) {
135 
136  const g2_field_type_value &X1 = current.X, &Y1 = current.Y, &Z1 = current.Z, &T1 = current.T;
137  const g2_field_type_value &X2 = base.X, &Y2 = base.Y, &T2 = base.T;
138 
139  const g2_field_type_value A = X1 * X2; // A = X1*X2
140  const g2_field_type_value B = Y1 * Y2; // B = Y1*Y2
141  const g2_field_type_value C = Z1 * T2; // C = Z1*T2
142  const g2_field_type_value E = T1 + C; // E = T1+C
143  const g2_field_type_value F = (X1 - Y1) * (X2 + Y2) + B - A; // F = (X1-Y1)*(X2+Y2)+B-A
144  // G = B + twisted_a * A
145  const g2_field_type_value G =
146  B + g2_type::value_type::mul_by_a(A); // param_twist_coeff_a is 1*X for us
147  const g2_field_type_value H = T1 - C; // H = T1-C
148  const g2_field_type_value I = T1 * T2; // I = T1*T2
149 
150  // c_ZZ = delta_3* ((T1-X1)*(T2+X2)-I+A)
151  cc.c_ZZ = g2_type::value_type::mul_by_a((T1 - X1) * (T2 + X2) - I +
152  A); // param_twist_coeff_a is 1*X for us
153 
154  cc.c_XY = X1 - X2 * Z1 + F; // c_XY = X1*Z2-X2*Z1+F
155  cc.c_XZ = (Y1 - T1) * (Y2 + T2) - B + I - H; // c_XZ = (Y1-T1)*(Y2+T2)-B+I-H
156  current.X = E * F; // X3 = E*F
157  current.Y = G * H; // Y3 = G*H
158  current.Z = F * G; // Z3 = F*G
159  current.T = E * H; // T3 = E*H
160  }
161 
162  public:
163  using g2_precomputed_type = typename policy_type::ate_g2_precomputed_type;
164 
165  static g2_precomputed_type process(const typename g2_type::value_type &Q) {
166 
167  g2_precomputed_type result;
168  typename g2_affine_type::value_type Qcopy = Q.to_affine();
169  extended_g2_projective Q_ext;
170  Q_ext.X = Qcopy.X;
171  Q_ext.Y = Qcopy.Y;
172  Q_ext.Z = Qcopy.Z;
173  Q_ext.T = Qcopy.X * Qcopy.Y;
174 
175  extended_g2_projective R = Q_ext;
176 
177  const typename policy_type::integral_type &loop_count = params_type::ate_loop_count;
178 
179  bool found_one = false;
180  for (long i = params_type::integral_type_max_bits - 1; i >= 0; --i) {
181  const bool bit = nil::crypto3::multiprecision::bit_test(loop_count, i);
182  if (!found_one) {
183  /* this skips the MSB itself */
184  found_one |= bit;
185  continue;
186  }
187 
188  typename policy_type::Fq3_conic_coefficients cc;
189  doubling_step_for_flipped_miller_loop(R, cc);
190  result.push_back(cc);
191  if (bit) {
192  mixed_addition_step_for_flipped_miller_loop(Q_ext, R, cc);
193  result.push_back(cc);
194  }
195  }
196 
197  return result;
198  }
199  };
200  } // namespace pairing
201  } // namespace algebra
202  } // namespace crypto3
203 } // namespace nil
204 #endif // CRYPTO3_ALGEBRA_PAIRING_BLS12_ATE_PRECOMPUTE_G2_HPP
Definition: pairing/detail/alt_bn128/params.hpp:38
Definition: pairing/detail/edwards/183/types.hpp:38
typename policy_type::ate_g2_precomputed_type g2_precomputed_type
Definition: edwards/183/ate_precompute_g2.hpp:163
static g2_precomputed_type process(const typename g2_type::value_type &Q)
Definition: edwards/183/ate_precompute_g2.hpp:165
Definition: edwards/183/ate_precompute_g2.hpp:42
Definition: pair.hpp:31
A struct representing a Edwards curve, providing 128 bits of security.
Definition: curves/edwards.hpp:51
IETF IPsec groups.
Definition: edwards/base_field.hpp:46