blob: a10be2f17a703cbfbca06b57176bb7be0302f7a8 [file] [log] [blame]
/***************************************************************************
*
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