diff --git a/src/Nethermind/Nethermind.Consensus/Signer.cs b/src/Nethermind/Nethermind.Consensus/Signer.cs index 922fab54f15..66a70c68ad5 100644 --- a/src/Nethermind/Nethermind.Consensus/Signer.cs +++ b/src/Nethermind/Nethermind.Consensus/Signer.cs @@ -40,7 +40,7 @@ public Signer(ulong chainId, IProtectedPrivateKey key, ILogManager logManager) public Signature Sign(in ValueHash256 message) { if (!CanSign) throw new InvalidOperationException("Cannot sign without provided key."); - byte[] rs = SpanSecP256k1.SignCompact(message.Bytes, _key!.KeyBytes, out int v); + byte[] rs = SecP256k1.SignCompact(message.Bytes, _key!.KeyBytes, out int v); return new Signature(rs, v); } diff --git a/src/Nethermind/Nethermind.Core.Test/Crypto/SignatureTests.cs b/src/Nethermind/Nethermind.Core.Test/Crypto/SignatureTests.cs index d810fd16248..939457a1f4d 100644 --- a/src/Nethermind/Nethermind.Core.Test/Crypto/SignatureTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Crypto/SignatureTests.cs @@ -41,7 +41,7 @@ public void can_recover_from_message() var signatureObject = new Signature(signatureSlice, recoveryId); var keccak = Keccak.Compute(Bytes.Concat(messageType, data)); Span publicKey = stackalloc byte[65]; - bool result = SpanSecP256k1.RecoverKeyFromCompact(publicKey, keccak.Bytes, signatureObject.Bytes.ToArray(), signatureObject.RecoveryId, false); + bool result = SecP256k1.RecoverKeyFromCompact(publicKey, keccak.Bytes, signatureObject.Bytes, signatureObject.RecoveryId, false); result.Should().BeTrue(); } } diff --git a/src/Nethermind/Nethermind.Crypto/Ecdsa.cs b/src/Nethermind/Nethermind.Crypto/Ecdsa.cs index 36b7ba7f49f..e980ed857d2 100644 --- a/src/Nethermind/Nethermind.Crypto/Ecdsa.cs +++ b/src/Nethermind/Nethermind.Crypto/Ecdsa.cs @@ -21,7 +21,7 @@ public Signature Sign(PrivateKey privateKey, in ValueHash256 message) InvalidPrivateKey(); } - byte[] signatureBytes = SpanSecP256k1.SignCompact(message.Bytes, privateKey.KeyBytes, out int recoveryId); + byte[] signatureBytes = SecP256k1.SignCompact(message.Bytes, privateKey.KeyBytes, out int recoveryId); Signature signature = new(signatureBytes, recoveryId); #if DEBUG @@ -40,7 +40,7 @@ public Signature Sign(PrivateKey privateKey, in ValueHash256 message) public PublicKey? RecoverPublicKey(Signature signature, in ValueHash256 message) { Span publicKey = stackalloc byte[65]; - bool success = SpanSecP256k1.RecoverKeyFromCompact(publicKey, message.Bytes, signature.Bytes, signature.RecoveryId, false); + bool success = SecP256k1.RecoverKeyFromCompact(publicKey, message.Bytes, signature.Bytes, signature.RecoveryId, false); if (!success) { return null; @@ -52,7 +52,7 @@ public Signature Sign(PrivateKey privateKey, in ValueHash256 message) public CompressedPublicKey? RecoverCompressedPublicKey(Signature signature, in ValueHash256 message) { Span publicKey = stackalloc byte[33]; - bool success = SpanSecP256k1.RecoverKeyFromCompact(publicKey, message.Bytes, signature.Bytes, signature.RecoveryId, true); + bool success = SecP256k1.RecoverKeyFromCompact(publicKey, message.Bytes, signature.Bytes, signature.RecoveryId, true); if (!success) { return null; diff --git a/src/Nethermind/Nethermind.Crypto/EthereumEcdsa.cs b/src/Nethermind/Nethermind.Crypto/EthereumEcdsa.cs index 73f844d8aca..fa4f58359e0 100644 --- a/src/Nethermind/Nethermind.Crypto/EthereumEcdsa.cs +++ b/src/Nethermind/Nethermind.Crypto/EthereumEcdsa.cs @@ -30,7 +30,7 @@ public class EthereumEcdsa(ulong chainId) : Ecdsa, IEthereumEcdsa private static Address? RecoverAddress(Span signatureBytes64, byte v, ReadOnlySpan message) { Span publicKey = stackalloc byte[65]; - bool success = SpanSecP256k1.RecoverKeyFromCompact( + bool success = SecP256k1.RecoverKeyFromCompact( publicKey, message, signatureBytes64, @@ -41,7 +41,7 @@ public class EthereumEcdsa(ulong chainId) : Ecdsa, IEthereumEcdsa } public static bool RecoverAddressRaw(ReadOnlySpan signatureBytes64, byte v, ReadOnlySpan message, Span resultPublicKey65) => - SpanSecP256k1.RecoverKeyFromCompact( + SecP256k1.RecoverKeyFromCompact( resultPublicKey65, message, signatureBytes64, diff --git a/src/Nethermind/Nethermind.Crypto/SpanSecP256k1.cs b/src/Nethermind/Nethermind.Crypto/SpanSecP256k1.cs deleted file mode 100644 index cbe4fb1aea4..00000000000 --- a/src/Nethermind/Nethermind.Crypto/SpanSecP256k1.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; - -namespace Nethermind.Crypto; - -/// -/// Span wrapper upon SecP256k1. Try to avoid allocations if given span is of Keccak size. -/// -public static class SpanSecP256k1 -{ - [ThreadStatic] private static byte[]? _signMessageHash; - [ThreadStatic] private static byte[]? _signPrivateKey; - - public static byte[]? SignCompact(ReadOnlySpan messageHash, ReadOnlySpan privateKey, out int recoveryId) - { - byte[] messageHashArray; - if (messageHash.Length == 32) - { - _signMessageHash ??= new byte[32]; - messageHash.CopyTo(_signMessageHash); - messageHashArray = _signMessageHash; - } - else - { - // Why? Dont know... - messageHashArray = messageHash.ToArray(); - } - - byte[] privateKeyArray; - if (privateKey.Length == 32) - { - _signPrivateKey ??= new byte[32]; - privateKey.CopyTo(_signPrivateKey); - privateKeyArray = _signPrivateKey; - } - else - { - // Why? Dont know... - privateKeyArray = privateKey.ToArray(); - } - - return SecP256k1.SignCompact(messageHashArray, privateKeyArray, out recoveryId); - } - - [ThreadStatic] private static byte[]? _recoverMessageHash; - - public static bool RecoverKeyFromCompact(Span publicKey, ReadOnlySpan messageHash, ReadOnlySpan signature, int recoveryId, bool compressed) - { - byte[] messageHashArray; - if (messageHash.Length == 32) - { - _recoverMessageHash ??= new byte[32]; - messageHash.CopyTo(_recoverMessageHash); - messageHashArray = _recoverMessageHash; - } - else - { - // Why? Dont know... - messageHashArray = messageHash.ToArray(); - } - - return SecP256k1.RecoverKeyFromCompact(publicKey, messageHashArray, signature, recoveryId, compressed); - } -} diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/EcRecoverPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/EcRecoverPrecompile.cs index c6e0b475962..666cc07d6bb 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/EcRecoverPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/EcRecoverPrecompile.cs @@ -3,6 +3,7 @@ using System; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; @@ -70,8 +71,13 @@ private Result RunInternal(ReadOnlySpan inputDataSpan) return Empty; } - byte[] result = ValueKeccak.Compute(publicKey.Slice(1, 64)).ToByteArray(); - result.AsSpan(0, 12).Clear(); + byte[] result = new byte[32]; + KeccakHash.ComputeHashBytesToSpan(publicKey.Slice(1, 64), result); + + ref byte refResut = ref MemoryMarshal.GetArrayDataReference(result); + + // Clear first 12 bytes, as address is last 20 bytes of the hash + Unsafe.InitBlockUnaligned(ref refResut, 0, 12); return result; } } diff --git a/src/Nethermind/Nethermind.Optimism/CL/P2P/P2PBlockValidator.cs b/src/Nethermind/Nethermind.Optimism/CL/P2P/P2PBlockValidator.cs index 4f8c7495049..36b3655e20c 100644 --- a/src/Nethermind/Nethermind.Optimism/CL/P2P/P2PBlockValidator.cs +++ b/src/Nethermind/Nethermind.Optimism/CL/P2P/P2PBlockValidator.cs @@ -153,7 +153,7 @@ private bool IsSignatureValid(ReadOnlySpan payloadData, Span signatu byte[] signedHash = KeccakHash.ComputeHashBytes(sequencerSignedData); Span publicKey = stackalloc byte[65]; - bool success = SpanSecP256k1.RecoverKeyFromCompact( + bool success = SecP256k1.RecoverKeyFromCompact( publicKey, signedHash, signature.Slice(0, 64), diff --git a/src/Nethermind/Nethermind.Wallet/DevKeyStoreWallet.cs b/src/Nethermind/Nethermind.Wallet/DevKeyStoreWallet.cs index bc056c21f84..d0d2743a4a7 100644 --- a/src/Nethermind/Nethermind.Wallet/DevKeyStoreWallet.cs +++ b/src/Nethermind/Nethermind.Wallet/DevKeyStoreWallet.cs @@ -100,7 +100,7 @@ public Signature Sign(Hash256 message, Address address, SecureString passphrase) key = _keyStore.GetKey(address, passphrase).PrivateKey; } - var rs = SpanSecP256k1.SignCompact(message.Bytes, key.KeyBytes, out int v); + var rs = SecP256k1.SignCompact(message.Bytes, key.KeyBytes, out int v); return new Signature(rs, v); } @@ -116,7 +116,7 @@ public Signature Sign(Hash256 message, Address address) throw new SecurityException("Can only sign without passphrase when account is unlocked."); } - var rs = SpanSecP256k1.SignCompact(message.Bytes, key.KeyBytes, out int v); + var rs = SecP256k1.SignCompact(message.Bytes, key.KeyBytes, out int v); return new Signature(rs, v); } } diff --git a/src/Nethermind/Nethermind.Wallet/DevWallet.cs b/src/Nethermind/Nethermind.Wallet/DevWallet.cs index cd941753bc7..e5ca68166a8 100644 --- a/src/Nethermind/Nethermind.Wallet/DevWallet.cs +++ b/src/Nethermind/Nethermind.Wallet/DevWallet.cs @@ -117,7 +117,7 @@ private bool CheckPassword(Address address, SecureString passphrase) public Signature Sign(Hash256 message, Address address) { - var rs = SpanSecP256k1.SignCompact(message.Bytes, _keys[address].KeyBytes, out int v); + var rs = SecP256k1.SignCompact(message.Bytes, _keys[address].KeyBytes, out int v); return new Signature(rs, v); } } diff --git a/src/Nethermind/Nethermind.Wallet/ProtectedKeyStoreWallet.cs b/src/Nethermind/Nethermind.Wallet/ProtectedKeyStoreWallet.cs index c33deb9ee7a..2afe410ddfa 100644 --- a/src/Nethermind/Nethermind.Wallet/ProtectedKeyStoreWallet.cs +++ b/src/Nethermind/Nethermind.Wallet/ProtectedKeyStoreWallet.cs @@ -97,7 +97,7 @@ private Signature SignCore(Hash256 message, Address address, Func ge { var protectedPrivateKey = (ProtectedPrivateKey)_unlockedAccounts.Get(address.ToString()); using PrivateKey key = protectedPrivateKey is not null ? protectedPrivateKey.Unprotect() : getPrivateKeyWhenNotFound(); - var rs = SpanSecP256k1.SignCompact(message.Bytes, key.KeyBytes, out int v); + var rs = SecP256k1.SignCompact(message.Bytes, key.KeyBytes, out int v); return new Signature(rs, v); } }