/*************************************************************************** * 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 . * * 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. * * ***************************************************************************/ /* * * MIRACL C++ Header file big.h * * AUTHOR : N.Coghlan * Modified by M.Scott * * PURPOSE : Definition of class Big * * Bigs are normally created on the heap, but by defining BIGS=m * on the compiler command line, Bigs are instead mostly created from the * stack. Note that m must be same or less than the n in the main program * with for example * * Miracl precison(n,0); * * where n is the (fixed) size in words of each Big. * * This may be faster, as C++ tends to create and destroy lots of * temporaries. Especially recommended if m is small. Do not use * for program development * * However Bigs created from a string are always allocated from the heap. * This is useful for creating large read-only constants which are larger * than m. * * NOTE:- I/O conversion * * To convert a hex character string to a Big * * Big x; * char c[100]; * * mip->IOBASE=16; * x=c; * * To convert a Big to a hex character string * * mip->IOBASE=16; * c << x; * * To convert to/from pure binary, see the from_binary() * and to_binary() friend functions. * * int len; * char c[100]; * ... * Big x=from_binary(len,c); // creates Big x from len bytes of binary in c * * len=to_binary(x,100,c,FALSE); // converts Big x to len bytes binary in c[100] * len=to_binary(x,100,c,TRUE); // converts Big x to len bytes binary in c[100] * // (right justified with leading zeros) */ #ifndef BIG_H #define BIG_H #include //#include #include #include "mirdef.h" #ifdef MR_CPP #include "miracl.h" #else extern "C" { #include "miracl.h" } #endif #ifndef MR_NO_STANDARD_IO #include using std::istream; using std::ostream; #endif #ifndef MIRACL_CLASS #define MIRACL_CLASS #ifdef __cplusplus #ifdef MR_GENERIC_MT #error "The generic method isn't supported for C++, its C only" #endif #endif class Miracl { /* dummy class to initialise MIRACL - MUST be called before any Bigs * * are created. This could be a problem for static/global data declared * * in modules other than the main module */ miracl *mr; public: Miracl(int nd,mr_small nb=0) {mr=mirsys(nd,nb); #ifdef MR_FLASH mr->RPOINT=TRUE; #endif } miracl *operator&() {return mr;} ~Miracl() {mirexit();} }; #endif /* #ifdef BIGS #define MR_INIT_BIG memset(mem,0,mr_big_reserve(1,BIGS)); fn=(big)mirvar_mem_variable(mem,0,BIGS); #else #define MR_INIT_BIG mem=(char *)memalloc(1); fn=(big)mirvar_mem(mem,0); #endif */ #ifdef BIGS #define MR_INIT_BIG fn=&b; b.w=a; b.len=0; for (int i=0;ilen=1; fn->w[0]=s; return *this;} Big& operator=(const Big& b) {copy(b.fn,fn); return *this;} Big& operator=(big& b) {copy(b,fn); return *this;} Big& operator=(big* b) {fn=*b; return *this;} #ifndef MR_SIMPLE_IO #ifdef MR_SIMPLE_BASE Big& operator=(char* s){instr(fn,s);return *this;} #else Big& operator=(char* s){cinstr(fn,s);return *this;} #endif #endif Big& operator++() {incr(fn,1,fn); return *this;} Big& operator--() {decr(fn,1,fn); return *this;} Big& operator+=(int i) {incr(fn,i,fn); return *this;} Big& operator+=(const Big& b){add(fn,b.fn,fn); return *this;} Big& operator-=(int i) {decr(fn,i,fn); return *this;} Big& operator-=(const Big& b) {subtract(fn,b.fn,fn); return *this;} Big& operator*=(int i) {premult(fn,i,fn); return *this;} Big& operator*=(const Big& b) {multiply(fn,b.fn,fn); return *this;} Big& operator/=(int i) {subdiv(fn,i,fn); return *this;} Big& operator/=(const Big& b) {divide(fn,b.fn,fn); return *this;} Big& operator%=(int i) {convert(subdiv(fn,i,fn),fn); return *this;} Big& operator%=(const Big& b) {divide(fn,b.fn,b.fn); return *this;} Big& operator<<=(int i) {sftbit(fn,i,fn); return *this;} Big& operator>>=(int i) {sftbit(fn,-i,fn); return *this;} Big& shift(int n) {mr_shift(fn,n,fn); return *this;} mr_small& operator[](int i) {return fn->w[i];} void negate() const; BOOL iszero() const; BOOL isone() const; int get(int index) { int m; m=getdig(fn,index); return m; } void set(int index,int n) { putdig(n,fn,index);} int len() const; big getbig() const; friend class Flash; friend Big operator-(const Big&); friend Big operator+(const Big&,int); friend Big operator+(int,const Big&); friend Big operator+(const Big&,const Big&); friend Big operator-(const Big&, int); friend Big operator-(int,const Big&); friend Big operator-(const Big&,const Big&); friend Big operator*(const Big&, int); friend Big operator*(int,const Big&); friend Big operator*(const Big&,const Big&); friend BOOL fmth(int n,const Big&,const Big&,Big&); // fast mult - top half friend Big operator/(const Big&,int); friend Big operator/(const Big&,const Big&); friend int operator%(const Big&, int); friend Big operator%(const Big&, const Big&); friend Big operator<<(const Big&, int); friend Big operator>>(const Big&, int); friend BOOL operator<=(const Big& b1,const Big& b2) {if (mr_compare(b1.fn,b2.fn)<=0) return TRUE; else return FALSE;} friend BOOL operator>=(const Big& b1,const Big& b2) {if (mr_compare(b1.fn,b2.fn)>=0) return TRUE; else return FALSE;} friend BOOL operator==(const Big& b1,const Big& b2) {if (mr_compare(b1.fn,b2.fn)==0) return TRUE; else return FALSE;} friend BOOL operator!=(const Big& b1,const Big& b2) {if (mr_compare(b1.fn,b2.fn)!=0) return TRUE; else return FALSE;} friend BOOL operator<(const Big& b1,const Big& b2) {if (mr_compare(b1.fn,b2.fn)<0) return TRUE; else return FALSE;} friend BOOL operator>(const Big& b1,const Big& b2) {if (mr_compare(b1.fn,b2.fn)>0) return TRUE; else return FALSE;} friend Big from_binary(int,char *); friend int to_binary(const Big& b,int max,char *ptr,BOOL justify=FALSE) { return big_to_bytes(max,b.fn,ptr,justify); } //friend int to_binary(const Big&,int,char *,BOOL justify=FALSE); friend Big modmult(const Big&,const Big&,const Big&); friend Big mad(const Big&,const Big&,const Big&,const Big&,Big&); friend Big norm(const Big&); friend Big sqrt(const Big&); friend Big root(const Big&,int); friend Big gcd(const Big&,const Big&); friend void set_zzn3(int cnr,Big& sru) {get_mip()->cnr=cnr; nres(sru.fn,get_mip()->sru);} friend int recode(const Big& e,int t,int w,int i) {return recode(e.fn,t,w,i);} #ifndef MR_FP friend Big land(const Big&,const Big&); // logical AND friend Big lxor(const Big&,const Big&); // logical XOR #endif friend Big pow(const Big&,int); // x^m friend Big pow(const Big&, int, const Big&); // x^m mod n friend Big pow(int, const Big&, const Big&); // x^m mod n friend Big pow(const Big&, const Big&, const Big&); // x^m mod n friend Big pow(const Big&, const Big&, const Big&, const Big&, const Big&); // x^m.y^k mod n friend Big pow(int,Big *,Big *,Big); // x[0]^m[0].x[1].m[1]... mod n friend Big luc(const Big& b1,const Big& b2, const Big& b3, Big *b4=NULL) { Big z; if (b4!=NULL) lucas(b1.fn,b2.fn,b3.fn,b4->fn,z.fn); else lucas(b1.fn,b2.fn,b3.fn,z.fn,z.fn); return z; } //friend Big luc(const Big& ,const Big&, const Big&, Big *b4=NULL); friend Big moddiv(const Big&,const Big&,const Big&); friend Big inverse(const Big&, const Big&); friend void multi_inverse(int,Big*,const Big&,Big *); #ifndef MR_NO_RAND friend Big rand(const Big&); // 0 < rand < parameter friend Big rand(int,int); // (digits,base) e.g. (32,16) friend Big randbits(int); // n random bits friend Big strong_rand(csprng *,const Big&); friend Big strong_rand(csprng *,int,int); #endif friend Big abs(const Big&); // This next only works if MIRACL is using a binary base... friend int bit(const Big& b,int i) {return mr_testbit(b.fn,i);} friend int bits(const Big& b) {return logb2(b.fn);} friend int ham(const Big& b) {return hamming(b.fn);} friend int jacobi(const Big& b1,const Big& b2) {return jack(b1.fn,b2.fn);} friend int toint(const Big& b) {return size(b.fn);} friend BOOL prime(const Big& b) {return isprime(b.fn);} friend Big nextprime(const Big&); friend Big nextsafeprime(int type,int subset,const Big&); friend Big trial_divide(const Big& b); friend BOOL small_factors(const Big& b); friend BOOL perfect_power(const Big& b); friend Big sqrt(const Big&,const Big&); friend void ecurve(const Big&,const Big&,const Big&,int); friend BOOL ecurve2(int,int,int,int,const Big&,const Big&,BOOL,int); friend BOOL is_on_curve(const Big&); friend void modulo(const Big&); friend BOOL modulo(int,int,int,int,BOOL); friend Big get_modulus(void); friend int window(const Big& x,int i,int* nbs,int *nzs,int window_size=5) { return mr_window(x.fn,i,nbs,nzs,window_size); } //friend int window(const Big&,int,int*,int*,int window_size=5); friend int naf_window(const Big& x,const Big& x3,int i,int* nbs,int* nzs,int store=11) { return mr_naf_window(x.fn,x3.fn,i,nbs,nzs,store); } //friend int naf_window(const Big&,const Big&,int,int*,int*,int store=11); friend void jsf(const Big&,const Big&,Big&,Big&,Big&,Big&); /* Montgomery stuff */ friend Big nres(const Big&); friend Big redc(const Big&); /* friend Big nres_negate(const Big&); friend Big nres_modmult(const Big&,const Big&); friend Big nres_premult(const Big&,int); friend Big nres_pow(const Big&,const Big&); friend Big nres_pow2(const Big&,const Big&,const Big&,const Big&); friend Big nres_pown(int,Big *,Big *); friend Big nres_luc(const Big&,const Big&,Big *b3=NULL); friend Big nres_sqrt(const Big&); friend Big nres_modadd(const Big&,const Big&); friend Big nres_modsub(const Big&,const Big&); friend Big nres_moddiv(const Big&,const Big&); */ /* these are faster.... */ /* friend void nres_modmult(Big& a,const Big& b,Big& c) {nres_modmult(a.fn,b.fn,c.fn);} friend void nres_modadd(Big& a,const Big& b,Big& c) {nres_modadd(a.fn,b.fn,c.fn);} friend void nres_modsub(Big& a,const Big& b,Big& c) {nres_modsub(a.fn,b.fn,c.fn);} friend void nres_negate(Big& a,Big& b) {nres_negate(a.fn,b.fn);} friend void nres_premult(Big& a,int b,Big& c) {nres_premult(a.fn,b,c.fn);} friend void nres_moddiv(Big & a,const Big& b,Big& c) {nres_moddiv(a.fn,b.fn,c.fn);} */ friend Big shift(const Big&b,int n); friend int length(const Big&b); /* Note that when inputting text as a number the CR is NOT * * included in the text, unlike C I/O which does include CR. */ #ifndef MR_NO_STANDARD_IO friend istream& operator>>(istream&, Big&); friend ostream& operator<<(ostream&, const Big&); friend ostream& otfloat(ostream&,const Big&,int); #endif // output Big to a String friend char * operator<<(char * s,const Big&); ~Big() { // zero(fn); #ifndef BIGS mr_free(fn); #endif } }; extern BOOL modulo(int,int,int,int,BOOL); extern Big get_modulus(void); extern Big rand(int,int); extern Big strong_rand(csprng *,int,int); extern Big from_binary(int,char *); //extern int to_binary(const Big&,int,char *,BOOL); using namespace std; #endif