Skip to content

Commit e5daa15

Browse files
authored
Remove defensive copies from SecP256k1 (#9817)
* Remove defensive copies from SecP256k1 * Remove type entirely * Remove unneeded .ToArray() * Max optimize
1 parent 67e9c6e commit e5daa15

File tree

10 files changed

+20
-77
lines changed

10 files changed

+20
-77
lines changed

src/Nethermind/Nethermind.Consensus/Signer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public Signer(ulong chainId, IProtectedPrivateKey key, ILogManager logManager)
4040
public Signature Sign(in ValueHash256 message)
4141
{
4242
if (!CanSign) throw new InvalidOperationException("Cannot sign without provided key.");
43-
byte[] rs = SpanSecP256k1.SignCompact(message.Bytes, _key!.KeyBytes, out int v);
43+
byte[] rs = SecP256k1.SignCompact(message.Bytes, _key!.KeyBytes, out int v);
4444
return new Signature(rs, v);
4545
}
4646

src/Nethermind/Nethermind.Core.Test/Crypto/SignatureTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public void can_recover_from_message()
4141
var signatureObject = new Signature(signatureSlice, recoveryId);
4242
var keccak = Keccak.Compute(Bytes.Concat(messageType, data));
4343
Span<byte> publicKey = stackalloc byte[65];
44-
bool result = SpanSecP256k1.RecoverKeyFromCompact(publicKey, keccak.Bytes, signatureObject.Bytes.ToArray(), signatureObject.RecoveryId, false);
44+
bool result = SecP256k1.RecoverKeyFromCompact(publicKey, keccak.Bytes, signatureObject.Bytes, signatureObject.RecoveryId, false);
4545
result.Should().BeTrue();
4646
}
4747
}

src/Nethermind/Nethermind.Crypto/Ecdsa.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public Signature Sign(PrivateKey privateKey, in ValueHash256 message)
2121
InvalidPrivateKey();
2222
}
2323

24-
byte[] signatureBytes = SpanSecP256k1.SignCompact(message.Bytes, privateKey.KeyBytes, out int recoveryId);
24+
byte[] signatureBytes = SecP256k1.SignCompact(message.Bytes, privateKey.KeyBytes, out int recoveryId);
2525
Signature signature = new(signatureBytes, recoveryId);
2626

2727
#if DEBUG
@@ -40,7 +40,7 @@ public Signature Sign(PrivateKey privateKey, in ValueHash256 message)
4040
public PublicKey? RecoverPublicKey(Signature signature, in ValueHash256 message)
4141
{
4242
Span<byte> publicKey = stackalloc byte[65];
43-
bool success = SpanSecP256k1.RecoverKeyFromCompact(publicKey, message.Bytes, signature.Bytes, signature.RecoveryId, false);
43+
bool success = SecP256k1.RecoverKeyFromCompact(publicKey, message.Bytes, signature.Bytes, signature.RecoveryId, false);
4444
if (!success)
4545
{
4646
return null;
@@ -52,7 +52,7 @@ public Signature Sign(PrivateKey privateKey, in ValueHash256 message)
5252
public CompressedPublicKey? RecoverCompressedPublicKey(Signature signature, in ValueHash256 message)
5353
{
5454
Span<byte> publicKey = stackalloc byte[33];
55-
bool success = SpanSecP256k1.RecoverKeyFromCompact(publicKey, message.Bytes, signature.Bytes, signature.RecoveryId, true);
55+
bool success = SecP256k1.RecoverKeyFromCompact(publicKey, message.Bytes, signature.Bytes, signature.RecoveryId, true);
5656
if (!success)
5757
{
5858
return null;

src/Nethermind/Nethermind.Crypto/EthereumEcdsa.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public class EthereumEcdsa(ulong chainId) : Ecdsa, IEthereumEcdsa
3030
private static Address? RecoverAddress(Span<byte> signatureBytes64, byte v, ReadOnlySpan<byte> message)
3131
{
3232
Span<byte> publicKey = stackalloc byte[65];
33-
bool success = SpanSecP256k1.RecoverKeyFromCompact(
33+
bool success = SecP256k1.RecoverKeyFromCompact(
3434
publicKey,
3535
message,
3636
signatureBytes64,
@@ -41,7 +41,7 @@ public class EthereumEcdsa(ulong chainId) : Ecdsa, IEthereumEcdsa
4141
}
4242

4343
public static bool RecoverAddressRaw(ReadOnlySpan<byte> signatureBytes64, byte v, ReadOnlySpan<byte> message, Span<byte> resultPublicKey65) =>
44-
SpanSecP256k1.RecoverKeyFromCompact(
44+
SecP256k1.RecoverKeyFromCompact(
4545
resultPublicKey65,
4646
message,
4747
signatureBytes64,

src/Nethermind/Nethermind.Crypto/SpanSecP256k1.cs

Lines changed: 0 additions & 63 deletions
This file was deleted.

src/Nethermind/Nethermind.Evm.Precompiles/EcRecoverPrecompile.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.Runtime.CompilerServices;
6+
using System.Runtime.InteropServices;
67
using Nethermind.Core;
78
using Nethermind.Core.Crypto;
89
using Nethermind.Core.Extensions;
@@ -70,8 +71,13 @@ private Result<byte[]> RunInternal(ReadOnlySpan<byte> inputDataSpan)
7071
return Empty;
7172
}
7273

73-
byte[] result = ValueKeccak.Compute(publicKey.Slice(1, 64)).ToByteArray();
74-
result.AsSpan(0, 12).Clear();
74+
byte[] result = new byte[32];
75+
KeccakHash.ComputeHashBytesToSpan(publicKey.Slice(1, 64), result);
76+
77+
ref byte refResut = ref MemoryMarshal.GetArrayDataReference(result);
78+
79+
// Clear first 12 bytes, as address is last 20 bytes of the hash
80+
Unsafe.InitBlockUnaligned(ref refResut, 0, 12);
7581
return result;
7682
}
7783
}

src/Nethermind/Nethermind.Optimism/CL/P2P/P2PBlockValidator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ private bool IsSignatureValid(ReadOnlySpan<byte> payloadData, Span<byte> signatu
153153
byte[] signedHash = KeccakHash.ComputeHashBytes(sequencerSignedData);
154154

155155
Span<byte> publicKey = stackalloc byte[65];
156-
bool success = SpanSecP256k1.RecoverKeyFromCompact(
156+
bool success = SecP256k1.RecoverKeyFromCompact(
157157
publicKey,
158158
signedHash,
159159
signature.Slice(0, 64),

src/Nethermind/Nethermind.Wallet/DevKeyStoreWallet.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public Signature Sign(Hash256 message, Address address, SecureString passphrase)
100100
key = _keyStore.GetKey(address, passphrase).PrivateKey;
101101
}
102102

103-
var rs = SpanSecP256k1.SignCompact(message.Bytes, key.KeyBytes, out int v);
103+
var rs = SecP256k1.SignCompact(message.Bytes, key.KeyBytes, out int v);
104104
return new Signature(rs, v);
105105
}
106106

@@ -116,7 +116,7 @@ public Signature Sign(Hash256 message, Address address)
116116
throw new SecurityException("Can only sign without passphrase when account is unlocked.");
117117
}
118118

119-
var rs = SpanSecP256k1.SignCompact(message.Bytes, key.KeyBytes, out int v);
119+
var rs = SecP256k1.SignCompact(message.Bytes, key.KeyBytes, out int v);
120120
return new Signature(rs, v);
121121
}
122122
}

src/Nethermind/Nethermind.Wallet/DevWallet.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ private bool CheckPassword(Address address, SecureString passphrase)
117117

118118
public Signature Sign(Hash256 message, Address address)
119119
{
120-
var rs = SpanSecP256k1.SignCompact(message.Bytes, _keys[address].KeyBytes, out int v);
120+
var rs = SecP256k1.SignCompact(message.Bytes, _keys[address].KeyBytes, out int v);
121121
return new Signature(rs, v);
122122
}
123123
}

src/Nethermind/Nethermind.Wallet/ProtectedKeyStoreWallet.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ private Signature SignCore(Hash256 message, Address address, Func<PrivateKey> ge
9797
{
9898
var protectedPrivateKey = (ProtectedPrivateKey)_unlockedAccounts.Get(address.ToString());
9999
using PrivateKey key = protectedPrivateKey is not null ? protectedPrivateKey.Unprotect() : getPrivateKeyWhenNotFound();
100-
var rs = SpanSecP256k1.SignCompact(message.Bytes, key.KeyBytes, out int v);
100+
var rs = SecP256k1.SignCompact(message.Bytes, key.KeyBytes, out int v);
101101
return new Signature(rs, v);
102102
}
103103
}

0 commit comments

Comments
 (0)