Skip to content

Commit 064421b

Browse files
authored
Bls precompile: Use MUL for single point MSM (#7931)
1 parent d7d62a7 commit 064421b

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

src/Nethermind/Nethermind.Evm/Precompiles/Bls/G1MSMPrecompile.cs

+26
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,33 @@ public long DataGasCost(ReadOnlyMemory<byte> inputData, IReleaseSpec releaseSpec
4646
}
4747

4848
int nItems = inputData.Length / ItemSize;
49+
return nItems == 1 ? Mul(inputData) : MSM(inputData, nItems);
50+
}
51+
52+
private (ReadOnlyMemory<byte>, bool) Mul(ReadOnlyMemory<byte> inputData)
53+
{
54+
G1 x = new(stackalloc long[G1.Sz]);
55+
if (!x.TryDecodeRaw(inputData[..BlsConst.LenG1].Span) || !(BlsConst.DisableSubgroupChecks || x.InGroup()))
56+
{
57+
return IPrecompile.Failure;
58+
}
4959

60+
bool scalarIsInfinity = !inputData.Span[BlsConst.LenG1..].ContainsAnyExcept((byte)0);
61+
if (scalarIsInfinity || x.IsInf())
62+
{
63+
return (BlsConst.G1Inf, true);
64+
}
65+
66+
Span<byte> scalar = stackalloc byte[32];
67+
inputData.Span[BlsConst.LenG1..].CopyTo(scalar);
68+
scalar.Reverse();
69+
70+
G1 res = x.Mult(scalar);
71+
return (res.EncodeRaw(), true);
72+
}
73+
74+
private (ReadOnlyMemory<byte>, bool) MSM(ReadOnlyMemory<byte> inputData, int nItems)
75+
{
5076
using ArrayPoolList<long> rawPoints = new(nItems * G1.Sz, nItems * G1.Sz);
5177
using ArrayPoolList<byte> rawScalars = new(nItems * 32, nItems * 32);
5278
using ArrayPoolList<int> pointDestinations = new(nItems);

src/Nethermind/Nethermind.Evm/Precompiles/Bls/G2MSMPrecompile.cs

+27
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,34 @@ public long DataGasCost(ReadOnlyMemory<byte> inputData, IReleaseSpec releaseSpec
4646
}
4747

4848
int nItems = inputData.Length / ItemSize;
49+
return nItems == 1 ? Mul(inputData) : MSM(inputData, nItems);
50+
}
51+
52+
53+
private (ReadOnlyMemory<byte>, bool) Mul(ReadOnlyMemory<byte> inputData)
54+
{
55+
G2 x = new(stackalloc long[G2.Sz]);
56+
if (!x.TryDecodeRaw(inputData[..BlsConst.LenG2].Span) || !(BlsConst.DisableSubgroupChecks || x.InGroup()))
57+
{
58+
return IPrecompile.Failure;
59+
}
60+
61+
bool scalarIsInfinity = !inputData[BlsConst.LenG2..].Span.ContainsAnyExcept((byte)0);
62+
if (scalarIsInfinity || x.IsInf())
63+
{
64+
return (BlsConst.G2Inf, true);
65+
}
66+
67+
Span<byte> scalar = stackalloc byte[32];
68+
inputData.Span[BlsConst.LenG2..].CopyTo(scalar);
69+
scalar.Reverse();
4970

71+
G2 res = x.Mult(scalar);
72+
return (res.EncodeRaw(), true);
73+
}
74+
75+
private (ReadOnlyMemory<byte>, bool) MSM(ReadOnlyMemory<byte> inputData, int nItems)
76+
{
5077
using ArrayPoolList<long> pointBuffer = new(nItems * G2.Sz, nItems * G2.Sz);
5178
using ArrayPoolList<byte> scalarBuffer = new(nItems * 32, nItems * 32);
5279
using ArrayPoolList<int> pointDestinations = new(nItems);

0 commit comments

Comments
 (0)