From 82779add803eeeb7cb15b1118b08352b015454fc Mon Sep 17 00:00:00 2001 From: Shargon Date: Fri, 16 Jul 2021 01:01:03 -0500 Subject: [PATCH] OSX compatible (#2511) --- src/neo/Cryptography/Crypto.cs | 54 ++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/src/neo/Cryptography/Crypto.cs b/src/neo/Cryptography/Crypto.cs index aec25ecd09..3b042fd8b5 100644 --- a/src/neo/Cryptography/Crypto.cs +++ b/src/neo/Cryptography/Crypto.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.InteropServices; using System.Security.Cryptography; namespace Neo.Cryptography @@ -8,6 +9,8 @@ namespace Neo.Cryptography /// public static class Crypto { + private static readonly bool IsOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX); + /// /// Calculates the 160-bit hash value of the specified message. /// @@ -59,21 +62,46 @@ public static byte[] Sign(byte[] message, byte[] prikey, byte[] pubkey) /// if the signature is valid; otherwise, . public static bool VerifySignature(ReadOnlySpan message, ReadOnlySpan signature, ECC.ECPoint pubkey) { - ECCurve curve = - pubkey.Curve == ECC.ECCurve.Secp256r1 ? ECCurve.NamedCurves.nistP256 : - pubkey.Curve == ECC.ECCurve.Secp256k1 ? ECCurve.CreateFromFriendlyName("secP256k1") : - throw new NotSupportedException(); - byte[] buffer = pubkey.EncodePoint(false); - using var ecdsa = ECDsa.Create(new ECParameters + if (signature.Length != 64) return false; + + if (IsOSX && pubkey.Curve == ECC.ECCurve.Secp256k1) { - Curve = curve, - Q = new ECPoint + var curve = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256k1"); + var domain = new Org.BouncyCastle.Crypto.Parameters.ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H); + var point = curve.Curve.CreatePoint( + new Org.BouncyCastle.Math.BigInteger(pubkey.X.Value.ToString()), + new Org.BouncyCastle.Math.BigInteger(pubkey.Y.Value.ToString())); + var pubKey = new Org.BouncyCastle.Crypto.Parameters.ECPublicKeyParameters("ECDSA", point, domain); + var signer = Org.BouncyCastle.Security.SignerUtilities.GetSigner("SHA-256withECDSA"); + + signer.Init(false, pubKey); + signer.BlockUpdate(message.ToArray(), 0, message.Length); + + var sig = signature.ToArray(); + var r = new Org.BouncyCastle.Math.BigInteger(1, sig, 0, 32); + var s = new Org.BouncyCastle.Math.BigInteger(1, sig, 32, 32); + sig = new Org.BouncyCastle.Asn1.DerSequence(new Org.BouncyCastle.Asn1.DerInteger(r), new Org.BouncyCastle.Asn1.DerInteger(s)).GetDerEncoded(); + + return signer.VerifySignature(sig); + } + else + { + ECCurve curve = + pubkey.Curve == ECC.ECCurve.Secp256r1 ? ECCurve.NamedCurves.nistP256 : + pubkey.Curve == ECC.ECCurve.Secp256k1 ? ECCurve.CreateFromFriendlyName("secP256k1") : + throw new NotSupportedException(); + byte[] buffer = pubkey.EncodePoint(false); + using var ecdsa = ECDsa.Create(new ECParameters { - X = buffer[1..33], - Y = buffer[33..] - } - }); - return ecdsa.VerifyData(message, signature, HashAlgorithmName.SHA256); + Curve = curve, + Q = new ECPoint + { + X = buffer[1..33], + Y = buffer[33..] + } + }); + return ecdsa.VerifyData(message, signature, HashAlgorithmName.SHA256); + } } ///