示例#1
0
 private void CheckOnCurve(EllipticCurvePoint a)
 {
     if (!curve.IsOnCurve(a))
     {
         throw new ArgumentException("Point not on curve");
     }
 }
示例#2
0
        public EllipticCurvePoint ScalarMult(BigInteger k, EllipticCurvePoint a)
        {
            CheckOnCurve(a);

            if (k.ModulusGF(curve.N) == 0 || EllipticCurvePoint.IsInfinity(a))
            {
                return(EllipticCurvePoint.InfinityPoint);
            }

            if (k < 0)
            {
                return(ScalarMult(-k, NegativePoint(a)));
            }

            EllipticCurvePoint res  = EllipticCurvePoint.InfinityPoint;
            EllipticCurvePoint temp = a;

            while (k != 0)
            {
                if ((k & 1) == 1)
                {
                    res = Add(res, temp);
                }

                temp = Twice(temp);

                k >>= 1;
            }

            return(res);
        }
示例#3
0
        public EllipticCurve(BigInteger a, BigInteger b, BigInteger p, BigInteger n, uint m, EllipticCurvePoint basePoint = null)
        {
            A = a;
            B = b;
            P = p;
            N = n;
            M = m;

            this.basePoint = basePoint;
        }
示例#4
0
        public bool IsValidPrivateKey(BigInteger privateKey, EllipticCurvePoint publicKey)
        {
            EllipticCurvePoint p = NegativePoint(ScalarMult(privateKey, curve.BasePoint));

            if (EllipticCurvePoint.IsInfinity(p))
            {
                return(false);
            }

            return(p.X == publicKey.X && p.Y == publicKey.Y);
        }
示例#5
0
        public (BigInteger, EllipticCurvePoint) GenenrateKeyPair()
        {
            if (!Initialized)
            {
                throw new Exception("Elliptic curve wasn't initialized");
            }
            BigInteger d = GetRandomIntegerFromField();

            EllipticCurvePoint p = NegativePoint(ScalarMult(d, curve.BasePoint));

            return(d, p);
        }
示例#6
0
        public EllipticCurvePoint GenerateBasePoint()
        {
            EllipticCurvePoint result;

            do
            {
                result = GeneratePoint();
            }while (!EllipticCurvePoint.IsInfinity(ScalarMult(curve.N, result)));

            CheckOnCurve(result);

            return(result);
        }
示例#7
0
        public EllipticCurvePoint NegativePoint(EllipticCurvePoint a)
        {
            CheckOnCurve(a);

            if (EllipticCurvePoint.IsInfinity(a))
            {
                return(a);
            }

            var result = new EllipticCurvePoint(a.X, a.X.AddGF(a.Y));

            CheckOnCurve(a);
            return(result);
        }
示例#8
0
        public bool IsOnCurve(EllipticCurvePoint point)
        {
            if (EllipticCurvePoint.IsInfinity(point))
            {
                return(true);
            }

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

            BigInteger lhs = y.SquareGF(P).AddGF(x.MultGF(y, P));
            BigInteger rhs = x.SquareGF(P).MultGF(x, P).AddGF(x.SquareGF(P).MultGF(A, P)).AddGF(B);

            return(lhs == rhs);
        }
示例#9
0
        public EllipticCurvePoint Twice(EllipticCurvePoint a)
        {
            if (EllipticCurvePoint.IsInfinity(a))
            {
                return(a);
            }

            BigInteger sigma = a.X.InverseGF(curve.P).MultGF(a.Y, curve.P).AddGF(a.X);
            BigInteger x     = sigma.SquareGF(curve.P).AddGF(sigma).AddGF(curve.A);
            BigInteger y     = a.X.SquareGF(curve.P).AddGF(sigma.AddGF(BigInteger.One).MultGF(x, curve.P));

            var result = new EllipticCurvePoint(x, y);

            //CheckOnCurve(result);
            return(result);
        }
示例#10
0
        public EllipticCurvePoint GeneratePoint()
        {
            EllipticCurvePoint result = EllipticCurvePoint.InfinityPoint;
            BigInteger         u, z;
            int k;

            do
            {
                u = GetRandomIntegerFromField();
                BigInteger w = u.SquareGF(curve.P).MultGF(u, curve.P).AddGF(u.SquareGF(curve.P).MultGF(curve.A, curve.P)).AddGF(curve.B);
                k = SolveQuadraticEquation(u, w, out z);
            }while (k == 0);

            result = new EllipticCurvePoint(u, z);
            CheckOnCurve(result);
            return(result);
        }
示例#11
0
        public (BigInteger, BigInteger) PreComputedSign()
        {
            if (EllipticCurvePoint.IsInfinity(curve.BasePoint))
            {
                throw new Exception("Base point uninitialized");
            }

            while (true)
            {
                BigInteger         e = GetRandomIntegerFromField();
                EllipticCurvePoint r = ScalarMult(e, curve.BasePoint);

                if (!EllipticCurvePoint.IsInfinity(r) && r.X != 0)
                {
                    return(e, r.X);
                }
            }
        }
示例#12
0
        public bool IsValidPublicKey(EllipticCurvePoint publicKey)
        {
            if (EllipticCurvePoint.IsInfinity(publicKey))
            {
                return(false);
            }

            if (publicKey.X >= curve.P || publicKey.Y >= curve.P || publicKey.X * publicKey.Y == 0)
            {
                return(false);
            }

            if (!curve.IsOnCurve(publicKey))
            {
                return(false);
            }

            return(EllipticCurvePoint.IsInfinity(ScalarMult(curve.N, publicKey)));
        }
示例#13
0
        public bool VerifySign(byte[] message, EllipticCurvePoint publicKey, BigInteger r, BigInteger s, HashAlgorithm hashAlgorithm)
        {
            if (!IsValidPublicKey(publicKey))
            {
                throw new Exception("Public key is invalid");
            }

            if (r >= curve.N || s >= curve.N || r <= 0 || s <= 0)
            {
                return(false);
            }

            byte[]     hash    = hashAlgorithm.ComputeHash(message);
            BigInteger hashInt = TransformHash(hash);

            var R  = Add(ScalarMult(s, curve.BasePoint), ScalarMult(r, publicKey));
            var y  = R.X.MultGF(hashInt, curve.P);
            var r1 = y.Seek(curve.N.GetBitCount() - 1);

            return(r1 == r);
        }
示例#14
0
        public EllipticCurvePoint Add(EllipticCurvePoint a, EllipticCurvePoint b)
        {
            if (EllipticCurvePoint.IsInfinity(a))
            {
                CheckOnCurve(b);
                return(b);
            }

            if (EllipticCurvePoint.IsInfinity(b))
            {
                CheckOnCurve(a);
                return(a);
            }

            CheckOnCurve(a);
            CheckOnCurve(b);

            BigInteger x, y;

            if (a.X == b.X)
            {
                if (a.Y != b.Y || a.X == BigInteger.Zero)
                {
                    return(EllipticCurvePoint.InfinityPoint);
                }

                return(Twice(a));
            }
            else
            {
                BigInteger lambda = a.X.AddGF(b.X).InverseGF(curve.P).MultGF(a.Y.AddGF(b.Y), curve.P);
                x = lambda.SquareGF(curve.P).AddGF(lambda).AddGF(a.X).AddGF(b.X).AddGF(curve.A);
                y = a.X.AddGF(x).MultGF(lambda, curve.P).AddGF(x).AddGF(a.Y);
            }

            var result = new EllipticCurvePoint(x, y);

            CheckOnCurve(result);
            return(result);
        }
示例#15
0
 public static bool IsInfinity(EllipticCurvePoint point) => point == InfinityPoint;
示例#16
0
        public (BigInteger, BigInteger) SignMessage(byte[] message, BigInteger privateKey, EllipticCurvePoint publicKey, HashAlgorithm hashAlgorithm)
        {
            if (!IsValidPrivateKey(privateKey, publicKey))
            {
                throw new Exception("Private key is invalid");
            }

            byte[]     hash    = hashAlgorithm.ComputeHash(message);
            BigInteger hashInt = TransformHash(hash);

            BigInteger e, fe, r, s;

            do
            {
                (e, fe) = PreComputedSign();
                r       = fe.MultGF(hashInt, curve.P).Seek(curve.N.GetBitCount() - 1);
                s       = (r * privateKey + e) % curve.N;//r.MultGF(privateKey, curve.P).AddGF(e).ModulusGF(curve.N);
            } while (r == 0 || s == 0);

            return(r, s);
        }