//return: P * factor on the elliptic curves domain. public OwnECPoint MultiplyWithEndomorphism(OwnECPoint p, ulong[] factor) { OwnECPoint result; if (!this.SupportsEndomorphism) { result = this.Multiply(p, factor); return(result); } BigInteger lambda = W1ModOrder.ToBigInteger(); BigInteger k = factor.ToBigInteger(), k1, k2; SplitKToHalfBits(k, lambda, out k1, out k2); OwnECPoint q = p.Copy(); MultiplyModP(q.X, W1ModP); //OwnECPoint test1 = Multiply(p, W1ModOrder); //bool testok = test1.ToString() == q.ToString(); //if (!testok) //{ // Debugger.Break(); //} result = DualMultiply(p, k1, q, k2); return(result); }
public OwnECPoint Negative(OwnECPoint point) { OwnECPoint result = point.Copy(); SubtractModP(this.P, result.Y, result.Y); return(result); }
//return: P * factor on the elliptic curves domain. public OwnECPoint MultiplyReference(OwnECPoint p, ulong[] factor) { int high = HighBit(factor); if (high < 0) { return(new OwnECPoint(p.X, p.Y, true)); } OwnECPoint result = p.Copy(); for (int i = high; --i >= 0;) { GetDouble(ref result); if ((factor[i >> 6] & (1UL << (i & 63))) != 0) { Add(ref result, p); } } RemodFriendlyPrime(result.X); RemodFriendlyPrime(result.Y); return(result); }
//return: P * factor on the elliptic curves domain. public OwnECPoint DualMultiply(OwnECPoint p1, BigInteger k1, OwnECPoint p2, BigInteger k2) { if (k1 < 0) { p1 = Negative(p1); k1 = -k1; } if (k2 < 0) { p2 = Negative(p2); k2 = -k2; } BigInteger exp1 = k1 ^ (k1 * 3); BigInteger exp2 = k2 ^ (k2 * 3); BigInteger max = BigInteger.Max(exp1, exp2); int high = max <= 0 ? 0 : 1 + (int)Math.Ceiling(BigInteger.Log(max, 2)); JacobianECPoint x = new JacobianECPoint(p1.X, p1.Y, true); OwnECPoint cacheAdd = p1.Copy(); OwnECPoint cacheSub = p1.Copy(); Add(ref cacheAdd, p2); Subtract(ref cacheSub, p2); BigInteger bit = BigInteger.One << high; for (int i = high; --i >= 0; bit >>= 1) { GetDouble(ref x); if ((exp1 & bit) != 0 && (exp2 & bit) != 0) { int branch = ((k1 & bit) != 0 ? 0 : 1) + ((k2 & bit) != 0 ? 0 : 2); switch (branch) { case 0: Subtract(ref x, cacheAdd); break; case 1: Add(ref x, cacheSub); break; case 2: Subtract(ref x, cacheSub); break; case 3: Add(ref x, cacheAdd); break; } continue; } if ((exp1 & bit) != 0) { if ((k1 & bit) != 0) { Subtract(ref x, p1); } else { Add(ref x, p1); } continue; } if ((exp2 & bit) != 0) { if ((k2 & bit) != 0) { Subtract(ref x, p2); } else { Add(ref x, p2); } continue; } } OwnECPoint result = x.ToECPoint(this); return(result); }