From 5862ff4da7cf4ddc7a38b1e200e1661622cded8b Mon Sep 17 00:00:00 2001 From: Marc Harvey-Hill Date: Wed, 18 Dec 2024 23:10:55 +0800 Subject: [PATCH] use mul for 1 point MSM --- .../Precompiles/Bls/G1MSMPrecompile.cs | 26 ++++++++++++++++++ .../Precompiles/Bls/G2MSMPrecompile.cs | 27 +++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/G1MSMPrecompile.cs b/src/Nethermind/Nethermind.Evm/Precompiles/Bls/G1MSMPrecompile.cs index 8f3f734f37f..3627c6bfae7 100644 --- a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/G1MSMPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm/Precompiles/Bls/G1MSMPrecompile.cs @@ -46,7 +46,33 @@ public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec } int nItems = inputData.Length / ItemSize; + return nItems == 1 ? Mul(inputData) : MSM(inputData, nItems); + } + + private (ReadOnlyMemory, bool) Mul(ReadOnlyMemory inputData) + { + G1 x = new(stackalloc long[G1.Sz]); + if (!x.TryDecodeRaw(inputData[..BlsConst.LenG1].Span) || !(BlsConst.DisableSubgroupChecks || x.InGroup())) + { + return IPrecompile.Failure; + } + bool scalarIsInfinity = !inputData.Span[BlsConst.LenG1..].ContainsAnyExcept((byte)0); + if (scalarIsInfinity || x.IsInf()) + { + return (BlsConst.G1Inf, true); + } + + Span scalar = stackalloc byte[32]; + inputData.Span[BlsConst.LenG1..].CopyTo(scalar); + scalar.Reverse(); + + G1 res = x.Mult(scalar); + return (res.EncodeRaw(), true); + } + + private (ReadOnlyMemory, bool) MSM(ReadOnlyMemory inputData, int nItems) + { using ArrayPoolList rawPoints = new(nItems * G1.Sz, nItems * G1.Sz); using ArrayPoolList rawScalars = new(nItems * 32, nItems * 32); using ArrayPoolList pointDestinations = new(nItems); diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/G2MSMPrecompile.cs b/src/Nethermind/Nethermind.Evm/Precompiles/Bls/G2MSMPrecompile.cs index 495e5c91a59..ca261920ed7 100644 --- a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/G2MSMPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm/Precompiles/Bls/G2MSMPrecompile.cs @@ -46,7 +46,34 @@ public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec } int nItems = inputData.Length / ItemSize; + return nItems == 1 ? Mul(inputData) : MSM(inputData, nItems); + } + + + private (ReadOnlyMemory, bool) Mul(ReadOnlyMemory inputData) + { + G2 x = new(stackalloc long[G2.Sz]); + if (!x.TryDecodeRaw(inputData[..BlsConst.LenG2].Span) || !(BlsConst.DisableSubgroupChecks || x.InGroup())) + { + return IPrecompile.Failure; + } + + bool scalarIsInfinity = !inputData[BlsConst.LenG2..].Span.ContainsAnyExcept((byte)0); + if (scalarIsInfinity || x.IsInf()) + { + return (BlsConst.G2Inf, true); + } + + Span scalar = stackalloc byte[32]; + inputData.Span[BlsConst.LenG2..].CopyTo(scalar); + scalar.Reverse(); + G2 res = x.Mult(scalar); + return (res.EncodeRaw(), true); + } + + private (ReadOnlyMemory, bool) MSM(ReadOnlyMemory inputData, int nItems) + { using ArrayPoolList pointBuffer = new(nItems * G2.Sz, nItems * G2.Sz); using ArrayPoolList scalarBuffer = new(nItems * 32, nItems * 32); using ArrayPoolList pointDestinations = new(nItems);