/* Line function */ static void PAIR_line(FP12 *v,ECP2 *A,ECP2 *B,BIG Qx,BIG Qy) { ECP2 P; FP2 Z3,X,Y,ZZ,T,NY; FP4 a,b,c; int D; ECP2_copy(&P,A); if (A==B) D=ECP2_dbl(A); // check these return numbers... else D=ECP2_add(A,B); if (D<0) { /* Infinity */ FP12_one(v); return; } FP2_copy(&Z3,&(A->z)); FP4_zero(&c); FP2_sqr(&ZZ,&(P.z)); /* ZZ=Z^2 */ if (D==0) { /* addition */ ECP2_get(&X,&Y,B); FP2_mul(&T,&(P.z),&Y); /* T=Z*Y2 */ FP2_mul(&ZZ,&ZZ,&T); FP2_neg(&NY,&(P.y)); FP2_add(&ZZ,&ZZ,&NY); /* ZZ=Z^3*Y2-Y (slope numerator) */ FP2_pmul(&Z3,&Z3,Qy); /* Z3*Qy */ FP2_mul(&T,&T,&(P.x)); FP2_mul(&X,&X,&NY); FP2_add(&T,&T,&X); /* Z*Y2*X-X2*Y */ FP4_from_FP2s(&a,&Z3,&T); /* a=[Z3*Qy,Z*Y2*X-X2*Y] */ FP2_neg(&ZZ,&ZZ); FP2_pmul(&ZZ,&ZZ,Qx); FP4_from_FP2(&b,&ZZ); /* b=-slope*Qx */ } else { /* doubling */ FP2_sqr(&T,&(P.x)); FP2_imul(&T,&T,3); /* T=3X^2 (slope numerator) */ FP2_sqr(&Y,&(P.y)); FP2_add(&Y,&Y,&Y); /* Y=2Y^2 */ FP2_mul(&Z3,&Z3,&ZZ); /* Z3=Z3*ZZ */ FP2_pmul(&Z3,&Z3,Qy); /* Z3=Z3*ZZ*Qy */ FP2_mul(&X,&(P.x),&T); FP2_sub(&X,&X,&Y); /* X=X*slope-2Y^2 */ FP4_from_FP2s(&a,&Z3,&X); /* a=[Z3*ZZ*Qy , X*slope-2Y^2] */ FP2_neg(&T,&T); FP2_mul(&ZZ,&ZZ,&T); FP2_pmul(&ZZ,&ZZ,Qx); FP4_from_FP2(&b,&ZZ); /* b=-slope*ZZ*Qx */ } FP12_from_FP4s(v,&a,&b,&c); }
void FP12_pinpow(FP12 *r,int e,int bts) { int i,b; FP12 R[2]; FP12_one(&R[0]); FP12_copy(&R[1],r); for (i=bts-1;i>=0;i--) { b=(e>>i)&1; FP12_mul(&R[1-b],&R[b]); FP12_usqr(&R[b],&R[b]); } FP12_copy(r,&R[0]); }
void FP12_pow(FP12 *r,FP12 *a,BIG b) { FP12 w; BIG z,zilch; int bt; BIG_zero(zilch); BIG_norm(b); BIG_copy(z,b); FP12_copy(&w,a); FP12_one(r); while(1) { bt=BIG_parity(z); BIG_shr(z,1); if (bt) FP12_mul(r,&w); if (BIG_comp(z,zilch)==0) break; FP12_usqr(&w,&w); } FP12_reduce(r); }
/* Optimal R-ate pairing r=e(P,Q) */ void PAIR_ate(FP12 *r,ECP2 *P,ECP *Q) { FP2 X; BIG x,n,Qx,Qy; int i,nb; ECP2 A; FP12 lv; #if CHOICE<BLS_CURVES ECP2 KA; #endif BIG_rcopy(Qx,CURVE_Fra); BIG_rcopy(Qy,CURVE_Frb); FP2_from_BIGs(&X,Qx,Qy); BIG_rcopy(x,CURVE_Bnx); #if CHOICE<BLS_CURVES BIG_pmul(n,x,6); BIG_dec(n,2); #else BIG_copy(n,x); #endif BIG_norm(n); ECP2_affine(P); ECP_affine(Q); BIG_copy(Qx,Q->x); BIG_copy(Qy,Q->y); ECP2_copy(&A,P); FP12_one(r); nb=BIG_nbits(n); /* Main Miller Loop */ for (i=nb-2; i>=1; i--) { PAIR_line(&lv,&A,&A,Qx,Qy); FP12_smul(r,&lv); if (BIG_bit(n,i)) { PAIR_line(&lv,&A,P,Qx,Qy); FP12_smul(r,&lv); } FP12_sqr(r,r); } PAIR_line(&lv,&A,&A,Qx,Qy); FP12_smul(r,&lv); if (BIG_parity(n)) { PAIR_line(&lv,&A,P,Qx,Qy); FP12_smul(r,&lv); } /* R-ate fixup required for BN curves */ #if CHOICE<BLS_CURVES ECP2_copy(&KA,P); ECP2_frob(&KA,&X); ECP2_neg(&A); FP12_conj(r,r); PAIR_line(&lv,&A,&KA,Qx,Qy); FP12_smul(r,&lv); ECP2_frob(&KA,&X); ECP2_neg(&KA); PAIR_line(&lv,&A,&KA,Qx,Qy); FP12_smul(r,&lv); #endif }
void FP12_pow4(FP12 *p,FP12 *q,BIG u[4]) { int i,j,a[4],nb,m; FP12 g[8],c,s[2]; BIG t[4],mt; sign8 w[NLEN*BASEBITS+1]; for (i=0;i<4;i++) BIG_copy(t[i],u[i]); FP12_copy(&g[0],&q[0]); FP12_conj(&s[0],&q[1]); FP12_mul(&g[0],&s[0]); /* P/Q */ FP12_copy(&g[1],&g[0]); FP12_copy(&g[2],&g[0]); FP12_copy(&g[3],&g[0]); FP12_copy(&g[4],&q[0]); FP12_mul(&g[4],&q[1]); /* P*Q */ FP12_copy(&g[5],&g[4]); FP12_copy(&g[6],&g[4]); FP12_copy(&g[7],&g[4]); FP12_copy(&s[1],&q[2]); FP12_conj(&s[0],&q[3]); FP12_mul(&s[1],&s[0]); /* R/S */ FP12_conj(&s[0],&s[1]); FP12_mul(&g[1],&s[0]); FP12_mul(&g[2],&s[1]); FP12_mul(&g[5],&s[0]); FP12_mul(&g[6],&s[1]); FP12_copy(&s[1],&q[2]); FP12_mul(&s[1],&q[3]); /* R*S */ FP12_conj(&s[0],&s[1]); FP12_mul(&g[0],&s[0]); FP12_mul(&g[3],&s[1]); FP12_mul(&g[4],&s[0]); FP12_mul(&g[7],&s[1]); /* if power is even add 1 to power, and add q to correction */ FP12_one(&c); BIG_zero(mt); for (i=0;i<4;i++) { if (BIG_parity(t[i])==0) { BIG_inc(t[i],1); BIG_norm(t[i]); FP12_mul(&c,&q[i]); } BIG_add(mt,mt,t[i]); BIG_norm(mt); } FP12_conj(&c,&c); nb=1+BIG_nbits(mt); /* convert exponent to signed 1-bit window */ for (j=0;j<nb;j++) { for (i=0;i<4;i++) { a[i]=BIG_lastbits(t[i],2)-2; BIG_dec(t[i],a[i]); BIG_norm(t[i]); BIG_fshr(t[i],1); } w[j]=8*a[0]+4*a[1]+2*a[2]+a[3]; } w[nb]=8*BIG_lastbits(t[0],2)+4*BIG_lastbits(t[1],2)+2*BIG_lastbits(t[2],2)+BIG_lastbits(t[3],2); FP12_copy(p,&g[(w[nb]-1)/2]); for (i=nb-1;i>=0;i--) { m=w[i]>>7; j=(w[i]^m)-m; /* j=abs(w[i]) */ j=(j-1)/2; FP12_copy(&s[0],&g[j]); FP12_conj(&s[1],&g[j]); FP12_usqr(p,p); FP12_mul(p,&s[m&1]); } FP12_mul(p,&c); /* apply correction */ FP12_reduce(p); }
/* Optimal R-ate pairing r=e(P,Q) */ void PAIR_ate(FP12 *r,ECP2 *P,ECP *Q) { FP2 X; BIG x,n,Qx,Qy; int i,nb; ECP2 A,KA; FP12 lv; BIG_rcopy(Qx,CURVE_Fra); BIG_rcopy(Qy,CURVE_Frb); FP2_from_BIGs(&X,Qx,Qy); BIG_rcopy(x,CURVE_Bnx); BIG_pmul(n,x,6); BIG_dec(n,2); BIG_norm(n); ECP2_affine(P); ECP_affine(Q); BIG_copy(Qx,Q->x); BIG_copy(Qy,Q->y); ECP2_copy(&A,P); FP12_one(r); nb=BIG_nbits(n); /* Main Miller Loop */ for (i=nb-2;i>=1;i--) { PAIR_line(&lv,&A,&A,Qx,Qy); FP12_smul(r,&lv); if (BIG_bit(n,i)) { PAIR_line(&lv,&A,P,Qx,Qy); FP12_smul(r,&lv); } FP12_sqr(r,r); } PAIR_line(&lv,&A,&A,Qx,Qy); FP12_smul(r,&lv); /* R-ate fixup */ ECP2_copy(&KA,P); ECP2_frob(&KA,&X); ECP2_neg(&A); FP12_conj(r,r); PAIR_line(&lv,&A,&KA,Qx,Qy); FP12_smul(r,&lv); ECP2_frob(&KA,&X); ECP2_neg(&KA); PAIR_line(&lv,&A,&KA,Qx,Qy); FP12_smul(r,&lv); }