in src/ecp4.js [764:872]
ECP4.mul8 = function(Q, u) {
var W = new ECP4(),
P = new ECP4(),
T1 = [],
T2 = [],
mt = new ctx.BIG(),
t = [],
w1 = [],
s1 = [],
w2 = [],
s2 = [],
F=ECP4.frob_constants(),
i, j, k, nb, bt, pb1, pb2;
for (i = 0; i < 8; i++) {
t[i] = new ctx.BIG(u[i]); t[i].norm();
//Q[i].affine();
}
T1[0] = new ECP4(); T1[0].copy(Q[0]); // Q[0]
T1[1] = new ECP4(); T1[1].copy(T1[0]); T1[1].add(Q[1]); // Q[0]+Q[1]
T1[2] = new ECP4(); T1[2].copy(T1[0]); T1[2].add(Q[2]); // Q[0]+Q[2]
T1[3] = new ECP4(); T1[3].copy(T1[1]); T1[3].add(Q[2]); // Q[0]+Q[1]+Q[2]
T1[4] = new ECP4(); T1[4].copy(T1[0]); T1[4].add(Q[3]); // Q[0]+Q[3]
T1[5] = new ECP4(); T1[5].copy(T1[1]); T1[5].add(Q[3]); // Q[0]+Q[1]+Q[3]
T1[6] = new ECP4(); T1[6].copy(T1[2]); T1[6].add(Q[3]); // Q[0]+Q[2]+Q[3]
T1[7] = new ECP4(); T1[7].copy(T1[3]); T1[7].add(Q[3]); // Q[0]+Q[1]+Q[2]+Q[3]
// Use Frobenius
for (i=0;i<8;i++) {
T2[i] = new ECP4(); T2[i].copy(T1[i]);
T2[i].frob(F,4);
}
// Make it odd
pb1=1-t[0].parity();
t[0].inc(pb1);
t[0].norm();
pb2=1-t[4].parity();
t[4].inc(pb2);
t[4].norm();
// Number of bits
mt.zero();
for (i=0;i<8;i++) {
mt.or(t[i]);
}
nb=1+mt.nbits();
// Sign pivot
s1[nb-1]=1;
s2[nb-1]=1;
for (i=0;i<nb-1;i++) {
t[0].fshr(1);
s1[i]=2*t[0].parity()-1;
t[4].fshr(1);
s2[i]=2*t[4].parity()-1;
}
// Recoded exponent
for (i=0; i<nb; i++) {
w1[i]=0;
k=1;
for (j=1; j<4; j++) {
bt=s1[i]*t[j].parity();
t[j].fshr(1);
t[j].dec(bt>>1);
t[j].norm();
w1[i]+=bt*k;
k*=2;
}
w2[i]=0;
k=1;
for (j=5; j<8; j++) {
bt=s2[i]*t[j].parity();
t[j].fshr(1);
t[j].dec(bt>>1);
t[j].norm();
w2[i]+=bt*k;
k*=2;
}
}
// Main loop
P.select(T1,2*w1[nb-1]+1);
W.select(T2,2*w2[nb-1]+1);
P.add(W);
for (i=nb-2;i>=0;i--) {
P.dbl();
W.select(T1,2*w1[i]+s1[i]);
P.add(W);
W.select(T2,2*w2[i]+s2[i]);
P.add(W);
}
// apply correction
W.copy(P);
W.sub(Q[0]);
P.cmove(W,pb1);
W.copy(P);
W.sub(Q[4]);
P.cmove(W,pb2);
P.affine();
return P;
};