| /*************************************************************************** |
| * |
| Copyright 2012 CertiVox IOM Ltd. * |
| * |
| This file is part of CertiVox MIRACL Crypto SDK. * |
| * |
| The CertiVox MIRACL Crypto SDK provides developers with an * |
| extensive and efficient set of cryptographic functions. * |
| For further information about its features and functionalities please * |
| refer to http://www.certivox.com * |
| * |
| * The CertiVox MIRACL Crypto SDK is free software: you can * |
| redistribute it and/or modify it under the terms of the * |
| GNU Affero General Public License as published by the * |
| Free Software Foundation, either version 3 of the License, * |
| or (at your option) any later version. * |
| * |
| * The CertiVox MIRACL Crypto SDK is distributed in the hope * |
| that it will be useful, but WITHOUT ANY WARRANTY; without even the * |
| implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * |
| See the GNU Affero General Public License for more details. * |
| * |
| * You should have received a copy of the GNU Affero General Public * |
| License along with CertiVox MIRACL Crypto SDK. * |
| If not, see <http://www.gnu.org/licenses/>. * |
| * |
| You can be released from the requirements of the license by purchasing * |
| a commercial license. Buying such a license is mandatory as soon as you * |
| develop commercial activities involving the CertiVox MIRACL Crypto SDK * |
| without disclosing the source code of your own applications, or shipping * |
| the CertiVox MIRACL Crypto SDK with a closed source product. * |
| * |
| ***************************************************************************/ |
| /* |
| * pfc.h |
| * |
| * High level interface to pairing functions - Type 3 pairings |
| * |
| * GT=pairing(G2,G1) |
| * |
| * This is calculated on a Pairing Friendly Curve (PFC), which must first be defined. |
| * |
| * G1 is a point over the base field, and G2 is a point over an extension field. |
| * GT is a finite field point over the k-th extension, where k is the embedding degree. |
| */ |
| |
| #ifndef PFC_H |
| #define PFC_H |
| |
| #include "ecn.h" // G1 |
| |
| // K=2 Cocks-Pinch curve |
| #ifdef MR_PAIRING_CP |
| #include "zzn2.h" |
| #define WINDOW_SIZE_PFC 8 // window size for precomputation |
| #define G2_TYPE ECn |
| #define G2_SUBTYPE ZZn |
| #define GT_TYPE ZZn2 |
| #endif |
| |
| // k=6 MNT curve |
| #ifdef MR_PAIRING_MNT |
| #include "zzn2.h" |
| #include "ecn3.h" // G2 |
| #include "zzn6a.h" // GT |
| #define WINDOW_SIZE_PFC 8 // window size for precomputation |
| #define G2_TYPE ECn3 |
| #define G2_SUBTYPE ZZn3 |
| #define GT_TYPE ZZn6 |
| #define FROB_TYPE ZZn2 |
| #endif |
| |
| //k=12 BN curve |
| #ifdef MR_PAIRING_BN |
| #include "zzn2.h" |
| #include "ecn2.h" // G2 |
| #include "zzn12a.h" // GT |
| #define WINDOW_SIZE_PFC 8 // window size for precomputation |
| #define G2_TYPE ECn2 |
| #define G2_SUBTYPE ZZn2 |
| #define GT_TYPE ZZn12 |
| #define FROB_TYPE ZZn2 |
| #endif |
| |
| // k=18 KSS curve |
| #ifdef MR_PAIRING_KSS |
| #include "ecn3.h" // G2 |
| #include "zzn18.h" // GT |
| #define WINDOW_SIZE_PFC 8 // window size for precomputation |
| #define G2_TYPE ECn3 |
| #define G2_SUBTYPE ZZn3 |
| #define GT_TYPE ZZn18 |
| #define FROB_TYPE ZZn |
| #endif |
| |
| // k=24 BLS curve |
| #ifdef MR_PAIRING_BLS |
| #include "ecn4.h" // G2 |
| #include "zzn24.h" // GT |
| #define WINDOW_SIZE_PFC 8 // window size for precomputation |
| #define G2_TYPE ECn4 |
| #define G2_SUBTYPE ZZn4 |
| #define GT_TYPE ZZn24 |
| #define FROB_TYPE ZZn2 |
| #endif |
| |
| // Multiples of G1 may be precomputed. If it is, the instance becomes read-only. |
| // Read-only instances cannot be written to - causes an error and exits |
| // Precomputation for pairing calculation only possible for G2 for ate pairing |
| |
| class G1 |
| { |
| friend G1 operator-( const G1& ); |
| |
| public: |
| G1() : mtable(NULL), mtbits(0) {} |
| G1( const G1& w ) : mtable(NULL), mtbits(0), g(w.g) {} |
| inline ~G1(); |
| |
| int spill(char*&); |
| void restore(char*); |
| |
| inline G1& operator=( const G1& w ); |
| inline G1 operator+( const G1& ); |
| inline bool operator==( const G1& ); |
| inline bool operator!=( const G1& x ); |
| |
| ECn g; |
| ECn *mtable; // pointer to values precomputed for multiplication |
| int mtbits; |
| }; |
| |
| // |
| // This is just a G2_TYPE. But we want to restrict the ways in which it can be used. |
| // We want the instances to always be of an order compatible with the PFC |
| // |
| |
| class G2 |
| { |
| friend G2 operator-( const G2& ); |
| |
| public: |
| G2() : ptable(NULL), mtable(NULL), mtbits(0) {} |
| G2( const G2& w ) : ptable(NULL), mtable(NULL), mtbits(0), g(w.g) {} |
| inline ~G2(); |
| |
| int spill( char*& ); |
| void restore( char* ); |
| |
| inline G2& operator=( const G2& w ); |
| inline G2 operator+( const G2& x ); |
| inline bool operator==( G2& x ); |
| inline bool operator!=( G2& x ); |
| |
| G2_TYPE g; |
| G2_SUBTYPE *ptable; // pointer to values precomputed for pairing |
| G2_TYPE *mtable; // pointer to values precomputed for multiplication |
| int mtbits; |
| }; |
| |
| class GT |
| { |
| public: |
| GT() : etable(NULL), etbits(0) {} |
| GT( const GT& w ) : etable(NULL), etbits(0), g(w.g) {} |
| GT( int d ) : etable(NULL), etbits(0), g(d) {} |
| inline ~GT(); |
| |
| int spill( char*& ); |
| void restore( char* ); |
| |
| inline GT& operator=( const GT& w ); |
| inline GT operator*( const GT& x ); |
| inline GT operator/( const GT& x ); |
| inline bool operator==( const GT& x ); |
| inline bool operator!=( const GT& x ); |
| |
| GT_TYPE g; |
| GT_TYPE *etable; |
| int etbits; |
| }; |
| |
| // pairing friendly curve class |
| |
| class PFC |
| { |
| public: |
| Big B; // y^2=x^3+Ax+B. This is B |
| Big x; // curve parameter |
| Big mod; |
| Big ord; |
| Big cof; |
| Big npoints; |
| Big trace; |
| |
| #ifdef MR_PAIRING_BN |
| Big BB[4][4],WB[4],SB[2][2],W[2]; |
| ZZn Beta; |
| #endif |
| #ifdef MR_PAIRING_KSS |
| Big BB[6][6],WB[6],SB[2][2],W[2]; |
| ZZn Beta; |
| #endif |
| #ifdef MR_PAIRING_BLS |
| ZZn Beta; |
| #endif |
| #ifdef FROB_TYPE |
| FROB_TYPE frob; // Frobenius constant |
| #endif |
| |
| int S; |
| #ifdef MR_PAIRING_MNT |
| sha SH; |
| #else |
| sha256 SH; |
| #endif |
| |
| #ifndef MR_NO_RAND |
| csprng *RNG; |
| #endif |
| |
| PFC( int, csprng* rng = NULL ); |
| ~PFC(); |
| |
| Big order() const { return ord; } |
| GT power( const GT&, const Big& ); |
| G1 mult( const G1&, const Big& ); |
| G2 mult( const G2&, const Big& ); |
| void hash_and_map( G1&, char* ); |
| void hash_and_map( G2&, char* ); |
| void random( Big& ); |
| void rankey( Big& ); |
| void random( G1& ); |
| void random( G2& ); |
| bool member( const GT& ); // test if element is member of pairing friendly group |
| |
| // small=true if exponent is always less than full group size and equal to 2*Security level |
| // creates a smaller table |
| int precomp_for_pairing( G2& ); // precompute multiples of G2 that occur in Miller loop |
| int precomp_for_mult( G1&, bool bSmall = false ); // precompute multiples of G1 for precomputation |
| int precomp_for_mult( G2&, bool bSmall = false ); |
| int precomp_for_power( GT&, bool bSmall = false ); // returns number of precomputed values |
| |
| int spill( G2&, char*& ); |
| void restore( char*, G2& ); |
| |
| Big hash_to_aes_key( const GT& ); |
| Big hash_to_group( char* ); |
| Big hash_to_group( char*, int ); |
| GT miller_loop( const G2&, const G1& ); |
| GT final_exp( const GT& ); |
| GT pairing( const G2&, const G1& ); |
| // parameters: number of pairings n, pointers to G1 and G2 elements |
| GT multi_miller( int n, G2**, G1** ); |
| GT multi_pairing( int n, G2**, G1** ); //product of pairings |
| void start_hash(); |
| void add_to_hash( const G1& ); |
| void add_to_hash( const G2& ); |
| void add_to_hash( const GT& ); |
| void add_to_hash( const Big& ); |
| Big finish_hash_to_group(); |
| Big finish_hash_to_aes_key(); |
| void seed_rng( int s ); |
| }; |
| |
| void read_only_error(void); |
| |
| G1::~G1() |
| { |
| if ( mtable != NULL ) |
| { |
| delete [] mtable; |
| mtable=NULL; |
| } |
| } |
| |
| G1& G1::operator=( const G1& w ) |
| { |
| if ( mtable == NULL ) |
| g = w.g; |
| else |
| read_only_error(); |
| |
| return *this; |
| } |
| |
| G1 G1::operator+( const G1& x ) |
| { |
| G1 z = *this; |
| z.g += x.g; |
| return z; |
| } |
| |
| bool G1::operator==( const G1& x ) |
| { |
| return ( this->g == x.g ); |
| } |
| |
| bool G1::operator!=( const G1& x ) |
| { |
| return ( this->g != x.g ); |
| } |
| |
| inline G1 operator-( const G1& x ) |
| { |
| G1 z = x; |
| z.g = -z.g; |
| return z; |
| } |
| |
| G2::~G2() |
| { |
| if ( ptable != NULL ) |
| { |
| delete [] ptable; |
| ptable = NULL; |
| } |
| |
| if ( mtable != NULL ) |
| { |
| delete [] mtable; |
| mtable = NULL; |
| } |
| } |
| |
| G2& G2::operator=( const G2& w ) |
| { |
| if ( ptable == NULL && mtable == NULL ) |
| g = w.g; |
| else |
| read_only_error(); |
| |
| return *this; |
| } |
| |
| G2 G2::operator+( const G2& x ) |
| { |
| G2 z = *this; |
| ECn2 t = x.g; |
| z.g += t; |
| |
| return z; |
| } |
| |
| bool G2::operator==( G2& x ) |
| { |
| return ( this->g == x.g ); |
| } |
| |
| bool G2::operator!=( G2& x ) |
| { |
| return ( this->g != x.g ); |
| } |
| |
| inline G2 operator-( const G2& x ) |
| { |
| G2 z = x; |
| z.g = -z.g; |
| |
| return z; |
| } |
| |
| GT::~GT() |
| { |
| if ( etable != NULL ) |
| { |
| delete [] etable; |
| etable = NULL; |
| } |
| } |
| |
| GT& GT::operator=( const GT& w ) |
| { |
| if ( etable == NULL ) |
| g = w.g; |
| else |
| read_only_error(); |
| |
| return *this; |
| } |
| |
| inline GT GT::operator*( const GT& x ) |
| { |
| GT z = *this; |
| z.g *= x.g; |
| return z; |
| } |
| |
| inline GT GT::operator/( const GT& x ) |
| { |
| GT z = *this; |
| z.g /= x.g; |
| return z; |
| } |
| |
| bool GT::operator==( const GT& x ) |
| { |
| return ( this->g == x.g ); |
| } |
| |
| bool GT::operator!=( const GT& x ) |
| { |
| return ( this->g != x.g ); |
| } |
| |
| |
| #ifndef MR_AFFINE_ONLY |
| |
| void force(ZZn&,ZZn&,ZZn&,ECn&); |
| void extract(ECn&,ZZn&,ZZn&,ZZn&); |
| |
| #endif |
| |
| void force(ZZn&,ZZn&,ECn&); |
| void extract(ECn&,ZZn&,ZZn&); |
| |
| #endif |