in src/pair.js [472:614]
fexp: function(m) {
var fa, fb, f, x, r, lv,
x0, x1, x2, x3, x4, x5,
y0, y1, y2, y3;
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);
x = new ctx.BIG(0);
x.rcopy(ctx.ROM_CURVE.CURVE_Bnx);
r = new ctx.FP12(m);
/* Easy part of final exp */
lv = new ctx.FP12(r);
lv.inverse();
r.conj();
r.mul(lv);
lv.copy(r);
r.frob(f);
r.frob(f);
r.mul(lv);
// if (r.isunity())
// {
// r.zero();
// return r;
// }
/* Hard part of final exp */
if (ctx.ECP.CURVE_PAIRING_TYPE == ctx.ECP.BN) {
lv.copy(r);
lv.frob(f);
x0 = new ctx.FP12(lv); //x0.copy(lv);
x0.frob(f);
lv.mul(r);
x0.mul(lv);
x0.frob(f);
x1 = new ctx.FP12(r); //x1.copy(r);
x1.conj();
x4 = r.pow(x);
if (ctx.ECP.SIGN_OF_X == ctx.ECP.POSITIVEX) {
x4.conj();
}
x3 = new ctx.FP12(x4); //x3.copy(x4);
x3.frob(f);
x2 = x4.pow(x);
if (ctx.ECP.SIGN_OF_X == ctx.ECP.POSITIVEX) {
x2.conj();
}
x5 = new ctx.FP12(x2); /*x5.copy(x2);*/
x5.conj();
lv = x2.pow(x);
if (ctx.ECP.SIGN_OF_X == ctx.ECP.POSITIVEX) {
lv.conj();
}
x2.frob(f);
r.copy(x2);
r.conj();
x4.mul(r);
x2.frob(f);
r.copy(lv);
r.frob(f);
lv.mul(r);
lv.usqr();
lv.mul(x4);
lv.mul(x5);
r.copy(x3);
r.mul(x5);
r.mul(lv);
lv.mul(x2);
r.usqr();
r.mul(lv);
r.usqr();
lv.copy(r);
lv.mul(x1);
r.mul(x0);
lv.usqr();
r.mul(lv);
r.reduce();
} else {
// Ghamman & Fouotsa Method
y0 = new ctx.FP12(r);
y0.usqr();
y1 = y0.pow(x);
if (ctx.ECP.SIGN_OF_X==ctx.ECP.NEGATIVEX) {
y1.conj();
}
x.fshr(1);
y2 = y1.pow(x);
if (ctx.ECP.SIGN_OF_X==ctx.ECP.NEGATIVEX) {
y2.conj();
}
x.fshl(1);
y3 = new ctx.FP12(r);
y3.conj();
y1.mul(y3);
y1.conj();
y1.mul(y2);
y2 = y1.pow(x);
if (ctx.ECP.SIGN_OF_X==ctx.ECP.NEGATIVEX) {
y2.conj();
}
y3 = y2.pow(x);
if (ctx.ECP.SIGN_OF_X==ctx.ECP.NEGATIVEX) {
y3.conj();
}
y1.conj();
y3.mul(y1);
y1.conj();
y1.frob(f);
y1.frob(f);
y1.frob(f);
y2.frob(f);
y2.frob(f);
y1.mul(y2);
y2 = y3.pow(x);
if (ctx.ECP.SIGN_OF_X==ctx.ECP.NEGATIVEX) {
y2.conj();
}
y2.mul(y0);
y2.mul(r);
y1.mul(y2);
y2.copy(y3);
y2.frob(f);
y1.mul(y2);
r.copy(y1);
r.reduce();
}
return r;
}