internal EllipticCurvePoint AddChecked(EllipticCurvePoint point1, EllipticCurvePoint point2) { if (point1 == EllipticCurvePoint.InfinityPoint) { return(point2); } if (point2 == EllipticCurvePoint.InfinityPoint) { return(point1); } BigInteger m; if (point1.X == point2.X) { if (point1.Y != point2.Y) // (x,y) + (x,−y) = O { return(EllipticCurvePoint.InfinityPoint); } // Point double or (x,y) + (x,y) m = ((3 * point1.X * point1.X) + curve.A) * (2 * point1.Y).ModInverse(curve.P); // Note that since points are on a group with a prime (mod p) all of them do have multiplicative inverses. } else // point1 != point2. (x1,y1) + (x2,y2) { m = (point1.Y - point2.Y) * (point1.X - point2.X).ModInverse(curve.P); } BigInteger x3 = ((m * m) - point1.X - point2.X).Mod(curve.P); BigInteger y3 = (m * (point1.X - x3) - point1.Y).Mod(curve.P); return(new EllipticCurvePoint(x3, y3)); }
public EllipticCurvePoint Add(EllipticCurvePoint point1, EllipticCurvePoint point2) { CheckOnCurve(point1); CheckOnCurve(point2); return(AddChecked(point1, point2)); }
/// <summary> /// Checks to see if the given point is on the used elliptic curve. /// </summary> /// <exception cref="ArgumentOutOfRangeException"/> /// <param name="point">Point to check</param> public void CheckOnCurve(EllipticCurvePoint point) { if (!curve.IsOnCurve(point)) { throw new ArgumentOutOfRangeException("The given point is not on the given curve."); } }
public bool IsOnCurve(EllipticCurvePoint point) { if (point == EllipticCurvePoint.InfinityPoint) { return(true); } // Big*Big is faster than Pow(Big,2). Only true for 2 though. BigInteger rem = ((point.Y * point.Y) - BigInteger.Pow(point.X, 3) - (A * point.X) - B) % P; return(rem == 0); }
public EllipticCurvePoint Multiply(BigInteger k, EllipticCurvePoint point) { CheckOnCurve(point); if (k % curve.N == 0 || point == EllipticCurvePoint.InfinityPoint) { return(EllipticCurvePoint.InfinityPoint); } return((k < 0) ? MultiplyChecked(-k, PointNegChecked(point)) : MultiplyChecked(k, point)); }
internal EllipticCurvePoint DoubleChecked(EllipticCurvePoint point1) { if (point1 == EllipticCurvePoint.InfinityPoint) { return(point1); } BigInteger m = 3 * point1.X * point1.X * (2 * point1.Y).ModInverse(curve.P); BigInteger x3 = ((m * m) - (2 * point1.X)).Mod(curve.P); BigInteger y3 = (m * (point1.X - x3) - point1.Y).Mod(curve.P); return(new EllipticCurvePoint(x3, y3)); }
internal bool TryRecoverPublicKeys(Signature sig, byte[] hashedData, out EllipticCurvePoint[] results) { List <EllipticCurvePoint> temp = new List <EllipticCurvePoint>(curve.H * 4); for (int j = 0; j <= curve.H; j++) { BigInteger x = sig.R + (j * curve.N); if (!TryFindY(x, 2, out BigInteger y)) { continue; } EllipticCurvePoint R = new EllipticCurvePoint(x, y); if (!curve.IsOnCurve(R)) { continue; } BigInteger e = CalculateE(hashedData); for (int k = 1; k <= 2; k++) { // Q = r^−1(sR − eG). EllipticCurvePoint Q = Multiply( sig.R.ModInverse(curve.N), AddChecked( MultiplyChecked(sig.S, R), PointNegChecked(MultiplyChecked(e, curve.G)) ) ); if (curve.IsOnCurve(Q)) { if (!temp.Contains(Q)) { // TODO: we are missing step 1.6.2 (verify if this pubkey + signature is valid) temp.Add(Q); } } R = PointNegChecked(R); } } results = temp.ToArray(); return(results.Length != 0); }
internal EllipticCurvePoint MultiplyChecked(BigInteger k, EllipticCurvePoint point) { EllipticCurvePoint result = EllipticCurvePoint.InfinityPoint; EllipticCurvePoint addend = point; while (k != 0) { if ((k & 1) == 1) { result = AddChecked(result, addend); } addend = DoubleChecked(addend); k >>= 1; } return(result); }
internal EllipticCurvePoint PointNegChecked(EllipticCurvePoint point) { return((point == EllipticCurvePoint.InfinityPoint) ? point : new EllipticCurvePoint(point.X, (-point.Y).Mod(curve.P))); }
public EllipticCurvePoint PointNeg(EllipticCurvePoint point) { CheckOnCurve(point); return(PointNegChecked(point)); }