From 5c7fcd96dab0785401747c82dc5c5fd324d60c6c Mon Sep 17 00:00:00 2001 From: Kealan McCusker Date: Fri, 24 Jun 2016 16:08:23 +0100 Subject: [PATCH] fix issue with friend declariations for mac g++ build --- mac.txt | 4 + source/mac/big.cpp | 449 +++++++++++++++++++++++++++++++++++++++++++++ source/mac/big.h | 440 ++++++++++++++++++++++++++++++++++++++++++++ source/mac/zzn.cpp | 192 +++++++++++++++++++ source/mac/zzn.h | 215 ++++++++++++++++++++++ 5 files changed, 1300 insertions(+) create mode 100644 source/mac/big.cpp create mode 100644 source/mac/big.h create mode 100644 source/mac/zzn.cpp create mode 100644 source/mac/zzn.h diff --git a/mac.txt b/mac.txt index 965e4ae..4123ce2 100644 --- a/mac.txt +++ b/mac.txt @@ -11,3 +11,7 @@ On a MAC using GCC, use the flag when compiling MIRACL assembly language modules.. (Thanks Augusto) + +There is also a known problem with the mac port of g++ involving friend +declarations in big.h and zzn.h. This can be solved by substituting the files +in ./source/mac for the ones found in ./include and ./source diff --git a/source/mac/big.cpp b/source/mac/big.cpp new file mode 100644 index 0000000..f8196a4 --- /dev/null +++ b/source/mac/big.cpp @@ -0,0 +1,449 @@ + +/*************************************************************************** + * +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++ functions big.cpp + * + * AUTHOR : N.Coghlan + * Modified by M.Scott + * + * PURPOSE : Implementation of class Big functions + */ + +#include "big.h" + +void Big::negate() const + { negify(fn,fn); } +big Big::getbig() const + { return fn;} +BOOL Big::iszero() const + { if (size(fn)==0) return TRUE; return FALSE;} +BOOL Big::isone() const + { if (size(fn)==1) return TRUE; return FALSE;} +int Big::len() const + { return numdig(fn); } + +Big operator-(const Big& b) +{Big nb; negify(b.fn,nb.fn); return nb;} +Big operator+(const Big& b,int i) +{Big abi; incr(b.fn, i, abi.fn); return abi;} +Big operator+(int i,const Big& b) +{Big aib; incr(b.fn, i, aib.fn); return aib;} +Big operator+(const Big& b1, const Big& b2) +{Big abb;add(b1.fn,b2.fn,abb.fn);return abb;} + +Big operator-(const Big& b, int i) +{Big mbi; decr(b.fn, i, mbi.fn); return mbi;} +Big operator-(int i, const Big& b) +{Big mib;decr(b.fn, i, mib.fn);negify(mib.fn,mib.fn);return mib;} +Big operator-(const Big& b1, const Big& b2) +{Big mbb; subtract(b1.fn,b2.fn,mbb.fn); return mbb;} + +Big operator*(const Big& b, int i) +{Big xbi; premult(b.fn, i, xbi.fn); return xbi;} +Big operator*(int i, const Big& b) +{Big xib; premult(b.fn, i, xib.fn); return xib;} +Big operator*(const Big& b1, const Big& b2) +{Big xbb; multiply(b1.fn,b2.fn,xbb.fn); return xbb;} + +#ifndef MR_STATIC +BOOL fmt(int n,const Big& b1,const Big& b2,Big& f) +{ +#ifdef MR_KCM + return kcm_top(n,b1.fn,b2.fn,f.fn); /* see mrkcm.tpl */ +#else + return fastmultop(n,b1.fn,b2.fn,f.fn); /* see mrfast.c */ +#endif +} +#endif + +Big operator/(const Big& b, int i) +{Big dbi; subdiv(b.fn, i, dbi.fn); return dbi;} +Big operator/(const Big& b1, const Big& b2) +{Big dbb; copy(b1.fn,dbb.fn); divide(dbb.fn,b2.fn,dbb.fn); return dbb;} + +int operator%(const Big& b, int i) +{Big mdbi; return(subdiv(b.fn,i, mdbi.fn));} +Big operator%(const Big& b1, const Big& b2) +{Big mdbb;copy(b1.fn,mdbb.fn);divide(mdbb.fn,b2.fn,b2.fn);return mdbb;} + +Big operator<<(const Big& b, int i) +{Big ms; sftbit(b.fn,i,ms.fn); return ms;} + +Big operator>>(const Big& b, int i) +{Big ms; sftbit(b.fn,-i,ms.fn); return ms;} + +#ifndef MR_FP +Big land(const Big& x,const Big& y) +{Big z; mr_and(x.fn,y.fn,z.fn); return z;} +Big lxor(const Big& x,const Big& y) +{Big z; mr_xor(x.fn,y.fn,z.fn); return z;} + +#endif + +Big from_binary(int len,char *ptr) +{Big z; bytes_to_big(len,ptr,z.fn); return z;} +//int to_binary(const Big& b,int max,char *ptr,BOOL justify) +//{ return big_to_bytes(max,b.fn,ptr,justify);} + +Big modmult(const Big& b1,const Big& b2,const Big& m) +{Big z; mad(b1.fn,b2.fn,b2.fn,m.fn,m.fn,z.fn); return z;} +Big mad(const Big& b1,const Big& b2,const Big& b3,const Big& m,Big &r) +{Big q; mad(b1.fn,b2.fn,b3.fn,m.fn,q.fn,r.fn); return q;} + +Big norm(const Big& b) {Big z; normalise(b.fn,z.fn); return z;} +Big sqrt(const Big& b) {Big z; nroot(b.fn, 2, z.fn); return z;} +Big abs(const Big& b) {Big z; absol(b.fn,z.fn); return z;} +Big root(const Big &b,int n) {Big z; nroot(b.fn, n, z.fn); return z;} +Big gcd(const Big& b1, const Big& b2){Big z;egcd(b1.fn,b2.fn,z.fn);return z;} +Big pow(const Big& b,int n) +{Big z;int x; +if (mr_abs(x=size(b.fn))fn,z.fn); +// else lucas(b1.fn,b2.fn,b3.fn,z.fn,z.fn); +//return z;} + + +Big inverse(const Big& b1, const Big& b2) +{Big z; xgcd(b1.fn,b2.fn,z.fn,z.fn,z.fn);return z;} + +Big moddiv(const Big& b1,const Big& b2,const Big& m) +{Big z; xgcd(b2.fn,m.fn,z.fn,z.fn,z.fn); mad(b1.fn,z.fn,z.fn,m.fn,m.fn,z.fn); return z;} + +#ifndef MR_NO_RAND + +Big rand(const Big& b) {Big z; bigrand(b.fn,z.fn); return z;} +Big rand(int n,int b) {Big z; bigdig(n,b,z.fn); return z;} +Big randbits(int n) {Big z; bigbits(n,z.fn); return z;} + +Big strong_rand(csprng *rng,const Big& b) {Big z; strong_bigrand(rng,b.fn,z.fn); return z;} +Big strong_rand(csprng *rng,int n,int b) {Big z; strong_bigdig(rng,n,b,z.fn); return z;} + +#endif + +Big nextprime(const Big& b) {Big z; nxprime(b.fn,z.fn); return z;} +Big nextsafeprime(int type,int subset,const Big& b) {Big z; +nxsafeprime(type,subset,b.fn,z.fn); return z; } +Big trial_divide(const Big& b) {Big r; trial_division(b.fn,r.fn); return r;} +BOOL small_factors(const Big& b) +{if (trial_division(b.fn,b.fn)==0) return TRUE; return FALSE;} +BOOL perfect_power(const Big& b) +{int i; + miracl *mip=get_mip(); + if (size(b.fn)<4) return FALSE; + for (i=2;;i++) + { + if (nroot(b.fn,i,mip->w8)) return TRUE; + if (size(mip->w8)<=1) break; + } + return FALSE; +} + + +Big sqrt(const Big& x,const Big& p) {Big z; sqroot(x.fn,p.fn,z.fn); return z;} + +void modulo(const Big& n) {prepare_monty(n.fn);} +Big get_modulus() +{Big m; +miracl *mip=get_mip(); +copy(mip->modulus,m.fn); +return m;} + + +Big nres(const Big& b) {Big z; nres(b.fn,z.fn); return z;} +Big redc(const Big& b) {Big z; redc(b.fn,z.fn);return z;} + +/* + +Big nres_negate(const Big& b) +{ Big z; nres_negate(b.fn,z.fn); return z;} +Big nres_modmult(const Big& b1,const Big& b2) +{ Big z; nres_modmult(b1.fn,b2.fn,z.fn); return z;} +Big nres_premult(const Big& b1,int i) +{ Big z; nres_premult(b1.fn,i,z.fn); return z;} + +Big nres_modadd(const Big& b1,const Big& b2) +{ Big z; nres_modadd(b1.fn,b2.fn,z.fn); return z;} +Big nres_modsub(const Big& b1,const Big& b2) +{ Big z; nres_modsub(b1.fn,b2.fn,z.fn); return z;} +Big nres_moddiv(const Big& b1,const Big& b2) +{ Big z; nres_moddiv(b1.fn,b2.fn,z.fn); return z;} +Big nres_pow(const Big& b1,const Big& b2) +{ Big z; nres_powmod(b1.fn,b2.fn,z.fn); return z;} + + + + +Big nres_pow2(const Big& b1,const Big& b2,const Big& b3,const Big& b4) +{ Big z; nres_powmod2(b1.fn,b2.fn,b3.fn,b4.fn,z.fn); return z;} + + +Big nres_pown(int n,Big *a,Big *b) +{ + Big z; + int i; + big *x=(big *)mr_alloc(n,sizeof(big)); + big *y=(big *)mr_alloc(n,sizeof(big)); + for (i=0;ifn,z.fn); + else nres_lucas(b1.fn,b2.fn,z.fn,z.fn); + return z;} + +Big nres_sqrt(const Big& b) +{ Big z; nres_sqroot(b.fn,z.fn); return z;} +*/ + +Big shift(const Big&b,int n) +{ + Big r; + mr_shift(b.fn,n,r.fn); + return r; +} + +int length(const Big& b) +{ + return mr_lent(b.fn); +} + +/* 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 +#ifndef MR_SIMPLE_IO + +istream& operator>>(istream& s, Big& x) +{ + miracl *mip=get_mip(); +#ifndef MR_SIMPLE_BASE + + if (mip->IOBASE>60) + { + s.sync(); + s.getline(mip->IOBUFF,mip->IOBSIZ); + } + else +#endif + s >> mip->IOBUFF; + if (s.eof() || s.bad()) + { + zero(x.fn); + return s; + } +#ifdef MR_SIMPLE_BASE + instr(x.fn,mip->IOBUFF); +#else + cinstr(x.fn,mip->IOBUFF); +#endif + return s; +} + +#endif +#endif + +// Note new parameter of window_size. Default to 5, but reduce to 4 (or even 3) to save RAM + +//int window(const Big& x,int i,int *nbs,int *nzs,int window_size) +//{ /* returns sliding window value, max. of 5 bits, * +// * starting at i-th bit of big x. nbs is number of bits * +// * processed, nzs is the number of additional trailing * +// * zeros detected. Returns valid bit pattern 1x..x1 with * + // * no two adjacent 0's. So 10101 will return 21 with * +// * nbs=5, nzs=0. 11001 will return 3, with nbs=2, nzs=2, * + // * having stopped after the first 11.. */ + + // return mr_window(x.fn,i,nbs,nzs,window_size); +//} + +//int naf_window(const Big& x,const Big& x3,int i,int *nbs,int *nzs,int store) +//{ /* returns sliding window value, max of 5 bits * +// * starting at i-th bit of x. nbs is number of bits * +// * processed. nzs is number of additional trailing * +// * zeros detected. x and x3 (which is 3*x) are * +// * combined to produce the NAF (non-adjacent form) * +// * So if x=11011(27) and x3 is 1010001, the LSB is * +// * ignored and the value 100T0T (32-4-1=27) processed, * +// * where T is -1. Note x.P = (3x-x)/2.P. This value will * +// * return +7, with nbs=4 and nzs=1, having stopped after * +// * the first 4 bits. Note in an NAF non-zero elements * +// * are never side by side, so 10T10T won't happen */ + + +// return mr_naf_window(x.fn,x3.fn,i,nbs,nzs,store); +//} + +#ifndef MR_NO_ECC_MULTIADD +void jsf(const Big& k0,const Big& k1,Big& u0p,Big& u0m,Big& u1p,Big& u1m) +{ + mr_jsf(k0.fn,k1.fn,u0p.fn,u0m.fn,u1p.fn,u1m.fn); +} +#endif + +#ifndef MR_NO_STANDARD_IO + +ostream& operator<<(ostream& s, const Big& x) +{ + miracl *mip=get_mip(); +#if defined(MR_SIMPLE_BASE) || defined(MR_SIMPLE_IO) + otstr(x.fn,mip->IOBUFF); +#else + cotstr(x.fn,mip->IOBUFF); +#endif + s << mip->IOBUFF; + return s; +} + +#ifdef MR_FLASH + +ostream& otfloat(ostream& s,const Big& m,int e) +{ + miracl *mip=get_mip(); + copy(m.fn,mip->w5); + + convert(1,mip->w6); + copy(mip->w6,mip->w9); + mr_shift(mip->w6,mr_lent(m.fn),mip->w6); + mround(mip->w5,mip->w6,mip->w8); + if (e>=-2 && e<=2) + { + if (e>0) + { + mr_shift(mip->w9,e,mip->w9); + fmul(mip->w8,mip->w9,mip->w8); + } + else + { + mr_shift(mip->w9,-e,mip->w9); + fdiv(mip->w8,mip->w9,mip->w8); + } +#if defined(MR_SIMPLE_BASE) || defined(MR_SIMPLE_IO) + otstr(mip->w8,mip->IOBUFF); +#else + cotstr(mip->w8,mip->IOBUFF); +#endif + s << mip->IOBUFF; + } + else + { +#if defined(MR_SIMPLE_BASE) || defined(MR_SIMPLE_IO) + otstr(mip->w8,mip->IOBUFF); +#else + cotstr(mip->w8,mip->IOBUFF); +#endif + s << mip->IOBUFF; + s << ".2^" << e*MIRACL; + } + + return s; +} + +#endif + +#endif + +char* operator<<(char *s,const Big& x) +{ + miracl *mip=get_mip(); + int i,n; +#if defined(MR_SIMPLE_BASE) || defined(MR_SIMPLE_IO) + n=otstr(x.fn,mip->IOBUFF); +#else + n=cotstr(x.fn,mip->IOBUFF); +#endif + if (s!=mip->IOBUFF) for (i=0;i<=n;i++) s[i]=mip->IOBUFF[i]; + return s; +} + +void ecurve(const Big& a,const Big& b,const Big& p,int t) +{ + ecurve_init(a.fn,b.fn,p.fn,t); +} + +BOOL ecurve2(int m,int a,int b,int c,const Big& a2,const Big& a6,BOOL check,int t) +{ return ecurve2_init(m,a,b,c,a2.fn,a6.fn,check,t);} + diff --git a/source/mac/big.h b/source/mac/big.h new file mode 100644 index 0000000..0888e0e --- /dev/null +++ b/source/mac/big.h @@ -0,0 +1,440 @@ + +/*************************************************************************** + * +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 fmt(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 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 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 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 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 + diff --git a/source/mac/zzn.cpp b/source/mac/zzn.cpp new file mode 100644 index 0000000..09a69c7 --- /dev/null +++ b/source/mac/zzn.cpp @@ -0,0 +1,192 @@ + +/*************************************************************************** + * +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++ functions zzn.cpp + * + * AUTHOR : M. Scott + * + * PURPOSE : Implementation of class ZZn functions using Montgomery + * representation + * NOTE : Must be used in conjunction with big.h and big.cpp + * + */ + +#include "zzn.h" + +big ZZn::getzzn(void) const + { return fn;} + +ZZn& ZZn::operator/=(int i) +{ + if (i==1) return *this; + if (i==2) + { // make a special effort... modulus is odd + nres_div2(fn,fn); + return *this; + } + ZZn x=i; + nres_moddiv(fn,x.fn,fn); + return *this; +} + +BOOL ZZn::iszero() const +{ if (size(fn)==0) return TRUE; return FALSE;} + +ZZn operator-(const ZZn& b) +{ZZn x=b; nres_negate(x.fn,x.fn); return x;} + +ZZn operator+(const ZZn& b,int i) +{ZZn abi=b; abi+=i; return abi;} +ZZn operator+(int i, const ZZn& b) +{ZZn aib=b; aib+=i; return aib;} +ZZn operator+(const ZZn& b1, const ZZn& b2) +{ZZn abb=b1; abb+=b2; return abb;} + +ZZn operator-(const ZZn& b, int i) +{ZZn mbi=b; mbi-=i; return mbi;} +ZZn operator-(int i, const ZZn& b) +{ZZn mib=i; mib-=b; return mib;} +ZZn operator-(const ZZn& b1, const ZZn& b2) +{ZZn mbb=b1; mbb-=b2; return mbb;} + +ZZn operator*(const ZZn& b,int i) +{ZZn xbb=b; xbb*=i; return xbb;} +ZZn operator*(int i, const ZZn& b) +{ZZn xbb=b; xbb*=i; return xbb;} +ZZn operator*(const ZZn& b1, const ZZn& b2) +{ZZn xbb=b1; xbb*=b2; return xbb;} + +ZZn operator/(const ZZn& b1, int i) +{ZZn z=b1; z/=i; return z; } + +ZZn operator/(int i, const ZZn& b2) +{ZZn z=i; nres_moddiv(z.fn,b2.fn,z.fn); return z;} +ZZn operator/(const ZZn& b1, const ZZn& b2) +{ZZn z=b1; z/=b2; return z;} + +ZZn pow( const ZZn& b1, const Big& b2) +{ZZn z; nres_powmod(b1.fn,b2.getbig(),z.fn);return z;} + +ZZn pow( const ZZn& b,int i) +{ZZn z; Big ib=i; nres_powmod(b.fn,ib.getbig(),z.fn); return z;} + +ZZn pow( const ZZn& b1, const Big& b2, const ZZn& b3,const Big& b4) +{ZZn z; nres_powmod2(b1.fn,b2.getbig(),b3.fn,b4.getbig(),z.fn); return z;} + +int jacobi(const ZZn& x) +{redc(x.fn,get_mip()->w1); return jack(get_mip()->w1,get_mip()->modulus); } + +#ifndef MR_NO_RAND +ZZn randn(void) +{ZZn z; bigrand(get_mip()->modulus,z.fn); return z;} +#endif +BOOL qr(const ZZn& x) +{redc(x.fn,get_mip()->w1); if (jack(get_mip()->w1,get_mip()->modulus)==1) return TRUE; return FALSE; } + +BOOL qnr(const ZZn& x) +{redc(x.fn,get_mip()->w1); if (jack(get_mip()->w1,get_mip()->modulus)==-1) return TRUE; return FALSE;} + +ZZn one(void) +{ + ZZn w; + w=get_mip()->one; + return w; +} + +ZZn getA(void) +{ + ZZn w; + if (get_mip()->AsizeAsize; + else w=get_mip()->A; + return w; +} + +ZZn getB(void) +{ + ZZn w; + if (get_mip()->BsizeBsize; + else w=get_mip()->B; + return w; +} + +#ifndef MR_STATIC + +ZZn pow(int n,ZZn *a,Big *b) +{ + ZZn z; + int i; + big *x=(big *)mr_alloc(n,sizeof(big)); + big *y=(big *)mr_alloc(n,sizeof(big)); + for (i=0;ifn,z.fn); +// else nres_lucas(b1.fn,b2.getbig(),z.fn,z.fn); +// return z;} + + +ZZn sqrt(const ZZn& b) +{ZZn z; nres_sqroot(b.fn,z.fn); return z;} + +#ifndef MR_NO_STANDARD_IO + +ostream& operator<<(ostream& s,const ZZn& xx) +{ + ZZn b=xx; + Big x=(Big)b; + s << x; + return s; +} + +#endif diff --git a/source/mac/zzn.h b/source/mac/zzn.h new file mode 100644 index 0000000..36ca294 --- /dev/null +++ b/source/mac/zzn.h @@ -0,0 +1,215 @@ + +/*************************************************************************** + * +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 zzn.h + * + * AUTHOR : M. Scott + * + * PURPOSE : Definition of class ZZn (Arithmetic mod n), using + * Montgomery's Method for modular multiplication + * NOTE : Must be used in conjunction with zzn.cpp + * The modulus n is always set dynamically (via the modulo() + * routine) - so beware the pitfalls implicit in declaring + * static or global ZZn's (which are initialised before n is + * set!). Uninitialised data is OK + */ + +#ifndef ZZN_H +#define ZZN_H + +#include "big.h" + +/* + +#ifdef ZZNS +#define MR_INIT_ZZN memset(mem,0,mr_big_reserve(1,ZZNS)); fn=(big)mirvar_mem_variable(mem,0,ZZNS); +#define MR_CLONE_ZZN(x) fn->len=x->len; for (int i=0;iw[i]=x->w[i]; +#define MR_ZERO_ZZN {fn->len=0; for (int i=0;iw[i]=0;} +#else +#define MR_INIT_ZZN mem=(char *)memalloc(1); fn=(big)mirvar_mem(mem,0); +#define MR_CLONE_ZZN(x) copy(x,fn); +#define MR_ZERO_ZZN zero(fn); +#endif + +*/ + +#ifdef ZZNS +#ifdef MR_COMBA +#define UZZNS ZZNS +#else +#define UZZNS ZZNS+1 // one extra required in case of carry overflow in addition +#endif +#endif + +#ifdef ZZNS +#define MR_INIT_ZZN fn=&b; b.w=a; b.len=UZZNS; +#define MR_CLONE_ZZN(x) b.len=x->len; for (int i=0;iw[i]; +#define MR_ZERO_ZZN {b.len=0; for (int i=0;i ZZn */ + ZZn(big& c) {MR_INIT_ZZN MR_CLONE_ZZN(c);} + ZZn(const ZZn& c) {MR_INIT_ZZN MR_CLONE_ZZN(c.fn);} + ZZn(char* s) {MR_INIT_ZZN cinstr(fn,s); nres(fn,fn);} + + ZZn& operator=(const ZZn& c) {MR_CLONE_ZZN(c.fn) return *this;} + ZZn& operator=(big c) {MR_CLONE_ZZN(c) return *this; } + + ZZn& operator=(int i) {if (i==0) MR_ZERO_ZZN else {convert(i,fn); nres(fn,fn);} return *this;} + ZZn& operator=(char* s){cinstr(fn,s); nres(fn,fn); return *this;} + + +/* Use fast in-line code */ + + ZZn& operator++() + {nres_modadd(fn,get_mip()->one,fn);return *this;} + ZZn& operator--() + {nres_modsub(fn,get_mip()->one,fn);return *this;} + ZZn& operator+=(int i) + {ZZn inc=i; nres_modadd(fn,inc.fn,fn);return *this;} + ZZn& operator-=(int i) + {ZZn dec=i; nres_modsub(fn,dec.fn,fn); return *this;} + ZZn& operator+=(const ZZn& b) + {nres_modadd(fn,b.fn,fn); return *this;} + ZZn& operator-=(const ZZn& b) + {nres_modsub(fn,b.fn,fn); return *this;} + ZZn& operator*=(const ZZn& b) + {nres_modmult(fn,b.fn,fn); return *this;} + ZZn& operator*=(int i) + {nres_premult(fn,i,fn); return *this;} + + ZZn& negate() + {nres_negate(fn,fn); return *this;} + + BOOL iszero() const; + + operator Big() {Big c; redc(fn,c.getbig()); return c;} /* ZZn -> Big */ + friend big getbig(ZZn& z) {return z.fn;} + + ZZn& operator/=(const ZZn& b) {nres_moddiv(fn,b.fn,fn); return *this;} + ZZn& operator/=(int); + + friend ZZn operator-(const ZZn&); + friend ZZn operator+(const ZZn&,int); + friend ZZn operator+(int, const ZZn&); + friend ZZn operator+(const ZZn&, const ZZn&); + + friend ZZn operator-(const ZZn&, int); + friend ZZn operator-(int, const ZZn&); + friend ZZn operator-(const ZZn&, const ZZn&); + + friend ZZn operator*(const ZZn&,int); + friend ZZn operator*(int, const ZZn&); + friend ZZn operator*(const ZZn&, const ZZn&); + + friend ZZn operator/(const ZZn&, int); + friend ZZn operator/(int, const ZZn&); + friend ZZn operator/(const ZZn&, const ZZn&); + + friend BOOL operator==(const ZZn& b1,const ZZn& b2) + { if (mr_compare(b1.fn,b2.fn)==0) return TRUE; else return FALSE;} + friend BOOL operator!=(const ZZn& b1,const ZZn& b2) + { if (mr_compare(b1.fn,b2.fn)!=0) return TRUE; else return FALSE;} + + friend ZZn one(void); + friend ZZn pow( const ZZn&, const Big&); + friend ZZn pow( const ZZn&,int); + friend ZZn powl(const ZZn&, const Big&); + friend ZZn pow( const ZZn&, const Big&, const ZZn&, const Big&); + friend ZZn pow( int,ZZn *,Big *); + friend int jacobi(const ZZn&); +#ifndef MR_NO_RAND + friend ZZn randn(void); // random number < modulus +#endif + friend BOOL qr(const ZZn&); // test for quadratic residue + friend BOOL qnr(const ZZn&); // test for quadratic non-residue + friend ZZn getA(void); // get A parameter of elliptic curve + friend ZZn getB(void); // get B parameter of elliptic curve + + friend ZZn sqrt(const ZZn&); // only works if modulus is prime + friend ZZn luc( const ZZn& b1, const Big& b2, ZZn* b3=NULL) +{ZZn z; if (b3!=NULL) nres_lucas(b1.fn,b2.getbig(),b3->fn,z.fn); + else nres_lucas(b1.fn,b2.getbig(),z.fn,z.fn); + return z;} + + + big getzzn(void) const; + +#ifndef MR_NO_STANDARD_IO + friend ostream& operator<<(ostream&,const ZZn&); +#endif + + + ~ZZn() + { + // MR_ZERO_ZZN // slower but safer +#ifndef ZZNS + mr_free(fn); +#endif + } +}; +#ifndef MR_NO_RAND +extern ZZn randn(void); +#endif +extern ZZn getA(void); +extern ZZn getB(void); +extern ZZn one(void); + +#endif +