CvStrongRng::CvStrongRng(CSRNG_TYPE type) { const int size = ( AES_SECURITY/sizeof(mr_small) ); String random; char seed[size]; #ifdef WIN32 if ( m_bEnableEntropy ) { CvEntropyServer( m_aEntropyServerUrl ).Generate( CvEntropyServer::StringToAlgorithm( m_aEntropyAlgorithm ), CvEntropyServer::enEncoding_Raw, size, random ); memcpy((void*)seed, (void*)random.data(), size); } #elif defined __linux__ FILE* fdRandom; if ( m_bEnableEntropy ) { CvEntropyServer( m_aEntropyServerUrl ).Generate( CvEntropyServer::StringToAlgorithm( m_aEntropyAlgorithm ), CvEntropyServer::enEncoding_Raw, size, random ); fdRandom = fmemopen( (void*)random.data(), size, "r" ); } else { fdRandom = fopen( "/dev/urandom", "r" ); } if ( fdRandom == NULL ) { mr_berror( _MIPP_ MR_ERR_DEV_RANDOM ); } for ( int i = 0; i < size; ++i ) { int c = fgetc( fdRandom ); seed[i] = c; if ( c == -1 ) { mr_berror( _MIPP_ MR_ERR_DEV_RANDOM ); } } if ( fdRandom != NULL ) { fclose( fdRandom ); } #endif time_t tod; time( &tod ); strong_init( &m_csprng, size, seed, tod ); }
void mr_psub(_MIPD_ big x,big y,big z) { /* subtract two big numbers z=x-y * * where x and y are positive and x>y */ int i,lx,ly; mr_small borrow,pdiff; mr_small *gx,*gy,*gz; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif lx = (int)x->len; ly = (int)y->len; if (ly>lx) { mr_berror(_MIPP_ MR_ERR_NEG_RESULT); return; } if (y!=z) copy(x,z); else ly=lx; z->len=lx; gx=x->w; gy=y->w; gz=z->w; borrow=0; #ifndef MR_SIMPLE_BASE if (mr_mip->base==0) { #endif for (i=0;i<ly || borrow>0;i++) { /* subtract by columns */ if (i>lx) { mr_berror(_MIPP_ MR_ERR_NEG_RESULT); return; } pdiff=gx[i]-gy[i]-borrow; if (pdiff<gx[i]) borrow=0; else if (pdiff>gx[i]) borrow=1; gz[i]=pdiff; } #ifndef MR_SIMPLE_BASE } else for (i=0;i<ly || borrow>0;i++) { /* subtract by columns */ if (i>lx) { mr_berror(_MIPP_ MR_ERR_NEG_RESULT); return; } pdiff=gy[i]+borrow; borrow=0; if (gx[i]>=pdiff) pdiff=gx[i]-pdiff; else { /* set borrow */ pdiff=mr_mip->base+gx[i]-pdiff; borrow=1; } gz[i]=pdiff; } #endif mr_lzero(z); }
mr_small prepare_monty(_MIPD_ big n) { /* prepare Montgomery modulus */ #ifdef MR_KCM int nl; #endif #ifdef MR_PENTIUM mr_small ndash; mr_small base; mr_small magic=13835058055282163712.0; int control=0x1FFF; #endif #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return (mr_small)0; /* Is it set-up already? */ if (size(mr_mip->modulus)!=0) if (mr_compare(n,mr_mip->modulus)==0) return mr_mip->ndash; MR_IN(80) if (size(n)<=2) { mr_berror(_MIPP_ MR_ERR_BAD_MODULUS); MR_OUT return (mr_small)0; }
BOOL ebrick_init(_MIPD_ ebrick *B,big x,big y,big a,big b,big n,int window,int nb) { /* Uses Montgomery arithmetic internally * * (x,y) is the fixed base * * a,b and n are parameters and modulus of the curve * * window is the window size in bits and * * nb is the maximum number of bits in the multiplier */ int i,j,k,t,bp,len,bptr,is; epoint **table; epoint *w; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (nb<2 || window<1 || window>nb || mr_mip->ERNUM) return FALSE; t=MR_ROUNDUP(nb,window); if (t<2) return FALSE; MR_IN(115) #ifndef MR_ALWAYS_BINARY if (mr_mip->base != mr_mip->base2) { mr_berror(_MIPP_ MR_ERR_NOT_SUPPORTED); MR_OUT return FALSE; }
void fexp(_MIPD_ flash x,flash y) { /* calculates y=exp(x) */ int i,n,nsq,m,sqrn,op[5]; BOOL minus,rem; #ifndef MR_GENERIC_MT miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; if (size(x)==0) { convert(_MIPP_ 1,y); return; } copy(x,y); MR_IN(54) minus=FALSE; if (size(y)<0) { minus=TRUE; negate(y,y); } ftrunc(_MIPP_ y,y,mr_mip->w9); n=size(y); if (n==MR_TOOBIG) { mr_berror(_MIPP_ MR_ERR_FLASH_OVERFLOW); MR_OUT return; }
BOOL froot(_MIPD_ flash x,int n,flash w) { /* extract nth root of x - w=x^(1/n) using Newtons method */ BOOL minus,rn,rm,hack; int nm,dn,s,op[5]; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif copy(x,w); if (mr_mip->ERNUM || n==1) return TRUE; if (n==(-1)) { frecip(_MIPP_ w,w); return TRUE; } MR_IN(52) minus=FALSE; if (n<0) { minus=TRUE; n=(-n); } s=exsign(w); if (n%2==0 && s==MINUS) { mr_berror(_MIPP_ MR_ERR_NEG_ROOT); MR_OUT return FALSE; }
BOOL brick_init(_MIPD_ brick *b,big g,big n,int window,int nb) { /* Uses Montgomery arithmetic internally * * g is the fixed base for exponentiation * * n is the fixed modulus * * nb is the maximum number of bits in the exponent */ int i,j,k,t,bp,len,bptr; big *table; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (nb<2 || window<1 || window>nb || mr_mip->ERNUM) return FALSE; t=MR_ROUNDUP(nb,window); if (t<2) return FALSE; MR_IN(109) #ifndef MR_ALWAYS_BINARY if (mr_mip->base != mr_mip->base2) { mr_berror(_MIPP_ MR_ERR_NOT_SUPPORTED); MR_OUT return FALSE; }
BOOL double_inverse(_MIPD_ big n,big x,big y,big w,big z) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif MR_IN(146) mad(_MIPP_ x,w,w,n,n,mr_mip->w6); if (size(mr_mip->w6)==0) { mr_berror(_MIPP_ MR_ERR_DIV_BY_ZERO); MR_OUT return FALSE; }
void strong_bigdig(_MIPD_ csprng *rng,int n,int b,big x) { /* generate random number n digits long * * to "printable" base b */ #ifndef MR_GENERIC_MT miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(19) if (b<2 || b>256) { mr_berror(_MIPP_ MR_ERR_BASE_TOO_BIG); MR_OUT return; }
flash mirvar(_MIPD_ int iv) { /* initialize big/flash number */ flash x; int align; char *ptr; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return NULL; MR_IN(23); if (!(mr_mip->active)) { mr_berror(_MIPP_ MR_ERR_NO_MIRSYS); MR_OUT return NULL; }
BOOL multi_inverse(_MIPD_ int m,big *x,big n,big *w) { /* find w[i]=1/x[i] mod n, for i=0 to m-1 * * x and w MUST be distinct */ int i; #ifndef MR_GENERIC_MT miracl *mr_mip=get_mip(); #endif if (m==0) return TRUE; if (m<0) return FALSE; MR_IN(25) if (x==w) { mr_berror(_MIPP_ MR_ERR_BAD_PARAMETERS); MR_OUT return FALSE; }
BOOL crt_init(_MIPD_ big_chinese *c,int r,big *moduli) { /* calculate CRT constants */ int i,j,k; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (r<2 || mr_mip->ERNUM) return FALSE; for (i=0;i<r;i++) if (size(moduli[i])<2) return FALSE; MR_IN(73) c->M=(big *)mr_alloc(_MIPP_ r,sizeof(big)); if (c->M==NULL) { mr_berror(_MIPP_ MR_ERR_OUT_OF_MEMORY); MR_OUT return FALSE; }
void expint(_MIPD_ int b,int n,big x) { /* sets x=b^n */ unsigned int bit,un; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; convert(_MIPP_ 1,x); if (n==0) return; MR_IN(50) if (n<0) { mr_berror(_MIPP_ MR_ERR_NEG_POWER); MR_OUT return; }
void *mr_alloc(_MIPD_ int num,int size) { char *p; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip==NULL) { p=(char *)calloc(num,size); return (void *)p; } if (mr_mip->ERNUM) return NULL; p=(char *)calloc(num,size); if (p==NULL) mr_berror(_MIPP_ MR_ERR_OUT_OF_MEMORY); return (void *)p; }
double fdsize(_MIPD_ flash w) { /* express flash number as double. */ int i,s,en,ed; double n,d,b,BIGGEST; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM || size(w)==0) return (0.0); MR_IN(11) BIGGEST=pow(2.0,(double)(1<<(MR_EBITS-4))); mr_mip->EXACT=FALSE; n=0.0; d=0.0; if (mr_mip->base==0) b=pow(2.0,(double)MIRACL); else b=(double)mr_mip->base; numer(_MIPP_ w,mr_mip->w1); s=exsign(mr_mip->w1); insign(PLUS,mr_mip->w1); en=(int)mr_mip->w1->len; for (i=0;i<en;i++) n=(double)mr_mip->w1->w[i]+(n/b); denom(_MIPP_ w,mr_mip->w1); ed=(int)mr_mip->w1->len; for (i=0;i<ed;i++) d=(double)mr_mip->w1->w[i]+(d/b); n/=d; while (en!=ed) { if (en>ed) { ed++; if (BIGGEST/b<n) { mr_berror(_MIPP_ MR_ERR_DOUBLE_FAIL); MR_OUT return (0.0); } n*=b; }
void mround(_MIPD_ big num,big den,flash z) { /* reduces and rounds the fraction num/den into z */ int s; #ifndef MR_GENERIC_MT miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; if (size(num)==0) { zero(z); return; } MR_IN(34) if (size(den)==0) { mr_berror(_MIPP_ MR_ERR_FLASH_OVERFLOW); MR_OUT return; }
void expb2(_MIPD_ int n,big x) { /* sets x=2^n */ int r,p; #ifndef MR_ALWAYS_BINARY int i; #endif #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; convert(_MIPP_ 1,x); if (n==0) return; MR_IN(149) if (n<0) { mr_berror(_MIPP_ MR_ERR_NEG_POWER); MR_OUT return; }
int instr(_MIPD_ flash x,char *string) { /* input a big number * * returns length in digits */ int i,ipt,n,s,e; int ch; #ifdef MR_FLASH BOOL frac; #endif #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return 0; MR_IN(76) if (mr_mip->apbase==0 || mr_mip->apbase>256) { mr_berror(_MIPP_ MR_ERR_BASE_TOO_BIG); MR_OUT return 0; }
void gprime(_MIPD_ int maxp) { /* generate all primes less than maxp into global PRIMES */ char *sv; int pix,i,k,prime; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; if (maxp<=0) { if (mr_mip->PRIMES!=NULL) mr_free(mr_mip->PRIMES); mr_mip->PRIMES=NULL; return; } MR_IN(70) if (maxp>=MR_TOOBIG) { mr_berror(_MIPP_ MR_ERR_TOO_BIG); MR_OUT return; }
static void mr_select(_MIPD_ big x,int d,big y,big z) { /* perform required add or subtract operation */ int sx,sy,sz,jf,xgty; #ifdef MR_FLASH if (mr_notint(x) || mr_notint(y)) { mr_berror(_MIPP_ MR_ERR_INT_OP); return; } #endif sx=exsign(x); sy=exsign(y); sz=0; x->len&=MR_OBITS; /* force operands to be positive */ y->len&=MR_OBITS; xgty=mr_compare(x,y); jf=(1+sx)+(1+d*sy)/2; switch (jf) { /* branch according to signs of operands */ case 0: if (xgty>=0) mr_padd(_MIPP_ x,y,z); else mr_padd(_MIPP_ y,x,z); sz=MINUS; break; case 1: if (xgty<=0) { mr_psub(_MIPP_ y,x,z); sz=PLUS; } else { mr_psub(_MIPP_ x,y,z); sz=MINUS; } break; case 2: if (xgty>=0) { mr_psub(_MIPP_ x,y,z); sz=PLUS; } else { mr_psub(_MIPP_ y,x,z); sz=MINUS; } break; case 3: if (xgty>=0) mr_padd(_MIPP_ x,y,z); else mr_padd(_MIPP_ y,x,z); sz=PLUS; break; } if (sz<0) z->len^=MR_MSBIT; /* set sign of result */ if (x!=z && sx<0) x->len^=MR_MSBIT; /* restore signs to operands */ if (y!=z && y!=x && sy<0) y->len^=MR_MSBIT; }
void mr_padd(_MIPD_ big x,big y,big z) { /* add two big numbers, z=x+y where * * x and y are positive */ int i,lx,ly,lz,la; mr_small carry,psum; mr_small *gx,*gy,*gz; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif lx = (int)x->len; ly = (int)y->len; if (ly>lx) { lz=ly; la=lx; if (x!=z) copy(y,z); else la=ly; } else { lz=lx; la=ly; if (y!=z) copy(x,z); else la=lx; } carry=0; z->len=lz; gx=x->w; gy=y->w; gz=z->w; if (lz<mr_mip->nib || !mr_mip->check) z->len++; #ifndef MR_SIMPLE_BASE if (mr_mip->base==0) { #endif for (i=0;i<la;i++) { /* add by columns to length of the smaller number */ psum=gx[i]+gy[i]+carry; if (psum>gx[i]) carry=0; else if (psum<gx[i]) carry=1; gz[i]=psum; } for (;i<lz && carry>0;i++ ) { /* add by columns to the length of larger number (if there is a carry) */ psum=gx[i]+gy[i]+carry; if (psum>gx[i]) carry=0; else if (psum<gx[i]) carry=1; gz[i]=psum; } if (carry) { /* carry left over - possible overflow */ if (mr_mip->check && i>=mr_mip->nib) { mr_berror(_MIPP_ MR_ERR_OVERFLOW); return; } gz[i]=carry; } #ifndef MR_SIMPLE_BASE } else { for (i=0;i<la;i++) { /* add by columns */ psum=gx[i]+gy[i]+carry; carry=0; if (psum>=mr_mip->base) { /* set carry */ carry=1; psum-=mr_mip->base; } gz[i]=psum; } for (;i<lz && carry>0;i++) { psum=gx[i]+gy[i]+carry; carry=0; if (psum>=mr_mip->base) { /* set carry */ carry=1; psum-=mr_mip->base; } gz[i]=psum; } if (carry) { /* carry left over - possible overflow */ if (mr_mip->check && i>=mr_mip->nib) { mr_berror(_MIPP_ MR_ERR_OVERFLOW); return; } gz[i]=carry; } } #endif if (gz[z->len-1]==0) z->len--; }