/// <summary>
        /// Generates a random private-public key pair.
        /// </summary>
        /// <returns>The tuple consists of a private and public key</returns>
        public (BigInteger privateKey, BigIntegerPoint publicKey) GenerateKeyPair()
        {
            BigInteger      privateKey = RandomIntegerBelow(Curve.n);
            BigIntegerPoint publicKey  = ScalarMult(privateKey, Curve.G);

            return(privateKey, publicKey);
        }
        /// <summary>
        /// Generates signature.
        /// </summary>
        /// <param name="privateKey"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public (BigInteger r, BigInteger s) SignMessage(BigInteger privateKey, string message)
        {
            BigInteger z = HashMessage(message);

            BigInteger r = 0;
            BigInteger s = 0;

            while (r == 0 || s == 0)
            {
                BigInteger      k     = RandomIntegerBelow(Curve.n);
                BigIntegerPoint point = ScalarMult(k, Curve.G);

                r = MathMod(point.X, Curve.n);
                s = MathMod((z + r * privateKey) * InverseMod(k, Curve.n), Curve.n);
            }

            return(r, s);
        }
 public bool VerifySignature(BigIntegerPoint publicKey, string message,
                             (BigInteger r, BigInteger s) signature)