/* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */ void PAIR_fexp(FP12 *r) { FP2 X; BIG x,a,b; FP12 t0,y0,y1,y2,y3; BIG_rcopy(x,CURVE_Bnx); BIG_rcopy(a,CURVE_Fra); BIG_rcopy(b,CURVE_Frb); FP2_from_BIGs(&X,a,b); /* Easy part of final exp */ FP12_inv(&t0,r); FP12_conj(r,r); FP12_mul(r,&t0); FP12_copy(&t0,r); FP12_frob(r,&X); FP12_frob(r,&X); FP12_mul(r,&t0); /* Hard part of final exp - see Duquesne & Ghamman eprint 2015/192.pdf */ #if CHOICE<BLS_CURVES FP12_pow(&t0,r,x); // t0=f^-u FP12_usqr(&y3,&t0); // y3=t0^2 FP12_copy(&y0,&t0); FP12_mul(&y0,&y3); // y0=t0*y3 FP12_copy(&y2,&y3); FP12_frob(&y2,&X); // y2=y3^p FP12_mul(&y2,&y3); //y2=y2*y3 FP12_usqr(&y2,&y2); //y2=y2^2 FP12_mul(&y2,&y3); // y2=y2*y3 FP12_pow(&t0,&y0,x); //t0=y0^-u FP12_conj(&y0,r); //y0=~r FP12_copy(&y1,&t0); FP12_frob(&y1,&X); FP12_frob(&y1,&X); //y1=t0^p^2 FP12_mul(&y1,&y0); // y1=y0*y1 FP12_conj(&t0,&t0); // t0=~t0 FP12_copy(&y3,&t0); FP12_frob(&y3,&X); //y3=t0^p FP12_mul(&y3,&t0); // y3=t0*y3 FP12_usqr(&t0,&t0); // t0=t0^2 FP12_mul(&y1,&t0); // y1=t0*y1 FP12_pow(&t0,&y3,x); // t0=y3^-u FP12_usqr(&t0,&t0); //t0=t0^2 FP12_conj(&t0,&t0); //t0=~t0 FP12_mul(&y3,&t0); // y3=t0*y3 FP12_frob(r,&X); FP12_copy(&y0,r); FP12_frob(r,&X); FP12_mul(&y0,r); FP12_frob(r,&X); FP12_mul(&y0,r); FP12_usqr(r,&y3); //r=y3^2 FP12_mul(r,&y2); //r=y2*r FP12_copy(&y3,r); FP12_mul(&y3,&y0); // y3=r*y0 FP12_mul(r,&y1); // r=r*y1 FP12_usqr(r,r); // r=r^2 FP12_mul(r,&y3); // r=r*y3 FP12_reduce(r); #else // Ghamman & Fouotsa Method FP12_usqr(&y0,r); FP12_pow(&y1,&y0,x); BIG_fshr(x,1); FP12_pow(&y2,&y1,x); BIG_fshl(x,1); // x must be even FP12_conj(&y3,r); FP12_mul(&y1,&y3); FP12_conj(&y1,&y1); FP12_mul(&y1,&y2); FP12_pow(&y2,&y1,x); FP12_pow(&y3,&y2,x); FP12_conj(&y1,&y1); FP12_mul(&y3,&y1); FP12_conj(&y1,&y1); FP12_frob(&y1,&X); FP12_frob(&y1,&X); FP12_frob(&y1,&X); FP12_frob(&y2,&X); FP12_frob(&y2,&X); FP12_mul(&y1,&y2); FP12_pow(&y2,&y3,x); FP12_mul(&y2,&y0); FP12_mul(&y2,r); FP12_mul(&y1,&y2); FP12_copy(&y2,&y3); FP12_frob(&y2,&X); FP12_mul(&y1,&y2); FP12_copy(r,&y1); FP12_reduce(r); // Aranha et al method as described by Ghamman & Fouotsa /* FP12_usqr(&y0,r); // t0=f^2 FP12_conj(&y3,&y0); // t0=f^-2 FP12_pow(&t0,r,x); // t5=f^u FP12_usqr(&y1,&t0); // t1=t5^2 FP12_mul(&y3,&t0); // t3=t0*t5 FP12_pow(&y0,&y3,x); FP12_pow(&y2,&y0,x); FP12_pow(&y4,&y2,x); FP12_mul(&y4,&y1); FP12_pow(&y1,&y4,x); FP12_conj(&y3,&y3); FP12_mul(&y1,&y3); FP12_mul(&y1,r); FP12_conj(&y3,r); FP12_mul(&y0,r); FP12_frob(&y0,&X); FP12_frob(&y0,&X); FP12_frob(&y0,&X); FP12_mul(&y4,&y3); FP12_frob(&y4,&X); FP12_mul(&t0,&y2); FP12_frob(&t0,&X); FP12_frob(&t0,&X); FP12_mul(&t0,&y0); FP12_mul(&t0,&y4); FP12_mul(&t0,&y1); FP12_copy(r,&t0); FP12_reduce(r);*/ //----------------------------------- /* FP12_copy(&y0,r); // y0=r; FP12_copy(&y1,r); // y1=r; FP12_copy(&t0,r); FP12_frob(&t0,&X); // t0=Frobenius(r,X,1); FP12_conj(&y3,&t0); FP12_mul(&y1,&y3); // y1*=inverse(t0); FP12_frob(&t0,&X); FP12_frob(&t0,&X); // t0=Frobenius(t0,X,2); FP12_mul(&y1,&t0); // y1*=t0; FP12_pow(r,r,x); // r=pow(r,x); FP12_conj(&y3,r); FP12_mul(&y1,&y3); // y1*=inverse(r); FP12_copy(&t0,r); FP12_frob(&t0,&X); // t0=Frobenius(r,X,1); FP12_mul(&y0,&t0); // y0*=t0; FP12_frob(&t0,&X); // t0=Frobenius(t0,X,1); FP12_mul(&y1,&t0); // y1*=t0; FP12_frob(&t0,&X); // t0=Frobenius(t0,X,1); FP12_conj(&y3,&t0); FP12_mul(&y0,&y3); // y0*=inverse(t0); FP12_pow(r,r,x); // r=pow(r,x); FP12_mul(&y0,r); // y0*=r; FP12_copy(&t0,r); FP12_frob(&t0,&X); FP12_frob(&t0,&X); // t0=Frobenius(r,X,2); FP12_conj(&y3,&t0); FP12_mul(&y0,&y3); // y0*=inverse(t0); FP12_frob(&t0,&X); // t0=Frobenius(t0,X,1); FP12_mul(&y1,&t0); // y1*=t0; FP12_pow(r,r,x); // r=pow(r,x); // r^x3 FP12_copy(&t0,r); FP12_frob(&t0,&X); // t0=Frobenius(r,X,1); FP12_conj(&y3,&t0); FP12_mul(&y0,&y3); // y0*=inverse(t0); FP12_frob(&t0,&X); // t0=Frobenius(t0,X,1); FP12_mul(&y1,&t0); // y1*=t0; FP12_pow(r,r,x); // r=pow(r,x); // r^x4 FP12_conj(&y3,r); FP12_mul(&y0,&y3); // y0*=inverse(r); FP12_copy(&t0,r); FP12_frob(&t0,&X); // t0=Frobenius(r,X,1); FP12_mul(&y1,&t0); //y1*=t0; FP12_pow(r,r,x); // r=pow(r,x); // r^x5 FP12_mul(&y1,r); // y1*=r; FP12_usqr(&y0,&y0); // r=y0*y0*y1; FP12_mul(&y0,&y1); FP12_copy(r,&y0); FP12_reduce(r); */ #endif }
/* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */ void PAIR_fexp(FP12 *r) { FP2 X; BIG x,a,b; FP12 t0,y0,y1,y2,y3; BIG_rcopy(x,CURVE_Bnx); BIG_rcopy(a,CURVE_Fra); BIG_rcopy(b,CURVE_Frb); FP2_from_BIGs(&X,a,b); /* Easy part of final exp */ FP12_inv(&t0,r); FP12_conj(r,r); FP12_mul(r,&t0); FP12_copy(&t0,r); FP12_frob(r,&X); FP12_frob(r,&X); FP12_mul(r,&t0); /* Hard part of final exp - see Duquesne & Ghamman eprint 2015/192.pdf */ FP12_pow(&t0,r,x); // t0=f^-u FP12_usqr(&y3,&t0); // y3=t0^2 FP12_copy(&y0,&t0); FP12_mul(&y0,&y3); // y0=t0*y3 FP12_copy(&y2,&y3); FP12_frob(&y2,&X); // y2=y3^p FP12_mul(&y2,&y3); //y2=y2*y3 FP12_usqr(&y2,&y2); //y2=y2^2 FP12_mul(&y2,&y3); // y2=y2*y3 FP12_pow(&t0,&y0,x); //t0=y0^-u FP12_conj(&y0,r); //y0=~r FP12_copy(&y1,&t0); FP12_frob(&y1,&X); FP12_frob(&y1,&X); //y1=t0^p^2 FP12_mul(&y1,&y0); // y1=y0*y1 FP12_conj(&t0,&t0); // t0=~t0 FP12_copy(&y3,&t0); FP12_frob(&y3,&X); //y3=t0^p FP12_mul(&y3,&t0); // y3=t0*y3 FP12_usqr(&t0,&t0); // t0=t0^2 FP12_mul(&y1,&t0); // y1=t0*y1 FP12_pow(&t0,&y3,x); // t0=y3^-u FP12_usqr(&t0,&t0); //t0=t0^2 FP12_conj(&t0,&t0); //t0=~t0 FP12_mul(&y3,&t0); // y3=t0*y3 FP12_frob(r,&X); FP12_copy(&y0,r); FP12_frob(r,&X); FP12_mul(&y0,r); FP12_frob(r,&X); FP12_mul(&y0,r); FP12_usqr(r,&y3); //r=y3^2 FP12_mul(r,&y2); //r=y2*r FP12_copy(&y3,r); FP12_mul(&y3,&y0); // y3=r*y0 FP12_mul(r,&y1); // r=r*y1 FP12_usqr(r,r); // r=r^2 FP12_mul(r,&y3); // r=r*y3 FP12_reduce(r); /* our way */ /* // FP12 lv,x0,x1,x2,x3,x4,x5; FP12_copy(&lv,r); FP12_frob(&lv,&X); FP12_copy(&x0,&lv); FP12_frob(&x0,&X); FP12_mul(&lv,r); FP12_mul(&x0,&lv); FP12_frob(&x0,&X); FP12_conj(&x1,r); FP12_pow(&x4,r,x); FP12_copy(&x3,&x4); FP12_frob(&x3,&X); FP12_pow(&x2,&x4,x); FP12_conj(&x5,&x2); FP12_pow(&lv,&x2,x); FP12_frob(&x2,&X); FP12_conj(r,&x2); FP12_mul(&x4,r); FP12_frob(&x2,&X); FP12_copy(r,&lv); FP12_frob(r,&X); FP12_mul(&lv,r); FP12_usqr(&lv,&lv); FP12_mul(&lv,&x4); FP12_mul(&lv,&x5); FP12_copy(r,&x3); FP12_mul(r,&x5); FP12_mul(r,&lv); FP12_mul(&lv,&x2); FP12_usqr(r,r); FP12_mul(r,&lv); FP12_usqr(r,r); FP12_copy(&lv,r); FP12_mul(&lv,&x1); FP12_mul(r,&x0); FP12_usqr(&lv,&lv); FP12_mul(r,&lv); FP12_reduce(r); */ }