private bool VerifyHash(byte[] hash, PublicKey publicKey) { if (hash.Length != 32) { CustomTools.Console.DebugWarning("A sha256 hash should be 32 bytes long, instead got ", hash.Length); } return(ECDSA.Verify(Curve.SecP256k1, hash, new ECSignature(r, s), publicKey.Q)); }
private PublicKey RecoverPublicKey(byte[] bufferSha256) { var e = BigInteger.FromBuffer(bufferSha256); var q = ECDSA.RecoverPublicKey(Curve.SecP256k1, e, new ECSignature(r, s), (byte)((i - 27) & 3)); e.Dispose(); return(PublicKey.FromPoint(q)); }
private static Signature SignBufferSha256(byte[] bufferSha256, PrivateKey privateKey) { if (bufferSha256.Length != 32) { throw new ArgumentException("bufferSha256: 32 byte buffer requred"); } var nonce = uint.MinValue; var e = BigInteger.FromBuffer(bufferSha256); ECSignature ecSignature = null; var i = byte.MinValue; while (true) { ecSignature?.Dispose(); ecSignature = ECDSA.Sign(Curve.SecP256k1, bufferSha256, privateKey.D, nonce++); var der = ecSignature.ToDER(); var lengthR = der[3]; var lengthS = der[5 + lengthR]; der.Clear(); if (lengthR == 32 && lengthS == 32) { i = ECDSA.CalculatePublicKeyRecoveryParameter(Curve.SecP256k1, e, ecSignature, privateKey.PublicKey.Q); i += 4; // compressed i += 27; // compact // 24 or 27 :( forcing odd-y 2nd key candidate) break; } if (nonce % 10 == 0) { CustomTools.Console.DebugWarning(nonce, "attempts to find canonical signature"); } } e.Dispose(); var result = new Signature(ecSignature.R.Clone(), ecSignature.S.Clone(), i); ecSignature.Dispose(); return(result); }