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 zzn2_qr(_MIPD_ zzn2 *u) { int j; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return FALSE; if (zzn2_iszero(u)) return TRUE; if (size(u->b)==0) return TRUE; if (mr_mip->qnr==-1 && size(u->a)==0) return TRUE; MR_IN(203) nres_modmult(_MIPP_ u->b,u->b,mr_mip->w1); if (mr_mip->qnr==-2) nres_modadd(_MIPP_ mr_mip->w1,mr_mip->w1,mr_mip->w1); nres_modmult(_MIPP_ u->a,u->a,mr_mip->w2); nres_modadd(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w1); redc(_MIPP_ mr_mip->w1,mr_mip->w1); j=jack(_MIPP_ mr_mip->w1,mr_mip->modulus); MR_OUT if (j==1) return TRUE; return FALSE; }
void strong_bigrand(_MIPD_ csprng *rng,big w,big x) { int i, m; mr_small r; unsigned int ran; unsigned int ch; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(20) m = 0; zero(mr_mip->w1); do { m++; mr_mip->w1->len=m; for (r = 0, i = 0; i < sizeof(mr_small); i++) { ch=(unsigned char)strong_rng(rng); ran=ch; r = (r << 8) ^ ran; } if (mr_mip->base==0) mr_mip->w1->w[m-1]=r; else mr_mip->w1->w[m-1]=MR_REMAIN(r,mr_mip->base); } while (mr_compare(mr_mip->w1,w)<0); mr_lzero(mr_mip->w1); divide(_MIPP_ mr_mip->w1,w,w); copy(mr_mip->w1,x); MR_OUT }
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; }
void zzn3_div2(_MIPD_ zzn3 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(188) copy(w->a,mr_mip->w1); if (remain(_MIPP_ mr_mip->w1,2)!=0) add(_MIPP_ mr_mip->w1,mr_mip->modulus,mr_mip->w1); subdiv(_MIPP_ mr_mip->w1,2,mr_mip->w1); copy(mr_mip->w1,w->a); copy(w->b,mr_mip->w1); if (remain(_MIPP_ mr_mip->w1,2)!=0) add(_MIPP_ mr_mip->w1,mr_mip->modulus,mr_mip->w1); subdiv(_MIPP_ mr_mip->w1,2,mr_mip->w1); copy(mr_mip->w1,w->b); copy(w->c,mr_mip->w1); if (remain(_MIPP_ mr_mip->w1,2)!=0) add(_MIPP_ mr_mip->w1,mr_mip->modulus,mr_mip->w1); subdiv(_MIPP_ mr_mip->w1,2,mr_mip->w1); copy(mr_mip->w1,w->c); MR_OUT }
void frand(_MIPD_ flash x) { /* generates random flash number 0<x<1 */ int i; #ifdef MR_FP mr_small dres; #endif #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(46) zero(mr_mip->w6); mr_mip->w6->len=mr_mip->nib; for (i=0;i<mr_mip->nib;i++) { /* generate a full width random number */ if (mr_mip->base==0) mr_mip->w6->w[i]=brand(_MIPPO_ ); else mr_mip->w6->w[i]=MR_REMAIN(brand(_MIPPO_ ),mr_mip->base); } mr_mip->check=OFF; bigrand(_MIPP_ mr_mip->w6,mr_mip->w5); mr_mip->check=ON; mround(_MIPP_ mr_mip->w5,mr_mip->w6,x); MR_OUT }
void zzn4_inv(_MIPD_ zzn4 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif zzn2 t1,t2; if (mr_mip->ERNUM) return; if (w->unitary) { zzn4_conj(_MIPP_ w,w); return; } MR_IN(FUNC_BASE+10) t1.a=mr_mip->w8; t1.b=mr_mip->w9; t2.a=mr_mip->w10; t2.b=mr_mip->w11; zzn2_mul(_MIPP_ &(w->a),&(w->a),&t1); zzn2_mul(_MIPP_ &(w->b),&(w->b),&t2); zzn2_txx(_MIPP_ &t2); zzn2_sub(_MIPP_ &t1,&t2,&t1); zzn2_inv(_MIPP_ &t1); zzn2_mul(_MIPP_ &(w->a),&t1,&(w->a)); zzn2_negate(_MIPP_ &t1,&t1); zzn2_mul(_MIPP_ &(w->b),&t1,&(w->b)); MR_OUT }
void nres_powltr(_MIPD_ int x,big y,big w) { /* calculates w=x^y mod z using Left to Right Method */ /* uses only n^2 modular squarings, because x is small */ /* Note: x is NOT an nresidue */ int i,nb; #ifndef MR_GENERIC_MT miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; copy(y,mr_mip->w1); MR_IN(86) zero(w); if (x==0) { if (size(mr_mip->w1)==0) { /* 0^0 = 1 */ convert(_MIPP_ 1,w); nres(_MIPP_ w,w); } MR_OUT return; } convert(_MIPP_ 1,w); nres(_MIPP_ w,w); if (size(mr_mip->w1)==0) { MR_OUT return; }
void zzn4_mul(_MIPD_ zzn4 *x,zzn4 *y,zzn4 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif zzn2 t1,t2,t3; if (mr_mip->ERNUM) return; if (x==y) {zzn4_sqr(_MIPP_ x,w); return; } MR_IN(FUNC_BASE+9) t1.a=mr_mip->w12; t1.b=mr_mip->w13; t2.a=mr_mip->w8; t2.b=mr_mip->w9; t3.a=mr_mip->w10; t3.b=mr_mip->w11; zzn2_copy(&(x->a),&t1); zzn2_copy(&(x->b),&t2); zzn2_mul(_MIPP_ &t1,&(y->a),&t1); /* t1= x->a * y->a */ zzn2_mul(_MIPP_ &t2,&(y->b),&t2); /* t2 = x->b * y->b */ zzn2_copy(&(y->a),&t3); zzn2_add(_MIPP_ &t3,&(y->b),&t3); /* y->a + y->b */ zzn2_add(_MIPP_ &(x->b),&(x->a),&(w->b)); /* x->a + x->b */ zzn2_mul(_MIPP_ &(w->b),&t3,&(w->b)); /* t3= (x->a + x->b)*(y->a + y->b) */ zzn2_sub(_MIPP_ &(w->b),&t1,&(w->b)); zzn2_sub(_MIPP_ &(w->b),&t2,&(w->b)); /* w->b = t3-(t1+t2) */ zzn2_copy(&t1,&(w->a)); zzn2_txx(_MIPP_ &t2); zzn2_add(_MIPP_ &(w->a),&t2,&(w->a)); /* w->a = t1+tx(t2) */ if (x->unitary && y->unitary) w->unitary=TRUE; else w->unitary=FALSE; MR_OUT }
void sftbit(_MIPD_ big x,int n,big z) { /* shift x by n bits */ int m; mr_small sm; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; copy(x,z); if (n==0) return; MR_IN(47) m=mr_abs(n); sm=mr_shiftbits((mr_small)1,m%mr_mip->lg2b); if (n>0) { /* shift left */ #ifndef MR_ALWAYS_BINARY if (mr_mip->base==mr_mip->base2) { #endif mr_shift(_MIPP_ z,n/mr_mip->lg2b,z); mr_pmul(_MIPP_ z,sm,z); #ifndef MR_ALWAYS_BINARY } else { expb2(_MIPP_ m,mr_mip->w1); multiply(_MIPP_ z,mr_mip->w1,z); } #endif } else { /* shift right */ #ifndef MR_ALWAYS_BINARY if (mr_mip->base==mr_mip->base2) { #endif mr_shift(_MIPP_ z,n/mr_mip->lg2b,z); #ifdef MR_FP_ROUNDING mr_sdiv(_MIPP_ z,sm,mr_invert(sm),z); #else mr_sdiv(_MIPP_ z,sm,z); #endif #ifndef MR_ALWAYS_BINARY } else { expb2(_MIPP_ m,mr_mip->w1); divide(_MIPP_ z,mr_mip->w1,z); } #endif } MR_OUT }
void zzn3_ssub(_MIPD_ zzn3 *x,big y,zzn3 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(183) nres_modsub(_MIPP_ x->a,y,w->a); MR_OUT }
void zzn2_sadd(_MIPD_ zzn2 *x,big y,zzn2 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(169) nres_modadd(_MIPP_ x->a,y,w->a); MR_OUT }
void zzn4_powq(_MIPD_ zzn2 *fr,zzn4 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif MR_IN(FUNC_BASE+12) zzn2_conj(_MIPP_ &(w->a),&(w->a)); zzn2_conj(_MIPP_ &(w->b),&(w->b)); zzn2_mul(_MIPP_ &(w->b),fr,&(w->b)); MR_OUT }
void zzn4_sadd(_MIPD_ zzn4 *x,zzn2 *y,zzn4 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(FUNC_BASE+4) zzn2_add(_MIPP_ &(x->a),y,&(w->a)); w->unitary=FALSE; MR_OUT }
void zzn4_negate(_MIPD_ zzn4 *x,zzn4 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(FUNC_BASE+1) zzn4_copy(x,w); zzn2_negate(_MIPP_ &(w->a),&(w->a)); zzn2_negate(_MIPP_ &(w->b),&(w->b)); MR_OUT }
void zzn3_sub(_MIPD_ zzn3 *x,zzn3 *y,zzn3 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(182) nres_modsub(_MIPP_ x->a,y->a,w->a); nres_modsub(_MIPP_ x->b,y->b,w->b); nres_modsub(_MIPP_ x->c,y->c,w->c); MR_OUT }
void zzn3_from_big(_MIPD_ big x, zzn3 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(177) nres(_MIPP_ x,w->a); zero(w->b); zero(w->c); MR_OUT }
void zzn4_imul(_MIPD_ zzn4 *x,int y,zzn4 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(FUNC_BASE+14) zzn2_imul(_MIPP_ &(x->a),y,&(w->a)); zzn2_imul(_MIPP_ &(x->b),y,&(w->b)); MR_OUT }
void zzn2_from_bigs(_MIPD_ big x,big y, zzn2 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(166) nres(_MIPP_ x,w->a); nres(_MIPP_ y,w->b); MR_OUT }
int invmodp(_MIPD_ big x,big y,big z) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif int gcd; MR_IN(213); gcd=xgcd(_MIPP_ x,y,z,z,z); MR_OUT return gcd; }
void zzn4_from_big(_MIPD_ big x, zzn4 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(FUNC_BASE+16) zzn2_from_big(_MIPP_ x,&(w->a)); zzn2_zero(&(w->b)); MR_OUT }
void zzn2_negate(_MIPD_ zzn2 *x,zzn2 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(157) zzn2_copy(x,w); nres_negate(_MIPP_ w->a,w->a); nres_negate(_MIPP_ w->b,w->b); MR_OUT }
void zzn2_div5(_MIPD_ zzn2 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(209) nres_div5(_MIPP_ w->a,w->a); nres_div5(_MIPP_ w->b,w->b); MR_OUT }
void add(_MIPD_ big x,big y,big z) { /* add two signed big numbers together z=x+y */ #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(27) mr_select(_MIPP_ x,PLUS,y,z); MR_OUT }
void subtract(_MIPD_ big x,big y,big z) { /* subtract two big signed numbers z=x-y */ #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(28) mr_select(_MIPP_ x,MINUS,y,z); MR_OUT }
void zzn2_from_int(_MIPD_ int i,zzn2 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(156) convert(_MIPP_ i,mr_mip->w1); nres(_MIPP_ mr_mip->w1,w->a); zero(w->b); MR_OUT }
void zzn2_sub(_MIPD_ zzn2 *x,zzn2 *y,zzn2 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; #ifdef MR_COUNT_OPS fpaq++; #endif MR_IN(160) nres_modsub(_MIPP_ x->a,y->a,w->a); nres_modsub(_MIPP_ x->b,y->b,w->b); MR_OUT }
void fmodulo(_MIPD_ flash x,flash y,flash z) { /* sets z=x mod y */ #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(89) fdiv(_MIPP_ x,y,mr_mip->w8); ftrunc(_MIPP_ mr_mip->w8,mr_mip->w8,mr_mip->w8); fmul(_MIPP_ mr_mip->w8,y,mr_mip->w8); fsub(_MIPP_ x,mr_mip->w8,z); MR_OUT }
void zzn3_powq(_MIPD_ zzn3 *x,zzn3 *w) { /* sru - precalculated sixth root of unity */ #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif MR_IN(178) zzn3_copy(x,w); nres_modmult(_MIPP_ mr_mip->sru,mr_mip->sru,mr_mip->w1); /* cube root of unity */ nres_modmult(_MIPP_ w->b,mr_mip->w1,w->b); nres_modmult(_MIPP_ w->c,mr_mip->w1,w->c); nres_modmult(_MIPP_ w->c,mr_mip->w1,w->c); MR_OUT }
BOOL zzn2_isunity(_MIPD_ zzn2 *x) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM || size(x->b)!=0) return FALSE; MR_IN(155) redc(_MIPP_ x->a,mr_mip->w1); MR_OUT if (size(mr_mip->w1)==1) return TRUE; return FALSE; }