Esempio n. 1
0
        /// <summary>
        /// Returns k * point computed using the double and <see cref="PointAdd"/> algorithm.
        /// </summary>
        /// <param name="k"></param>
        /// <param name="point"></param>
        /// <returns></returns>
        public BigIntegerPoint ScalarMult(BigInteger k, BigIntegerPoint point)
        {
            if (EllipticCurveHelpers.MathMod(k, this.N) == 0 || point.IsEmpty())
            {
                return(BigIntegerPoint.GetEmpty());
            }

            if (k < 0)
            {
                return(this.ScalarMult(-k, this.NegatePoint(point)));
            }

            BigIntegerPoint result = BigIntegerPoint.GetEmpty();
            BigIntegerPoint addend = point;

            while (k > 0)
            {
                if ((k & 1) > 0)
                {
                    result = this.PointAdd(result, addend);
                }

                addend = this.PointAdd(addend, addend);

                k >>= 1;
            }

            return(result);
        }
Esempio n. 2
0
        /// <summary>
        /// Returns the inverse of k modulo p.
        /// </summary>
        /// <param name="k">Must be non-zero</param>
        /// <param name="p">Must be a prime</param>
        /// <returns></returns>
        public BigInteger InverseMod(BigInteger k, BigInteger p)
        {
            if (k == 0)
            {
                return(BigInteger.Zero);
                //throw new DivideByZeroException(nameof(k));
            }

            if (k < 0)
            {
                return(p - this.InverseMod(-k, p));
            }

            (BigInteger gcd, BigInteger x, BigInteger y)result = EllipticCurveHelpers.ExtendedGcd(p, k);

            if (result.gcd != 1)
            {
                throw new ArgumentException("Gcd is not 1");
            }

            if (EllipticCurveHelpers.MathMod(k * result.x, p) != 1)
            {
                throw new ArgumentException("(k * result.x) % p != 1");
            }

            return(EllipticCurveHelpers.MathMod(result.x, p));
        }
Esempio n. 3
0
        /// <summary>
        /// Returns <c>true</c> if the given point lies on the elliptic curve.
        /// </summary>
        /// <param name="point"></param>
        /// <returns></returns>
        public bool IsOnCurve(BigIntegerPoint point)
        {
            if (point.IsEmpty())
            {
                return(true);
            }

            BigInteger x = point.X;
            BigInteger y = point.Y;

            return(EllipticCurveHelpers.MathMod(y * y - x * x * x - this.A * x - this.B, this.P) == 0);
        }
Esempio n. 4
0
        /// <summary>
        /// Returns -point.
        /// </summary>
        /// <param name="point"></param>
        /// <returns></returns>
        public BigIntegerPoint NegatePoint(BigIntegerPoint point)
        {
            if (point.IsEmpty())
            {
                return(point);
            }

            BigInteger      x      = point.X;
            BigInteger      y      = point.Y;
            BigIntegerPoint result = new BigIntegerPoint(x, EllipticCurveHelpers.MathMod(-y, this.P));

            return(result);
        }
Esempio n. 5
0
        public IEnumerable <BigIntegerPoint> GenerateAllPoints()
        {
            for (BigInteger x = 0; x < this.P; x++)
            {
                BigInteger ySquare  = BigInteger.ModPow(x, 3, this.P) + this.A * x + this.B;
                bool       isSquare = EllipticCurveHelpers.Legendre(ySquare, this.P) != -1;
                if (isSquare)
                {
                    var y = EllipticCurveHelpers.ShanksSqrt(ySquare, this.P);
                    yield return(new BigIntegerPoint(x, y));

                    yield return(new BigIntegerPoint(x, EllipticCurveHelpers.MathMod(-y, this.P)));
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Returns the result of lhs + rhs according to the group law.
        /// </summary>
        /// <param name="lhs"></param>
        /// <param name="rhs"></param>
        /// <returns></returns>
        public BigIntegerPoint PointAdd(BigIntegerPoint lhs, BigIntegerPoint rhs)
        {
            if (lhs.IsEmpty())
            {
                return(rhs);
            }

            if (rhs.IsEmpty())
            {
                return(lhs);
            }

            BigInteger x1 = lhs.X, y1 = lhs.Y;
            BigInteger x2 = rhs.X, y2 = rhs.Y;

            if (x1 == x2 && y1 != y2)
            {
                return(BigIntegerPoint.GetEmpty());
            }

            BigInteger m;

            if (x1 == x2)
            {
                m = (3 * x1 * x1 + this.A) * this.InverseMod(2 * y1, this.P);
            }
            else
            {
                m = (y1 - y2) * this.InverseMod(x1 - x2, this.P);
            }

            BigInteger      x3     = m * m - x1 - x2;
            BigInteger      y3     = y1 + m * (x3 - x1);
            BigIntegerPoint result = new BigIntegerPoint(EllipticCurveHelpers.MathMod(x3, this.P), EllipticCurveHelpers.MathMod(-y3, this.P));

            return(result);
        }