public static bool VerifySignature(Address signerAddress, byte[] signature, byte[] data)
        {
            CheckArgument(signerAddress != null, "signerAddress should not be null");
            CheckArgument(signature != null && signature.Length == 65, "signature should be 65 bytes length");

            var r = new byte[32];
            var s = new byte[32];
            var v = signature[64];

            Array.Copy(signature, 0, r, 0, 32);
            Array.Copy(signature, 32, s, 0, 32);
            var sig = new BigInteger[] { new BigInteger(1, r), new BigInteger(1, s) };

            var signerResult = EcdsaSignature.RecoverFromSignature(v, sig, data);

            if (signerResult == null)
            {
                return(false);
            }

            var signedBytes = new Bytes(signerResult);
            var address     = IconKeys.GetAddress(signedBytes);

            return(address?.Equals(signerAddress) ?? false);
        }
        /// <summary>
        ///    Returns the recovery ID, a byte with value between 0 and 3, inclusive, that specifies which of 4 possible
        ///    curve points was used to sign a message. This value is also referred to as "v".
        /// </summary>
        public byte FindRecoveryId(BigInteger[] sig, byte[] message)
        {
            var publicKey = IconKeys.GetPublicKey(_privateKey);
            var p         = new BigInteger(1, publicKey.ToByteArray());
            var recId     = -1;

            for (byte i = 0; i < 4; i++)
            {
                var k = RecoverFromSignature(i, sig, message);
                if (k != null && k.Equals(p))
                {
                    recId = i;
                    break;
                }
            }

            if (recId == -1)
            {
                throw new Exception("Could not construct a recoverable key. This should never happen.");
            }

            return((byte)recId);
        }