1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use super::quadratic_extension::*;
use crate::fields::PrimeField;
use core::marker::PhantomData;
pub trait Fp2Parameters: 'static + Send + Sync {
type Fp: PrimeField;
const NONRESIDUE: Self::Fp;
const QUADRATIC_NONRESIDUE: (Self::Fp, Self::Fp);
const FROBENIUS_COEFF_FP2_C1: &'static [Self::Fp];
#[inline(always)]
fn mul_fp_by_nonresidue(fe: &Self::Fp) -> Self::Fp {
Self::NONRESIDUE * fe
}
#[inline(always)]
fn add_and_mul_fp_by_nonresidue(x: &Self::Fp, y: &Self::Fp) -> Self::Fp {
*x + Self::mul_fp_by_nonresidue(y)
}
#[inline(always)]
fn add_and_mul_fp_by_nonresidue_plus_one(x: &Self::Fp, y: &Self::Fp) -> Self::Fp {
let mut tmp = *x;
tmp += y;
Self::add_and_mul_fp_by_nonresidue(&tmp, &y)
}
#[inline(always)]
fn sub_and_mul_fp_by_nonresidue(x: &Self::Fp, y: &Self::Fp) -> Self::Fp {
*x - Self::mul_fp_by_nonresidue(y)
}
}
pub struct Fp2ParamsWrapper<P: Fp2Parameters>(PhantomData<P>);
impl<P: Fp2Parameters> QuadExtParameters for Fp2ParamsWrapper<P> {
type BasePrimeField = P::Fp;
type BaseField = P::Fp;
type FrobCoeff = P::Fp;
const DEGREE_OVER_BASE_PRIME_FIELD: usize = 2;
const NONRESIDUE: Self::BaseField = P::NONRESIDUE;
const FROBENIUS_COEFF_C1: &'static [Self::FrobCoeff] = P::FROBENIUS_COEFF_FP2_C1;
#[inline(always)]
fn mul_base_field_by_nonresidue(fe: &Self::BaseField) -> Self::BaseField {
P::mul_fp_by_nonresidue(fe)
}
#[inline(always)]
fn add_and_mul_base_field_by_nonresidue(
x: &Self::BaseField,
y: &Self::BaseField,
) -> Self::BaseField {
P::add_and_mul_fp_by_nonresidue(x, y)
}
#[inline(always)]
fn add_and_mul_base_field_by_nonresidue_plus_one(
x: &Self::BaseField,
y: &Self::BaseField,
) -> Self::BaseField {
P::add_and_mul_fp_by_nonresidue_plus_one(x, y)
}
#[inline(always)]
fn sub_and_mul_base_field_by_nonresidue(
x: &Self::BaseField,
y: &Self::BaseField,
) -> Self::BaseField {
P::sub_and_mul_fp_by_nonresidue(x, y)
}
fn mul_base_field_by_frob_coeff(fe: &mut Self::BaseField, power: usize) {
*fe *= &Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD];
}
}
pub type Fp2<P> = QuadExtField<Fp2ParamsWrapper<P>>;
impl<P: Fp2Parameters> Fp2<P> {
pub fn mul_assign_by_fp(&mut self, other: &P::Fp) {
self.c0 *= other;
self.c1 *= other;
}
}