/*************************************************************************** * 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; } //friend ZZn luc( const ZZn&, const Big&, ZZn* b3=NULL); 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