void mul(_MIPD_ big *a,big *b,big *r) { /* Special multiplier for GF(2^{4m}) values of the form (x,y,y+1,0) */ fcopy2(a[1],mr_mip->w2); fcopy2(b[1],mr_mip->w3); fadd2(a[1],a[0],mr_mip->w8); /* e=w+p */ fadd2(b[1],b[0],mr_mip->w9); /* s=t+q */ /* only 3 modmults.. */ modmult2(_MIPP_ mr_mip->w9,mr_mip->w8,mr_mip->w9); /* z=(w+p)*(t+q) */ modmult2(_MIPP_ mr_mip->w3,mr_mip->w2,mr_mip->w4); /* tw=t*w */ modmult2(_MIPP_ a[0],b[0],mr_mip->w8); /* pq=p*q */ fincr2(mr_mip->w4,mr_mip->w9); /* z+=tw */ fincr2(mr_mip->w8,mr_mip->w9); /* z+=pq */ fincr2(mr_mip->w3,mr_mip->w2); /* w+=t */ fadd2(mr_mip->w2,mr_mip->w4,mr_mip->w3); /* t=w+tw */ incr2(mr_mip->w3,1,mr_mip->w3); /* t=w+tw+1 */ fadd2(mr_mip->w9,a[0],mr_mip->w12); /* x=z+p */ fincr2(b[0],mr_mip->w12); /* x=z+p+q */ fadd2(mr_mip->w8,mr_mip->w3,r[0]); /* r[0]=pq+t */ fadd2(mr_mip->w9,mr_mip->w3,r[1]); /* r[1]=z+t */ fadd2(mr_mip->w12,mr_mip->w4,r[2]); /* r[2]=z+p+q+tw */ fcopy2(mr_mip->w2,r[3]); /* r[3]=w */ }
void mult4(_MIPD_ big *a,big *b,big *c) { fadd2(a[1],a[3],mr_mip->w3); fadd2(a[0],a[2],mr_mip->w4); fadd2(b[1],b[3],mr_mip->w8); fadd2(b[0],b[2],mr_mip->w9); modmult2(_MIPP_ mr_mip->w8,mr_mip->w3,mr_mip->w10); modmult2(_MIPP_ mr_mip->w9,mr_mip->w4,mr_mip->w11); modmult2(_MIPP_ a[1],b[1],mr_mip->w2); modmult2(_MIPP_ a[2],b[2],mr_mip->w1); fadd2(mr_mip->w2,mr_mip->w1,mr_mip->w13); fadd2(a[1],a[0],c[1]); fadd2(b[0],b[1],mr_mip->w12); modmult2(_MIPP_ c[1],mr_mip->w12,c[1]); modmult2(_MIPP_ a[0],b[0],c[0]); fincr2(c[0],c[1]); fincr2(mr_mip->w2,c[1]); fcopy2(a[2],c[2]); fadd2(a[2],a[3],mr_mip->w12); fadd2(b[2],b[3],mr_mip->w2); modmult2(_MIPP_ mr_mip->w12,mr_mip->w2,mr_mip->w12); fincr2(mr_mip->w12,mr_mip->w1); modmult2(_MIPP_ a[3],b[3],mr_mip->w2); fincr2(mr_mip->w2,mr_mip->w1); fadd2(mr_mip->w9,mr_mip->w8,mr_mip->w12); fcopy2(mr_mip->w12,c[3]); fadd2(mr_mip->w4,mr_mip->w3,mr_mip->w12); modmult2(_MIPP_ c[3],mr_mip->w12,c[3]); fincr2(mr_mip->w2,mr_mip->w1); fincr2(mr_mip->w10,c[3]); fincr2(mr_mip->w11,c[3]); fincr2(mr_mip->w1,c[3]); fincr2(c[1],c[3]); fadd2(mr_mip->w13,c[0],c[2]); fincr2(mr_mip->w11,c[2]); fincr2(mr_mip->w1,c[2]); fincr2(mr_mip->w1,c[1]); fincr2(mr_mip->w10,mr_mip->w13); fincr2(mr_mip->w13,c[1]); fincr2(mr_mip->w2,mr_mip->w13); fincr2(mr_mip->w13,c[0]); return; }
GF2m& GF2m::operator/=(const GF2m& b) { GF2m z=b; inverse2(z.fn,z.fn); modmult2(fn,z.fn,fn); return *this; }
GF2m operator/(const GF2m& b1,const GF2m& b2) { GF2m abb; inverse2(b2.fn,abb.fn); modmult2(b1.fn,abb.fn,abb.fn); return abb; }
void eta_T(_MIPD_ epoint *P,epoint *Q,big *f,big *res) { big xp,yp,xq,yq,t,d; big miller[4],v[4],u[4]; int i,m=M; int promptr; #ifndef MR_STATIC char *mem=(char *)memalloc(_MIPP_ 18); #else char mem[MR_BIG_RESERVE(18)]; /* 972 bytes from stack */ memset(mem,0,MR_BIG_RESERVE(18)); #endif xp=mirvar_mem(_MIPP_ mem,0); yp=mirvar_mem(_MIPP_ mem,1); xq=mirvar_mem(_MIPP_ mem,2); yq=mirvar_mem(_MIPP_ mem,3); t=mirvar_mem(_MIPP_ mem,4); d=mirvar_mem(_MIPP_ mem,5); for (i=0;i<4;i++) miller[i]=mirvar_mem(_MIPP_ mem,6+i); for (i=0;i<4;i++) v[i]=mirvar_mem(_MIPP_ mem,10+i); for (i=0;i<4;i++) u[i]=mirvar_mem(_MIPP_ mem,14+i); fcopy2(P->X,xp); fcopy2(P->Y,yp); fcopy2(Q->X,xq); fcopy2(Q->Y,yq); incr2(xp,1,t); /* t=xp+1 */ fadd2(xp,xq,d); incr2(d,1,d); /* xp+xq+1 */ modmult2(_MIPP_ d,t,d); /* t*(xp+xq+1) */ fincr2(yp,d); fincr2(yq,d); incr2(d,B,d); incr2(d,1,f[0]); /* f[0]=t*(xp+xq+1)+yp+yq+B+1 */ convert(_MIPP_ 1,miller[0]); fadd2(t,xq,f[2]); /* f[2]=t+xq */ incr2(f[2],1,f[1]); /* f[1]=t+xq+1 */ zero(f[3]); promptr=0; for (i=0;i<(m-1)/2;i+=2) { fcopy2(xp,t); sqroot2(_MIPP_ xp,xp); sqroot2(_MIPP_ yp,yp); fadd2(xp,xq,d); modmult2(_MIPP_ d,t,d); fincr2(yp,d); fincr2(yq,d); fadd2(d,xp,v[0]); /* v[0]=t*(xp+xq)+yp+yq+xp */ fadd2(t,xq,v[2]); /* v[2]=t+xq */ incr2(v[2],1,v[1]); /* v[1]=t+xq+1 */ modsquare2(_MIPP_ xq,xq); /* xq*=xq */ modsquare2(_MIPP_ yq,yq); /* yp*=yp */ fcopy2(xp,t); /* same again - unlooped times 2 */ sqroot2(_MIPP_ xp,xp); sqroot2(_MIPP_ yp,yp); fadd2(xp,xq,d); modmult2(_MIPP_ d,t,d); fincr2(yp,d); fincr2(yq,d); fadd2(d,xp,u[0]); fadd2(t,xq,u[2]); incr2(u[2],1,u[1]); modsquare2(_MIPP_ xq,xq); modsquare2(_MIPP_ yq,yq); mul(_MIPP_ u,v,u); /* fast mul */ mult4(_MIPP_ miller,u,miller); } mult4(_MIPP_ miller,f,miller); for (i=0;i<4;i++) { fcopy2(miller[i],u[i]); fcopy2(miller[i],v[i]); fcopy2(miller[i],f[i]); } /* final exponentiation */ for (i=0;i<(m+1)/2;i++) square4(_MIPP_ u,u); /* u*=u */ powq(_MIPP_ u); powq(_MIPP_ f); for(i=0;i<4;i++) fcopy2(f[i],v[i]); powq(_MIPP_ f); for(i=0;i<4;i++) fcopy2(f[i],res[i]); powq(_MIPP_ f); mult4(_MIPP_ f,u,f); mult4(_MIPP_ f,miller,f); mult4(_MIPP_ res,v,res); powq(_MIPP_ u); powq(_MIPP_ u); mult4(_MIPP_ res,u,res); /* doing inversion here could kill the stack... */ #ifndef MR_STATIC memkill(_MIPP_ mem,18); #else memset(mem,0,MR_BIG_RESERVE(18)); #endif }
void invert(_MIPD_ big *x) { int degF,degG,degB,degC,d,i,j; big alpha,beta,gamma,BB[4],FF[5],CC[4],GG[5],t; big *BP=BB,*CP=CC,*FP=FF,*GP=GG,*TP; #ifndef MR_STATIC char *mem=(char *)memalloc(_MIPP_ 22); #else char mem[MR_BIG_RESERVE(22)]; /* 972 bytes from the stack */ memset(mem,0,MR_BIG_RESERVE(22)); #endif alpha=mirvar_mem(_MIPP_ mem,0); beta=mirvar_mem(_MIPP_ mem,1); gamma=mirvar_mem(_MIPP_ mem,2); t=mirvar_mem(_MIPP_ mem,3); for (i=0;i<4;i++) BB[i]=mirvar_mem(_MIPP_ mem,4+i); for (i=0;i<5;i++) FF[i]=mirvar_mem(_MIPP_ mem,8+i); for (i=0;i<4;i++) CC[i]=mirvar_mem(_MIPP_ mem,13+i); for (i=0;i<5;i++) GG[i]=mirvar_mem(_MIPP_ mem,17+i); convert(_MIPP_ 1,CP[0]); convert(_MIPP_ 1,FP[0]); convert(_MIPP_ 1,FP[1]); convert(_MIPP_ 1,FP[4]); /* F = x^4+x+1 - irreducible polynomial for GF(2^{4m}) */ degF=4; degG=degree(x); degC=0; degB=-1; if (degG==0) { inverse2(_MIPP_ x[0],x[0]); return; } for (i=0;i<4;i++) { fcopy2(x[i],GP[i]); zero(x[i]); } while (degF!=0) { if (degF<degG) { /* swap */ TP=FP; FP=GP; GP=TP; d=degF; degF=degG; degG=d; TP=BP; BP=CP; CP=TP; d=degB; degB=degC; degC=d; } j=degF-degG; modsquare2(_MIPP_ GP[degG],alpha); modmult2(_MIPP_ FP[degF],GP[degG],beta); modmult2(_MIPP_ GP[degG],FP[degF-1],t); modmult2(_MIPP_ FP[degF],GP[degG-1],gamma); fincr2(t,gamma); zero(t); for (i=0;i<=degF;i++ ) { modmult2(_MIPP_ FP[i],alpha,FP[i]); if (i>=j-1) { modmult2(_MIPP_ gamma,GP[i-j+1],t); fincr2(t,FP[i]); } if (i>=j) { modmult2(_MIPP_ beta,GP[i-j],t); fincr2(t,FP[i]); } } for (i=0;i<=degB || i<=(degC+j);i++) { modmult2(_MIPP_ BP[i],alpha,BP[i]); if (i>=j-1) { modmult2(_MIPP_ gamma,CP[i-j+1],t); fincr2(t,BP[i]); } if (i>=j) { modmult2(_MIPP_ beta,CP[i-j],t); fincr2(t,BP[i]); } } while (degF>=0 && size(FP[degF])==0) degF--; if (degF==degG) { fcopy2(FP[degF],alpha); for (i=0;i<=degF;i++) { modmult2(_MIPP_ FP[i],GP[degF],FP[i]); modmult2(_MIPP_ alpha,GP[i],t); fincr2(t,FP[i]); } for (i=0;i<=4-degF;i++) { modmult2(_MIPP_ BP[i],GP[degF],BP[i]); modmult2(_MIPP_ CP[i],alpha,t); fincr2(t,BP[i]); } while (degF>=0 && size(FP[degF])==0) degF--; } degB=3; while (degB>=0 && size(BP[degB])==0) degB--; } inverse2(_MIPP_ FP[0],alpha); for (i=0;i<=degB;i++) modmult2(_MIPP_ alpha,BP[i],x[i]); #ifndef MR_STATIC memkill(_MIPP_ mem,22); #else memset(mem,0,MR_BIG_RESERVE(22)); #endif }