1use super::field::Mersenne31Field;
2use crate::field::{
3 element::FieldElement,
4 errors::FieldError,
5 traits::{IsFFTField, IsField, IsSubFieldOf},
6};
7#[cfg(feature = "alloc")]
8use alloc::vec::Vec;
9
10type FpE = FieldElement<Mersenne31Field>;
11type Fp2E = FieldElement<Degree2ExtensionField>;
12type Fp4E = FieldElement<Degree4ExtensionField>;
13
14#[derive(Clone, Debug)]
15pub struct Degree2ExtensionField;
16
17impl Degree2ExtensionField {
18 pub fn mul_fp2_by_nonresidue(a: &Fp2E) -> Fp2E {
19 Fp2E::new([
20 a.value()[0].double() - a.value()[1],
21 a.value()[1].double() + a.value()[0],
22 ])
23 }
24}
25
26impl IsField for Degree2ExtensionField {
27 type BaseType = [FpE; 2];
29
30 fn add(a: &Self::BaseType, b: &Self::BaseType) -> Self::BaseType {
32 [a[0] + b[0], a[1] + b[1]]
33 }
34
35 fn mul(a: &Self::BaseType, b: &Self::BaseType) -> Self::BaseType {
37 let a0b0 = a[0] * b[0];
38 let a1b1 = a[1] * b[1];
39 let z = (a[0] + a[1]) * (b[0] + b[1]);
40 [a0b0 - a1b1, z - a0b0 - a1b1]
41 }
42
43 fn square(a: &Self::BaseType) -> Self::BaseType {
44 let [a0, a1] = a;
45 let v0 = a0 * a1;
46 let c0 = (a0 + a1) * (a0 - a1);
47 let c1 = v0.double();
48 [c0, c1]
49 }
50 fn sub(a: &Self::BaseType, b: &Self::BaseType) -> Self::BaseType {
52 [a[0] - b[0], a[1] - b[1]]
53 }
54
55 fn neg(a: &Self::BaseType) -> Self::BaseType {
57 [-a[0], -a[1]]
58 }
59
60 fn inv(a: &Self::BaseType) -> Result<Self::BaseType, FieldError> {
62 let inv_norm = (a[0].square() + a[1].square()).inv()?;
63 Ok([a[0] * inv_norm, -a[1] * inv_norm])
64 }
65
66 fn div(a: &Self::BaseType, b: &Self::BaseType) -> Result<Self::BaseType, FieldError> {
68 let b_inv = &Self::inv(b).map_err(|_| FieldError::DivisionByZero)?;
69 Ok(<Self as IsField>::mul(a, b_inv))
70 }
71
72 fn eq(a: &Self::BaseType, b: &Self::BaseType) -> bool {
74 a[0] == b[0] && a[1] == b[1]
75 }
76
77 fn one() -> Self::BaseType {
79 [FpE::one(), FpE::zero()]
80 }
81
82 fn from_u64(x: u64) -> Self::BaseType {
84 [FpE::from(x), FpE::zero()]
85 }
86
87 fn from_base_type(x: Self::BaseType) -> Self::BaseType {
92 x
93 }
94}
95
96impl IsFFTField for Degree2ExtensionField {
97 const TWO_ADICITY: u64 = 31;
100 const TWO_ADIC_PRIMITVE_ROOT_OF_UNITY: Self::BaseType =
101 [FpE::const_from_raw(2), FpE::const_from_raw(1268011823)];
102}
103
104impl IsSubFieldOf<Degree2ExtensionField> for Mersenne31Field {
105 fn add(
106 a: &Self::BaseType,
107 b: &<Degree2ExtensionField as IsField>::BaseType,
108 ) -> <Degree2ExtensionField as IsField>::BaseType {
109 [FpE::from(a) + b[0], b[1]]
110 }
111
112 fn sub(
113 a: &Self::BaseType,
114 b: &<Degree2ExtensionField as IsField>::BaseType,
115 ) -> <Degree2ExtensionField as IsField>::BaseType {
116 [FpE::from(a) - b[0], -b[1]]
117 }
118
119 fn mul(
120 a: &Self::BaseType,
121 b: &<Degree2ExtensionField as IsField>::BaseType,
122 ) -> <Degree2ExtensionField as IsField>::BaseType {
123 [FpE::from(a) * b[0], FpE::from(a) * b[1]]
124 }
125
126 fn div(
127 a: &Self::BaseType,
128 b: &<Degree2ExtensionField as IsField>::BaseType,
129 ) -> Result<<Degree2ExtensionField as IsField>::BaseType, FieldError> {
130 let b_inv = Degree2ExtensionField::inv(b).map_err(|_| FieldError::DivisionByZero)?;
131 Ok(<Self as IsSubFieldOf<Degree2ExtensionField>>::mul(
132 a, &b_inv,
133 ))
134 }
135
136 fn embed(a: Self::BaseType) -> <Degree2ExtensionField as IsField>::BaseType {
137 [FieldElement::from_raw(a), FieldElement::zero()]
138 }
139
140 #[cfg(feature = "alloc")]
141 fn to_subfield_vec(
142 b: <Degree2ExtensionField as IsField>::BaseType,
143 ) -> alloc::vec::Vec<Self::BaseType> {
144 b.into_iter().map(|x| x.to_raw()).collect()
145 }
146}
147
148#[derive(Clone, Debug)]
149pub struct Degree4ExtensionField;
150
151impl Degree4ExtensionField {
152 pub const fn const_from_coefficients(a: u32, b: u32, c: u32, d: u32) -> Fp4E {
153 Fp4E::const_from_raw([
154 Fp2E::const_from_raw([FpE::const_from_raw(a), FpE::const_from_raw(b)]),
155 Fp2E::const_from_raw([FpE::const_from_raw(c), FpE::const_from_raw(d)]),
156 ])
157 }
158}
159
160impl IsField for Degree4ExtensionField {
161 type BaseType = [Fp2E; 2];
162
163 fn add(a: &Self::BaseType, b: &Self::BaseType) -> Self::BaseType {
164 [&a[0] + &b[0], &a[1] + &b[1]]
165 }
166
167 fn sub(a: &Self::BaseType, b: &Self::BaseType) -> Self::BaseType {
168 [&a[0] - &b[0], &a[1] - &b[1]]
169 }
170
171 fn neg(a: &Self::BaseType) -> Self::BaseType {
172 [-&a[0], -&a[1]]
173 }
174
175 fn mul(a: &Self::BaseType, b: &Self::BaseType) -> Self::BaseType {
176 let a0b0 = &a[0] * &b[0];
178 let a1b1 = &a[1] * &b[1];
179 [
180 &a0b0 + Degree2ExtensionField::mul_fp2_by_nonresidue(&a1b1),
181 (&a[0] + &a[1]) * (&b[0] + &b[1]) - a0b0 - a1b1,
182 ]
183 }
184
185 fn square(a: &Self::BaseType) -> Self::BaseType {
186 let a0_square = &a[0].square();
187 let a1_square = &a[1].square();
188 [
189 a0_square + Degree2ExtensionField::mul_fp2_by_nonresidue(a1_square),
190 (&a[0] + &a[1]).square() - a0_square - a1_square,
191 ]
192 }
193
194 fn inv(a: &Self::BaseType) -> Result<Self::BaseType, FieldError> {
195 let inv_norm =
196 (a[0].square() - Degree2ExtensionField::mul_fp2_by_nonresidue(&a[1].square())).inv()?;
197 Ok([&a[0] * &inv_norm, -&a[1] * &inv_norm])
198 }
199
200 fn div(a: &Self::BaseType, b: &Self::BaseType) -> Result<Self::BaseType, FieldError> {
201 let b_inv = &Self::inv(b).map_err(|_| FieldError::DivisionByZero)?;
202 Ok(<Self as IsField>::mul(a, b_inv))
203 }
204
205 fn eq(a: &Self::BaseType, b: &Self::BaseType) -> bool {
206 a[0] == b[0] && a[1] == b[1]
207 }
208
209 fn zero() -> Self::BaseType {
210 [Fp2E::zero(), Fp2E::zero()]
211 }
212
213 fn one() -> Self::BaseType {
214 [Fp2E::one(), Fp2E::zero()]
215 }
216
217 fn from_u64(x: u64) -> Self::BaseType {
218 [Fp2E::from(x), Fp2E::zero()]
219 }
220
221 fn from_base_type(x: Self::BaseType) -> Self::BaseType {
222 x
223 }
224}
225
226impl IsSubFieldOf<Degree4ExtensionField> for Mersenne31Field {
227 fn add(
228 a: &Self::BaseType,
229 b: &<Degree4ExtensionField as IsField>::BaseType,
230 ) -> <Degree4ExtensionField as IsField>::BaseType {
231 [FpE::from(a) + &b[0], b[1].clone()]
232 }
233
234 fn sub(
235 a: &Self::BaseType,
236 b: &<Degree4ExtensionField as IsField>::BaseType,
237 ) -> <Degree4ExtensionField as IsField>::BaseType {
238 [FpE::from(a) - &b[0], -&b[1]]
239 }
240
241 fn mul(
242 a: &Self::BaseType,
243 b: &<Degree4ExtensionField as IsField>::BaseType,
244 ) -> <Degree4ExtensionField as IsField>::BaseType {
245 let c0 = FpE::from(a) * &b[0];
246 let c1 = FpE::from(a) * &b[1];
247 [c0, c1]
248 }
249
250 fn div(
251 a: &Self::BaseType,
252 b: &<Degree4ExtensionField as IsField>::BaseType,
253 ) -> Result<<Degree4ExtensionField as IsField>::BaseType, FieldError> {
254 let b_inv = Degree4ExtensionField::inv(b).map_err(|_| FieldError::DivisionByZero)?;
255 Ok(<Self as IsSubFieldOf<Degree4ExtensionField>>::mul(
256 a, &b_inv,
257 ))
258 }
259
260 fn embed(a: Self::BaseType) -> <Degree4ExtensionField as IsField>::BaseType {
261 [
262 Fp2E::from_raw(<Self as IsSubFieldOf<Degree2ExtensionField>>::embed(a)),
263 Fp2E::zero(),
264 ]
265 }
266
267 #[cfg(feature = "alloc")]
268 fn to_subfield_vec(
269 b: <Degree4ExtensionField as IsField>::BaseType,
270 ) -> alloc::vec::Vec<Self::BaseType> {
271 let mut result = Vec::new();
274 for fp2e in b {
275 result.push(fp2e.value()[0].to_raw());
276 result.push(fp2e.value()[1].to_raw());
277 }
278 result
279 }
280}
281
282#[cfg(test)]
283mod tests {
284 use core::ops::Neg;
285
286 use crate::field::fields::mersenne31::field::MERSENNE_31_PRIME_FIELD_ORDER;
287
288 use super::*;
289
290 type FpE = FieldElement<Mersenne31Field>;
291 type Fp2E = FieldElement<Degree2ExtensionField>;
292 type Fp4E = FieldElement<Degree4ExtensionField>;
293
294 #[test]
295 fn add_real_one_plus_one_is_two() {
296 assert_eq!(Fp2E::one() + Fp2E::one(), Fp2E::from(2))
297 }
298
299 #[test]
300 fn add_real_neg_one_plus_one_is_zero() {
301 assert_eq!(Fp2E::one() + Fp2E::one().neg(), Fp2E::zero())
302 }
303
304 #[test]
305 fn add_real_neg_one_plus_two_is_one() {
306 assert_eq!(Fp2E::one().neg() + Fp2E::from(2), Fp2E::one())
307 }
308
309 #[test]
310 fn add_real_neg_one_plus_neg_one_is_order_sub_two() {
311 assert_eq!(
312 Fp2E::one().neg() + Fp2E::one().neg(),
313 Fp2E::new([FpE::from(&(MERSENNE_31_PRIME_FIELD_ORDER - 2)), FpE::zero()])
314 )
315 }
316
317 #[test]
318 fn add_complex_one_plus_one_two() {
319 let one_i = Fp2E::new([FpE::zero(), FpE::one()]);
320 let two_i = Fp2E::new([FpE::zero(), FpE::from(2)]);
321 assert_eq!(&one_i + &one_i, two_i)
322 }
323
324 #[test]
325 fn add_complex_neg_one_plus_one_is_zero() {
326 let neg_one_i = Fp2E::new([FpE::zero(), -FpE::one()]);
328 let one_i = Fp2E::new([FpE::zero(), FpE::one()]);
329 assert_eq!(neg_one_i + one_i, Fp2E::zero())
330 }
331
332 #[test]
333 fn add_complex_neg_one_plus_two_is_one() {
334 let neg_one_i = Fp2E::new([FpE::zero(), -FpE::one()]);
335 let two_i = Fp2E::new([FpE::zero(), FpE::from(2)]);
336 let one_i = Fp2E::new([FpE::zero(), FpE::one()]);
337 assert_eq!(&neg_one_i + &two_i, one_i)
338 }
339
340 #[test]
341 fn add_complex_neg_one_plus_neg_one_imag_is_order_sub_two() {
342 let neg_one_i = Fp2E::new([FpE::zero(), -FpE::one()]);
343 assert_eq!(
344 (&neg_one_i + &neg_one_i).value()[1],
345 FpE::from(&(MERSENNE_31_PRIME_FIELD_ORDER - 2))
346 )
347 }
348
349 #[test]
350 fn add_order() {
351 let a = Fp2E::new([-FpE::one(), FpE::one()]);
352 let b = Fp2E::new([
353 FpE::from(2),
354 FpE::from(&(MERSENNE_31_PRIME_FIELD_ORDER - 2)),
355 ]);
356 let c = Fp2E::new([FpE::one(), -FpE::one()]);
357 assert_eq!(&a + &b, c)
358 }
359
360 #[test]
361 fn add_equal_zero() {
362 let a = Fp2E::new([-FpE::one(), -FpE::one()]);
363 let b = Fp2E::new([FpE::one(), FpE::one()]);
364 assert_eq!(&a + &b, Fp2E::zero())
365 }
366
367 #[test]
368 fn add_plus_one() {
369 let a = Fp2E::new([FpE::one(), FpE::from(2)]);
370 let b = Fp2E::new([FpE::one(), FpE::one()]);
371 let c = Fp2E::new([FpE::from(2), FpE::from(3)]);
372 assert_eq!(&a + &b, c)
373 }
374
375 #[test]
376 fn sub_real_one_sub_one_is_zero() {
377 assert_eq!(&Fp2E::one() - &Fp2E::one(), Fp2E::zero())
378 }
379
380 #[test]
381 fn sub_real_two_sub_two_is_zero() {
382 assert_eq!(&Fp2E::from(2) - &Fp2E::from(2), Fp2E::zero())
383 }
384
385 #[test]
386 fn sub_real_neg_one_sub_neg_one_is_zero() {
387 assert_eq!(Fp2E::one().neg() - Fp2E::one().neg(), Fp2E::zero())
388 }
389
390 #[test]
391 fn sub_real_two_sub_one_is_one() {
392 assert_eq!(Fp2E::from(2) - Fp2E::one(), Fp2E::one())
393 }
394
395 #[test]
396 fn sub_real_neg_one_sub_zero_is_neg_one() {
397 assert_eq!(Fp2E::one().neg() - Fp2E::zero(), Fp2E::one().neg())
398 }
399
400 #[test]
401 fn sub_complex_one_sub_one_is_zero() {
402 let one = Fp2E::new([FpE::zero(), FpE::one()]);
403 assert_eq!(&one - &one, Fp2E::zero())
404 }
405
406 #[test]
407 fn sub_complex_two_sub_two_is_zero() {
408 let two = Fp2E::new([FpE::zero(), FpE::from(2)]);
409 assert_eq!(&two - &two, Fp2E::zero())
410 }
411
412 #[test]
413 fn sub_complex_neg_one_sub_neg_one_is_zero() {
414 let neg_one = Fp2E::new([FpE::zero(), -FpE::one()]);
415 assert_eq!(&neg_one - &neg_one, Fp2E::zero())
416 }
417
418 #[test]
419 fn sub_complex_two_sub_one_is_one() {
420 let two = Fp2E::new([FpE::zero(), FpE::from(2)]);
421 let one = Fp2E::new([FpE::zero(), FpE::one()]);
422 assert_eq!(&two - &one, one)
423 }
424
425 #[test]
426 fn sub_complex_neg_one_sub_zero_is_neg_one() {
427 let neg_one = Fp2E::new([FpE::zero(), -FpE::one()]);
428 assert_eq!(&neg_one - &Fp2E::zero(), neg_one)
429 }
430
431 #[test]
432 fn mul_fp2_is_correct() {
433 let a = Fp2E::new([FpE::from(2), FpE::from(2)]);
434 let b = Fp2E::new([FpE::from(4), FpE::from(5)]);
435 let c = Fp2E::new([-FpE::from(2), FpE::from(18)]);
436 assert_eq!(&a * &b, c)
437 }
438
439 #[test]
440 fn square_equals_mul_by_itself() {
441 let a = Fp2E::new([FpE::from(2), FpE::from(3)]);
442 assert_eq!(a.square(), &a * &a)
443 }
444
445 #[test]
446 fn test_fp2_add() {
447 let a = Fp2E::new([FpE::from(0), FpE::from(3)]);
448 let b = Fp2E::new([-FpE::from(2), FpE::from(8)]);
449 let expected_result = Fp2E::new([FpE::from(0) - FpE::from(2), FpE::from(3) + FpE::from(8)]);
450 assert_eq!(a + b, expected_result);
451 }
452
453 #[test]
454 fn test_fp2_add_2() {
455 let a = Fp2E::new([FpE::from(2), FpE::from(4)]);
456 let b = Fp2E::new([-FpE::from(2), -FpE::from(4)]);
457 let expected_result = Fp2E::new([FpE::from(2) - FpE::from(2), FpE::from(4) - FpE::from(4)]);
458 assert_eq!(a + b, expected_result);
459 }
460
461 #[test]
462 fn test_fp2_add_3() {
463 let a = Fp2E::new([FpE::from(&MERSENNE_31_PRIME_FIELD_ORDER), FpE::from(1)]);
464 let b = Fp2E::new([FpE::from(1), FpE::from(&MERSENNE_31_PRIME_FIELD_ORDER)]);
465 let expected_result = Fp2E::new([FpE::from(1), FpE::from(1)]);
466 assert_eq!(a + b, expected_result);
467 }
468
469 #[test]
470 fn test_fp2_sub() {
471 let a = Fp2E::new([FpE::from(0), FpE::from(3)]);
472 let b = Fp2E::new([-FpE::from(2), FpE::from(8)]);
473 let expected_result = Fp2E::new([FpE::from(0) + FpE::from(2), FpE::from(3) - FpE::from(8)]);
474 assert_eq!(a - b, expected_result);
475 }
476
477 #[test]
478 fn test_fp2_sub_2() {
479 let a = Fp2E::new([FpE::zero(), FpE::from(&MERSENNE_31_PRIME_FIELD_ORDER)]);
480 let b = Fp2E::new([FpE::one(), -FpE::one()]);
481 let expected_result =
482 Fp2E::new([FpE::from(&(MERSENNE_31_PRIME_FIELD_ORDER - 1)), FpE::one()]);
483 assert_eq!(a - b, expected_result);
484 }
485
486 #[test]
487 fn test_fp2_sub_3() {
488 let a = Fp2E::new([FpE::from(5), FpE::from(&MERSENNE_31_PRIME_FIELD_ORDER)]);
489 let b = Fp2E::new([FpE::from(5), FpE::from(&MERSENNE_31_PRIME_FIELD_ORDER)]);
490 let expected_result = Fp2E::new([FpE::zero(), FpE::zero()]);
491 assert_eq!(a - b, expected_result);
492 }
493
494 #[test]
495 fn test_fp2_mul() {
496 let a = Fp2E::new([FpE::from(12), FpE::from(5)]);
497 let b = Fp2E::new([-FpE::from(4), FpE::from(2)]);
498 let expected_result = Fp2E::new([-FpE::from(58), FpE::new(4)]);
499 assert_eq!(a * b, expected_result);
500 }
501
502 #[test]
503 fn test_fp2_mul_2() {
504 let a = Fp2E::new([FpE::one(), FpE::zero()]);
505 let b = Fp2E::new([FpE::from(12), -FpE::from(8)]);
506 let expected_result = Fp2E::new([FpE::from(12), -FpE::new(8)]);
507 assert_eq!(a * b, expected_result);
508 }
509
510 #[test]
511 fn test_fp2_mul_3() {
512 let a = Fp2E::new([FpE::zero(), FpE::zero()]);
513 let b = Fp2E::new([FpE::from(2), FpE::from(7)]);
514 let expected_result = Fp2E::new([FpE::zero(), FpE::zero()]);
515 assert_eq!(a * b, expected_result);
516 }
517
518 #[test]
519 fn test_fp2_mul_4() {
520 let a = Fp2E::new([FpE::from(2), FpE::from(7)]);
521 let b = Fp2E::new([FpE::zero(), FpE::zero()]);
522 let expected_result = Fp2E::new([FpE::zero(), FpE::zero()]);
523 assert_eq!(a * b, expected_result);
524 }
525
526 #[test]
527 fn test_fp2_mul_5() {
528 let a = Fp2E::new([FpE::from(&MERSENNE_31_PRIME_FIELD_ORDER), FpE::one()]);
529 let b = Fp2E::new([FpE::from(2), FpE::from(&MERSENNE_31_PRIME_FIELD_ORDER)]);
530 let expected_result = Fp2E::new([FpE::zero(), FpE::from(2)]);
531 assert_eq!(a * b, expected_result);
532 }
533
534 #[test]
535 fn test_fp2_inv() {
536 let a = Fp2E::new([FpE::one(), FpE::zero()]);
537 let expected_result = Fp2E::new([FpE::one(), FpE::zero()]);
538 assert_eq!(a.inv().unwrap(), expected_result);
539 }
540
541 #[test]
542 fn test_fp2_inv_2() {
543 let a = Fp2E::new([FpE::from(&(MERSENNE_31_PRIME_FIELD_ORDER - 1)), FpE::one()]);
544 let expected_result = Fp2E::new([FpE::from(1073741823), FpE::from(1073741823)]);
545 assert_eq!(a.inv().unwrap(), expected_result);
546 }
547
548 #[test]
549 fn test_fp2_inv_3() {
550 let a = Fp2E::new([FpE::from(2063384121), FpE::from(1232183486)]);
551 let expected_result = Fp2E::new([FpE::from(1244288232), FpE::from(1321511038)]);
552 assert_eq!(a.inv().unwrap(), expected_result);
553 }
554
555 #[test]
556 fn test_fp2_mul_inv() {
557 let a = Fp2E::new([FpE::from(12), FpE::from(5)]);
558 let b = a.inv().unwrap();
559 let expected_result = Fp2E::new([FpE::one(), FpE::zero()]);
560 assert_eq!(a * b, expected_result);
561 }
562
563 #[test]
564 fn test_fp2_div() {
565 let a = Fp2E::new([FpE::from(12), FpE::from(5)]);
566 let b = Fp2E::new([FpE::from(4), FpE::from(2)]);
567 let expected_result = Fp2E::new([FpE::from(644245097), FpE::from(1288490188)]);
568 assert_eq!((a / b).unwrap(), expected_result);
569 }
570
571 #[test]
572 fn test_fp2_div_2() {
573 let a = Fp2E::new([FpE::from(4), FpE::from(7)]);
574 let b = Fp2E::new([FpE::one(), FpE::zero()]);
575 let expected_result = Fp2E::new([FpE::from(4), FpE::from(7)]);
576 assert_eq!((a / b).unwrap(), expected_result);
577 }
578
579 #[test]
580 fn test_fp2_div_3() {
581 let a = Fp2E::new([FpE::zero(), FpE::zero()]);
582 let b = Fp2E::new([FpE::from(3), FpE::from(12)]);
583 let expected_result = Fp2E::new([FpE::zero(), FpE::zero()]);
584 assert_eq!((a / b).unwrap(), expected_result);
585 }
586
587 #[test]
588 fn mul_fp4_by_zero_is_zero() {
589 let a = Fp4E::new([
590 Fp2E::new([FpE::from(2), FpE::from(3)]),
591 Fp2E::new([FpE::from(4), FpE::from(5)]),
592 ]);
593 assert_eq!(Fp4E::zero(), a * Fp4E::zero())
594 }
595
596 #[test]
597 fn mul_fp4_by_one_is_identity() {
598 let a = Fp4E::new([
599 Fp2E::new([FpE::from(2), FpE::from(3)]),
600 Fp2E::new([FpE::from(4), FpE::from(5)]),
601 ]);
602 assert_eq!(a, a.clone() * Fp4E::one())
603 }
604
605 #[test]
606 fn square_fp4_equals_mul_two_times() {
607 let a = Fp4E::new([
608 Fp2E::new([FpE::from(3), FpE::from(4)]),
609 Fp2E::new([FpE::from(5), FpE::from(6)]),
610 ]);
611
612 assert_eq!(a.square(), &a * &a)
613 }
614
615 #[test]
616 fn fp4_mul_by_inv_is_one() {
617 let a = Fp4E::new([
618 Fp2E::new([FpE::from(2147483647), FpE::from(2147483648)]),
619 Fp2E::new([FpE::from(2147483649), FpE::from(2147483650)]),
620 ]);
621
622 assert_eq!(&a * a.inv().unwrap(), Fp4E::one())
623 }
624
625 #[test]
626 fn embed_fp_with_fp4() {
627 let a = FpE::from(3);
628 let a_extension = Fp4E::from(3);
629 assert_eq!(a.to_extension::<Degree4ExtensionField>(), a_extension);
630 }
631
632 #[test]
633 fn add_fp_and_fp4() {
634 let a = FpE::from(3);
635 let a_extension = Fp4E::from(3);
636 let b = Fp4E::from(2);
637 assert_eq!(a + &b, a_extension + b);
638 }
639
640 #[test]
641 fn mul_fp_by_fp4() {
642 let a = FpE::from(30000000000);
643 let a_extension = a.to_extension::<Degree4ExtensionField>();
644 let b = Fp4E::new([
645 Fp2E::new([FpE::from(1), FpE::from(2)]),
646 Fp2E::new([FpE::from(3), FpE::from(4)]),
647 ]);
648 assert_eq!(a * &b, a_extension * b);
649 }
650}