barretenberg
Loading...
Searching...
No Matches
field12.hpp
1#pragma once
2#include "barretenberg/numeric/random/engine.hpp"
3
4namespace barretenberg {
5template <typename quadratic_field, typename base_field, typename Fq12Params> class field12 {
6 public:
7 constexpr field12(const base_field& a = base_field::zero(), const base_field& b = base_field::zero())
8 : c0(a)
9 , c1(b)
10 {}
11
12 constexpr field12(const field12& other)
13 : c0(other.c0)
14 , c1(other.c1)
15 {}
16
17 constexpr field12(field12&& other) noexcept
18 : c0(other.c0)
19 , c1(other.c1)
20 {}
21
22 constexpr field12& operator=(const field12& other) noexcept
23 {
24 if (this == &other) {
25 return *this;
26 }
27 c0 = other.c0;
28 c1 = other.c1;
29 return *this;
30 }
31
32 constexpr field12& operator=(field12&& other) noexcept
33 {
34 c0 = other.c0;
35 c1 = other.c1;
36 return *this;
37 }
38
39 constexpr ~field12() noexcept = default;
40
41 base_field c0;
42 base_field c1;
43
44 struct ell_coeffs {
45 quadratic_field o;
46 quadratic_field vw;
47 quadratic_field vv;
48 };
49
50 static constexpr field12 zero() { return { base_field::zero(), base_field::zero() }; };
51 static constexpr field12 one() { return { base_field::one(), base_field::zero() }; };
52
53 static constexpr base_field mul_by_non_residue(const base_field& a)
54 {
55 return {
56 base_field::mul_by_non_residue(a.c2),
57 a.c0,
58 a.c1,
59 };
60 }
61
62 constexpr field12 operator+(const field12& other) const
63 {
64 return {
65 c0 + other.c0,
66 c1 + other.c1,
67 };
68 }
69
70 constexpr field12 operator-(const field12& other) const
71 {
72 return {
73 c0 - other.c0,
74 c1 - other.c1,
75 };
76 }
77
78 constexpr field12 operator*(const field12& other) const
79 {
80 base_field T0 = c0 * other.c0;
81 base_field T1 = c1 * other.c1;
82 base_field T2 = c0 + c1;
83 base_field T3 = other.c0 + other.c1;
84
85 return {
86 mul_by_non_residue(T1) + T0,
87 T2 * T3 - (T0 + T1),
88 };
89 }
90
91 constexpr field12 operator/(const field12& other) const { return operator*(other.invert()); }
92
93 constexpr field12 operator+=(const field12& other)
94 {
95 c0 += other.c0;
96 c1 += other.c1;
97 return *this;
98 }
99
100 constexpr field12 operator-=(const field12& other)
101 {
102 c0 -= other.c0;
103 c1 -= other.c1;
104 return *this;
105 }
106
107 constexpr field12 operator*=(const field12& other)
108 {
109 *this = operator*(other);
110 return *this;
111 }
112
113 constexpr field12 operator/=(const field12& other)
114 {
115 *this = operator/(other);
116 return *this;
117 }
118
119 constexpr void self_sparse_mul(const ell_coeffs& ell)
120 {
121 // multiplicand is sparse fp12 element (ell.0, 0, ell.vv) + \beta(0, ell.vw, 0)
122 quadratic_field d0 = c0.c0 * ell.o;
123 quadratic_field d2 = c0.c2 * ell.vv;
124 quadratic_field d4 = c1.c1 * ell.vw;
125 quadratic_field t2 = c0.c0 + c1.c1;
126 quadratic_field t1 = c0.c0 + c0.c2;
127 quadratic_field s0 = c0.c1 + c1.c0;
128 s0 += c1.c2;
129
130 quadratic_field s1 = c0.c1 * ell.vv;
131 quadratic_field t3 = s1 + d4;
132 quadratic_field t4 = base_field::mul_by_non_residue(t3);
133 c0.c0 = t4 + d0;
134
135 t3 = c1.c2 * ell.vw;
136 s1 += t3;
137 t3 += d2;
138 t4 = base_field::mul_by_non_residue(t3);
139 t3 = c0.c1 * ell.o;
140 s1 += t3;
141 c0.c1 = t4 + t3;
142
143 quadratic_field t0 = ell.o + ell.vv;
144 t3 = t1 * t0;
145 t3 -= d0;
146 t3 -= d2;
147 t4 = c1.c0 * ell.vw;
148 s1 += t4;
149
150 t0 = c0.c2 + c1.c1;
151 c0.c2 = t3 + t4;
152
153 t1 = ell.vv + ell.vw;
154 t3 = t0 * t1;
155 t3 -= d2;
156 t3 -= d4;
157 t4 = base_field::mul_by_non_residue(t3);
158 t3 = c1.c0 * ell.o;
159 s1 += t3;
160 c1.c0 = t3 + t4;
161
162 t3 = c1.c2 * ell.vv;
163 s1 += t3;
164 t4 = base_field::mul_by_non_residue(t3);
165 t0 = ell.o + ell.vw;
166 t3 = t0 * t2;
167 t3 -= d0;
168 t3 -= d4;
169 c1.c1 = t3 + t4;
170
171 t0 = ell.o + ell.vv;
172 t0 += ell.vw;
173 t3 = s0 * t0;
174 c1.c2 = t3 - s1;
175 }
176
177 constexpr field12 sqr() const
178 {
179 base_field T0 = c0 + c1;
180 base_field T1 = mul_by_non_residue(c1) + c0;
181
182 T0 *= T1;
183 T1 = c0 * c1;
184
185 return {
186 T0 - (T1 + mul_by_non_residue(T1)),
187 T1 + T1,
188 };
189 }
190
191 constexpr field12 invert() const
192 {
193 /* From "High-Speed Software Implementation of the Optimal Ate Pairing over Barreto-Naehrig Curves"; Algorithm 8
194 */
195 base_field T0 = (c0.sqr() - mul_by_non_residue(c1.sqr())).invert();
196 return {
197 c0 * T0,
198 -(c1 * T0),
199 };
200 }
201
202 constexpr field12 frobenius_map_three() const
203 {
204 return {
205 c0.frobenius_map_three(),
206 c1.frobenius_map_three().mul_by_fq2(Fq12Params::frobenius_coefficients_3),
207 };
208 }
209
210 constexpr field12 frobenius_map_two() const
211 {
212 return {
213 c0.frobenius_map_two(),
214 c1.frobenius_map_two().mul_by_fq2(Fq12Params::frobenius_coefficients_2),
215 };
216 }
217
218 constexpr field12 frobenius_map_one() const
219 {
220 return {
221 c0.frobenius_map_one(),
222 c1.frobenius_map_one().mul_by_fq2(Fq12Params::frobenius_coefficients_1),
223 };
224 }
225
226 constexpr field12 cyclotomic_squared() const
227 {
228 // Possible Optimization: The cyclotomic squaring can be implemented more than efficiently
229 // than the generic squaring.
230 return sqr();
231 }
232
233 constexpr field12 unitary_inverse() const
234 {
235 return {
236 c0,
237 -c1,
238 };
239 }
240
241 static constexpr field12 random_element(numeric::random::Engine* engine = nullptr)
242 {
243 return {
244 base_field::random_element(engine),
245 base_field::random_element(engine),
246 };
247 }
248
249 constexpr field12 to_montgomery_form()
250 {
251 return {
252 c0.to_montgomery_form(),
253 c1.to_montgomery_form(),
254 };
255 }
256
257 constexpr field12 from_montgomery_form()
258 {
259 return {
260 c0.from_montgomery_form(),
261 c1.from_montgomery_form(),
262 };
263 }
264
265 [[nodiscard]] constexpr bool is_zero() const { return c0.is_zero() && c1.is_zero(); }
266
267 constexpr bool operator==(const field12& other) const { return c0 == other.c0 && c1 == other.c1; }
268};
269} // namespace barretenberg
Definition: field12.hpp:5
Definition: engine.hpp:10
constexpr_utils defines some helper methods that perform some stl-equivalent operations but in a cons...
Definition: constexpr_utils.hpp:16
Definition: field12.hpp:44