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