detail/element/fp6_3over2.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_FIELDS_ELEMENT_FP6_3OVER2_HPP
27 #define CRYPTO3_ALGEBRA_FIELDS_ELEMENT_FP6_3OVER2_HPP
28 
31 
32 namespace nil {
33  namespace crypto3 {
34  namespace algebra {
35  namespace fields {
36  namespace detail {
37 
38  template<typename FieldParams>
40  typedef FieldParams policy_type;
41 
42  public:
43  typedef typename policy_type::non_residue_type non_residue_type;
44  constexpr static const non_residue_type non_residue = policy_type::non_residue;
45 
46  typedef typename policy_type::underlying_type underlying_type;
47 
48  using data_type = std::array<underlying_type, 3>;
49 
51 
52  constexpr element_fp6_3over2() {
53  data =
54  data_type({underlying_type::zero(), underlying_type::zero(), underlying_type::zero()});
55  }
56 
57  constexpr element_fp6_3over2(underlying_type in_data0,
58  underlying_type in_data1,
59  underlying_type in_data2) {
60  data = data_type({in_data0, in_data1, in_data2});
61  }
62 
63  constexpr element_fp6_3over2(const data_type &in_data) {
64  data = data_type({in_data[0], in_data[1], in_data[2]});
65  };
66 
67  constexpr element_fp6_3over2(const element_fp6_3over2 &B) : data {B.data} {};
68 
69  constexpr inline static element_fp6_3over2 zero() {
70  return element_fp6_3over2(
71  underlying_type::zero(), underlying_type::zero(), underlying_type::zero());
72  }
73 
74  constexpr inline static element_fp6_3over2 one() {
75  return element_fp6_3over2(
76  underlying_type::one(), underlying_type::zero(), underlying_type::zero());
77  }
78 
79  constexpr bool operator==(const element_fp6_3over2 &B) const {
80  return (data[0] == B.data[0]) && (data[1] == B.data[1]) && (data[2] == B.data[2]);
81  }
82 
83  constexpr bool operator!=(const element_fp6_3over2 &B) const {
84  return (data[0] != B.data[0]) || (data[1] != B.data[1]) || (data[2] != B.data[2]);
85  }
86 
88  data[0] = B.data[0];
89  data[1] = B.data[1];
90  data[2] = B.data[2];
91 
92  return *this;
93  }
94 
95  constexpr element_fp6_3over2 operator+(const element_fp6_3over2 &B) const {
96  return element_fp6_3over2(data[0] + B.data[0], data[1] + B.data[1], data[2] + B.data[2]);
97  }
98 
99  constexpr element_fp6_3over2 doubled() const {
100  return element_fp6_3over2(data[0].doubled(), data[1].doubled(), data[2].doubled());
101  }
102 
103  constexpr element_fp6_3over2 operator-(const element_fp6_3over2 &B) const {
104  return element_fp6_3over2(data[0] - B.data[0], data[1] - B.data[1], data[2] - B.data[2]);
105  }
106 
108  data[0] -= B.data[0];
109  data[1] -= B.data[1];
110  data[2] -= B.data[2];
111 
112  return *this;
113  }
114 
116  data[0] += B.data[0];
117  data[1] += B.data[1];
118  data[2] += B.data[2];
119 
120  return *this;
121  }
122 
123  constexpr element_fp6_3over2 operator-() const {
124  return zero() - *this;
125  }
126 
127  constexpr element_fp6_3over2 operator*(const element_fp6_3over2 &B) const {
128  const underlying_type A0B0 = data[0] * B.data[0], A1B1 = data[1] * B.data[1],
129  A2B2 = data[2] * B.data[2];
130 
131  return element_fp6_3over2(
132  A0B0 + mul_by_non_residue((data[1] + data[2]) * (B.data[1] + B.data[2]) - A1B1 - A2B2),
133  (data[0] + data[1]) * (B.data[0] + B.data[1]) - A0B0 - A1B1 + mul_by_non_residue(A2B2),
134  (data[0] + data[2]) * (B.data[0] + B.data[2]) - A0B0 + A1B1 - A2B2);
135  }
136 
138 
139  // compute squared root with Tonelli--Shanks
140  }
141 
143  return element_fp6_3over2(data[0], data[1].mul_Fp_0(B), data[2]);
144  }
145 
147  return element_fp6_3over2(data[0], data[1], data[2].mul_Fp_0(B));
148  }
149 
151  return element_fp6_3over2(data[0], data[1].mul_Fp_0(B[1]), data[2].mul_Fp_0(B[0]));
152  }
153 
154  constexpr element_fp6_3over2 squared() const {
155  return (*this) * (*this); // maybe can be done more effective
156  }
157 
158  template<typename PowerType>
159  constexpr element_fp6_3over2 pow(const PowerType &pwr) const {
160  return element_fp6_3over2(power(*this, pwr));
161  }
162 
163  constexpr element_fp6_3over2 inversed() const {
164 
165  /* From "High-Speed Software Implementation of the Optimal Ate Pairing over Barreto-Naehrig
166  * Curves"; Algorithm 17 */
167 
168  const underlying_type &A0 = data[0], &A1 = data[1], &A2 = data[2];
169 
170  const underlying_type t0 = A0.squared();
171  const underlying_type t1 = A1.squared();
172  const underlying_type t2 = A2.squared();
173  const underlying_type t3 = A0 * A1;
174  const underlying_type t4 = A0 * A2;
175  const underlying_type t5 = A1 * A2;
176  const underlying_type c0 = t0 - mul_by_non_residue(t5);
177  const underlying_type c1 = mul_by_non_residue(t2) - t3;
178  const underlying_type c2 =
179  t1 - t4; // typo in paper referenced above. should be "-" as per Scott, but is "*"
180  const underlying_type t6 = (A0 * c0 + mul_by_non_residue(A2 * c1 + A1 * c2)).inversed();
181  return element_fp6_3over2(t6 * c0, t6 * c1, t6 * c2);
182  }
183 
184  template<typename PowerType>
185  constexpr element_fp6_3over2 Frobenius_map(const PowerType &pwr) const {
186  // return element_fp6_3over2(data[0].Frobenius_map(pwr),
187  // policy_type::Frobenius_coeffs_c1[pwr % 6] *
188  // data[1].Frobenius_map(pwr),
189  // policy_type::Frobenius_coeffs_c2[pwr % 6] *
190  // data[2].Frobenius_map(pwr)});
191  return element_fp6_3over2(data[0].Frobenius_map(pwr),
192  typename policy_type::non_residue_type(
193  policy_type::Frobenius_coeffs_c1[(pwr % 6) * 2],
194  policy_type::Frobenius_coeffs_c1[(pwr % 6) * 2 + 1]) *
195  data[1].Frobenius_map(pwr),
196  typename policy_type::non_residue_type(
197  policy_type::Frobenius_coeffs_c2[(pwr % 6) * 2],
198  policy_type::Frobenius_coeffs_c2[(pwr % 6) * 2 + 1]) *
199  data[2].Frobenius_map(pwr));
200  }
201 
202  constexpr /*inline static*/ underlying_type mul_by_non_residue(const underlying_type &A) const {
203  return underlying_type(non_residue * A);
204  }
205  };
206 
207  template<typename FieldParams>
208  constexpr element_fp6_3over2<FieldParams>
209  operator*(const typename FieldParams::underlying_type::underlying_type &lhs,
210  const element_fp6_3over2<FieldParams> &rhs) {
211 
212  return element_fp6_3over2<FieldParams>(lhs * rhs.data[0], lhs * rhs.data[1], lhs * rhs.data[2]);
213  }
214 
215  template<typename FieldParams>
216  constexpr element_fp6_3over2<FieldParams>
218  const typename FieldParams::underlying_type::underlying_type &rhs) {
219 
220  return rhs * lhs;
221  }
222 
223  template<typename FieldParams>
224  constexpr element_fp6_3over2<FieldParams>
225  operator*(const typename FieldParams::underlying_type &lhs,
226  const element_fp6_3over2<FieldParams> &rhs) {
227 
228  return element_fp6_3over2<FieldParams>(lhs * rhs.data[0], lhs * rhs.data[1], lhs * rhs.data[2]);
229  }
230 
231  template<typename FieldParams>
232  constexpr element_fp6_3over2<FieldParams>
234  const typename FieldParams::underlying_type &rhs) {
235 
236  return rhs * lhs;
237  }
238 
239  template<typename FieldParams>
242  } // namespace detail
243  } // namespace fields
244  } // namespace algebra
245  } // namespace crypto3
246 } // namespace nil
247 
248 #endif // CRYPTO3_ALGEBRA_FIELDS_ELEMENT_FP6_3OVER2_HPP
Definition: detail/element/fp6_3over2.hpp:39
policy_type::non_residue_type non_residue_type
Definition: detail/element/fp6_3over2.hpp:43
constexpr element_fp6_3over2 operator*(const element_fp6_3over2 &B) const
Definition: detail/element/fp6_3over2.hpp:127
constexpr element_fp6_3over2 & operator-=(const element_fp6_3over2 &B)
Definition: detail/element/fp6_3over2.hpp:107
constexpr static element_fp6_3over2 one()
Definition: detail/element/fp6_3over2.hpp:74
element_fp6_3over2 mulFp6_24_Fp_01(const element_fp< FieldParams > *B)
Definition: detail/element/fp6_3over2.hpp:150
constexpr bool operator==(const element_fp6_3over2 &B) const
Definition: detail/element/fp6_3over2.hpp:79
constexpr element_fp6_3over2(underlying_type in_data0, underlying_type in_data1, underlying_type in_data2)
Definition: detail/element/fp6_3over2.hpp:57
constexpr element_fp6_3over2 operator+(const element_fp6_3over2 &B) const
Definition: detail/element/fp6_3over2.hpp:95
constexpr underlying_type mul_by_non_residue(const underlying_type &A) const
Definition: detail/element/fp6_3over2.hpp:202
std::array< underlying_type, 3 > data_type
Definition: detail/element/fp6_3over2.hpp:48
constexpr element_fp6_3over2()
Definition: detail/element/fp6_3over2.hpp:52
policy_type::underlying_type underlying_type
Definition: detail/element/fp6_3over2.hpp:46
constexpr element_fp6_3over2 operator-(const element_fp6_3over2 &B) const
Definition: detail/element/fp6_3over2.hpp:103
element_fp6_3over2 sqrt() const
Definition: detail/element/fp6_3over2.hpp:137
constexpr element_fp6_3over2(const element_fp6_3over2 &B)
Definition: detail/element/fp6_3over2.hpp:67
constexpr element_fp6_3over2 doubled() const
Definition: detail/element/fp6_3over2.hpp:99
constexpr element_fp6_3over2 & operator+=(const element_fp6_3over2 &B)
Definition: detail/element/fp6_3over2.hpp:115
constexpr static element_fp6_3over2 zero()
Definition: detail/element/fp6_3over2.hpp:69
constexpr element_fp6_3over2 inversed() const
Definition: detail/element/fp6_3over2.hpp:163
constexpr element_fp6_3over2 Frobenius_map(const PowerType &pwr) const
Definition: detail/element/fp6_3over2.hpp:185
data_type data
Definition: detail/element/fp6_3over2.hpp:50
element_fp6_3over2 mul_Fp_b(const element_fp< FieldParams > &B)
Definition: detail/element/fp6_3over2.hpp:142
constexpr element_fp6_3over2 squared() const
Definition: detail/element/fp6_3over2.hpp:154
constexpr bool operator!=(const element_fp6_3over2 &B) const
Definition: detail/element/fp6_3over2.hpp:83
constexpr static const non_residue_type non_residue
Definition: detail/element/fp6_3over2.hpp:44
constexpr element_fp6_3over2 operator-() const
Definition: detail/element/fp6_3over2.hpp:123
constexpr element_fp6_3over2(const data_type &in_data)
Definition: detail/element/fp6_3over2.hpp:63
constexpr element_fp6_3over2 pow(const PowerType &pwr) const
Definition: detail/element/fp6_3over2.hpp:159
element_fp6_3over2 mul_Fp_c(const element_fp< FieldParams > &B)
Definition: detail/element/fp6_3over2.hpp:146
constexpr element_fp6_3over2 & operator=(const element_fp6_3over2 &B)
Definition: detail/element/fp6_3over2.hpp:87
constexpr FieldValueType power(const FieldValueType &base, const NumberType &exponent)
Definition: algebra/include/nil/crypto3/algebra/fields/detail/exponentiation.hpp:41
element_fp12_2over3over2< FieldParams > operator*(const typename FieldParams::underlying_type::underlying_type::underlying_type &lhs, const element_fp12_2over3over2< FieldParams > &rhs)
Definition: detail/element/fp12_2over3over2.hpp:364
Definition: pair.hpp:31