1use halo2curves_axiom::ff;
2
3use crate::{field::Field, DivAssignUnsafe, DivUnsafe};
4
5macro_rules! field_impls {
6 ($($t:ty),*) => {
7 $(
8 impl DivUnsafe for $t {
9 type Output = $t;
10
11 fn div_unsafe(self, other: Self) -> Self::Output {
12 self * other.invert().unwrap()
13 }
14 }
15
16 impl<'a> DivUnsafe<&'a $t> for $t {
17 type Output = $t;
18
19 fn div_unsafe(self, other: &'a $t) -> Self::Output {
20 self * other.invert().unwrap()
21 }
22 }
23
24 impl<'a> DivUnsafe<&'a $t> for &'a $t {
25 type Output = $t;
26
27 fn div_unsafe(self, other: &'a $t) -> Self::Output {
28 *self * other.invert().unwrap()
29 }
30 }
31
32 impl DivAssignUnsafe for $t {
33 fn div_assign_unsafe(&mut self, other: Self) {
34 *self *= other.invert().unwrap();
35 }
36 }
37
38 impl<'a> DivAssignUnsafe<&'a $t> for $t {
39 fn div_assign_unsafe(&mut self, other: &'a $t) {
40 *self *= other.invert().unwrap();
41 }
42 }
43
44 impl Field for $t {
45 const ZERO: Self = <$t as ff::Field>::ZERO;
46 const ONE: Self = <$t as ff::Field>::ONE;
47
48 type SelfRef<'a> = &'a Self;
49
50 fn double_assign(&mut self) {
51 *self += *self;
52 }
53
54 fn square_assign(&mut self) {
55 *self = self.square();
56 }
57 }
58
59 )*
60 };
61}
62
63field_impls!(
64 halo2curves_axiom::bls12_381::Fq,
65 halo2curves_axiom::bls12_381::Fq12,
66 halo2curves_axiom::bls12_381::Fq2
67);
68field_impls!(
69 halo2curves_axiom::bn256::Fq,
70 halo2curves_axiom::bn256::Fq12,
71 halo2curves_axiom::bn256::Fq2
72);
73
74mod bn254 {
75 use alloc::vec::Vec;
76
77 use halo2curves_axiom::bn256::{Fq, Fq12, Fq2, Fq6};
78
79 use crate::field::{ComplexConjugate, FieldExtension};
80
81 pub fn bytes_to_bn254_fq(bytes: &[u8]) -> Fq {
82 assert_eq!(bytes.len(), 32);
83 Fq::from_bytes(&bytes.try_into().unwrap()).unwrap()
84 }
85
86 impl FieldExtension<Fq> for Fq2 {
88 const D: usize = 2;
89 type Coeffs = [Fq; 2];
90
91 fn from_coeffs(coeffs: Self::Coeffs) -> Self {
92 Fq2 {
93 c0: coeffs[0],
94 c1: coeffs[1],
95 }
96 }
97
98 fn from_bytes(bytes: &[u8]) -> Self {
99 assert_eq!(bytes.len(), 64);
100 Self::from_coeffs([
101 bytes_to_bn254_fq(&bytes[0..32]),
102 bytes_to_bn254_fq(&bytes[32..64]),
103 ])
104 }
105
106 fn to_coeffs(self) -> Self::Coeffs {
107 [self.c0, self.c1]
108 }
109
110 fn to_bytes(&self) -> Vec<u8> {
111 let mut bytes = Vec::with_capacity(64);
112 bytes.extend_from_slice(&self.c0.to_bytes());
113 bytes.extend_from_slice(&self.c1.to_bytes());
114 bytes
115 }
116
117 fn embed(c0: Fq) -> Self {
118 Fq2 { c0, c1: Fq::zero() }
119 }
120
121 fn frobenius_map(&self, power: usize) -> Self {
122 let mut s = *self;
123 Fq2::frobenius_map(&mut s, power);
124 s
125 }
126
127 fn mul_base(&self, rhs: &Fq) -> Self {
128 Fq2 {
129 c0: self.c0 * rhs,
130 c1: self.c1 * rhs,
131 }
132 }
133 }
134
135 impl ComplexConjugate for Fq2 {
136 fn conjugate(self) -> Self {
137 let mut s = self;
138 Fq2::conjugate(&mut s);
139 s
140 }
141
142 fn conjugate_assign(&mut self) {
143 Fq2::conjugate(self);
144 }
145 }
146
147 impl FieldExtension<Fq2> for Fq12 {
150 const D: usize = 6;
151 type Coeffs = [Fq2; 6];
152
153 fn from_coeffs(coeffs: Self::Coeffs) -> Self {
154 Fq12 {
155 c0: Fq6 {
156 c0: coeffs[0],
157 c1: coeffs[2],
158 c2: coeffs[4],
159 },
160 c1: Fq6 {
161 c0: coeffs[1],
162 c1: coeffs[3],
163 c2: coeffs[5],
164 },
165 }
166 }
167
168 fn from_bytes(bytes: &[u8]) -> Self {
169 assert_eq!(bytes.len(), 384);
170 Self::from_coeffs([
171 <Fq2 as FieldExtension<Fq>>::from_bytes(&bytes[0..64]),
172 <Fq2 as FieldExtension<Fq>>::from_bytes(&bytes[64..128]),
173 <Fq2 as FieldExtension<Fq>>::from_bytes(&bytes[128..192]),
174 <Fq2 as FieldExtension<Fq>>::from_bytes(&bytes[192..256]),
175 <Fq2 as FieldExtension<Fq>>::from_bytes(&bytes[256..320]),
176 <Fq2 as FieldExtension<Fq>>::from_bytes(&bytes[320..384]),
177 ])
178 }
179
180 fn to_coeffs(self) -> Self::Coeffs {
181 [
182 self.c0.c0, self.c1.c0, self.c0.c1, self.c1.c1, self.c0.c2, self.c1.c2,
183 ]
184 }
185
186 fn to_bytes(&self) -> Vec<u8> {
187 let coeffs = self.to_coeffs();
188 let mut bytes = Vec::with_capacity(384);
189 for coeff in coeffs {
190 bytes.extend_from_slice(&coeff.to_bytes());
191 }
192 bytes
193 }
194
195 fn embed(c0: Fq2) -> Self {
196 let fq6_pt = Fq6 {
197 c0,
198 c1: Fq2::zero(),
199 c2: Fq2::zero(),
200 };
201 Fq12 {
202 c0: fq6_pt,
203 c1: Fq6::zero(),
204 }
205 }
206
207 fn frobenius_map(&self, power: usize) -> Self {
208 let mut s = *self;
209 Fq12::frobenius_map(&mut s, power);
210 s
211 }
212
213 fn mul_base(&self, rhs: &Fq2) -> Self {
214 let fq6_pt = Fq6 {
215 c0: *rhs,
216 c1: Fq2::zero(),
217 c2: Fq2::zero(),
218 };
219 Fq12 {
220 c0: self.c0 * fq6_pt,
221 c1: self.c1 * fq6_pt,
222 }
223 }
224 }
225
226 impl ComplexConjugate for Fq12 {
228 fn conjugate(self) -> Self {
229 let mut s = self;
230 Fq12::conjugate(&mut s);
231 s
232 }
233
234 fn conjugate_assign(&mut self) {
235 Fq12::conjugate(self);
236 }
237 }
238}
239
240mod bls12_381 {
241 use alloc::vec::Vec;
242
243 use halo2curves_axiom::bls12_381::{Fq, Fq12, Fq2, Fq6};
244
245 use crate::field::{ComplexConjugate, FieldExtension};
246
247 pub fn bytes_to_bls12_381_fq(bytes: &[u8]) -> Fq {
248 assert_eq!(bytes.len(), 48);
249 Fq::from_bytes(&bytes.try_into().unwrap()).unwrap()
250 }
251
252 impl FieldExtension<Fq> for Fq2 {
254 const D: usize = 2;
255 type Coeffs = [Fq; 2];
256
257 fn from_coeffs(coeffs: [Fq; 2]) -> Self {
258 Fq2 {
259 c0: coeffs[0],
260 c1: coeffs[1],
261 }
262 }
263
264 fn from_bytes(bytes: &[u8]) -> Self {
265 assert_eq!(bytes.len(), 96);
266 Self::from_coeffs([
267 bytes_to_bls12_381_fq(&bytes[0..48]),
268 bytes_to_bls12_381_fq(&bytes[48..96]),
269 ])
270 }
271
272 fn to_coeffs(self) -> Self::Coeffs {
273 [self.c0, self.c1]
274 }
275
276 fn to_bytes(&self) -> Vec<u8> {
277 let mut bytes = Vec::with_capacity(96);
278 bytes.extend_from_slice(&self.c0.to_bytes());
279 bytes.extend_from_slice(&self.c1.to_bytes());
280 bytes
281 }
282
283 fn embed(c0: Fq) -> Self {
284 Fq2 { c0, c1: Fq::zero() }
285 }
286
287 fn frobenius_map(&self, power: usize) -> Self {
288 if power % 2 == 0 {
289 *self
290 } else {
291 Fq2::frobenius_map(self)
293 }
294 }
295
296 fn mul_base(&self, rhs: &Fq) -> Self {
297 Fq2 {
298 c0: self.c0 * rhs,
299 c1: self.c1 * rhs,
300 }
301 }
302 }
303
304 impl ComplexConjugate for Fq2 {
305 fn conjugate(self) -> Self {
306 Fq2::conjugate(&self)
307 }
308
309 fn conjugate_assign(&mut self) {
310 *self = Fq2::conjugate(self);
311 }
312 }
313
314 impl FieldExtension<Fq2> for Fq12 {
320 const D: usize = 6;
321 type Coeffs = [Fq2; 6];
322
323 fn from_coeffs(coeffs: [Fq2; 6]) -> Self {
324 Fq12 {
325 c0: Fq6 {
326 c0: coeffs[0],
327 c1: coeffs[2],
328 c2: coeffs[4],
329 },
330 c1: Fq6 {
331 c0: coeffs[1],
332 c1: coeffs[3],
333 c2: coeffs[5],
334 },
335 }
336 }
337
338 fn from_bytes(bytes: &[u8]) -> Self {
339 assert_eq!(bytes.len(), 576);
340 Self::from_coeffs([
341 <Fq2 as FieldExtension<Fq>>::from_bytes(&bytes[0..96]),
342 <Fq2 as FieldExtension<Fq>>::from_bytes(&bytes[96..192]),
343 <Fq2 as FieldExtension<Fq>>::from_bytes(&bytes[192..288]),
344 <Fq2 as FieldExtension<Fq>>::from_bytes(&bytes[288..384]),
345 <Fq2 as FieldExtension<Fq>>::from_bytes(&bytes[384..480]),
346 <Fq2 as FieldExtension<Fq>>::from_bytes(&bytes[480..576]),
347 ])
348 }
349
350 fn to_coeffs(self) -> Self::Coeffs {
351 [
352 self.c0.c0, self.c1.c0, self.c0.c1, self.c1.c1, self.c0.c2, self.c1.c2,
353 ]
354 }
355
356 fn to_bytes(&self) -> Vec<u8> {
357 let coeffs = self.to_coeffs();
358 let mut bytes = Vec::with_capacity(576);
359 for coeff in coeffs {
360 bytes.extend_from_slice(&coeff.to_bytes());
361 }
362 bytes
363 }
364
365 fn embed(base_elem: Fq2) -> Self {
366 let fq6_pt = Fq6 {
367 c0: base_elem,
368 c1: Fq2::zero(),
369 c2: Fq2::zero(),
370 };
371 Fq12 {
372 c0: fq6_pt,
373 c1: Fq6::zero(),
374 }
375 }
376
377 fn frobenius_map(&self, power: usize) -> Self {
379 let mut x = *self;
380 for _ in 0..power % 12 {
381 x = Fq12::frobenius_map(&x);
382 }
383 x
384 }
385
386 fn mul_base(&self, rhs: &Fq2) -> Self {
387 let fq6_pt = Fq6 {
388 c0: *rhs,
389 c1: Fq2::zero(),
390 c2: Fq2::zero(),
391 };
392 Fq12 {
393 c0: self.c0 * fq6_pt,
394 c1: self.c1 * fq6_pt,
395 }
396 }
397 }
398
399 impl ComplexConjugate for Fq12 {
401 fn conjugate(self) -> Self {
402 Fq12::conjugate(&self)
403 }
404
405 fn conjugate_assign(&mut self) {
406 *self = Fq12::conjugate(self);
407 }
408 }
409}