barretenberg
Loading...
Searching...
No Matches
field6.hpp
1#pragma once
2#include "barretenberg/numeric/random/engine.hpp"
3
4namespace barretenberg {
5template <typename base_field, typename Fq6Params> class field6 {
6 public:
7 constexpr field6(const base_field& a = base_field::zero(),
8 const base_field& b = base_field::zero(),
9 const base_field& c = base_field::zero())
10 : c0(a)
11 , c1(b)
12 , c2(c)
13 {}
14
15 constexpr field6(const field6& other)
16 : c0(other.c0)
17 , c1(other.c1)
18 , c2(other.c2)
19 {}
20
21 constexpr field6(field6&& other) noexcept
22 : c0(other.c0)
23 , c1(other.c1)
24 , c2(other.c2)
25 {}
26
27 constexpr field6& operator=(const field6& other) noexcept
28 {
29 if (this == &other) {
30 return *this;
31 }
32 c0 = other.c0;
33 c1 = other.c1;
34 c2 = other.c2;
35 return *this;
36 }
37
38 constexpr field6& operator=(field6&& other) noexcept
39 {
40 c0 = other.c0;
41 c1 = other.c1;
42 c2 = other.c2;
43 return *this;
44 }
45
46 constexpr ~field6() noexcept = default;
47
48 base_field c0;
49 base_field c1;
50 base_field c2;
51
52 static constexpr field6 zero() { return { base_field::zero(), base_field::zero(), base_field::zero() }; };
53 static constexpr field6 one() { return { base_field::one(), base_field::zero(), base_field::zero() }; };
54
55 static constexpr base_field mul_by_non_residue(const base_field& a) { return Fq6Params::mul_by_non_residue(a); }
56
57 constexpr field6 operator+(const field6& other) const
58 {
59 return {
60 c0 + other.c0,
61 c1 + other.c1,
62 c2 + other.c2,
63 };
64 }
65
66 constexpr field6 operator-(const field6& other) const
67 {
68 return {
69 c0 - other.c0,
70 c1 - other.c1,
71 c2 - other.c2,
72 };
73 }
74
75 constexpr field6 operator-() const
76 {
77 return {
78 -c0,
79 -c1,
80 -c2,
81 };
82 }
83
84 constexpr field6 operator*(const field6& other) const
85 {
86 // /* Devegili OhEig Scott Dahab --- Multiplication and Squaring on Pairing-Friendly Fields.pdf; Section 4
87 // * (Karatsuba) */
88
89 base_field T0 = c0 * other.c0;
90 base_field T1 = c1 * other.c1;
91 base_field T2 = c2 * other.c2;
92
93 base_field T3 = (c0 + c2) * (other.c0 + other.c2);
94 base_field T4 = (c0 + c1) * (other.c0 + other.c1);
95 base_field T5 = (c1 + c2) * (other.c1 + other.c2);
96
97 return {
98 T0 + mul_by_non_residue(T5 - (T1 + T2)),
99 T4 - (T0 + T1) + mul_by_non_residue(T2),
100 T3 + T1 - (T0 + T2),
101 };
102 }
103
104 constexpr field6 operator/(const field6& other) const { return operator*(other.invert()); }
105
106 constexpr field6 sqr() const
107 {
108 /* Devegili OhEig Scott Dahab --- Multiplication and Squaring on Pairing-Friendly Fields.pdf; Section 4
109 * (CH-SQR2) */
110 base_field S0 = c0.sqr();
111 base_field S1 = c0 * c1;
112 S1 += S1;
113 base_field S2 = (c0 + c2 - c1).sqr();
114 base_field S3 = c1 * c2;
115 S3 += S3;
116 base_field S4 = c2.sqr();
117 return {
118 mul_by_non_residue(S3) + S0,
119 mul_by_non_residue(S4) + S1,
120 S1 + S2 + S3 - S0 - S4,
121 };
122 }
123
124 constexpr field6 operator+=(const field6& other)
125 {
126 c0 += other.c0;
127 c1 += other.c1;
128 c2 += other.c2;
129 return *this;
130 }
131
132 constexpr field6 operator-=(const field6& other)
133 {
134 c0 -= other.c0;
135 c1 -= other.c1;
136 c2 -= other.c2;
137 return *this;
138 }
139
140 constexpr field6 operator*=(const field6& other)
141 {
142 *this = operator*(other);
143 return *this;
144 }
145
146 constexpr field6 operator/=(const field6& other)
147 {
148 *this = operator/(other);
149 return *this;
150 }
151
152 constexpr field6 invert() const
153 {
154 /* From "High-Speed Software Implementation of the Optimal Ate Pairing over Barreto-Naehrig Curves"; Algorithm
155 * 17 */
156 base_field C0 = c0.sqr() - mul_by_non_residue(c1 * c2);
157 base_field C1 = mul_by_non_residue(c2.sqr()) - (c0 * c1);
158 base_field C2 = c1.sqr() - (c0 * c2);
159 base_field T0 = ((c0 * C0) + mul_by_non_residue((c2 * C1) + (c1 * C2))).invert();
160
161 return {
162 T0 * C0,
163 T0 * C1,
164 T0 * C2,
165 };
166 }
167
168 constexpr field6 mul_by_fq2(const base_field& other) const { return { other * c0, other * c1, other * c2 }; }
169
170 constexpr field6 frobenius_map_three() const
171 {
172 return {
173 c0.frobenius_map(),
174 Fq6Params::frobenius_coeffs_c1_3 * c1.frobenius_map(),
175 Fq6Params::frobenius_coeffs_c2_3 * c2.frobenius_map(),
176 };
177 }
178
179 constexpr field6 frobenius_map_two() const
180 {
181 return { c0, Fq6Params::frobenius_coeffs_c1_2 * c1, Fq6Params::frobenius_coeffs_c2_2 * c2 };
182 }
183
184 constexpr field6 frobenius_map_one() const
185 {
186 return {
187 c0.frobenius_map(),
188 Fq6Params::frobenius_coeffs_c1_1 * c1.frobenius_map(),
189 Fq6Params::frobenius_coeffs_c2_1 * c2.frobenius_map(),
190 };
191 }
192
193 static constexpr field6 random_element(numeric::random::Engine* engine = nullptr)
194 {
195 return {
196 base_field::random_element(engine),
197 base_field::random_element(engine),
198 base_field::random_element(engine),
199 };
200 }
201
202 constexpr field6 to_montgomery_form() const
203 {
204 return {
205 c0.to_montgomery_form(),
206 c1.to_montgomery_form(),
207 c2.to_montgomery_form(),
208 };
209 }
210
211 constexpr field6 from_montgomery_form() const
212 {
213 return {
214 c0.from_montgomery_form(),
215 c1.from_montgomery_form(),
216 c2.from_montgomery_form(),
217 };
218 }
219
220 [[nodiscard]] constexpr bool is_zero() const { return c0.is_zero() && c1.is_zero() && c2.is_zero(); }
221
222 constexpr bool operator==(const field6& other) const { return c0 == other.c0 && c1 == other.c1 && c2 == other.c2; }
223};
224} // namespace barretenberg
Definition: field6.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