/* 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); }