ark_ff/fields/models/
fp3.rs1use super::cubic_extension::{CubicExtConfig, CubicExtField};
2use crate::fields::{CyclotomicMultSubgroup, MulAssign, PrimeField, SqrtPrecomputation};
3use core::marker::PhantomData;
4
5pub trait Fp3Config: 'static + Send + Sync + Sized {
7 type Fp: PrimeField;
9 const NONRESIDUE: Self::Fp;
13
14 const FROBENIUS_COEFF_FP3_C1: &'static [Self::Fp];
15 const FROBENIUS_COEFF_FP3_C2: &'static [Self::Fp];
16
17 const TWO_ADICITY: u32;
19 const TRACE_MINUS_ONE_DIV_TWO: &'static [u64];
20 const QUADRATIC_NONRESIDUE_TO_T: Fp3<Self>;
22
23 #[inline(always)]
27 fn mul_fp_by_nonresidue_in_place(fe: &mut Self::Fp) -> &mut Self::Fp {
28 *fe *= Self::NONRESIDUE;
29 fe
30 }
31}
32
33pub struct Fp3ConfigWrapper<P: Fp3Config>(PhantomData<P>);
35
36impl<P: Fp3Config> CubicExtConfig for Fp3ConfigWrapper<P> {
37 type BasePrimeField = P::Fp;
38 type BaseField = P::Fp;
39 type FrobCoeff = P::Fp;
40
41 const DEGREE_OVER_BASE_PRIME_FIELD: usize = 3;
42 const NONRESIDUE: Self::BaseField = P::NONRESIDUE;
43
44 const SQRT_PRECOMP: Option<SqrtPrecomputation<CubicExtField<Self>>> =
45 Some(SqrtPrecomputation::TonelliShanks {
46 two_adicity: P::TWO_ADICITY,
47 quadratic_nonresidue_to_trace: P::QUADRATIC_NONRESIDUE_TO_T,
48 trace_of_modulus_minus_one_div_two: P::TRACE_MINUS_ONE_DIV_TWO,
49 });
50
51 const FROBENIUS_COEFF_C1: &'static [Self::FrobCoeff] = P::FROBENIUS_COEFF_FP3_C1;
52 const FROBENIUS_COEFF_C2: &'static [Self::FrobCoeff] = P::FROBENIUS_COEFF_FP3_C2;
53
54 #[inline(always)]
55 fn mul_base_field_by_nonresidue_in_place(fe: &mut Self::BaseField) -> &mut Self::BaseField {
56 P::mul_fp_by_nonresidue_in_place(fe)
57 }
58
59 fn mul_base_field_by_frob_coeff(
60 c1: &mut Self::BaseField,
61 c2: &mut Self::BaseField,
62 power: usize,
63 ) {
64 *c1 *= &Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD];
65 *c2 *= &Self::FROBENIUS_COEFF_C2[power % Self::DEGREE_OVER_BASE_PRIME_FIELD];
66 }
67}
68
69pub type Fp3<P> = CubicExtField<Fp3ConfigWrapper<P>>;
70
71impl<P: Fp3Config> Fp3<P> {
72 pub fn mul_assign_by_fp(&mut self, value: &P::Fp) {
95 self.c0.mul_assign(value);
96 self.c1.mul_assign(value);
97 self.c2.mul_assign(value);
98 }
99}
100
101impl<P: Fp3Config> CyclotomicMultSubgroup for Fp3<P> {}