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