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 w;
53 quadratic_field vw;
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
142 constexpr void self_sparse_mul(const ell_coeffs& ell)
143 {
144 quadratic_field A0 = ell.o * c0.c0;
145 quadratic_field A1 = ell.o * c0.c1;
146 quadratic_field A2 = ell.o * c0.c2;
147 base_field A{ A0, A1, A2 };
148 base_field B = c1.sparse_mul(ell.w, ell.vw);
149 base_field E = (c0 + c1).sparse_mul(ell.o + ell.w, ell.vw);
150 base_field F = E - (A + B);
151 base_field G{ base_field::mul_by_non_residue(B.c2), B.c0, B.c1 };
152 base_field H = A + G;
153
154 c0 = H;
155 c1 = F;
156 }
157
158 constexpr field12 sqr() const
159 {
160 base_field T0 = c0 + c1;
161 base_field T1 = mul_by_non_residue(c1) + c0;
162
163 T0 *= T1;
164 T1 = c0 * c1;
165
166 return {
167 T0 - (T1 + mul_by_non_residue(T1)),
168 T1 + T1,
169 };
170 }
171
172 constexpr field12 invert() const
173 {
174 /* From "High-Speed Software Implementation of the Optimal Ate Pairing over Barreto-Naehrig Curves"; Algorithm 8
175 */
176 base_field T0 = (c0.sqr() - mul_by_non_residue(c1.sqr())).invert();
177 return {
178 c0 * T0,
179 -(c1 * T0),
180 };
181 }
182
183 constexpr field12 frobenius_map_three() const
184 {
185 return {
187 c1.frobenius_map_three().mul_by_fq2(Fq12Params::frobenius_coefficients_3),
188 };
189 }
190
191 constexpr field12 frobenius_map_two() const
192 {
193 return {
195 c1.frobenius_map_two().mul_by_fq2(Fq12Params::frobenius_coefficients_2),
196 };
197 }
198
199 constexpr field12 frobenius_map_one() const
200 {
201 return {
203 c1.frobenius_map_one().mul_by_fq2(Fq12Params::frobenius_coefficients_1),
204 };
205 }
206
207 constexpr field12 cyclotomic_squared() const { return sqr(); }
208
209 constexpr field12 unitary_inverse() const
210 {
211 return {
212 c0,
213 -c1,
214 };
215 }
216
217 static constexpr field12 random_element(numeric::RNG* engine = nullptr)
218 {
219 return {
220 base_field::random_element(engine),
221 base_field::random_element(engine),
222 };
223 }
224
225 // Montgomery form conversions produced outputs where the components are all in strict/reduced form.
227 {
228 return {
231 };
232 }
233
235 {
236 return {
239 };
240 }
241
242 [[nodiscard]] constexpr bool is_zero() const { return c0.is_zero() && c1.is_zero(); }
243
244 constexpr bool operator==(const field12& other) const { return c0 == other.c0 && c1 == other.c1; }
245};
246} // 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:207
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:244
constexpr field12 operator+(const field12 &other) const
Definition field12.hpp:68
constexpr field12 frobenius_map_three() const
Definition field12.hpp:183
constexpr field12 invert() const
Definition field12.hpp:172
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:217
constexpr field12 operator-() const
Definition field12.hpp:84
constexpr bool is_zero() const
Definition field12.hpp:242
constexpr void self_sqr()
Definition field12.hpp:133
constexpr field12 unitary_inverse() const
Definition field12.hpp:209
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)
Multiply the element by a sparse element of the form ell.o + ell.w * w + ell.vw * wv.
Definition field12.hpp:142
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 sqr() const
Definition field12.hpp:158
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 from_montgomery_form() const
Definition field12.hpp:234
constexpr field12 operator*(const field12 &other) const
Definition field12.hpp:86
constexpr field12 frobenius_map_two() const
Definition field12.hpp:191
constexpr field12 frobenius_map_one() const
Definition field12.hpp:199
constexpr field12 to_montgomery_form()
Definition field12.hpp:226
FF a
FF b
#define G(r, i, a, b, c, d)
Definition blake2s.cpp:116
numeric::RNG & engine
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
quadratic_field w
Definition field12.hpp:52
quadratic_field vw
Definition field12.hpp:53
quadratic_field o
Definition field12.hpp:51