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; }
BOOL epoint_set(_MIPD_ big x,big y,int cb,epoint *p) { /* initialise a point on active ecurve * * if x or y == NULL, set to point at infinity * * if x==y, a y co-ordinate is calculated - if * * possible - and cb suggests LSB 0/1 of y * * (which "decompresses" y). Otherwise, check * * validity of given (x,y) point, ignoring cb. * * Returns TRUE for valid point, otherwise FALSE. */ BOOL valid; #ifndef MR_GENERIC_MT miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return FALSE; MR_IN(97) if (x==NULL || y==NULL) { convert(_MIPP_ 1,mr_mip->w1); nres(_MIPP_ mr_mip->w1,p->X); nres(_MIPP_ mr_mip->w1,p->Y); p->marker=MR_EPOINT_INFINITY; MR_OUT return TRUE; }
void zzn2_out(_MIPD_ char *p,zzn2 *x) { printf(p); printf("\n"); redc(_MIPP_ x->a,x->a); redc(_MIPP_ x->b,x->b); otnum(_MIPP_ x->a,stdout); otnum(_MIPP_ x->b,stdout); nres(_MIPP_ x->a,x->a); nres(_MIPP_ x->b,x->b); }
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 }
void zzn2_from_ints(_MIPD_ int i,int j,zzn2 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(168) convert(_MIPP_ i,mr_mip->w1); nres(_MIPP_ mr_mip->w1,w->a); convert(_MIPP_ j,mr_mip->w1); nres(_MIPP_ mr_mip->w1,w->b); MR_OUT }
void zzn4_powq(_MIPD_ big fr,zzn4 *w) { zzn2_conj(_MIPP_ &(w->x),&(w->x)); zzn2_conj(_MIPP_ &(w->y),&(w->y)); nres(_MIPP_ fr,mr_mip->w1); zzn2_smul(_MIPP_ &(w->y),mr_mip->w1,&(w->y)); }
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 ecurve_init(_MIPD_ big a,big b,big p,int type) { /* Initialize the active ecurve * * Asize indicate size of A * * Bsize indicate size of B */ int as; #ifndef MR_GENERIC_MT miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(93) prepare_monty(_MIPP_ p); mr_mip->Asize=size(a); if (mr_abs(mr_mip->Asize)==MR_TOOBIG) { if (mr_mip->Asize>=0) { /* big positive number - check it isn't minus something small */ copy(a,mr_mip->w1); divide(_MIPP_ mr_mip->w1,p,p); subtract(_MIPP_ p,mr_mip->w1,mr_mip->w1); as=size(mr_mip->w1); if (as<MR_TOOBIG) mr_mip->Asize=-as; else { if (mr_mip->A==NULL) mr_mip->A=mirvar(_MIPP_ 0); nres(_MIPP_ a,mr_mip->A); } } else { if (mr_mip->A==NULL) mr_mip->A=mirvar(_MIPP_ 0); nres(_MIPP_ a,mr_mip->A); } } mr_mip->Bsize=size(b); if (mr_abs(mr_mip->Bsize)==MR_TOOBIG) { if (mr_mip->B==NULL) mr_mip->B=mirvar(_MIPP_ 0); nres(_MIPP_ b,mr_mip->B); } mr_mip->coord=type; MR_OUT return; }
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 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 zzn3_from_int(_MIPD_ int i,zzn3 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(174) convert(_MIPP_ i,mr_mip->w1); nres(_MIPP_ mr_mip->w1,w->a); zero(w->b); zero(w->c); MR_OUT }
void zzn3_inv(_MIPD_ zzn3 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(187) nres_modmult(_MIPP_ w->a,w->a,mr_mip->w1); nres_modmult(_MIPP_ w->b,w->c,mr_mip->w2); nres_premult(_MIPP_ mr_mip->w2,mr_mip->cnr,mr_mip->w2); nres_modsub(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w3); nres_modmult(_MIPP_ w->c,w->c,mr_mip->w1); nres_modmult(_MIPP_ w->a,w->b,mr_mip->w2); nres_premult(_MIPP_ mr_mip->w1,mr_mip->cnr,mr_mip->w1); nres_modsub(_MIPP_ mr_mip->w2,mr_mip->w1,mr_mip->w4); nres_negate(_MIPP_ mr_mip->w4,mr_mip->w4); nres_modmult(_MIPP_ w->b,w->b,mr_mip->w1); nres_modmult(_MIPP_ w->a,w->c,mr_mip->w2); nres_modsub(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w5); nres_modmult(_MIPP_ w->b,mr_mip->w5,mr_mip->w1); nres_modmult(_MIPP_ w->c,mr_mip->w4,mr_mip->w2); nres_modadd(_MIPP_ mr_mip->w2,mr_mip->w1,mr_mip->w2); nres_premult(_MIPP_ mr_mip->w2,mr_mip->cnr,mr_mip->w2); nres_modmult(_MIPP_ w->a,mr_mip->w3,mr_mip->w1); nres_modadd(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w1); copy(mr_mip->w3,w->a); copy(mr_mip->w4,w->b); copy(mr_mip->w5,w->c); redc(_MIPP_ mr_mip->w1,mr_mip->w6); invmodp(_MIPP_ mr_mip->w6,mr_mip->modulus,mr_mip->w6); nres(_MIPP_ mr_mip->w6,mr_mip->w6); nres_modmult(_MIPP_ w->a,mr_mip->w6,w->a); nres_modmult(_MIPP_ w->b,mr_mip->w6,w->b); nres_modmult(_MIPP_ w->c,mr_mip->w6,w->c); MR_OUT }
void nres_lucas(_MIPD_ big p,big r,big vp,big v) { int i,nb; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(107) if (size(r)==0) { zero(vp); convert(_MIPP_ 2,v); nres(_MIPP_ v,v); MR_OUT return; }
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) if (i==1) { copy(mr_mip->one,w->a); } else { convert(_MIPP_ i,mr_mip->w1); nres(_MIPP_ mr_mip->w1,w->a); } zero(w->b); MR_OUT }
BOOL nres_sqroot(_MIPD_ big x,big w) { /* w=sqrt(x) mod p. This depends on p being prime! */ int t,js; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return FALSE; copy(x,w); if (size(w)==0) return TRUE; MR_IN(100) redc(_MIPP_ w,w); /* get it back into normal form */ if (size(w)==1) /* square root of 1 is 1 */ { nres(_MIPP_ w,w); MR_OUT return TRUE; }
/* void zzn2_print(_MIPD_ char *label, zzn2 *x) { char s1[1024], s2[1024]; big a, b; #ifdef MR_STATIC char mem_big[MR_BIG_RESERVE(2)]; memset(mem_big, 0, MR_BIG_RESERVE(2)); a=mirvar_mem(_MIPP_ mem_big,0); b=mirvar_mem(_MIPP_ mem_big,1); #else a = mirvar(_MIPP_ 0); b = mirvar(_MIPP_ 0); #endif redc(_MIPP_ x->a, a); otstr(_MIPP_ a, s1); redc(_MIPP_ x->b, b); otstr(_MIPP_ b, s2); printf("%s: [%s,%s]\n", label, s1, s2); #ifndef MR_STATIC mr_free(a); mr_free(b); #endif } static void nres_print(_MIPD_ char *label, big x) { char s[1024]; big a; #ifdef MR_STATIC char mem_big[MR_BIG_RESERVE(1)]; memset(mem_big, 0, MR_BIG_RESERVE(1)); a=mirvar_mem(_MIPP_ mem_big,0); #else a = mirvar(_MIPP_ 0); #endif redc(_MIPP_ x, a); otstr(_MIPP_ a, s); printf("%s: %s\n", label, s); #ifndef MR_STATIC mr_free(a); #endif } */ void zzn2_inv(_MIPD_ zzn2 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(163) nres_modmult(_MIPP_ w->a,w->a,mr_mip->w1); nres_modmult(_MIPP_ w->b,w->b,mr_mip->w2); nres_modadd(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w1); if (mr_mip->qnr==-2) nres_modadd(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w1); redc(_MIPP_ mr_mip->w1,mr_mip->w6); invmodp(_MIPP_ mr_mip->w6,mr_mip->modulus,mr_mip->w6); nres(_MIPP_ mr_mip->w6,mr_mip->w6); nres_modmult(_MIPP_ w->a,mr_mip->w6,w->a); nres_negate(_MIPP_ mr_mip->w6,mr_mip->w6); nres_modmult(_MIPP_ w->b,mr_mip->w6,w->b); MR_OUT }
int main() { /* factoring program using Lenstras Elliptic Curve method */ int phase,m,k,nc,iv,pos,btch,u,v; long i,p,pa,interval; big q,x,z,a,x1,z1,x2,z2,xt,zt,n,fvw; static big fu[1+MULT/2]; static BOOL cp[1+MULT/2]; mip=mirsys(30,0); q=mirvar(0); x=mirvar(0); z=mirvar(0); a=mirvar(0); x1=mirvar(0); z1=mirvar(0); x2=mirvar(0); z2=mirvar(0); n=mirvar(0); t=mirvar(0); s1=mirvar(0); d1=mirvar(0); s2=mirvar(0); d2=mirvar(0); ak=mirvar(0); xt=mirvar(0); zt=mirvar(0); fvw=mirvar(0); w=mirvar(0); gprime(LIMIT1); for (m=1;m<=MULT/2;m+=2) if (igcd(MULT,m)==1) { fu[m]=mirvar(0); cp[m]=TRUE; } else cp[m]=FALSE; printf("input number to be factored\n"); cinnum(n,stdin); if (isprime(n)) { printf("this number is prime!\n"); return 0; } prepare_monty(n); for (nc=1,k=6;k<100;k++) { /* try a new curve */ /* generating an elliptic curve */ u=k*k-5; v=4*k; convert(u,x); nres(x,x); convert(v,z); nres(z,z); nres_modsub(z,x,a); /* a=v-u */ copy(x,t); nres_modmult(x,x,x); nres_modmult(x,t,x); /* x=u^3 */ copy(z,t); nres_modmult(z,z,z); nres_modmult(z,t,z); /* z=v^3 */ copy(a,t); nres_modmult(t,t,t); nres_modmult(t,a,t); /* t=(v-u)^3 */ convert(3*u,a); nres(a,a); convert(v,ak); nres(ak,ak); nres_modadd(a,ak,a); nres_modmult(t,a,t); /* t=(v-u)^3.(3u+v) */ convert(u,a); nres(a,a); copy(a,ak); nres_modmult(a,a,a); nres_modmult(a,ak,a); /* a=u^3 */ convert(v,ak); nres(ak,ak); nres_modmult(a,ak,a); /* a=u^3.v */ nres_premult(a,16,a); nres_moddiv(t,a,ak); /* ak=(v-u)^3.(3u+v)/16u^3v */ nc++; phase=1; p=0; i=0; btch=50; printf("phase 1 - trying all primes less than %d\n",LIMIT1); printf("prime= %8ld",p); forever { /* main loop */ if (phase==1) { p=mip->PRIMES[i]; if (mip->PRIMES[i+1]==0) { /* now change gear */ phase=2; printf("\nphase 2 - trying last prime less than %ld\n", LIMIT2); printf("prime= %8ld",p); copy(x,xt); copy(z,zt); nres_modadd(x,z,s2); nres_modsub(x,z,d2); /* P = (s2,d2) */ duplication(s2,d2,x,z); nres_modadd(x,z,s1); nres_modsub(x,z,d1); /* 2.P = (s1,d1) */ nres_moddiv(x1,z1,fu[1]); /* fu[1] = x1/z1 */ addition(x1,z1,s1,d1,s2,d2,x2,z2); /* 3.P = (x2,z2) */ for (m=5;m<=MULT/2;m+=2) { /* calculate m.P = (x,z) and store fu[m] = x/z */ nres_modadd(x2,z2,s2); nres_modsub(x2,z2,d2); addition(x1,z1,s2,d2,s1,d1,x,z); copy(x2,x1); copy(z2,z1); copy(x,x2); copy(z,z2); if (!cp[m]) continue; copy(z2,fu[m]); nres_moddiv(x2,fu[m],fu[m]); } ellipse(xt,zt,MULT,x,z,x2,z2); nres_modadd(x,z,xt); nres_modsub(x,z,zt); /* MULT.P = (xt,zt) */ iv=(int)(p/MULT); if (p%MULT>MULT/2) iv++; interval=(long)iv*MULT; p=interval+1; ellipse(x,z,iv,x1,z1,x2,z2); /* (x1,z1) = iv.MULT.P */ nres_moddiv(x1,z1,fvw); /* fvw = x1/z1 */ nres_modsub(fvw,fu[p%MULT],q); marks(interval); btch*=100; i++; continue; } pa=p; while ((LIMIT1/p) > pa) pa*=p; ellipse(x,z,(int)pa,x1,z1,x2,z2); copy(x1,x); copy(z1,z); copy(z,q); } else { /* phase 2 - looking for last large prime factor of (p+1+d) */ p+=2; pos=(int)(p%MULT); if (pos>MULT/2) { /* increment giant step */ iv++; interval=(long)iv*MULT; p=interval+1; marks(interval); pos=1; nres_moddiv(x2,z2,fvw); nres_modadd(x2,z2,s2); nres_modsub(x2,z2,d2); addition(x1,z1,s2,d2,xt,zt,x,z); copy(x2,x1); copy(z2,z1); copy(x,x2); copy(z,z2); } if (!cp[pos]) continue; /* if neither interval +/- pos is prime, don't bother */ if (!plus[pos] && !minus[pos]) continue; nres_modsub(fvw,fu[pos],t); nres_modmult(q,t,q); } if (i++%btch==0) { /* try for a solution */ printf("\b\b\b\b\b\b\b\b%8ld",p); fflush(stdout); egcd(q,n,t); if (size(t)==1) { if (p>LIMIT2) break; else continue; } if (compare(t,n)==0) { printf("\ndegenerate case"); break; } printf("\nfactors are\n"); if (isprime(t)) printf("prime factor "); else printf("composite factor "); cotnum(t,stdout); divide(n,t,n); if (isprime(n)) printf("prime factor "); else printf("composite factor "); cotnum(n,stdout); return 0; } } if (nc>NCURVES) break; printf("\ntrying a different curve %d\n",nc); } printf("\nfailed to factor\n"); return 0; }