ark_ff/fields/models/
fp3.rs

1use super::cubic_extension::*;
2use crate::fields::*;
3use core::marker::PhantomData;
4
5/// Trait that specifies constants and methods for defining degree-three extension fields.
6pub trait Fp3Config: 'static + Send + Sync + Sized {
7    /// Base prime field underlying this extension.
8    type Fp: PrimeField;
9    /// Cubic non-residue in `Self::Fp` used to construct the extension
10    /// field. That is, `NONRESIDUE` is such that the cubic polynomial
11    /// `f(X) = X^3 - Self::NONRESIDUE` in Fp\[X\] is irreducible in `Self::Fp`.
12    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    /// p^3 - 1 = 2^s * t, where t is odd.
18    const TWO_ADICITY: u32;
19    const TRACE_MINUS_ONE_DIV_TWO: &'static [u64];
20    /// t-th power of a quadratic nonresidue in Fp3.
21    const QUADRATIC_NONRESIDUE_TO_T: Fp3<Self>;
22
23    /// Return `fe * Self::NONRESIDUE`.
24    /// The default implementation can be specialized if [`Self::NONRESIDUE`] has a special
25    /// structure that can speed up multiplication
26    #[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
33/// Wrapper for [`Fp3Config`], allowing combination of the [`Fp3Config`] and [`CubicExtConfig`] traits.
34pub 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
43    const NONRESIDUE: Self::BaseField = P::NONRESIDUE;
44
45    const SQRT_PRECOMP: Option<SqrtPrecomputation<CubicExtField<Self>>> =
46        Some(SqrtPrecomputation::TonelliShanks {
47            two_adicity: P::TWO_ADICITY,
48            quadratic_nonresidue_to_trace: P::QUADRATIC_NONRESIDUE_TO_T,
49            trace_of_modulus_minus_one_div_two: P::TRACE_MINUS_ONE_DIV_TWO,
50        });
51
52    const FROBENIUS_COEFF_C1: &'static [Self::FrobCoeff] = P::FROBENIUS_COEFF_FP3_C1;
53    const FROBENIUS_COEFF_C2: &'static [Self::FrobCoeff] = P::FROBENIUS_COEFF_FP3_C2;
54
55    #[inline(always)]
56    fn mul_base_field_by_nonresidue_in_place(fe: &mut Self::BaseField) -> &mut Self::BaseField {
57        P::mul_fp_by_nonresidue_in_place(fe)
58    }
59
60    fn mul_base_field_by_frob_coeff(
61        c1: &mut Self::BaseField,
62        c2: &mut Self::BaseField,
63        power: usize,
64    ) {
65        *c1 *= &Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD];
66        *c2 *= &Self::FROBENIUS_COEFF_C2[power % Self::DEGREE_OVER_BASE_PRIME_FIELD];
67    }
68}
69
70pub type Fp3<P> = CubicExtField<Fp3ConfigWrapper<P>>;
71
72impl<P: Fp3Config> Fp3<P> {
73    /// In-place multiply all coefficients `c0`, `c1`, and `c2` of `self`
74    /// by an element from [`Fp`](`Fp3Config::Fp`).
75    ///
76    /// # Examples
77    ///
78    /// ```
79    /// # use ark_std::test_rng;
80    /// # use ark_std::UniformRand;
81    /// # use ark_test_curves::mnt6_753 as ark_mnt6_753;
82    /// use ark_mnt6_753::{Fq as Fp, Fq3 as Fp3};
83    /// let c0: Fp = Fp::rand(&mut test_rng());
84    /// let c1: Fp = Fp::rand(&mut test_rng());
85    /// let c2: Fp = Fp::rand(&mut test_rng());
86    /// let mut ext_element: Fp3 = Fp3::new(c0, c1, c2);
87    ///
88    /// let base_field_element: Fp = Fp::rand(&mut test_rng());
89    /// ext_element.mul_assign_by_fp(&base_field_element);
90    ///
91    /// assert_eq!(ext_element.c0, c0 * base_field_element);
92    /// assert_eq!(ext_element.c1, c1 * base_field_element);
93    /// assert_eq!(ext_element.c2, c2 * base_field_element);
94    /// ```
95    pub fn mul_assign_by_fp(&mut self, value: &P::Fp) {
96        self.c0.mul_assign(value);
97        self.c1.mul_assign(value);
98        self.c2.mul_assign(value);
99    }
100}
101
102// We just use the default algorithms; there don't seem to be any faster ones.
103impl<P: Fp3Config> CyclotomicMultSubgroup for Fp3<P> {}