/* map octet string to point on curve */ static void mapit(octet *h,ECP *P) { BIG q,px; BIG_fromBytes(px,h->val); BIG_rcopy(q,Modulus); BIG_mod(px,q); while (!ECP_setx(P,px,0)) BIG_inc(px,1); }
/* maps a random u to a point on the curve */ static void map(ECP *P,BIG u,int cb) { BIG x,q; BIG_rcopy(q,Modulus); BIG_copy(x,u); BIG_mod(x,q); while (!ECP_setx(P,x,cb)) BIG_inc(x,1); }
/* r=x^n using XTR method on traces of FP12s */ void FP4_xtr_pow(FP4 *r,FP4 *x,BIG n) { int i,par,nb; BIG v; FP2 w; FP4 t,a,b,c; BIG_zero(v); BIG_inc(v,3); FP2_from_BIG(&w,v); FP4_from_FP2(&a,&w); FP4_copy(&b,x); FP4_xtr_D(&c,x); BIG_norm(n); par=BIG_parity(n); BIG_copy(v,n); BIG_shr(v,1); if (par==0) {BIG_dec(v,1); BIG_norm(v);} nb=BIG_nbits(v); for (i=nb-1;i>=0;i--) { if (!BIG_bit(v,i)) { FP4_copy(&t,&b); FP4_conj(x,x); FP4_conj(&c,&c); FP4_xtr_A(&b,&a,&b,x,&c); FP4_conj(x,x); FP4_xtr_D(&c,&t); FP4_xtr_D(&a,&a); } else { FP4_conj(&t,&a); FP4_xtr_D(&a,&b); FP4_xtr_A(&b,&c,&b,x,&t); FP4_xtr_D(&c,&c); } } if (par==0) FP4_copy(r,&c); else FP4_copy(r,&b); FP4_reduce(r); }
/* needed for SOK */ static void mapit2(octet *h,ECP2 *Q) { BIG q,one,Fx,Fy,x,hv; FP2 X; ECP2 T,K; BIG_fromBytes(hv,h->val); BIG_rcopy(q,Modulus); BIG_one(one); BIG_mod(hv,q); for (;;) { FP2_from_BIGs(&X,one,hv); if (ECP2_setx(Q,&X)) break; BIG_inc(hv,1); } /* Fast Hashing to G2 - Fuentes-Castaneda, Knapp and Rodriguez-Henriquez */ BIG_rcopy(Fx,CURVE_Fra); BIG_rcopy(Fy,CURVE_Frb); FP2_from_BIGs(&X,Fx,Fy); BIG_rcopy(x,CURVE_Bnx); ECP2_copy(&T,Q); ECP2_mul(&T,x); ECP2_neg(&T); /* our x is negative */ ECP2_copy(&K,&T); ECP2_dbl(&K); ECP2_add(&K,&T); ECP2_affine(&K); ECP2_frob(&K,&X); ECP2_frob(Q,&X); ECP2_frob(Q,&X); ECP2_frob(Q,&X); ECP2_add(Q,&T); ECP2_add(Q,&K); ECP2_frob(&T,&X); ECP2_frob(&T,&X); ECP2_add(Q,&T); ECP2_affine(Q); }
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); }