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); }