/* Create random BIG in portable way, one bit at a time */ public static BIG RandomNum(BIG q, RAND rng) { DBIG d = new DBIG(0); int i, b, j = 0, r = 0; for (i = 0; i < 2 * q.NBits(); i++) { if (j == 0) { r = rng.Byte; } else { r >>= 1; } b = r & 1; d.Shl(1); d.w[0] += b; // m.inc(b); j++; j &= 7; } BIG m = d.Mod(q); return(m); }
/* Return e.this+f.Q */ public ECP Mul2(BIG e, ECP Q, BIG f) { BIG te = new BIG(); BIG tf = new BIG(); BIG mt = new BIG(); ECP S = new ECP(); ECP T = new ECP(); ECP C = new ECP(); ECP[] W = new ECP[8]; sbyte[] w = new sbyte[1 + (BIG.NLEN * BIG.BASEBITS + 1) / 2]; int i, s, ns, nb; sbyte a, b; //affine(); //Q.affine(); te.Copy(e); tf.Copy(f); // precompute table W[1] = new ECP(); W[1].Copy(this); W[1].Sub(Q); W[2] = new ECP(); W[2].Copy(this); W[2].Add(Q); S.Copy(Q); S.Dbl(); W[0] = new ECP(); W[0].Copy(W[1]); W[0].Sub(S); W[3] = new ECP(); W[3].Copy(W[2]); W[3].Add(S); T.Copy(this); T.Dbl(); W[5] = new ECP(); W[5].Copy(W[1]); W[5].Add(T); W[6] = new ECP(); W[6].Copy(W[2]); W[6].Add(T); W[4] = new ECP(); W[4].Copy(W[5]); W[4].Sub(S); W[7] = new ECP(); W[7].Copy(W[6]); W[7].Add(S); // if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction s = te.Parity(); te.Inc(1); te.Norm(); ns = te.Parity(); mt.Copy(te); mt.Inc(1); mt.Norm(); te.CMove(mt, s); T.CMove(this, ns); C.Copy(T); s = tf.Parity(); tf.Inc(1); tf.Norm(); ns = tf.Parity(); mt.Copy(tf); mt.Inc(1); mt.Norm(); tf.CMove(mt, s); S.CMove(Q, ns); C.Add(S); mt.Copy(te); mt.Add(tf); mt.Norm(); nb = 1 + (mt.NBits() + 1) / 2; // convert exponent to signed 2-bit window for (i = 0; i < nb; i++) { a = (sbyte)(te.LastBits(3) - 4); te.Dec(a); te.Norm(); te.FShr(2); b = (sbyte)(tf.LastBits(3) - 4); tf.Dec(b); tf.Norm(); tf.FShr(2); w[i] = (sbyte)(4 * a + b); } w[nb] = (sbyte)(4 * te.LastBits(3) + tf.LastBits(3)); S.Copy(W[(w[nb] - 1) / 2]); for (i = nb - 1; i >= 0; i--) { T.Select(W, w[i]); S.Dbl(); S.Dbl(); S.Add(T); } S.Sub(C); // apply correction S.Affine(); return(S); }
/* return e.this */ public ECP Mul(BIG e) { if (e.IsZilch() || IsInfinity()) { return(new ECP()); } ECP P = new ECP(); if (CURVETYPE == MONTGOMERY) { /* use Ladder */ int nb, i, b; ECP D = new ECP(); ECP R0 = new ECP(); R0.Copy(this); ECP R1 = new ECP(); R1.Copy(this); R1.Dbl(); D.Copy(this); D.Affine(); nb = e.NBits(); for (i = nb - 2; i >= 0; i--) { b = e.Bit(i); P.Copy(R1); P.DAdd(R0, D); R0.CSwap(R1, b); R1.Copy(P); R0.Dbl(); R0.CSwap(R1, b); } P.Copy(R0); } else { // fixed size windows int i, nb, s, ns; BIG mt = new BIG(); BIG t = new BIG(); ECP Q = new ECP(); ECP C = new ECP(); ECP[] W = new ECP[8]; sbyte[] w = new sbyte[1 + (BIG.NLEN * BIG.BASEBITS + 3) / 4]; //affine(); // precompute table Q.Copy(this); Q.Dbl(); W[0] = new ECP(); W[0].Copy(this); for (i = 1; i < 8; i++) { W[i] = new ECP(); W[i].Copy(W[i - 1]); W[i].Add(Q); } // make exponent odd - add 2P if even, P if odd t.Copy(e); s = t.Parity(); t.Inc(1); t.Norm(); ns = t.Parity(); mt.Copy(t); mt.Inc(1); mt.Norm(); t.CMove(mt, s); Q.CMove(this, ns); C.Copy(Q); nb = 1 + (t.NBits() + 3) / 4; // convert exponent to signed 4-bit window for (i = 0; i < nb; i++) { w[i] = (sbyte)(t.LastBits(5) - 16); t.Dec(w[i]); t.Norm(); t.FShr(4); } w[nb] = (sbyte)t.LastBits(5); P.Copy(W[(w[nb] - 1) / 2]); for (i = nb - 1; i >= 0; i--) { Q.Select(W, w[i]); P.Dbl(); P.Dbl(); P.Dbl(); P.Dbl(); P.Add(Q); } P.Sub(C); // apply correction } P.Affine(); return(P); }
/* 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); }
/* P*=e */ public ECP2 Mul(BIG e) { /* fixed size windows */ int i, nb, s, ns; BIG mt = new BIG(); BIG t = new BIG(); ECP2 P = new ECP2(); ECP2 Q = new ECP2(); ECP2 C = new ECP2(); ECP2[] W = new ECP2[8]; sbyte[] w = new sbyte[1 + (BIG.NLEN * BIG.BASEBITS + 3) / 4]; if (IsInfinity()) { return(new ECP2()); } //affine(); /* precompute table */ Q.Copy(this); Q.Dbl(); W[0] = new ECP2(); W[0].Copy(this); for (i = 1; i < 8; i++) { W[i] = new ECP2(); W[i].Copy(W[i - 1]); W[i].Add(Q); } /* make exponent odd - add 2P if even, P if odd */ t.Copy(e); s = t.Parity(); t.Inc(1); t.Norm(); ns = t.Parity(); mt.Copy(t); mt.Inc(1); mt.Norm(); t.CMove(mt, s); Q.CMove(this, ns); C.Copy(Q); nb = 1 + (t.NBits() + 3) / 4; /* convert exponent to signed 4-bit window */ for (i = 0; i < nb; i++) { w[i] = (sbyte)(t.LastBits(5) - 16); t.Dec(w[i]); t.Norm(); t.FShr(4); } w[nb] = (sbyte)t.LastBits(5); P.Copy(W[(w[nb] - 1) / 2]); for (i = nb - 1; i >= 0; i--) { Q.Select(W, w[i]); P.Dbl(); P.Dbl(); P.Dbl(); P.Dbl(); P.Add(Q); } P.Sub(C); P.Affine(); return(P); }