1 /** @file
2  *****************************************************************************
3 
4  Declaration of interfaces for the MNT6 G2 group.
5 
6  *****************************************************************************
7  * @author     This file is part of libff, developed by SCIPR Lab
8  *             and contributors (see AUTHORS).
9  * @copyright  MIT license (see LICENSE file)
10  *****************************************************************************/
11 
12 #ifndef MNT6_G2_HPP_
13 #define MNT6_G2_HPP_
14 
15 #include <vector>
16 
17 #include <libff/algebra/curves/curve_utils.hpp>
18 #include <libff/algebra/curves/mnt/mnt6/mnt6_init.hpp>
19 
20 namespace libff {
21 
22 class mnt6_G2;
23 std::ostream& operator<<(std::ostream &, const mnt6_G2&);
24 std::istream& operator>>(std::istream &, mnt6_G2&);
25 
26 class mnt6_G2 {
27 private:
28     mnt6_Fq3 X_, Y_, Z_;
29 public:
30 #ifdef PROFILE_OP_COUNTS
31     static long long add_cnt;
32     static long long dbl_cnt;
33 #endif
34     static std::vector<size_t> wnaf_window_table;
35     static std::vector<size_t> fixed_base_exp_window_table;
36     static mnt6_G2 G2_zero;
37     static mnt6_G2 G2_one;
38     static mnt6_Fq3 twist;
39     static mnt6_Fq3 coeff_a;
40     static mnt6_Fq3 coeff_b;
41 
42     typedef mnt6_Fq base_field;
43     typedef mnt6_Fq3 twist_field;
44     typedef mnt6_Fr scalar_field;
45 
46     // using projective coordinates
47     mnt6_G2();
mnt6_G2(const mnt6_Fq3 & X,const mnt6_Fq3 & Y,const mnt6_Fq3 & Z)48     mnt6_G2(const mnt6_Fq3& X, const mnt6_Fq3& Y, const mnt6_Fq3& Z) : X_(X), Y_(Y), Z_(Z) {}
49 
X() const50     mnt6_Fq3 X() const { return X_; }
Y() const51     mnt6_Fq3 Y() const { return Y_; }
Z() const52     mnt6_Fq3 Z() const { return Z_; }
53 
54     static mnt6_Fq3 mul_by_a(const mnt6_Fq3 &elt);
55     static mnt6_Fq3 mul_by_b(const mnt6_Fq3 &elt);
56 
57     void print() const;
58     void print_coordinates() const;
59 
60     void to_affine_coordinates();
61     void to_special();
62     bool is_special() const;
63 
64     bool is_zero() const;
65 
66     bool operator==(const mnt6_G2 &other) const;
67     bool operator!=(const mnt6_G2 &other) const;
68 
69     mnt6_G2 operator+(const mnt6_G2 &other) const;
70     mnt6_G2 operator-() const;
71     mnt6_G2 operator-(const mnt6_G2 &other) const;
72 
73     mnt6_G2 add(const mnt6_G2 &other) const;
74     mnt6_G2 mixed_add(const mnt6_G2 &other) const;
75     mnt6_G2 dbl() const;
76     mnt6_G2 mul_by_q() const;
77 
78     bool is_well_formed() const;
79 
80     static mnt6_G2 zero();
81     static mnt6_G2 one();
82     static mnt6_G2 random_element();
83 
size_in_bits()84     static size_t size_in_bits() { return twist_field::size_in_bits() + 1; }
base_field_char()85     static bigint<base_field::num_limbs> base_field_char() { return base_field::field_char(); }
order()86     static bigint<scalar_field::num_limbs> order() { return scalar_field::field_char(); }
87 
88     friend std::ostream& operator<<(std::ostream &out, const mnt6_G2 &g);
89     friend std::istream& operator>>(std::istream &in, mnt6_G2 &g);
90 
91     static void batch_to_special_all_non_zeros(std::vector<mnt6_G2> &vec);
92 };
93 
94 template<mp_size_t m>
operator *(const bigint<m> & lhs,const mnt6_G2 & rhs)95 mnt6_G2 operator*(const bigint<m> &lhs, const mnt6_G2 &rhs)
96 {
97     return scalar_mul<mnt6_G2, m>(rhs, lhs);
98 }
99 
100 template<mp_size_t m, const bigint<m>& modulus_p>
operator *(const Fp_model<m,modulus_p> & lhs,const mnt6_G2 & rhs)101 mnt6_G2 operator*(const Fp_model<m,modulus_p> &lhs, const mnt6_G2 &rhs)
102 {
103     return scalar_mul<mnt6_G2, m>(rhs, lhs.as_bigint());
104 }
105 
106 } // libff
107 
108 #endif // MNT6_G2_HPP_
109