in src/pair.js [357:463]
ate2: function(P1, Q1, R1, S1) {
var fa, fb, f, x, n, n3, K, lv, lv2,
Qx, Qy, Sx, Sy, A, B, NP,NR,r, nb, bt,
i;
n = new ctx.BIG(0);
n3 = new ctx.BIG(0);
K = new ctx.ECP2();
if (ctx.ECP.CURVE_PAIRING_TYPE == ctx.ECP.BN) {
fa = new ctx.BIG(0);
fa.rcopy(ctx.ROM_FIELD.Fra);
fb = new ctx.BIG(0);
fb.rcopy(ctx.ROM_FIELD.Frb);
f = new ctx.FP2(fa, fb);
if (ctx.ECP.SEXTIC_TWIST == ctx.ECP.M_TYPE) {
f.inverse();
f.norm();
}
}
var P=new ctx.ECP2(); P.copy(P1); P.affine();
var Q=new ctx.ECP(); Q.copy(Q1); Q.affine();
var R=new ctx.ECP2(); R.copy(R1); R.affine();
var S=new ctx.ECP(); S.copy(S1); S.affine();
Qx = new ctx.FP(Q.getx());
Qy = new ctx.FP(Q.gety());
Sx = new ctx.FP(S.getx());
Sy = new ctx.FP(S.gety());
A = new ctx.ECP2();
B = new ctx.ECP2();
r = new ctx.FP12(1);
A.copy(P);
B.copy(R);
NP = new ctx.ECP2();
NP.copy(P);
NP.neg();
NR = new ctx.ECP2();
NR.copy(R);
NR.neg();
nb = PAIR.lbits(n3,n);
for (i = nb - 2; i >= 1; i--) {
r.sqr();
lv = PAIR.line(A, A, Qx, Qy);
lv2 = PAIR.line(B, B, Sx, Sy);
lv.smul(lv2);
r.ssmul(lv);
bt=n3.bit(i)-n.bit(i);
if (bt == 1) {
lv = PAIR.line(A, P, Qx, Qy);
lv2 = PAIR.line(B, R, Sx, Sy);
lv.smul(lv2);
r.ssmul(lv);
}
if (bt == -1) {
lv = PAIR.line(A, NP, Qx, Qy);
lv2 = PAIR.line(B, NR, Sx, Sy);
lv.smul(lv2);
r.ssmul(lv);
}
}
if (ctx.ECP.SIGN_OF_X == ctx.ECP.NEGATIVEX) {
r.conj();
}
// R-ate fixup required for BN curves
if (ctx.ECP.CURVE_PAIRING_TYPE == ctx.ECP.BN) {
if (ctx.ECP.SIGN_OF_X == ctx.ECP.NEGATIVEX) {
A.neg();
B.neg();
}
K.copy(P);
K.frob(f);
lv = PAIR.line(A, K, Qx, Qy);
K.frob(f);
K.neg();
lv2 = PAIR.line(A, K, Qx, Qy);
lv.smul(lv2);
r.ssmul(lv);
K.copy(R);
K.frob(f);
lv = PAIR.line(B, K, Sx, Sy);
K.frob(f);
K.neg();
lv2 = PAIR.line(B, K, Sx, Sy);
lv.smul(lv2);
r.ssmul(lv);
}
return r;
},