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

WTF is wrong with your perfomance?? #3588

Open
kzorin52 opened this issue Jan 4, 2024 · 3 comments
Open

WTF is wrong with your perfomance?? #3588

kzorin52 opened this issue Jan 4, 2024 · 3 comments

Comments

@kzorin52
Copy link

kzorin52 commented Jan 4, 2024

Benchmark:

Method Mean Error StdDev
BouncyCastlePub 484.89 us 7.248 us 6.780 us
NBitcoinSecp256K1Pub 123.40 us 0.765 us 0.716 us
NBitcoinPub 114.46 us 0.973 us 0.862 us
NativePub 36.64 us 0.432 us 0.404 us
EcdsaLibPub 80.81 us 0.792 us 0.702 us
NethermindPub 25.18 us 0.187 us 0.166 us
LibplanetPub 963.74 us 13.782 us 12.892 us

Code:

public class Secp256K1Tests
{
    private const int N = 32;
    private readonly byte[] _data;
    private readonly ReadOnlyMemory<byte> _dataSpan;
    private readonly Memory<byte> _dataMemory;

    private static readonly X9ECParameters Curve = SecNamedCurves.GetByName("secp256k1");
    private static readonly ECDomainParameters Params = new(Curve.Curve, Curve.G, Curve.N, Curve.H, Curve.GetSeed());
    private static readonly Secp256k1 Secp256K1 = new();

    public Secp256K1Tests()
    {
        _data = new byte[N];
        new Random(121).NextBytes(_data);
        _dataSpan = new ReadOnlyMemory<byte>(_data);
        _dataMemory = _data.AsMemory();
    }

    [Benchmark]
    public byte[] BouncyCastlePub()
    {
        var key = new ECPrivateKeyParameters(new BigInteger(1, _dataSpan.Span), Params);
        return key.Parameters.G.Multiply(key.D).GetEncoded(true);
    }

    [Benchmark]
    public byte[] NBitcoinSecp256K1Pub()
    {
        using var prv = NBitcoin.Secp256k1.ECPrivKey.Create(_dataSpan.Span);
        return prv.CreatePubKey().ToBytes(true);
    }

    [Benchmark]
    public byte[] NBitcoinPub()
    {
        return new NBitcoin.Key(_data).PubKey.ToBytes();
    }

    [Benchmark]
    public byte[] NativePub()
    {
        Span<byte> pub = stackalloc byte[64];
        Secp256K1.PublicKeyCreate(pub, _dataMemory.Span);

        Span<byte> pubCompr = stackalloc byte[33];
        Secp256K1.PublicKeySerialize(pubCompr, pub, Flags.SECP256K1_EC_COMPRESSED);

        return pubCompr.ToArray();
    }

    [Benchmark]
    public byte[] EcdsaLibPub()
    {
        return Cryptography.ECDSA.Secp256K1Manager.GetPublicKey(_data, true);
    }

    [Benchmark]
    public byte[] NethermindPub()
    {
        return Nethermind.Crypto.SecP256k1.GetPublicKey(_data, true)!;
    }

    [Benchmark]
    public byte[] LibplanetPub()
    {
        return [.. new Libplanet.Crypto.PrivateKey(_data).PublicKey.ToImmutableArray(true)];
    }
}
@kzorin52 kzorin52 changed the title WTF is wrong with your perfomance?? WTF is wrong with your performance?? Jan 4, 2024
@kzorin52 kzorin52 changed the title WTF is wrong with your performance?? WTF is wrong with your perfomance?? Jan 4, 2024
@riemannulus
Copy link
Member

Thank you for reporting the issue. Since we are using Pub, which wraps BouncyCastle, there should not be much difference in performance from BouncyCastle. Please tell me which version of BouncyCastle you used in your testing.

@kzorin52
Copy link
Author

Hi, latest

@riemannulus
Copy link
Member

@kzorin52 can you add this line for use BouncyCastle binding?

CryptoConfig.CryptoBackend = new Secp256k1CryptoBackend<SHA256>();

Maybe you need to import Libplanet.Crypto.Secp256k1 package too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants