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 }
int main () { /* hailstone numbers */ int iter,r; big x,y,mx; mirsys(400,10); x=mirvar(0); y=mirvar(0); mx=mirvar(0); iter=0; printf("number = \n"); innum(x,stdin); do { /* main loop */ if (compare(x,mx)>0) copy(x,mx); r=subdiv(x,2,y); if (r!=0) { /* what goes up ... */ premult(x,3,x); incr(x,1,x); } /* ... must come down */ else copy(y,x); otnum(x,stdout); iter++; } while (size(x)!=1); printf("path length = %d \n",iter); printf("maximum = \n"); otnum(mx,stdout); return 0; }
static gx_color_index dca_map_rgb_alpha_color(gx_device * dev, gx_color_value red, gx_color_value green, gx_color_value blue, gx_color_value alpha) { /* * We work exclusively with premultiplied color values, so we * have to premultiply the color components by alpha here. */ byte a = gx_color_value_to_byte(alpha); #define premult_(c)\ (((c) * a + gx_max_color_value / 2) / gx_max_color_value) #ifdef PREMULTIPLY_TOWARDS_WHITE byte bias = ~a; # define premult(c) (premult_(c) + bias) #else # define premult(c) premult_(c) #endif gx_color_index color; if (dev->color_info.num_components == 1) { uint lum = (red * lum_red_weight + green * lum_green_weight + blue * lum_blue_weight + lum_all_weights / 2) / lum_all_weights; if (a == 0xff) color = gx_color_value_to_byte(lum); else /* Premultiplication is necessary. */ color = premult(lum); } else { if (a == 0xff) color = ((uint) gx_color_value_to_byte(red) << 16) + ((uint) gx_color_value_to_byte(green) << 8) + gx_color_value_to_byte(blue); else /* Premultiplication is necessary. */ color = (premult(red) << 16) + (premult(green) << 8) + premult(blue); } #undef premult return (color << 8) + a; }
void fpmul(_MIPD_ flash x,int n,int d,flash y) { /* multiply x by small fraction n/d - y=x*n/d */ int r,g; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; if (n==0 || size(x)==0) { zero(y); return; } if (n==d) { copy(x,y); return; } MR_IN(42) if (d<0) { d=(-d); n=(-n); } numer(_MIPP_ x,mr_mip->w1); denom(_MIPP_ x,mr_mip->w2); r=subdiv(_MIPP_ mr_mip->w1,d,mr_mip->w3); g=igcd(d,r); r=subdiv(_MIPP_ mr_mip->w2,n,mr_mip->w3); g*=igcd(n,r); mr_mip->check=OFF; premult(_MIPP_ mr_mip->w1,n,mr_mip->w5); premult(_MIPP_ mr_mip->w2,d,mr_mip->w6); subdiv(_MIPP_ mr_mip->w5,g,mr_mip->w5); subdiv(_MIPP_ mr_mip->w6,g,mr_mip->w6); mr_mip->check=ON; if (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 }
void iterate(big x,big q,big r,big a,big b) { /* apply Pollards random mapping */ if (compare(x,lim1)<0) { mad(x,q,q,p,p,x); incr(a,1,a); if (compare(a,order)==0) zero(a); return; } if (compare(x,lim2)<0) { mad(x,x,x,p,p,x); premult(a,2,a); if (compare(a,order)>=0) subtract(a,order,a); premult(b,2,b); if (compare(b,order)>=0) subtract(b,order,b); return; } mad(x,r,r,p,p,x); incr(b,1,b); if (compare(b,order)==0) zero(b); }
int knuth(int mm,int *epr,big N,big D) { /* Input number to be factored N and find best multiplier k * * for use over a factor base epr[] of size mm. Set D=k.N. */ double dp,fks,top; BOOL found; int i,j,bk,nk,kk,r,p; static int K[]={0,1,2,3,5,6,7,10,11,13,14,15,17,0}; top=(-10.0e0); found=FALSE; nk=0; bk=0; epr[0]=1; epr[1]=2; do { /* search for best Knuth-Schroepel multiplier */ kk=K[++nk]; if (kk==0) { /* finished */ kk=K[bk]; found=TRUE; } premult(N,kk,D); fks=log(2.0e0)/(2.0e0); r=remain(D,8); if (r==1) fks*=(4.0e0); if (r==5) fks*=(2.0e0); fks-=log((double)kk)/(2.0e0); i=0; j=1; while (j<mm) { /* select small primes */ p=mip->PRIMES[++i]; r=remain(D,p); if (spmd(r,(p-1)/2,p)<=1) { /* use only if Jacobi symbol = 0 or 1 */ epr[++j]=p; dp=(double)p; if (kk%p==0) fks+=log(dp)/dp; else fks+=2*log(dp)/(dp-1.0e0); } } if (fks>top) { /* find biggest fks */ top=fks; bk=nk; } } while (!found); return kk; }
void SamplePointFromBytes(EC2 *point, BYTE* input, int inbytelen) { Big bigtmp; bytes_to_big (inbytelen, (const char*) input, bigtmp.getbig());//(bigtmp, inbytelen, input); premult(bigtmp.getbig(), MAXMSGSAMPLE, bigtmp.getbig()); for(int i = 0; i < MAXMSGSAMPLE; i++) { *point = EC2(bigtmp, 0); if(!point_at_infinity(point->get_point())) return; *point = EC2(bigtmp, 1); if(!point_at_infinity(point->get_point())) return; incr(bigtmp.getbig(), 1, bigtmp.getbig()); } cerr << "Error while sampling point, exiting!" << endl; exit(0); }
void getprime(char *fname) { /* get prime details from file */ FILE *fp; int i; fp=fopen(fname,"r"); fscanf(fp,"%d\n",&np); for (i=0;i<np;i++) cinnum(pp[i],fp); fclose(fp); convert(1,p1); for (i=0;i<np;i++) multiply(p1,pp[i],p1); incr(p1,1,p); if (!isprime(p)) { printf("Huh - modulus is not prime!"); exit(0); } subdiv(p,3,lim1); premult(lim1,2,lim2); }
void strong_bigrand(_MIPD_ csprng *rng,big w,big x) { unsigned int ran; unsigned int ch; #ifndef MR_GENERIC_MT miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(139) zero(mr_mip->w1); do { if (mr_mip->ERNUM) break; ch=(unsigned char)strong_rng(rng); ran=ch; premult(_MIPP_ mr_mip->w1,256,mr_mip->w1); incr(_MIPP_ mr_mip->w1,(int)ran,mr_mip->w1); } while (compare(mr_mip->w1,w)<0); divide(_MIPP_ mr_mip->w1,w,w); copy(mr_mip->w1,x); MR_OUT }
int main() { /* calculate factorial of number */ big nf; /* declare "big" variable nf */ int n; #if MIRACL==16 #ifdef MR_FLASH mirsys(500,10); /* initialise system to base 10, 500 digits per "big" */ #else mirsys(5000,10); /* bigger numbers possible if no flash arithmetic */ #endif #else mirsys(5000,10); /* 5000 digits per "big" */ #endif nf=mirvar(1); /* initialise "big" variable nf=1 */ printf("factorial program\n"); printf("input number n= \n"); scanf("%d",&n); getchar(); while (n>1) premult(nf,n--,nf); /* nf=n!=n*(n-1)*(n-2)*....3*2*1 */ printf("n!= \n"); otnum(nf,stdout); /* output result */ return 0; }
int xgcd(_MIPD_ big x,big y,big xd,big yd,big z) { /* greatest common divisor by Euclids method * * extended to also calculate xd and yd where * * z = x.xd + y.yd = gcd(x,y) * * if xd, yd not distinct, only xd calculated * * z only returned if distinct from xd and yd * * xd will always be positive, yd negative */ int q,r,a,b,c,d,s,n; mr_small m,sr; #ifdef mr_dltype mr_large u,v,lq,lr; #else mr_small u,v,lq,lr; #endif BOOL last; big t; #ifndef MR_GENERIC_MT miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return 0; MR_IN(30) copy(x,mr_mip->w1); copy(y,mr_mip->w2); s=exsign(mr_mip->w1); insign(PLUS,mr_mip->w1); insign(PLUS,mr_mip->w2); /* copy(mr_mip->w1,mr_mip->w3); copy(mr_mip->w2,mr_mip->w4); */ convert(_MIPP_ 1,mr_mip->w3); zero(mr_mip->w4); last=FALSE; a=b=c=d=0; while (size(mr_mip->w2)!=0) { if (b==0) { /* update mr_mip->w1 and mr_mip->w2 */ divide(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w5); t=mr_mip->w1,mr_mip->w1=mr_mip->w2,mr_mip->w2=t; /* swap(mr_mip->w1,mr_mip->w2) */ multiply(_MIPP_ mr_mip->w4,mr_mip->w5,mr_mip->w0); subtract(_MIPP_ mr_mip->w3,mr_mip->w0,mr_mip->w3); t=mr_mip->w3,mr_mip->w3=mr_mip->w4,mr_mip->w4=t; /* swap(xd,yd) */ } else { premult(_MIPP_ mr_mip->w1,c,mr_mip->w5); premult(_MIPP_ mr_mip->w1,a,mr_mip->w1); premult(_MIPP_ mr_mip->w2,b,mr_mip->w0); premult(_MIPP_ mr_mip->w2,d,mr_mip->w2); add_r(_MIPP_ mr_mip->w1,mr_mip->w0,mr_mip->w1); add_r(_MIPP_ mr_mip->w2,mr_mip->w5,mr_mip->w2); premult(_MIPP_ mr_mip->w3,c,mr_mip->w5); premult(_MIPP_ mr_mip->w3,a,mr_mip->w3); premult(_MIPP_ mr_mip->w4,b,mr_mip->w0); premult(_MIPP_ mr_mip->w4,d,mr_mip->w4); add_r(_MIPP_ mr_mip->w3,mr_mip->w0,mr_mip->w3); add_r(_MIPP_ mr_mip->w4,mr_mip->w5,mr_mip->w4); } if (mr_mip->ERNUM || size(mr_mip->w2)==0) break; n=(int)mr_mip->w1[0]; a=1; b=0; c=0; d=1; if (n==1) { last=TRUE; u=mr_mip->w1[1]; v=mr_mip->w2[1]; } else { m=mr_mip->w1[n]+1; if (mr_mip->base==0) { #ifdef mr_dltype /* use double length type if available */ if (n>2 && m!=0) { /* squeeze out as much significance as possible */ MR_TOP(u)=muldvm(mr_mip->w1[n],mr_mip->w1[n-1],m,&sr); MR_BOT(u)=muldvm(sr,mr_mip->w1[n-2],m,&sr); MR_TOP(v)=muldvm(mr_mip->w2[n],mr_mip->w2[n-1],m,&sr); MR_BOT(v)=muldvm(sr,mr_mip->w2[n-2],m,&sr); } else { MR_TOP(u)=mr_mip->w1[n]; MR_BOT(u)=mr_mip->w1[n-1]; MR_TOP(v)=mr_mip->w2[n]; MR_BOT(v)=mr_mip->w2[n-1]; if (n==2) last=TRUE; } #else if (m==0) { u=mr_mip->w1[n]; v=mr_mip->w2[n]; } else { u=muldvm(mr_mip->w1[n],mr_mip->w1[n-1],m,&sr); v=muldvm(mr_mip->w2[n],mr_mip->w2[n-1],m,&sr); } #endif } else { #ifdef mr_dltype /* use double length type if available */ if (n>2) { /* squeeze out as much significance as possible */ u=muldiv(mr_mip->w1[n],mr_mip->base,mr_mip->w1[n-1],m,&sr); u=u*mr_mip->base+muldiv(sr,mr_mip->base,mr_mip->w1[n-2],m,&sr); v=muldiv(mr_mip->w2[n],mr_mip->base,mr_mip->w2[n-1],m,&sr); v=v*mr_mip->base+muldiv(sr,mr_mip->base,mr_mip->w2[n-2],m,&sr); } else { u=(mr_large)mr_mip->base*mr_mip->w1[n]+mr_mip->w1[n-1]; v=(mr_large)mr_mip->base*mr_mip->w2[n]+mr_mip->w2[n-1]; last=TRUE; } #else u=muldiv(mr_mip->w1[n],mr_mip->base,mr_mip->w1[n-1],m,&sr); v=muldiv(mr_mip->w2[n],mr_mip->base,mr_mip->w2[n-1],m,&sr); #endif } } forever { /* work only with most significant piece */ if (last) { if (v==0) break; lq=u/v; } else { if (((v+c)==0) || ((v+d)==0)) break; lq=(u+a)/(v+c); if (lq!=(u+b)/(v+d)) break; } #ifdef mr_dltype if (lq>=(mr_large)(MR_TOOBIG/abs(d))) break; #else if (lq>=(mr_small)(MR_TOOBIG/abs(d))) break; #endif q=(int)lq; r=a-q*c; a=c; c=r; r=b-q*d; b=d; d=r; lr=u-lq*v; u=v; v=lr; } } if (s==MINUS) negate(mr_mip->w3,mr_mip->w3); if (size(mr_mip->w3)<=0) add_r(_MIPP_ mr_mip->w3,y,mr_mip->w3); if (xd!=yd) { negate(x,mr_mip->w2); mad(_MIPP_ mr_mip->w2,mr_mip->w3,mr_mip->w1,y,mr_mip->w4,mr_mip->w4); copy(mr_mip->w4,yd); } copy(mr_mip->w3,xd); if (z!=xd && z!=yd) copy(mr_mip->w1,z); MR_OUT return (size(mr_mip->w1)); }
int main() { FILE *fp; big p,q,h,g,n,s,t; long seed; miracl *mip=mirsys(100,0); p=mirvar(0); q=mirvar(0); h=mirvar(0); g=mirvar(0); n=mirvar(0); s=mirvar(0); t=mirvar(0); /* randomise */ printf("Enter 9 digit random number seed = "); scanf("%ld",&seed); getchar(); irand(seed); /* generate q */ forever { bigbits(QBITS,q); nxprime(q,q); if (logb2(q)>QBITS) continue; break; } printf("q= "); cotnum(q,stdout); /* generate p */ expb2(PBITS,t); decr(t,1,t); premult(q,2,n); divide(t,n,t); expb2(PBITS-1,s); decr(s,1,s); divide(s,n,s); forever { bigrand(t,p); if (mr_compare(p,s)<=0) continue; premult(p,2,p); multiply(p,q,p); incr(p,1,p); copy(p,n); if (isprime(p)) break; } printf("p= "); cotnum(p,stdout); /* generate g */ do { decr(p,1,t); bigrand(t,h); divide(t,q,t); powmod(h,t,p,g); } while (size(g)==1); printf("g= "); cotnum(g,stdout); fp=fopen("common.dss","wt"); fprintf(fp,"%d\n",PBITS); mip->IOBASE=16; cotnum(p,fp); cotnum(q,fp); cotnum(g,fp); fclose(fp); return 0; }
void build(_MIPD_ flash x,int (*gen)(_MIPT_ big,int)) { /* Build x from its regular c.f. * * generated by gen() */ mr_small ex1,ex2,ex,st,sr; int a,b,c,d,rm,q,n,prc,lw2,lw4,lz; BOOL finoff,last; big t; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(48) zero(mr_mip->w1); convert(_MIPP_ 1,mr_mip->w2); convert(_MIPP_ 1,mr_mip->w3); zero(mr_mip->w4); finoff=FALSE; last=FALSE; n=0; q=(*gen)(_MIPP_ x,n); /* Note - first quotient may be zero */ ex=mr_mip->base-1; if (mr_mip->nib==mr_mip->workprec) prc=mr_mip->nib; else prc=mr_mip->workprec+1; while (!mr_mip->ERNUM && q>=0) { if (q==MR_TOOBIG || n==0 || finoff) { if (q!=MR_TOOBIG) convert(_MIPP_ q,x); else last=FALSE; mr_mip->check=OFF; multiply(_MIPP_ mr_mip->w2,x,mr_mip->w0); subtract(_MIPP_ mr_mip->w1,mr_mip->w0,mr_mip->w7); mr_mip->check=ON; if ((int)(mr_mip->w7->len&MR_OBITS)>mr_mip->nib) break; copy(mr_mip->w7,mr_mip->w1); t=mr_mip->w1,mr_mip->w1=mr_mip->w2,mr_mip->w2=t; /* swap(w1,w2) */ mr_mip->check=OFF; multiply(_MIPP_ mr_mip->w4,x,mr_mip->w0); subtract(_MIPP_ mr_mip->w3,mr_mip->w0,mr_mip->w7); mr_mip->check=ON; if ((int)(mr_mip->w7->len&MR_OBITS)>mr_mip->nib) { /* oops! */ fpack(_MIPP_ mr_mip->w1,mr_mip->w4,x); negify(x,x); mr_mip->EXACT=FALSE; MR_OUT return; } copy(mr_mip->w7,mr_mip->w3); t=mr_mip->w3,mr_mip->w3=mr_mip->w4,mr_mip->w4=t; /* swap(w3,w4) */ n++; } lw2=(int)(mr_mip->w2->len&MR_OBITS); lw4=(int)(mr_mip->w4->len&MR_OBITS); lz=lw2+lw4; if (lz > prc) break; /* too big - exit */ if (last) { if (finoff) break; finoff=TRUE; q=(*gen)(_MIPP_ x,n); continue; } if (lz>=prc-1) { /* nearly finished - so be careful not to overshoot */ if (mr_mip->base==0) { #ifndef MR_NOFULLWIDTH st=mr_mip->w2->w[lw2-1]+1; if (st==0) ex1=1; else ex1=muldvm((mr_small)1,(mr_small)0,st,&sr); st=mr_mip->w4->w[lw4-1]+1; if (st==0) ex2=1; else ex2=muldvm((mr_small)1,(mr_small)0,st,&sr); #endif } else { ex1=mr_mip->base/(mr_mip->w2->w[lw2-1]+1); ex2=mr_mip->base/(mr_mip->w4->w[lw4-1]+1); } if (ex2>ex1) ex=ex1,ex1=ex2,ex2=ex; if (lz==prc) ex=ex2; else ex=ex1; last=TRUE; } a=1; b=0; c=0; d=1; forever { q=(*gen)(_MIPP_ x,n); if (q<0 || q>=MR_TOOBIG/mr_abs(d)) { /* there could be more.... *** V3.21 mod *** */ last=FALSE; break; } rm=b-q*d; b=d; d=rm; rm=a-q*c; a=c; c=rm; n++; if ((mr_small)(mr_abs(c-d))>ex) break; } premult(_MIPP_ mr_mip->w1,c,mr_mip->w7); premult(_MIPP_ mr_mip->w1,a,mr_mip->w1); premult(_MIPP_ mr_mip->w2,b,mr_mip->w0); premult(_MIPP_ mr_mip->w2,d,mr_mip->w2); add(_MIPP_ mr_mip->w1,mr_mip->w0,mr_mip->w1); add(_MIPP_ mr_mip->w2,mr_mip->w7,mr_mip->w2); premult(_MIPP_ mr_mip->w3,c,mr_mip->w7); premult(_MIPP_ mr_mip->w3,a,mr_mip->w3); premult(_MIPP_ mr_mip->w4,b,mr_mip->w0); premult(_MIPP_ mr_mip->w4,d,mr_mip->w4); add(_MIPP_ mr_mip->w3,mr_mip->w0,mr_mip->w3); add(_MIPP_ mr_mip->w4,mr_mip->w7,mr_mip->w4); }
int main() { /* decode using private key */ int i; big e,ep[NP],m,ke,kd,p[NP],kp[NP],mn,mx; FILE *ifile; FILE *ofile; char ifname[13],ofname[13]; BOOL flo; big_chinese ch; mip=mirsys(100,0); for (i=0;i<NP;i++) { p[i]=mirvar(0); ep[i]=mirvar(0); kp[i]=mirvar(0); } e=mirvar(0); m=mirvar(0); kd=mirvar(0); ke=mirvar(0); mn=mirvar(0); mx=mirvar(0); mip->IOBASE=60; if ((ifile=fopen("private.key","r"))==NULL) { printf("Unable to open file private.key\n"); return 0; } for (i=0;i<NP;i++) { cinnum(p[i],ifile); } fclose(ifile); /* generate public and private keys */ convert(1,ke); for (i=0;i<NP;i++) { multiply(ke,p[i],ke); } for (i=0;i<NP;i++) { /* kp[i]=(2*(p[i]-1)+1)/3 = 1/3 mod p[i]-1 */ decr(p[i],1,kd); premult(kd,2,kd); incr(kd,1,kd); subdiv(kd,3,kp[i]); } crt_init(&ch,NP,p); nroot(ke,3,mn); multiply(mn,mn,m); multiply(mn,m,mx); subtract(mx,m,mx); do { /* get input file */ printf("file to be decoded = "); gets(ifname); } while (strlen(ifname)==0); strip(ifname); strcat(ifname,".rsa"); printf("output filename = "); gets(ofname); flo=FALSE; if (strlen(ofname)>0) { /* set up output file */ flo=TRUE; ofile=fopen(ofname,"w"); } printf("decoding message\n"); if ((ifile=fopen(ifname,"r"))==NULL) { printf("Unable to open file %s\n",ifname); return 0; } forever { /* decode line by line */ mip->IOBASE=60; cinnum(m,ifile); if (size(m)==0) break; for (i=0;i<NP;i++) powmod(m,kp[i],p[i],ep[i]); crt(&ch,ep,e); /* Chinese remainder thereom */ if (compare(e,mx)>=0) divide(e,mn,mn); mip->IOBASE=128; if (flo) cotnum(e,ofile); cotnum(e,stdout); } crt_end(&ch); fclose(ifile); if (flo) fclose(ofile); printf("message ends\n"); return 0; }
int main() { int i; FILE *fp; big K,rid,id,w,a,b,n,q1; miracl *mip=mirsys(200,256); for (i=0;i<NPRIMES;i++) { pp[i]=mirvar(0); rem[i]=mirvar(0); } w=mirvar(0); n=mirvar(0); a=mirvar(0); b=mirvar(0); p=mirvar(0); p1=mirvar(0); q1=mirvar(0); K=mirvar(0); lim1=mirvar(0); lim2=mirvar(0); id=mirvar(0); rid=mirvar(0); order=mirvar(0); printf("Enter ID= "); innum(rid,stdin); getprime("trap1.dat"); copy(p,n); getprime("trap2.dat"); multiply(n,p,n); printf("\ncomposite =\n"); cotnum(n,stdout); premult(rid,256,id); while (jack(id,n)!=1) { /* bad identity - id=256*rid+i */ printf("No Discrete Log. for this ID -- incrementing\n"); incr(id,1,id); } getprime("trap1.dat"); copy(p1,q1); pollard(id,b); getprime("trap2.dat"); pollard(id,a); xgcd(p1,q1,K,K,K); subtract(b,a,w); mad(w,K,w,q1,q1,w); if(size(w)<0) add_r(w,q1,w); subdiv(w,2,w); multiply(w,p1,w); add_r(w,a,w); fp=fopen("secret.dat","w"); otnum(rid,fp); cotnum(w,fp); cotnum(n,fp); fclose(fp); printf("\nDiscrete log (secret key) \n"); cotnum(w,stdout); powltr(PROOT,w,n,id); subdiv(id,256,id); otstr(id,mip->IOBUFF); printf("Check Identity= %s\n",mip->IOBUFF); return 0; }
static int euclid(_MIPD_ big x,int num) { /* outputs next c.f. quotient from gcd(w5,w6) */ mr_small sr,m; #ifdef MR_FP mr_small dres; #endif mr_small lr,lq; big t; #ifndef MR_GENERIC_MT miracl *mr_mip=get_mip(); #endif if (num==0) { mr_mip->oldn=(-1); mr_mip->carryon=FALSE; mr_mip->last=FALSE; if (compare(mr_mip->w6,mr_mip->w5)>0) { /* ensure w5>w6 */ t=mr_mip->w5,mr_mip->w5=mr_mip->w6,mr_mip->w6=t; return (mr_mip->q=0); } } else if (num==mr_mip->oldn || mr_mip->q<0) return mr_mip->q; mr_mip->oldn=num; if (mr_mip->carryon) goto middle; start: if (size(mr_mip->w6)==0) return (mr_mip->q=(-1)); mr_mip->ndig=(int)mr_mip->w5->len; mr_mip->carryon=TRUE; mr_mip->a=1; mr_mip->b=0; mr_mip->c=0; mr_mip->d=1; if (mr_mip->ndig==1) { mr_mip->last=TRUE; mr_mip->u=mr_mip->w5->w[0]; mr_mip->v=mr_mip->w6->w[0]; } else { m=mr_mip->w5->w[mr_mip->ndig-1]+1; if (mr_mip->base==0) { #ifndef MR_NOFULLWIDTH if (m==0) { mr_mip->u=mr_mip->w5->w[mr_mip->ndig-1]; mr_mip->v=mr_mip->w6->w[mr_mip->ndig-1]; } else { mr_mip->u=muldvm(mr_mip->w5->w[mr_mip->ndig-1],mr_mip->w5->w[mr_mip->ndig-2],m,&sr); mr_mip->v=muldvm(mr_mip->w6->w[mr_mip->ndig-1],mr_mip->w6->w[mr_mip->ndig-2],m,&sr); } #endif } else { mr_mip->u=muldiv(mr_mip->w5->w[mr_mip->ndig-1],mr_mip->base,mr_mip->w5->w[mr_mip->ndig-2],m,&sr); mr_mip->v=muldiv(mr_mip->w6->w[mr_mip->ndig-1],mr_mip->base,mr_mip->w6->w[mr_mip->ndig-2],m,&sr); } } mr_mip->ku=mr_mip->u; mr_mip->kv=mr_mip->v; middle: forever { /* work only with most significant piece */ if (mr_mip->last) { if (mr_mip->v==0) return (mr_mip->q=(-1)); lq=MR_DIV(mr_mip->u,mr_mip->v); } else { if (((mr_mip->v+mr_mip->c)==0) || ((mr_mip->v+mr_mip->d)==0)) break; lq=MR_DIV((mr_mip->u+mr_mip->a),(mr_mip->v+mr_mip->c)); if (lq!=MR_DIV((mr_mip->u+mr_mip->b),(mr_mip->v+mr_mip->d))) break; } if (lq>=(mr_small)(MR_TOOBIG/mr_abs(mr_mip->d))) break; mr_mip->q=(int)lq; mr_mip->r=mr_mip->a-mr_mip->q*mr_mip->c; mr_mip->a=mr_mip->c; mr_mip->c=mr_mip->r; mr_mip->r=mr_mip->b-mr_mip->q*mr_mip->d; mr_mip->b=mr_mip->d; mr_mip->d=mr_mip->r; lr=mr_mip->u-lq*mr_mip->v; mr_mip->u=mr_mip->v; mr_mip->v=lr; return mr_mip->q; } mr_mip->carryon=FALSE; if (mr_mip->b==0) { /* update w5 and w6 */ mr_mip->check=OFF; divide(_MIPP_ mr_mip->w5,mr_mip->w6,mr_mip->w7); mr_mip->check=ON; if (mr_lent(mr_mip->w7)>mr_mip->nib) return (mr_mip->q=(-2)); t=mr_mip->w5,mr_mip->w5=mr_mip->w6,mr_mip->w6=t; /* swap(w5,w6) */ copy(mr_mip->w7,x); return (mr_mip->q=size(x)); } else { mr_mip->check=OFF; premult(_MIPP_ mr_mip->w5,mr_mip->c,mr_mip->w7); premult(_MIPP_ mr_mip->w5,mr_mip->a,mr_mip->w5); premult(_MIPP_ mr_mip->w6,mr_mip->b,mr_mip->w0); premult(_MIPP_ mr_mip->w6,mr_mip->d,mr_mip->w6); add(_MIPP_ mr_mip->w5,mr_mip->w0,mr_mip->w5); add(_MIPP_ mr_mip->w6,mr_mip->w7,mr_mip->w6); mr_mip->check=ON; } goto start; }
void zzn4_powu(_MIPD_ zzn4 *x,big k,zzn4 *u) { zzn4 t[5],u2; big k3; int i,j,n,nb,nbw,nzs; #ifndef MR_STATIC char *mem=memalloc(_MIPP_ 25); #else char mem[MR_BIG_RESERVE(25)]; memset(mem,0,MR_BIG_RESERVE(25)); #endif if (size(k)==0) { zzn4_from_int(_MIPP_ 1,u); return; } zzn4_copy(x,u); if (size(k)==1) return; for (j=i=0; i<5; i++) { t[i].x.a=mirvar_mem(_MIPP_ mem,j++); t[i].x.b=mirvar_mem(_MIPP_ mem,j++); t[i].y.a=mirvar_mem(_MIPP_ mem,j++); t[i].y.b=mirvar_mem(_MIPP_ mem,j++); t[i].unitary=FALSE; } u2.x.a=mirvar_mem(_MIPP_ mem,j++); u2.x.b=mirvar_mem(_MIPP_ mem,j++); u2.y.a=mirvar_mem(_MIPP_ mem,j++); u2.y.b=mirvar_mem(_MIPP_ mem,j++); u2.unitary=FALSE; k3=mirvar_mem(_MIPP_ mem,j); premult(_MIPP_ k,3,k3); zzn4_mul(_MIPP_ u,u,&u2); zzn4_copy(u,&t[0]); for (i=1; i<=4; i++) zzn4_mul(_MIPP_ &u2,&t[i-1],&t[i]); nb=logb2(_MIPP_ k3); for (i=nb-2; i>=1;) { n=mr_naf_window(_MIPP_ k,k3,i,&nbw,&nzs,5); for (j=0; j<nbw; j++) zzn4_mul(_MIPP_ u,u,u); if (n>0) zzn4_mul(_MIPP_ u,&t[n/2],u); if (n<0) { zzn4_conj(_MIPP_ &t[-n/2],&u2); zzn4_mul(_MIPP_ u,&u2,u); } i-=nbw; if (nzs) { for (j=0; j<nzs; j++) zzn4_mul(_MIPP_ u,u,u); i-=nzs; } } #ifndef MR_STATIC memkill(_MIPP_ mem,25); #else memset(mem,0,MR_BIG_RESERVE(25)); #endif }
Big operator*(int i, const Big& b) {Big xib; premult(b.fn, i, xib.fn); return xib;}
BOOL gotcha(void) { /* use new factorisation */ int r,j,i,k,n,rb,had,hp; unsigned int t; BOOL found; found=TRUE; if (partial) { /* check partial factorisation for usefulness */ had=lp%hmod; forever { /* hash search for matching large prime */ hp=hash[had]; if (hp<0) { /* failed to find match */ found=FALSE; break; } if (pr[hp]==lp) break; /* hash hit! */ had=(had+(hmod2-lp%hmod2))%hmod; } if (!found && nlp>=mlf) return FALSE; } copy(PP,XX); convert(1,YY); for (k=1;k<=mm;k++) { /* build up square part in YY * * reducing e[k] to 0s and 1s */ if (e[k]<2) continue; r=e[k]/2; e[k]%=2; expint(epr[k],r,TT); multiply(TT,YY,YY); } /* debug only cotnum(XX,stdout); cotnum(YY,stdout); if (e[0]==1) printf("-1"); else printf("1"); for (k=1;k<=mm;k++) { if (e[k]==0) continue; printf(".%d",epr[k]); } if (partial) printf(".%d\n",lp); else printf("\n"); */ if (partial) { /* factored with large prime */ if (!found) { /* store new partial factorization */ hash[had]=nlp; pr[nlp]=lp; copy(XX,z[nlp]); copy(YY,w[nlp]); for (n=0,rb=0,j=0;j<=mm;j++) { G[nlp][n]|=((e[j]&1)<<rb); if (++rb==nbts) n++,rb=0; } nlp++; } if (found) { /* match found so use as factorization */ printf("\b\b\b\b\b\b*"); fflush(stdout); mad(XX,z[hp],XX,NN,NN,XX); mad(YY,w[hp],YY,NN,NN,YY); for (n=0,rb=0,j=0;j<=mm;j++) { t=(G[hp][n]>>rb); e[j]+=(t&1); if (e[j]==2) { premult(YY,epr[j],YY); divide(YY,NN,NN); e[j]=0; } if (++rb==nbts) n++,rb=0; } premult(YY,lp,YY); divide(YY,NN,NN); } } else {
Big operator*(const Big& b, int i) {Big xbi; premult(b.fn, i, xbi.fn); return xbi;}
int main() { FILE *fp; big q,p,p1,h,t,g,low,high; big pool[POOL_SIZE]; BOOL fail; int i,j,p1bits,np; long seed,m,permutation; miracl *mip=mirsys(100,0); q=mirvar(0); p=mirvar(0); h=mirvar(0); t=mirvar(0); g=mirvar(0); p1=mirvar(0); low=mirvar(0); high=mirvar(0); gprime(10000); /* randomise */ printf("Enter 9 digit random number seed = "); scanf("%ld",&seed); getchar(); irand(seed); p1bits=PBITS-QBITS-1; /* find number of primes pa, pb, pc etc., that will be needed */ np=1; while (p1bits/np >= OBITS) np++; np--; /* find the high/low limits for these primes, so that the generated prime p will be exactly PBITS in length */ expb2(p1bits-1,t); nroot(t,np,low); /* np-th integer root */ incr(low,1,low); premult(t,2,t); decr(t,1,t); nroot(t,np,high); subtract(high,low,t); /* raise low limit up to half-way... */ subdiv(t,2,t); subtract(high,t,low); /* generate q */ forever { /* make sure leading two bits of q 11... */ expb2(QBITS,q); bigbits(QBITS-2,t); subtract(q,t,q); nxprime(q,q); if (logb2(q)>QBITS) continue; break; } printf("q= (%d bits)\n",logb2(q)); cotnum(q,stdout); /* generate prime pool from which permutations of np primes will be picked until a Lim-Lee prime is found */ for (i=0;i<POOL_SIZE;i++) { /* generate the primes pa, pb, pc etc.. */ pool[i]=mirvar(0); forever { bigrand(high,p1); if (mr_compare(p1,low)<0) continue; nxprime(p1,p1); if (mr_compare(p1,high)>0) continue; copy(p1,pool[i]); break; } } /* The '1' bits in the permutation indicate which primes are picked from the pool. If np=5, start at 11111, then 101111 etc */ permutation=1L; for (i=0;i<np;i++) permutation<<=1; permutation-=1; /* permuation = 2^np-1 */ /* generate p */ fail=FALSE; forever { convert(1,p1); for (i=j=0,m=1L;j<np;i++,m<<=1) { if (i>=POOL_SIZE) { /* ran out of primes... */ fail=TRUE; break; } if (m&permutation) { multiply(p1,pool[i],p1); j++; } } if (fail) break; printf("."); premult(q,2,p); multiply(p,p1,p); incr(p,1,p); permutation=increment(permutation); if (logb2(p)!=PBITS) continue; if (isprime(p)) break; } if (fail) { printf("\nFailed - very unlikely! - try increasing POOL_SIZE\n"); return 0; } printf("\np= (%d bits)\n",logb2(p)); cotnum(p,stdout); /* finally find g */ do { decr(p,1,t); bigrand(t,h); divide(t,q,t); powmod(h,t,p,g); } while(size(g)==1); printf("g= (%d bits)\n",logb2(g)); cotnum(g,stdout); fp=fopen("common.dss","wt"); fprintf(fp,"%d\n",PBITS); mip->IOBASE=16; cotnum(p,fp); cotnum(q,fp); cotnum(g,fp); fclose(fp); return 0; }
int egcd(_MIPD_ big x,big y,big z) { /* greatest common divisor z=gcd(x,y) by Euclids * * method using Lehmers algorithm for big numbers */ int q,r,a,b,c,d,n; mr_small sr,m,sm; mr_small u,v,lq,lr; #ifdef MR_FP mr_small dres; #endif big t; #ifndef MR_GENERIC_MT miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return 0; MR_IN(12) copy(x,mr_mip->w1); copy(y,mr_mip->w2); insign(PLUS,mr_mip->w1); insign(PLUS,mr_mip->w2); a=b=c=d=0; while (size(mr_mip->w2)!=0) { if (b==0) { /* update w1 and w2 */ divide(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w2); t=mr_mip->w1,mr_mip->w1=mr_mip->w2,mr_mip->w2=t; /* swap(w1,w2) */ } else { premult(_MIPP_ mr_mip->w1,c,z); premult(_MIPP_ mr_mip->w1,a,mr_mip->w1); premult(_MIPP_ mr_mip->w2,b,mr_mip->w0); premult(_MIPP_ mr_mip->w2,d,mr_mip->w2); add(_MIPP_ mr_mip->w1,mr_mip->w0,mr_mip->w1); add(_MIPP_ mr_mip->w2,z,mr_mip->w2); } if (mr_mip->ERNUM || size(mr_mip->w2)==0) break; n=(int)mr_mip->w1->len; if (mr_mip->w2->len==1) { /* special case if mr_mip->w2 is now small */ sm=mr_mip->w2->w[0]; #ifdef MR_FP_ROUNDING sr=mr_sdiv(_MIPP_ mr_mip->w1,sm,mr_invert(sm),mr_mip->w1); #else sr=mr_sdiv(_MIPP_ mr_mip->w1,sm,mr_mip->w1); #endif if (sr==0) { copy(mr_mip->w2,mr_mip->w1); break; } zero(mr_mip->w1); mr_mip->w1->len=1; mr_mip->w1->w[0]=sr; while ((sr=MR_REMAIN(mr_mip->w2->w[0],mr_mip->w1->w[0]))!=0) mr_mip->w2->w[0]=mr_mip->w1->w[0],mr_mip->w1->w[0]=sr; break; } a=1; b=0; c=0; d=1; m=mr_mip->w1->w[n-1]+1; if (mr_mip->base==0) { #ifndef MR_NOFULLWIDTH if (m==0) { u=mr_mip->w1->w[n-1]; v=mr_mip->w2->w[n-1]; } else { u=muldvm(mr_mip->w1->w[n-1],mr_mip->w1->w[n-2],m,&sr); v=muldvm(mr_mip->w2->w[n-1],mr_mip->w2->w[n-2],m,&sr); } #endif } else { u=muldiv(mr_mip->w1->w[n-1],mr_mip->base,mr_mip->w1->w[n-2],m,&sr); v=muldiv(mr_mip->w2->w[n-1],mr_mip->base,mr_mip->w2->w[n-2],m,&sr); } forever { /* work only with most significant piece */ if (((v+c)==0) || ((v+d)==0)) break; lq=MR_DIV((u+a),(v+c)); if (lq!=MR_DIV((u+b),(v+d))) break; if (lq>=(mr_small)(MR_TOOBIG/mr_abs(d))) break; q=(int)lq; r=a-q*c; a=c; c=r; r=b-q*d; b=d; d=r; lr=u-lq*v; u=v; v=lr; } } copy(mr_mip->w1,z); MR_OUT return (size(mr_mip->w1)); }
int main() { #ifdef MR_GENERIC_MT miracl instance; #endif big p,A,B,Fr,q,cf,sru,t,T; zzn3 res,Qx,Qy; epoint *P; int i,romptr; #ifndef MR_STATIC #ifdef MR_GENERIC_MT miracl *mr_mip=mirsys(&instance,WORDS*NPW,16); #else miracl *mr_mip=mirsys(WORDS*NPW,16); #endif char *mem=memalloc(_MIPP_ 18); char *mem1=ecp_memalloc(_MIPP_ 1); #else #ifdef MR_GENERIC_MT miracl *mr_mip=mirsys(&instance,MR_STATIC*NPW,16); #else miracl *mr_mip=mirsys(MR_STATIC*NPW,16); #endif char mem[MR_BIG_RESERVE(18)]; /* reserve space on the stack for 18 bigs */ char mem1[MR_ECP_RESERVE(1)]; /* reserve space on stack for 1 curve points */ memset(mem,0,MR_BIG_RESERVE(18)); /* clear this memory */ memset(mem1,0,MR_ECP_RESERVE(1)); #endif p=mirvar_mem(_MIPP_ mem,0); A=mirvar_mem(_MIPP_ mem,1); B=mirvar_mem(_MIPP_ mem,2); T=mirvar_mem(_MIPP_ mem,3); q=mirvar_mem(_MIPP_ mem,4); Fr=mirvar_mem(_MIPP_ mem,5); cf=mirvar_mem(_MIPP_ mem,6); res.a=mirvar_mem(_MIPP_ mem,7); res.b=mirvar_mem(_MIPP_ mem,8); res.c=mirvar_mem(_MIPP_ mem,9); sru=mirvar_mem(_MIPP_ mem,10); t=mirvar_mem(_MIPP_ mem,11); Qx.a=mirvar_mem(_MIPP_ mem,12); Qx.b=mirvar_mem(_MIPP_ mem,13); Qx.c=mirvar_mem(_MIPP_ mem,14); Qy.a=mirvar_mem(_MIPP_ mem,15); Qy.b=mirvar_mem(_MIPP_ mem,16); Qy.c=mirvar_mem(_MIPP_ mem,17); P=epoint_init_mem(_MIPP_ mem1,0); convert(_MIPP_ -3,A); romptr=0; init_big_from_rom(p,WORDS,romp,ROMSZ,&romptr); init_big_from_rom(B,WORDS,romp,ROMSZ,&romptr); init_big_from_rom(q,WORDS,romp,ROMSZ,&romptr); init_big_from_rom(cf,WORDS,romp,ROMSZ,&romptr); init_big_from_rom(sru,WORDS,romp,ROMSZ,&romptr); #ifndef MR_NO_STANDARD_IO printf("ROM size= %ld\n",sizeof(romp)+sizeof(Prom)); printf("sizeof(miracl)= %ld\n",sizeof(miracl)); #endif premult(_MIPP_ p,CF,t); subtract(_MIPP_ cf,t,cf); ecurve_init(_MIPP_ A,B,p,MR_BEST); zzn3_set(_MIPP_ CNR,sru); romptr=0; init_point_from_rom(P,WORDS,Prom,PROMSZ,&romptr); init_big_from_rom(Qx.a,WORDS,Prom,PROMSZ,&romptr); init_big_from_rom(Qx.b,WORDS,Prom,PROMSZ,&romptr); init_big_from_rom(Qx.c,WORDS,Prom,PROMSZ,&romptr); init_big_from_rom(Qy.a,WORDS,Prom,PROMSZ,&romptr); init_big_from_rom(Qy.b,WORDS,Prom,PROMSZ,&romptr); init_big_from_rom(Qy.c,WORDS,Prom,PROMSZ,&romptr); #ifdef MR_COUNT_OPS fpa=fpc=fpx=0; #endif ecap(_MIPP_ P,&Qx,&Qy,q,cf,&res); #ifdef MR_COUNT_OPS printf("fpc= %d\n",fpc); printf("fpa= %d\n",fpa); printf("fpx= %d\n",fpx); fpa=fpc=fpx=0; #endif bigbits(_MIPP_ 160,t); zzn3_powl(_MIPP_ &res,t,&res); #ifndef MR_NO_STANDARD_IO zzn3_out(_MIPP_ "res= ",&res); #endif ecurve_mult(_MIPP_ t,P,P); ecap(_MIPP_ P,&Qx,&Qy,q,cf,&res); #ifndef MR_NO_STANDARD_IO zzn3_out(_MIPP_ "res= ",&res); #endif #ifndef MR_STATIC memkill(_MIPP_ mem,18); ecp_memkill(_MIPP_ mem1,1); #else memset(mem,0,MR_BIG_RESERVE(18)); /* clear this stack memory */ memset(mem1,0,MR_ECP_RESERVE(1)); #endif return 0; }
void flop(_MIPD_ flash x,flash y,int *op,flash z) { /* Do basic flash operation - depending on * * op[]. Performs operations of the form A.f1(x,y) + B.f2(x,y) ------------------- C.f3(x,y) + D.f4(x,y) * Four functions f(x,y) are supported and * * coded thus * * 00 - Nx.Ny * * 01 - Nx.Dy * * 10 - Dx.Ny * * 11 - Dx.Dy * * where Nx is numerator of x, Dx denominator * * of x, etc. * * op[0] contains the codes for f1-f4 in last * * eight bits = 00000000f1f2f3f4 * * op[1], op[2], op[3], op[4] contain the * * single precision multipliers A, B, C, D */ int i,code; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(69) numer(_MIPP_ x,mr_mip->w1); denom(_MIPP_ x,mr_mip->w2); numer(_MIPP_ y,mr_mip->w3); denom(_MIPP_ y,mr_mip->w4); mr_mip->check=OFF; for (i=1;i<=4;i++) { zero(mr_mip->w0); if (op[i]==0) continue; code=(op[0]>>(2*(4-i)))&3; switch (code) { case 0 : if (x==y) multiply(_MIPP_ mr_mip->w1,mr_mip->w1,mr_mip->w0); else multiply(_MIPP_ mr_mip->w1,mr_mip->w3,mr_mip->w0); break; case 1 : multiply(_MIPP_ mr_mip->w1,mr_mip->w4,mr_mip->w0); break; case 2 : multiply(_MIPP_ mr_mip->w2,mr_mip->w3,mr_mip->w0); break; case 3 : if(x==y) multiply(_MIPP_ mr_mip->w2,mr_mip->w2,mr_mip->w0); else multiply(_MIPP_ mr_mip->w2,mr_mip->w4,mr_mip->w0); break; } premult(_MIPP_ mr_mip->w0,op[i],mr_mip->w0); switch (i) { case 1 : copy(mr_mip->w0,mr_mip->w5); break; case 2 : add(_MIPP_ mr_mip->w5,mr_mip->w0,mr_mip->w5); break; case 3 : copy(mr_mip->w0,mr_mip->w6); break; case 4 : add(_MIPP_ mr_mip->w6,mr_mip->w0,mr_mip->w6); break; } } mr_mip->check=ON; mround(_MIPP_ mr_mip->w5,mr_mip->w6,z); MR_OUT }