public CurvePoint Add(CurvePoint p1, CurvePoint p2) { #if SAFE_MATH CheckOnCurve(p1); CheckOnCurve(p2); #endif // Special cases if (p1.AtInfinity() && p2.AtInfinity()) { return(new CurvePoint()); } else if (p1.AtInfinity()) { return(p2); } else if (p2.AtInfinity()) { return(p1); } else if (p1.X == p2.X && p1.Y == Inverse(p2).Y ) { return(new CurvePoint()); } BigInteger x3 = 0, y3 = 0; if (type == CurveType.Weierstrass) { BigInteger slope = p1.X == p2.X && p1.Y == p2.Y ? Mod((3 * p1.X * p1.X + a) * MulInverse(2 * p1.Y)) : Mod(Mod(p2.Y - p1.Y) * MulInverse(p2.X - p1.X)); x3 = Mod((slope * slope) - p1.X - p2.X); y3 = Mod(-((slope * x3) + p1.Y - (slope * p1.X))); } else if (type == CurveType.Montgomery) { if ((p1.X == p2.X && p1.Y == p2.Y)) { BigInteger q = 3 * p1.X; BigInteger w = q * p1.X; BigInteger e = 2 * a; BigInteger r = e * p1.X; BigInteger t = 2 * b; BigInteger y = t * p1.Y; BigInteger u = MulInverse(y); BigInteger o = w + e + 1; BigInteger p = o * u; } BigInteger co = p1.X == p2.X && p1.Y == p2.Y ? Mod((3 * p1.X * p1.X + 2 * a * p1.X + 1) * MulInverse(2 * b * p1.Y)) : Mod(Mod(p2.Y - p1.Y) * MulInverse(p2.X - p1.X)); // Compute a commonly used coefficient x3 = Mod(b * co * co - a - p1.X - p2.X); y3 = Mod(((2 * p1.X + p2.X + a) * co) - (b * co * co * co) - p1.Y); } return(new CurvePoint(x3, y3)); }
public CurvePoint Multiply(CurvePoint p, BigInteger scalar) { if (scalar <= 0) { throw new System.Exception("Cannot multiply by a scalar which is <= 0"); } if (p.AtInfinity()) { return(new CurvePoint()); } CurvePoint p1 = new CurvePoint(p.X, p.Y); byte[] bytes = scalar.ToByteArray(); Int32 highBit = bytes.GetHighestBitSet(); // Double-and-add method while (highBit >= 0) { p1 = Add(p1, p1); // Double if (bytes.GetBit(highBit)) { p1 = Add(p1, p); // Add } --highBit; } return(p1); }
protected void CheckOnCurve(CurvePoint p) { if (!p.AtInfinity() && // The point at infinity is asserted to be on the curve (type == CurveType.Weierstrass && Mod(p.Y * p.Y) != Mod((p.X * p.X * p.X) + (p.X * a) + b)) || // Weierstrass formula (type == CurveType.Montgomery && Mod(b * p.Y * p.Y) != Mod((p.X * p.X * p.X) + (p.X * p.X * a) + p.X)) // Montgomery formula ) { throw new System.Exception("Point is not on curve"); } }