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
102
103
use super::cubic_extension::*;
use crate::fields::*;
use core::marker::PhantomData;
pub trait Fp3Config: 'static + Send + Sync + Sized {
type Fp: PrimeField;
const NONRESIDUE: Self::Fp;
const FROBENIUS_COEFF_FP3_C1: &'static [Self::Fp];
const FROBENIUS_COEFF_FP3_C2: &'static [Self::Fp];
const TWO_ADICITY: u32;
const TRACE_MINUS_ONE_DIV_TWO: &'static [u64];
const QUADRATIC_NONRESIDUE_TO_T: Fp3<Self>;
#[inline(always)]
fn mul_fp_by_nonresidue_in_place(fe: &mut Self::Fp) -> &mut Self::Fp {
*fe *= Self::NONRESIDUE;
fe
}
}
pub struct Fp3ConfigWrapper<P: Fp3Config>(PhantomData<P>);
impl<P: Fp3Config> CubicExtConfig for Fp3ConfigWrapper<P> {
type BasePrimeField = P::Fp;
type BaseField = P::Fp;
type FrobCoeff = P::Fp;
const DEGREE_OVER_BASE_PRIME_FIELD: usize = 3;
const NONRESIDUE: Self::BaseField = P::NONRESIDUE;
const SQRT_PRECOMP: Option<SqrtPrecomputation<CubicExtField<Self>>> =
Some(SqrtPrecomputation::TonelliShanks {
two_adicity: P::TWO_ADICITY,
quadratic_nonresidue_to_trace: P::QUADRATIC_NONRESIDUE_TO_T,
trace_of_modulus_minus_one_div_two: P::TRACE_MINUS_ONE_DIV_TWO,
});
const FROBENIUS_COEFF_C1: &'static [Self::FrobCoeff] = P::FROBENIUS_COEFF_FP3_C1;
const FROBENIUS_COEFF_C2: &'static [Self::FrobCoeff] = P::FROBENIUS_COEFF_FP3_C2;
#[inline(always)]
fn mul_base_field_by_nonresidue_in_place(fe: &mut Self::BaseField) -> &mut Self::BaseField {
P::mul_fp_by_nonresidue_in_place(fe)
}
fn mul_base_field_by_frob_coeff(
c1: &mut Self::BaseField,
c2: &mut Self::BaseField,
power: usize,
) {
*c1 *= &Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD];
*c2 *= &Self::FROBENIUS_COEFF_C2[power % Self::DEGREE_OVER_BASE_PRIME_FIELD];
}
}
pub type Fp3<P> = CubicExtField<Fp3ConfigWrapper<P>>;
impl<P: Fp3Config> Fp3<P> {
pub fn mul_assign_by_fp(&mut self, value: &P::Fp) {
self.c0.mul_assign(value);
self.c1.mul_assign(value);
self.c2.mul_assign(value);
}
}
impl<P: Fp3Config> CyclotomicMultSubgroup for Fp3<P> {}