1 /** @file
2  *****************************************************************************
3  Declaration of arithmetic in the finite field F[((p^2)^3)^2].
4  *****************************************************************************
5  * @author     This file is part of libff, developed by SCIPR Lab
6  *             and contributors (see AUTHORS).
7  * @copyright  MIT license (see LICENSE file)
8  *****************************************************************************/
9 
10 #ifndef FP12_2OVER3OVER2_HPP_
11 #define FP12_2OVER3OVER2_HPP_
12 #include <vector>
13 
14 #include <libff/algebra/fields/fp.hpp>
15 #include <libff/algebra/fields/fp2.hpp>
16 #include <libff/algebra/fields/fp6_3over2.hpp>
17 
18 namespace libff {
19 
20 template<mp_size_t n, const bigint<n>& modulus>
21 class Fp12_2over3over2_model;
22 
23 template<mp_size_t n, const bigint<n>& modulus>
24 std::ostream& operator<<(std::ostream &, const Fp12_2over3over2_model<n, modulus> &);
25 
26 template<mp_size_t n, const bigint<n>& modulus>
27 std::istream& operator>>(std::istream &, Fp12_2over3over2_model<n, modulus> &);
28 
29 /**
30  * Arithmetic in the finite field F[((p^2)^3)^2].
31  *
32  * Let p := modulus. This interface provides arithmetic for the extension field
33  * Fp12 = Fp6[W]/(W^2-V) where Fp6 = Fp2[V]/(V^3-non_residue) and non_residue is in Fp2
34  *
35  * ASSUMPTION: p = 1 (mod 6)
36  */
37 template<mp_size_t n, const bigint<n>& modulus>
38 class Fp12_2over3over2_model {
39 public:
40     typedef Fp_model<n, modulus> my_Fp;
41     typedef Fp2_model<n, modulus> my_Fp2;
42     typedef Fp6_3over2_model<n, modulus> my_Fp6;
43 
44     static Fp2_model<n, modulus> non_residue;
45     static Fp2_model<n, modulus> Frobenius_coeffs_c1[12]; // non_residue^((modulus^i-1)/6) for i=0,...,11
46 
47     my_Fp6 c0, c1;
Fp12_2over3over2_model()48     Fp12_2over3over2_model() {};
Fp12_2over3over2_model(const my_Fp6 & c0,const my_Fp6 & c1)49     Fp12_2over3over2_model(const my_Fp6& c0, const my_Fp6& c1) : c0(c0), c1(c1) {};
50 
clear()51     void clear() { c0.clear(); c1.clear(); }
print() const52     void print() const { printf("c0/c1:\n"); c0.print(); c1.print(); }
53 
54     static Fp12_2over3over2_model<n, modulus> zero();
55     static Fp12_2over3over2_model<n, modulus> one();
56     static Fp12_2over3over2_model<n, modulus> random_element();
57 
is_zero() const58     bool is_zero() const { return c0.is_zero() && c1.is_zero(); }
59     bool operator==(const Fp12_2over3over2_model &other) const;
60     bool operator!=(const Fp12_2over3over2_model &other) const;
61 
62     Fp12_2over3over2_model operator+(const Fp12_2over3over2_model &other) const;
63     Fp12_2over3over2_model operator-(const Fp12_2over3over2_model &other) const;
64     Fp12_2over3over2_model operator*(const Fp12_2over3over2_model &other) const;
65     Fp12_2over3over2_model operator-() const;
66     Fp12_2over3over2_model squared() const; // default is squared_complex
67     Fp12_2over3over2_model squared_karatsuba() const;
68     Fp12_2over3over2_model squared_complex() const;
69     Fp12_2over3over2_model inverse() const;
70     Fp12_2over3over2_model Frobenius_map(unsigned long power) const;
71     Fp12_2over3over2_model unitary_inverse() const;
72     Fp12_2over3over2_model cyclotomic_squared() const;
73 
74     Fp12_2over3over2_model mul_by_024(const my_Fp2 &ell_0, const my_Fp2 &ell_VW, const my_Fp2 &ell_VV) const;
75 
76     static my_Fp6 mul_by_non_residue(const my_Fp6 &elt);
77 
78     template<mp_size_t m>
79     Fp12_2over3over2_model cyclotomic_exp(const bigint<m> &exponent) const;
80 
base_field_char()81     static bigint<n> base_field_char() { return modulus; }
extension_degree()82     static size_t extension_degree() { return 12; }
83 
84     friend std::ostream& operator<< <n, modulus>(std::ostream &out, const Fp12_2over3over2_model<n, modulus> &el);
85     friend std::istream& operator>> <n, modulus>(std::istream &in, Fp12_2over3over2_model<n, modulus> &el);
86 };
87 
88 template<mp_size_t n, const bigint<n>& modulus>
89 std::ostream& operator<<(std::ostream& out, const std::vector<Fp12_2over3over2_model<n, modulus> > &v);
90 
91 template<mp_size_t n, const bigint<n>& modulus>
92 std::istream& operator>>(std::istream& in, std::vector<Fp12_2over3over2_model<n, modulus> > &v);
93 
94 template<mp_size_t n, const bigint<n>& modulus>
95 Fp12_2over3over2_model<n, modulus> operator*(const Fp_model<n, modulus> &lhs, const Fp12_2over3over2_model<n, modulus> &rhs);
96 
97 template<mp_size_t n, const bigint<n>& modulus>
98 Fp12_2over3over2_model<n, modulus> operator*(const Fp2_model<n, modulus> &lhs, const Fp12_2over3over2_model<n, modulus> &rhs);
99 
100 template<mp_size_t n, const bigint<n>& modulus>
101 Fp12_2over3over2_model<n, modulus> operator*(const Fp6_3over2_model<n, modulus> &lhs, const Fp12_2over3over2_model<n, modulus> &rhs);
102 
103 template<mp_size_t n, const bigint<n>& modulus, mp_size_t m>
104 Fp12_2over3over2_model<n, modulus> operator^(const Fp12_2over3over2_model<n, modulus> &self, const bigint<m> &exponent);
105 
106 template<mp_size_t n, const bigint<n>& modulus, mp_size_t m, const bigint<m>& exp_modulus>
107 Fp12_2over3over2_model<n, modulus> operator^(const Fp12_2over3over2_model<n, modulus> &self, const Fp_model<m, exp_modulus> &exponent);
108 
109 template<mp_size_t n, const bigint<n>& modulus>
110 Fp2_model<n, modulus> Fp12_2over3over2_model<n, modulus>::non_residue;
111 
112 template<mp_size_t n, const bigint<n>& modulus>
113 Fp2_model<n, modulus> Fp12_2over3over2_model<n, modulus>::Frobenius_coeffs_c1[12];
114 
115 } // libff
116 #include <libff/algebra/fields/fp12_2over3over2.tcc>
117 #endif // FP12_2OVER3OVER2_HPP_
118