Skip to content

Commit

Permalink
reduce allocations (#71)
Browse files Browse the repository at this point in the history
  • Loading branch information
tanishqjasoria authored Jun 12, 2024
1 parent 147a79d commit 08e541b
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 50 deletions.
10 changes: 10 additions & 0 deletions src/Nethermind.Verkle.Tests/Curve/BanderwagonTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,16 @@ public void TestSerialiseGen()
Assert.That(res == gen);
}

[Test]
public void TestSerialiseGenLittle()
{
Banderwagon gen = Banderwagon.Generator;

byte[]? serialized = gen.ToBytesUncompressedLittleEndian();
Banderwagon res = Banderwagon.FromBytesUncompressedUnchecked(serialized, false);
Assert.That(res == gen);
}

[Test]
public void TestScalarMulSmoke()
{
Expand Down
72 changes: 48 additions & 24 deletions src/Nethermind.Verkle/Curve/Banderwagon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,54 @@ public static Banderwagon FromBytesUncompressedUnchecked(ReadOnlySpan<byte> byte
return new Banderwagon(x, y);
}

public byte[] ToBytesUncompressed()
{
byte[] uncompressed = new byte[64];
Span<byte> ucSpan = uncompressed;
AffinePoint affine = ToAffine();

Span<byte> x = ucSpan[..32];
affine.X.ToBytesBigEndian(in x);
Span<byte> y = ucSpan[32..];
affine.Y.ToBytesBigEndian(in y);

return uncompressed;
}

public void ToBytesUncompressed(in Span<byte> target)
{
AffinePoint affine = ToAffine();

Span<byte> x = target[..32];
affine.X.ToBytesBigEndian(in x);
Span<byte> y = target[32..];
affine.Y.ToBytesBigEndian(in y);
}

public byte[] ToBytesUncompressedLittleEndian()
{
byte[] uncompressed = new byte[64];
Span<byte> ucSpan = uncompressed;
AffinePoint affine = ToAffine();

Span<byte> x = ucSpan[..32];
affine.X.ToBytes(in x);
Span<byte> y = ucSpan[32..];
affine.Y.ToBytes(in y);

return uncompressed;
}

public void ToBytesUncompressedLittleEndian(in Span<byte> target)
{
AffinePoint affine = ToAffine();

Span<byte> x = target[..32];
affine.X.ToBytes(in x);
Span<byte> y = target[32..];
affine.Y.ToBytes(in y);
}

private static int SubgroupCheck(FpE x)
{
FpE.MultiplyMod(x, x, out FpE res);
Expand Down Expand Up @@ -229,30 +277,6 @@ public byte[] ToBytes()
return x.ToBytesBigEndian();
}

public byte[] ToBytesUncompressed()
{
byte[] uncompressed = new byte[64];
Span<byte> ucSpan = uncompressed;
AffinePoint affine = ToAffine();

affine.X.ToBytesBigEndian().CopyTo(ucSpan[..32]);
affine.Y.ToBytesBigEndian().CopyTo(ucSpan[32..]);

return uncompressed;
}

public byte[] ToBytesUncompressedLittleEndian()
{
byte[] uncompressed = new byte[64];
Span<byte> ucSpan = uncompressed;
AffinePoint affine = ToAffine();

affine.X.ToBytes().CopyTo(ucSpan[..32]);
affine.Y.ToBytes().CopyTo(ucSpan[32..]);

return uncompressed;
}

public byte[] ToBytesLittleEndian()
{
AffinePoint affine = ToAffine();
Expand Down
22 changes: 20 additions & 2 deletions src/Nethermind.Verkle/Fields/FpEElement/Element.Convert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,32 @@ public static FE SetElement(BigInteger value)

public byte[] ToBytes()
{
byte[] returnEncoding = new byte[32];
Span<byte> target = returnEncoding;
ToRegular(in this, out FE x);
return ToLittleEndian(x.u0, x.u1, x.u2, x.u3);
ToLittleEndian(x.u0, x.u1, x.u2, x.u3, in target);
return returnEncoding;
}

public void ToBytes(in Span<byte> target)
{
ToRegular(in this, out FE x);
ToLittleEndian(x.u0, x.u1, x.u2, x.u3, in target);
}

public byte[] ToBytesBigEndian()
{
byte[] returnEncoding = new byte[32];
Span<byte> target = returnEncoding;
ToRegular(in this, out FE x);
ToBigEndian(x.u0, x.u1, x.u2, x.u3, in target);
return returnEncoding;
}

public void ToBytesBigEndian(in Span<byte> target)
{
ToRegular(in this, out FE x);
return ToBigEndian(x.u0, x.u1, x.u2, x.u3);
ToBigEndian(x.u0, x.u1, x.u2, x.u3, in target);
}

public static FE FromBytes(in ReadOnlySpan<byte> byteEncoded, bool isBigEndian = false)
Expand Down
15 changes: 4 additions & 11 deletions src/Nethermind.Verkle/Fields/FpEElement/Element.Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,23 +120,18 @@ private static int Len64(ulong x)
return 64 - BitOperations.LeadingZeroCount(x);
}

private static byte[] ToBigEndian(scoped in ulong u0, scoped in ulong u1, scoped in ulong u2,
scoped in ulong u3)
private static void ToBigEndian(scoped in ulong u0, scoped in ulong u1, scoped in ulong u2,
scoped in ulong u3, in Span<byte> target)
{
byte[] returnEncoding = new byte[32];
Span<byte> target = returnEncoding;
BinaryPrimitives.WriteUInt64BigEndian(target.Slice(0, 8), u3);
BinaryPrimitives.WriteUInt64BigEndian(target.Slice(8, 8), u2);
BinaryPrimitives.WriteUInt64BigEndian(target.Slice(16, 8), u1);
BinaryPrimitives.WriteUInt64BigEndian(target.Slice(24, 8), u0);
return returnEncoding;
}

private static byte[] ToLittleEndian(scoped in ulong u0, scoped in ulong u1, scoped in ulong u2,
scoped in ulong u3)
private static void ToLittleEndian(scoped in ulong u0, scoped in ulong u1, scoped in ulong u2,
scoped in ulong u3, in Span<byte> target)
{
byte[] returnEncoding = new byte[32];
Span<byte> target = returnEncoding;
if (Avx.IsSupported)
{
Unsafe.As<byte, Vector256<ulong>>(ref MemoryMarshal.GetReference(target)) =
Expand All @@ -149,8 +144,6 @@ private static byte[] ToLittleEndian(scoped in ulong u0, scoped in ulong u1, sco
BinaryPrimitives.WriteUInt64LittleEndian(target.Slice(16, 8), u2);
BinaryPrimitives.WriteUInt64LittleEndian(target.Slice(24, 8), u3);
}

return returnEncoding;
}

private static ReadOnlySpan<byte> SBroadcastLookup => new byte[]
Expand Down
22 changes: 20 additions & 2 deletions src/Nethermind.Verkle/Fields/FrEElement/Element.Convert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,32 @@ public static FE SetElement(BigInteger value)

public byte[] ToBytes()
{
byte[] returnEncoding = new byte[32];
Span<byte> target = returnEncoding;
ToRegular(in this, out FE x);
return ToLittleEndian(x.u0, x.u1, x.u2, x.u3);
ToLittleEndian(x.u0, x.u1, x.u2, x.u3, in target);
return returnEncoding;
}

public void ToBytes(in Span<byte> target)
{
ToRegular(in this, out FE x);
ToLittleEndian(x.u0, x.u1, x.u2, x.u3, in target);
}

public byte[] ToBytesBigEndian()
{
byte[] returnEncoding = new byte[32];
Span<byte> target = returnEncoding;
ToRegular(in this, out FE x);
ToBigEndian(x.u0, x.u1, x.u2, x.u3, in target);
return returnEncoding;
}

public void ToBytesBigEndian(in Span<byte> target)
{
ToRegular(in this, out FE x);
return ToBigEndian(x.u0, x.u1, x.u2, x.u3);
ToBigEndian(x.u0, x.u1, x.u2, x.u3, in target);
}

public static FE FromBytes(in ReadOnlySpan<byte> byteEncoded, bool isBigEndian = false)
Expand Down
15 changes: 4 additions & 11 deletions src/Nethermind.Verkle/Fields/FrEElement/Element.Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,23 +121,18 @@ private static int Len64(ulong x)
return 64 - BitOperations.LeadingZeroCount(x);
}

private static byte[] ToBigEndian(scoped in ulong u0, scoped in ulong u1, scoped in ulong u2,
scoped in ulong u3)
private static void ToBigEndian(scoped in ulong u0, scoped in ulong u1, scoped in ulong u2,
scoped in ulong u3, in Span<byte> target)
{
byte[] returnEncoding = new byte[32];
Span<byte> target = returnEncoding;
BinaryPrimitives.WriteUInt64BigEndian(target.Slice(0, 8), u3);
BinaryPrimitives.WriteUInt64BigEndian(target.Slice(8, 8), u2);
BinaryPrimitives.WriteUInt64BigEndian(target.Slice(16, 8), u1);
BinaryPrimitives.WriteUInt64BigEndian(target.Slice(24, 8), u0);
return returnEncoding;
}

private static byte[] ToLittleEndian(scoped in ulong u0, scoped in ulong u1, scoped in ulong u2,
scoped in ulong u3)
private static void ToLittleEndian(scoped in ulong u0, scoped in ulong u1, scoped in ulong u2,
scoped in ulong u3, in Span<byte> target)
{
byte[] returnEncoding = new byte[32];
Span<byte> target = returnEncoding;
if (Avx.IsSupported)
{
Unsafe.As<byte, Vector256<ulong>>(ref MemoryMarshal.GetReference(target)) =
Expand All @@ -150,8 +145,6 @@ private static byte[] ToLittleEndian(scoped in ulong u0, scoped in ulong u1, sco
BinaryPrimitives.WriteUInt64LittleEndian(target.Slice(16, 8), u2);
BinaryPrimitives.WriteUInt64LittleEndian(target.Slice(24, 8), u3);
}

return returnEncoding;
}

private static ReadOnlySpan<byte> SBroadcastLookup => new byte[]
Expand Down

0 comments on commit 08e541b

Please sign in to comment.