void zzn4_from_int(_MIPD_ int i,zzn4 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(FUNC_BASE+0) if (i==1) { copy(mr_mip->one,w->a.a); w->unitary=TRUE; } else { convert(_MIPP_ i,mr_mip->w1); nres(_MIPP_ mr_mip->w1,(w->a).a); w->unitary=FALSE; } zero((w->a).b); zero((w->b).a); zero((w->b).b); 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 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 }
mr_small normalise(_MIPD_ big x,big y) { /* normalise divisor */ mr_small norm,r; #ifdef MR_FP mr_small dres; #endif int len; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif MR_IN(4) if (x!=y) copy(x,y); len=(int)(y->len&MR_OBITS); #ifndef MR_SIMPLE_BASE if (mr_mip->base==0) { #endif #ifndef MR_NOFULLWIDTH if ((r=y->w[len-1]+1)==0) norm=1; #ifdef MR_NOASM else norm=(mr_small)(((mr_large)1 << MIRACL)/r); #else else norm=muldvm((mr_small)1,(mr_small)0,r,&r); #endif if (norm!=1) mr_pmul(_MIPP_ y,norm,y); #endif #ifndef MR_SIMPLE_BASE }
void uconvert(_MIPD_ unsigned int n ,big x) { /* convert integer n to big number format */ int m; #ifdef MR_FP mr_small dres; #endif #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif zero(x); if (n==0) return; m=0; if (mr_mip->base==0) { #ifndef MR_NOFULLWIDTH #if MR_IBITS > MIRACL while (n>0) { x->w[m++]=(mr_small)(n%((mr_small)1<<(MIRACL))); n/=((mr_small)1<<(MIRACL)); } #else x->w[m++]=(mr_small)n; #endif #endif } else while (n>0) { x->w[m++]=MR_REMAIN((mr_small)n,mr_mip->base); n/=mr_mip->base; } x->len=(m); }
int G2::spill(char *& bytes) { int i,j,n=(1<<WINDOW_SIZE); int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); int len=n*2*bytes_per_big; Big x,y; if (mtable==NULL) return 0; bytes=new char[len]; for (i=j=0;i<n;i++) { mtable[i].get(x,y); to_binary(x,bytes_per_big,&bytes[j],TRUE); x=from_binary(bytes_per_big,&bytes[j]); j+=bytes_per_big; to_binary(y,bytes_per_big,&bytes[j],TRUE); j+=bytes_per_big; } delete [] mtable; mtable=NULL; return len; }
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 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 fexp(_MIPD_ flash x,flash y) { /* calculates y=exp(x) */ int i,n,nsq,m,sqrn,op[5]; BOOL minus,rem; #ifdef MR_OS_THREADS 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; negify(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 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 G2::restore(char *bytes) { int i,j,n=(1<<WINDOW_SIZE); int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); int len=n*2*bytes_per_big; Big x,y,B; if (mtable!=NULL) return; mtable=new ECn[1<<WINDOW_SIZE]; B=getB(); B=-B; ecurve((Big)-3,B,get_modulus(),MR_PROJECTIVE); // move to twist for (i=j=0;i<n;i++) { x=from_binary(bytes_per_big,&bytes[j]); j+=bytes_per_big; y=from_binary(bytes_per_big,&bytes[j]); j+=bytes_per_big; mtable[i].set(x,y); } B=-B; ecurve((Big)-3,B,get_modulus(),MR_PROJECTIVE); // move back delete [] bytes; }
void PFC::restore(char * bytes,G2& w) { int i,j,len,m; int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); Big n; Big X=*x; ZZn a,b,c; if (w.ptable!=NULL) return; n=X/7; m=2*(bits(n)+ham(n)+1); len=m*3*bytes_per_big; w.ptable=new ZZn3[m]; for (i=j=0;i<m;i++) { a=from_binary(bytes_per_big,&bytes[j]); j+=bytes_per_big; b=from_binary(bytes_per_big,&bytes[j]); j+=bytes_per_big; c=from_binary(bytes_per_big,&bytes[j]); j+=bytes_per_big; w.ptable[i].set(a,b,c); } for (i=0;i<len;i++) bytes[i]=0; delete [] bytes; }
Big H1(char *string) { // Hash a zero-terminated string to a number < modulus Big h,p; char s[HASH_LEN]; int i,j,M; sha256 sh; shs256_init(&sh); for (i=0;;i++) { if (string[i]==0) break; shs256_process(&sh,string[i]); } shs256_hash(&sh,s); M=get_mip()->M; h=1; j=0; i=1; forever { h*=256; if (j==HASH_LEN) {h+=i++; j=0;} else h+=s[j++]; if (h>=p) break; } while (bits(h)<M) h*=257; while (bits(h)>=M) h/=2; return h; }
void G2::restore(char *bytes) { int i,j,n=(1<<WINDOW_SIZE); int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); int len=n*6*bytes_per_big; ZZn3 x,y; ZZn a,b,c; if (mtable!=NULL) return; mtable=new ECn3[1<<WINDOW_SIZE]; for (i=j=0;i<n;i++) { a=from_binary(bytes_per_big,&bytes[j]); j+=bytes_per_big; b=from_binary(bytes_per_big,&bytes[j]); j+=bytes_per_big; c=from_binary(bytes_per_big,&bytes[j]); j+=bytes_per_big; x.set(a,b,c); a=from_binary(bytes_per_big,&bytes[j]); j+=bytes_per_big; b=from_binary(bytes_per_big,&bytes[j]); j+=bytes_per_big; c=from_binary(bytes_per_big,&bytes[j]); j+=bytes_per_big; y.set(a,b,c); mtable[i].set(x,y); } delete [] bytes; }
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 cofactor(ECn3 &S,Big &x, ZZn2& X) { // S=Phi(2xP)+phi^2(2xP) ZZn6 X1,X2,Y1,Y2; ZZn3 Sx,Sy,T; ECn3 S2; int qnr=get_mip()->cnr; S*=x; S+=S; // hard work done here S.get(Sx,Sy); // untwist Sx=Sx/qnr; Sy=tx(Sy); Sy=Sy/(qnr*qnr); X1=shuffle(Sx,(ZZn3)0); Y1=shuffle((ZZn3)0,Sy); X1.powq(X); Y1.powq(X); X2=X1; Y2=Y1; X2.powq(X); Y2.powq(X); unshuffle(X1,Sx,T); unshuffle(Y1,T,Sy); // twist Sx=qnr*Sx; Sy=txd(Sy*qnr*qnr); S.set(Sx,Sy); unshuffle(X2,Sx,T); unshuffle(Y2,T,Sy); //twist (again, like we did last summer...) Sx=qnr*Sx; Sy=txd(Sy*qnr*qnr); S2.set(Sx,Sy); S+=S2; }
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 }
int PFC::spill(G2& w,char *& bytes) { int i,j,len,m; int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); ZZn a,b,c; Big X=*x; if (w.ptable==NULL) return 0; m=2*(bits(X)-2+ham(X)); len=m*3*bytes_per_big; bytes=new char[len]; for (i=j=0;i<m;i++) { w.ptable[i].get(a,b,c); to_binary((Big)a,bytes_per_big,&bytes[j],TRUE); j+=bytes_per_big; to_binary((Big)b,bytes_per_big,&bytes[j],TRUE); j+=bytes_per_big; to_binary((Big)c,bytes_per_big,&bytes[j],TRUE); j+=bytes_per_big; } delete [] w.ptable; w.ptable=NULL; return len; }
void fincr(_MIPD_ flash x,int n,int d,flash y) { /* increment x by small fraction n/d - y=x+(n/d) */ #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(43) if (d<0) { d=(-d); n=(-n); } numer(_MIPP_ x,mr_mip->w1); denom(_MIPP_ x,mr_mip->w2); mr_mip->check=OFF; premult(_MIPP_ mr_mip->w1,d,mr_mip->w5); premult(_MIPP_ mr_mip->w2,d,mr_mip->w6); premult(_MIPP_ mr_mip->w2,n,mr_mip->w0); add(_MIPP_ mr_mip->w5,mr_mip->w0,mr_mip->w5); mr_mip->check=ON; if (d==1 && fit(mr_mip->w5,mr_mip->w6,mr_mip->nib)) fpack(_MIPP_ mr_mip->w5,mr_mip->w6,y); else mround(_MIPP_ mr_mip->w5,mr_mip->w6,y); MR_OUT }
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 ecap(ECn& P,ECn3& Q,Big& x,ZZn2 &X,ZZn6& res) { BOOL Ok; ECn PP=P; ZZn3 Qx,Qy; int qnr=get_mip()->cnr; normalise(PP); Q.get(Qx,Qy); // untwist Qx=Qx/qnr; Qy=tx(Qy); Qy=Qy/(qnr*qnr); #ifdef MR_COUNT_OPS fpc=fpa=fpx=0; #endif Ok=fast_tate_pairing(PP,Qx,Qy,x,X,res); #ifdef MR_COUNT_OPS printf("After pairing fpc= %d fpa= %d fpx= %d\n",fpc,fpa,fpx); fpa=fpc=fpx=0; #endif if (Ok) return TRUE; return FALSE; }
int G2::spill(char *& bytes) { int i,j,n=(1<<WINDOW_SIZE); int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); int len=n*6*bytes_per_big; ZZn3 x,y; ZZn a,b,c; if (mtable==NULL) return 0; bytes=new char[len]; for (i=j=0;i<n;i++) { mtable[i].get(x,y); x.get(a,b,c); to_binary((Big)a,bytes_per_big,&bytes[j],TRUE); j+=bytes_per_big; to_binary((Big)b,bytes_per_big,&bytes[j],TRUE); j+=bytes_per_big; to_binary((Big)c,bytes_per_big,&bytes[j],TRUE); j+=bytes_per_big; y.get(a,b,c); to_binary((Big)a,bytes_per_big,&bytes[j],TRUE); j+=bytes_per_big; to_binary((Big)b,bytes_per_big,&bytes[j],TRUE); j+=bytes_per_big; to_binary((Big)c,bytes_per_big,&bytes[j],TRUE); j+=bytes_per_big; } delete [] mtable; mtable=NULL; return len; }
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; }
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); }
void zzn3_set(_MIPD_ int cnr,big sru) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif mr_mip->cnr=cnr; nres(_MIPP_ sru,mr_mip->sru); }
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 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 kcm_square(_MIPD_ int n,big x,big z) { /* n *must* be MR_KCM*2^m for m>=0 */ #ifndef MR_GENERIC_MT miracl *mr_mip=get_mip(); #endif zero(mr_mip->w0); mr_karsqr(n,&mr_mip->w7[1],&x[1],&mr_mip->w0[1]); mr_mip->w0[0]=mr_mip->w7[0]=2*n; copy(mr_mip->w0,z); }
void kill_monty(_MIPDO_ ) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif zero(mr_mip->modulus); #ifdef MR_KCM zero(mr_mip->big_ndash); #endif }