Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor Shutter Optimisation #7592

Merged
merged 2 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions src/Nethermind/Nethermind.Core.Test/Crypto/BlsSignerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

namespace Nethermind.Core.Test.Crypto;

using G1 = Bls.P1;

[TestFixture]
public class BlsTests
{
Expand All @@ -27,7 +29,9 @@ public void Verify_signature()
{
Bls.SecretKey sk = new(SkBytes, Bls.ByteOrder.LittleEndian);
BlsSigner.Signature s = BlsSigner.Sign(sk, MsgBytes);
Assert.That(BlsSigner.Verify(BlsSigner.GetPublicKey(sk).ToAffine(), s, MsgBytes));
G1 publicKey = new();
publicKey.FromSk(sk);
Assert.That(BlsSigner.Verify(publicKey.ToAffine(), s, MsgBytes));
}

[Test]
Expand All @@ -40,13 +44,19 @@ public void Rejects_bad_signature()
bytes[34] += 1;
BlsSigner.Signature bad = new(bytes);

Assert.That(BlsSigner.Verify(BlsSigner.GetPublicKey(sk).ToAffine(), bad, MsgBytes), Is.False);
G1 publicKey = new();
publicKey.FromSk(sk);
Assert.That(BlsSigner.Verify(publicKey.ToAffine(), bad, MsgBytes), Is.False);
}

[Test]
public void Public_key_from_private_key()
{
byte[] expected = [0x95, 0x39, 0x27, 0x35, 0x0c, 0x35, 0x31, 0xb0, 0xbc, 0x58, 0x64, 0xcd, 0x9c, 0x5f, 0xe1, 0x34, 0x74, 0xca, 0x0c, 0x9b, 0x59, 0x99, 0x51, 0xa7, 0x76, 0xc4, 0xb9, 0x8d, 0xf6, 0x6a, 0x0e, 0x62, 0x07, 0xa8, 0x5c, 0x7f, 0x7a, 0x85, 0x1a, 0x0c, 0x02, 0x2a, 0x87, 0xc0, 0x29, 0xc3, 0x65, 0x61];
Assert.That(BlsSigner.GetPublicKey(new(SkBytes, Bls.ByteOrder.LittleEndian)).Compress(), Is.EqualTo(expected));

G1 publicKey = new();
publicKey.FromSk(new(SkBytes, Bls.ByteOrder.LittleEndian));

Assert.That(publicKey.Compress(), Is.EqualTo(expected));
}
}
16 changes: 4 additions & 12 deletions src/Nethermind/Nethermind.Crypto/BlsSigner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,23 @@
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using System.Runtime.CompilerServices;
using System.Text;
using Nethermind.Core.Collections;

namespace Nethermind.Crypto;

using G1 = Bls.P1;
using G1Affine = Bls.P1Affine;
using G2 = Bls.P2;
using G2Affine = Bls.P2Affine;
using GT = Bls.PT;

public class BlsSigner
public static class BlsSigner
{
private static readonly byte[] Cryptosuite = Encoding.UTF8.GetBytes("BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_");
private const int InputLength = 64;

[SkipLocalsInit]
public static Signature Sign(Bls.SecretKey sk, ReadOnlySpan<byte> message)
{
G2 p = new(stackalloc long[G2.Sz]);
Expand All @@ -26,16 +27,7 @@ public static Signature Sign(Bls.SecretKey sk, ReadOnlySpan<byte> message)
return new(p.Compress());
}

public static void GetPublicKey(G1 res, Bls.SecretKey sk)
=> res.FromSk(sk);

public static G1 GetPublicKey(Bls.SecretKey sk)
{
G1 p = new();
GetPublicKey(p, sk);
return p;
}

[SkipLocalsInit]
public static bool Verify(G1Affine publicKey, Signature signature, ReadOnlySpan<byte> message)
{
int len = 2 * GT.Sz;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<RootNamespace>Nethermind.Shutter</RootNamespace>
<Nullable>enable</Nullable>
</PropertyGroup>
Expand Down
48 changes: 26 additions & 22 deletions src/Nethermind/Nethermind.Shutter/ShutterCrypto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Nethermind.Merkleization;
using System.Text;
using Nethermind.Core.Collections;
using System.Runtime.CompilerServices;

namespace Nethermind.Shutter;

Expand All @@ -37,6 +38,7 @@ public readonly ref struct EncryptedMessage

public class ShutterCryptoException(string message, Exception? innerException = null) : Exception(message, innerException);

[SkipLocalsInit]
public static void ComputeIdentity(G1 p, scoped ReadOnlySpan<byte> identityPrefix, in Address sender)
{
Span<byte> preimage = stackalloc byte[52];
Expand Down Expand Up @@ -97,18 +99,19 @@ public static EncryptedMessage DecodeEncryptedMessage(ReadOnlySpan<byte> bytes)
}
}

public static void RecoverSigma(out Span<byte> res, EncryptedMessage encryptedMessage, G1Affine decryptionKey)
public static void RecoverSigma(out Span<byte> sigma, EncryptedMessage encryptedMessage, G1Affine decryptionKey)
{
using ArrayPoolList<long> buf = new(GT.Sz, GT.Sz);
GT p = new(buf.AsSpan());
p.MillerLoop(encryptedMessage.C1.ToAffine(), decryptionKey);
res = Hash2(p); // key
res.Xor(encryptedMessage.C2);
sigma = Hash2(p); // key
sigma.Xor(encryptedMessage.C2);
}

public static void ComputeBlockKeys(Span<byte> res, ReadOnlySpan<byte> sigma, int n)
[SkipLocalsInit]
public static void ComputeBlockKeys(Span<byte> blockKeys, ReadOnlySpan<byte> sigma, int n)
{
if (res.Length != 32 * n)
if (blockKeys.Length != 32 * n)
{
throw new ArgumentException("Block keys buffer was the wrong size.");
}
Expand All @@ -132,7 +135,7 @@ public static void ComputeBlockKeys(Span<byte> res, ReadOnlySpan<byte> sigma, in
sigma.CopyTo(preimage);
suffix[(4 - suffixLength)..4].CopyTo(preimage[32..]);

Hash4(preimage).Bytes.CopyTo(res[(i * 32)..]);
Hash4(preimage).Bytes.CopyTo(blockKeys[(i * 32)..]);
}
}

Expand All @@ -156,7 +159,6 @@ public static Span<byte> Hash2(GT p)
return HashBytesToBlock(preimage);
}

// res should be intialised to one
public static void GTExp(ref GT x, UInt256 exp)
{
if (exp == 0)
Expand All @@ -178,6 +180,7 @@ public static void GTExp(ref GT x, UInt256 exp)
}
}

[SkipLocalsInit]
public static bool CheckDecryptionKey(G1Affine decryptionKey, G2Affine eonPublicKey, G1Affine identity)
{
int len = GT.Sz * 2;
Expand All @@ -189,8 +192,6 @@ public static bool CheckDecryptionKey(G1Affine decryptionKey, G2Affine eonPublic
return GT.FinalVerify(p1, p2);
}

private static readonly Ecdsa _ecdsa = new();

public static bool CheckSlotDecryptionIdentitiesSignature(
ulong instanceId,
ulong eon,
Expand All @@ -215,6 +216,7 @@ public static bool CheckSlotDecryptionIdentitiesSignature(
return expectedPubkey is not null && keyperAddress == expectedPubkey.Address;
}

[SkipLocalsInit]
public static bool CheckValidatorRegistrySignature(ReadOnlySpan<byte> pkBytes, ReadOnlySpan<byte> sigBytes, ReadOnlySpan<byte> msgBytes)
{
BlsSigner.Signature sig = new(sigBytes);
Expand Down Expand Up @@ -255,6 +257,8 @@ public static Span<byte> EncodeEncryptedMessage(EncryptedMessage encryptedMessag
return encoded;
}

private static readonly Ecdsa _ecdsa = new();

private static G2 ComputeC1(UInt256 r)
=> G2.Generator().Mult(r.ToLittleEndian());

Expand Down Expand Up @@ -284,37 +288,37 @@ private static Span<byte> ComputeC2(scoped ReadOnlySpan<byte> sigma, UInt256 r,
GT p = new(buf.AsSpan());
p.MillerLoop(eonKey, identity);
GTExp(ref p, r);
Span<byte> res = Hash2(p); //key
res.Xor(sigma);
return res;
Span<byte> c2 = Hash2(p); //key
c2.Xor(sigma);
return c2;
}

private static void ComputeC3(Span<byte> res, scoped ReadOnlySpan<byte> msgBlocks, ReadOnlySpan<byte> sigma)
private static void ComputeC3(Span<byte> c3, scoped ReadOnlySpan<byte> msgBlocks, ReadOnlySpan<byte> sigma)
{
// res = keys ^ msgs
ComputeBlockKeys(res, sigma, msgBlocks.Length / 32);
res.Xor(msgBlocks);
// c3 = keys ^ msgs
ComputeBlockKeys(c3, sigma, msgBlocks.Length / 32);
c3.Xor(msgBlocks);
}

private static int PaddedLength(ReadOnlySpan<byte> bytes)
=> bytes.Length + (32 - (bytes.Length % 32));

private static Span<byte> PadAndSplit(Span<byte> res, scoped ReadOnlySpan<byte> bytes)
private static Span<byte> PadAndSplit(Span<byte> paddedBytes, scoped ReadOnlySpan<byte> bytes)
{
int n = 32 - (bytes.Length % 32);
bytes.CopyTo(res);
res[bytes.Length..].Fill((byte)n);
return res;
bytes.CopyTo(paddedBytes);
paddedBytes[bytes.Length..].Fill((byte)n);
return paddedBytes;
}

private static void ComputeR(scoped ReadOnlySpan<byte> sigma, scoped ReadOnlySpan<byte> msg, out UInt256 res)
private static void ComputeR(scoped ReadOnlySpan<byte> sigma, scoped ReadOnlySpan<byte> msg, out UInt256 r)
{
int len = 32 + msg.Length;
using ArrayPoolList<byte> buf = new(len, len);
Span<byte> preimage = buf.AsSpan();
sigma.CopyTo(preimage);
msg.CopyTo(preimage[32..]);
Hash3(preimage, out res);
Hash3(preimage, out r);
}

internal static ValueHash256 GenerateHash(ulong instanceId, ulong eon, ulong slot, ulong txPointer, IEnumerable<ReadOnlyMemory<byte>> identityPreimages)
Expand Down
2 changes: 2 additions & 0 deletions src/Nethermind/Nethermind.Shutter/ShutterKeyValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Nethermind.Logging;
using Google.Protobuf;
using Nethermind.Core.Collections;
using System.Runtime.CompilerServices;

namespace Nethermind.Shutter;

Expand Down Expand Up @@ -65,6 +66,7 @@ public class ShutterKeyValidator(
}
}

[SkipLocalsInit]
private bool CheckDecryptionKeys(in Dto.DecryptionKeys decryptionKeys, in IShutterEon.Info eonInfo)
{
if (decryptionKeys.InstanceID != _instanceId)
Expand Down
3 changes: 3 additions & 0 deletions src/Nethermind/Nethermind.Shutter/ShutterTxLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using System.IO;
using Nethermind.Abi;
using Nethermind.Facade.Find;
using System.Runtime.CompilerServices;

namespace Nethermind.Shutter;

Expand Down Expand Up @@ -127,6 +128,7 @@ private Transaction[] FilterTransactions(IEnumerable<Transaction> transactions,
.ToPooledList(sequencedTransactions.Count);
}

[SkipLocalsInit]
private Transaction? DecryptSequencedTransaction(SequencedTransaction sequencedTransaction, (ReadOnlyMemory<byte> IdentityPreimage, ReadOnlyMemory<byte> Key) decryptionKey)
{
try
Expand Down Expand Up @@ -209,6 +211,7 @@ private IEnumerable<SequencedTransaction> GetNextTransactions(ulong eon, ulong t
}
}

[SkipLocalsInit]
private static SequencedTransaction EventToSequencedTransaction(ISequencerContract.TransactionSubmitted e, int index, ulong eon)
{
byte[] identityPreimage = new byte[52];
Expand Down
Loading