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.");
     }
 }
Example #4
0
        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);
        }
Example #5
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));
        }
Example #6
0
        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));
        }
Example #7
0
        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);
        }
Example #8
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);
        }
Example #9
0
 internal EllipticCurvePoint PointNegChecked(EllipticCurvePoint point)
 {
     return((point == EllipticCurvePoint.InfinityPoint) ? point : new EllipticCurvePoint(point.X, (-point.Y).Mod(curve.P)));
 }
Example #10
0
        public EllipticCurvePoint PointNeg(EllipticCurvePoint point)
        {
            CheckOnCurve(point);

            return(PointNegChecked(point));
        }