/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */ // Bos & Costello https://eprint.iacr.org/2013/458.pdf // Faz-Hernandez & Longa & Sanchez https://eprint.iacr.org/2013/158.pdf // Side channel attack secure public static ECP2 Mul4(ECP2[] Q, BIG[] u) { int i, j, nb, pb; ECP2 W = new ECP2(); ECP2 P = new ECP2(); ECP2[] T = new ECP2[8]; BIG mt = new BIG(); BIG[] t = new BIG[4]; sbyte[] w = new sbyte[BIG.NLEN * BIG.BASEBITS + 1]; sbyte[] s = new sbyte[BIG.NLEN * BIG.BASEBITS + 1]; for (i = 0; i < 4; i++) { t[i] = new BIG(u[i]); t[i].Norm(); //Q[i].affine(); } T[0] = new ECP2(); T[0].Copy(Q[0]); // Q[0] T[1] = new ECP2(); T[1].Copy(T[0]); T[1].Add(Q[1]); // Q[0]+Q[1] T[2] = new ECP2(); T[2].Copy(T[0]); T[2].Add(Q[2]); // Q[0]+Q[2] T[3] = new ECP2(); T[3].Copy(T[1]); T[3].Add(Q[2]); // Q[0]+Q[1]+Q[2] T[4] = new ECP2(); T[4].Copy(T[0]); T[4].Add(Q[3]); // Q[0]+Q[3] T[5] = new ECP2(); T[5].Copy(T[1]); T[5].Add(Q[3]); // Q[0]+Q[1]+Q[3] T[6] = new ECP2(); T[6].Copy(T[2]); T[6].Add(Q[3]); // Q[0]+Q[2]+Q[3] T[7] = new ECP2(); T[7].Copy(T[3]); T[7].Add(Q[3]); // Q[0]+Q[1]+Q[2]+Q[3] // Make it odd pb = 1 - t[0].Parity(); t[0].Inc(pb); t[0].Norm(); // Number of bits mt.Zero(); for (i = 0; i < 4; i++) { mt.Or(t[i]); } nb = 1 + mt.NBits(); // Sign pivot s[nb - 1] = 1; for (i = 0; i < nb - 1; i++) { t[0].FShr(1); s[i] = (sbyte)(2 * t[0].Parity() - 1); } // Recoded exponent for (i = 0; i < nb; i++) { w[i] = 0; int k = 1; for (j = 1; j < 4; j++) { sbyte bt = (sbyte)(s[i] * t[j].Parity()); t[j].FShr(1); t[j].Dec((int)(bt) >> 1); t[j].Norm(); w[i] += (sbyte)(bt * (sbyte)k); k *= 2; } } // Main loop P.Select(T, (int)(2 * w[nb - 1] + 1)); for (i = nb - 2; i >= 0; i--) { P.Dbl(); W.Select(T, (int)(2 * w[i] + s[i])); P.Add(W); } // apply correction W.Copy(P); W.Sub(Q[0]); P.CMove(W, pb); P.Affine(); return(P); }