302 lines
8.9 KiB
C++
302 lines
8.9 KiB
C++
|
|
/***************************************************************************
|
|
*
|
|
Copyright 2013 CertiVox UK 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. *
|
|
*
|
|
***************************************************************************/
|
|
/*
|
|
* pairing.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 PAIRING_3_H
|
|
#define PAIRING_3_H
|
|
|
|
#include "ecn.h" // G1
|
|
|
|
// K=2 Cocks-Pinch curve
|
|
#ifdef MR_PAIRING_CP
|
|
#include "zzn2.h"
|
|
#define WINDOW_SIZE 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 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 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 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 8 // window size for precomputation
|
|
#define G2_TYPE ECn4
|
|
#define G2_SUBTYPE ZZn4
|
|
#define GT_TYPE ZZn24
|
|
#define FROB_TYPE ZZn2
|
|
#endif
|
|
|
|
class PFC;
|
|
extern void read_only_error(void);
|
|
|
|
// 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
|
|
{
|
|
public:
|
|
ECn g;
|
|
|
|
ECn *mtable; // pointer to values precomputed for multiplication
|
|
|
|
int mtbits;
|
|
G1() {mtable=NULL; mtbits=0;}
|
|
G1(const G1& w) {mtable=NULL; mtbits=0; g=w.g;}
|
|
|
|
G1& operator=(const G1& w)
|
|
{
|
|
if (mtable==NULL) g=w.g;
|
|
else read_only_error();
|
|
return *this;
|
|
}
|
|
int spill(char *&);
|
|
void restore(char *);
|
|
friend G1 operator-(const G1&);
|
|
friend G1 operator+(const G1&,const G1&);
|
|
friend BOOL operator==(const G1& x,const G1& y)
|
|
{if (x.g==y.g) return TRUE; else return FALSE; }
|
|
friend BOOL operator!=(const G1& x,const G1& y)
|
|
{if (x.g!=y.g) return TRUE; else return FALSE; }
|
|
~G1() {if (mtable!=NULL) {delete [] mtable; mtable=NULL;}}
|
|
};
|
|
|
|
//
|
|
// 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
|
|
{
|
|
public:
|
|
G2_TYPE g;
|
|
|
|
G2_SUBTYPE *ptable; // pointer to values precomputed for pairing
|
|
G2_TYPE *mtable; // pointer to values precomputed for multiplication
|
|
int mtbits;
|
|
|
|
G2() {ptable=NULL; mtable=NULL; mtbits=0;}
|
|
G2(const G2& w) {ptable=NULL; mtable=NULL; mtbits=0; g=w.g;}
|
|
G2& operator=(const G2& w)
|
|
{
|
|
if (ptable==NULL && mtable==NULL) g=w.g;
|
|
else read_only_error();
|
|
return *this;
|
|
}
|
|
int spill(char *&);
|
|
void restore(char *);
|
|
|
|
friend G2 operator-(const G2&);
|
|
friend G2 operator+(const G2&,const G2&);
|
|
friend BOOL operator==(G2& x,G2& y)
|
|
{if (x.g==y.g) return TRUE; else return FALSE; }
|
|
friend BOOL operator!=(G2& x,G2& y)
|
|
{if (x.g!=y.g) return TRUE; else return FALSE; }
|
|
|
|
~G2() {if (ptable!=NULL) {delete [] ptable; ptable=NULL;}
|
|
if (mtable!=NULL) {delete [] mtable; mtable=NULL;}}
|
|
};
|
|
|
|
class GT
|
|
{
|
|
public:
|
|
GT_TYPE g;
|
|
|
|
GT_TYPE *etable;
|
|
int etbits;
|
|
|
|
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;}
|
|
|
|
GT& operator=(const GT& w)
|
|
{
|
|
if (etable==NULL) g=w.g;
|
|
else read_only_error();
|
|
return *this;
|
|
}
|
|
int spill(char *&);
|
|
void restore(char *);
|
|
friend GT operator*(const GT&,const GT&);
|
|
friend GT operator/(const GT&,const GT&);
|
|
friend BOOL operator==(const GT& x,const GT& y)
|
|
{if (x.g==y.g) return TRUE; else return FALSE; }
|
|
friend BOOL operator!=(const GT& x,const GT& y)
|
|
{if (x.g!=y.g) return TRUE; else return FALSE; }
|
|
~GT() {if (etable!=NULL) {delete [] etable; etable=NULL;}}
|
|
};
|
|
|
|
// 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);
|
|
Big order(void) {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
|
|
|
|
int precomp_for_pairing(G2&); // precompute multiples of G2 that occur in Miller loop
|
|
int precomp_for_mult(G1&,BOOL small=FALSE); // precompute multiples of G1 for precomputation
|
|
int precomp_for_mult(G2&,BOOL small=FALSE);
|
|
int precomp_for_power(GT&,BOOL small=FALSE); // returns number of precomputed values
|
|
// small=TRUE if exponent is always less than full group size and equal to 2*Security level
|
|
// creates a smaller table
|
|
|
|
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);
|
|
void add_to_hash(const G1&);
|
|
void add_to_hash(const G2&);
|
|
void add_to_hash(const GT&);
|
|
void add_to_hash(const Big&);
|
|
void add_to_hash(char *);
|
|
Big finish_hash_to_group(void);
|
|
Big finish_hash_to_aes_key(void);
|
|
void seed_rng(int s);
|
|
~PFC() ;
|
|
};
|
|
|
|
#ifndef MR_AFFINE_ONLY
|
|
|
|
extern void force(ZZn&,ZZn&,ZZn&,ECn&);
|
|
extern void extract(ECn&,ZZn&,ZZn&,ZZn&);
|
|
|
|
#endif
|
|
|
|
extern void force(ZZn&,ZZn&,ECn&);
|
|
extern void extract(ECn&,ZZn&,ZZn&);
|
|
|
|
#endif
|