Files
p256k1/bench/comparison_bench_test.go
mleku f259c9a2e1 Remove benchmark results file and update Go module dependencies
This commit deletes the `benchmark_results.txt` file, which contained performance metrics for various cryptographic operations. Additionally, the Go module has been updated to version 1.25.0, and new dependencies have been added, including `btcec` for enhanced signing capabilities. The `go.sum` file has also been updated to reflect these changes. A new benchmark report has been introduced to provide a comprehensive comparison of signer implementations.
2025-11-01 21:03:50 +00:00

360 lines
8.1 KiB
Go

//go:build cgo
// +build cgo
package bench
import (
"crypto/rand"
"testing"
p256knext "next.orly.dev/pkg/crypto/p256k"
"p256k1.mleku.dev/signer"
)
// This file contains benchmarks comparing the three signer implementations:
// 1. P256K1Signer (this package's new port from Bitcoin Core secp256k1)
// 2. BtcecSigner (pure Go btcec wrapper)
// 3. NextP256K Signer (CGO version using next.orly.dev/pkg/crypto/p256k)
var (
benchSeckey []byte
benchMsghash []byte
compBenchSignerP256K1 *signer.P256K1Signer
compBenchSignerBtcec *signer.BtcecSigner
compBenchSignerNext *p256knext.Signer
compBenchSignerP256K12 *signer.P256K1Signer
compBenchSignerBtcec2 *signer.BtcecSigner
compBenchSignerNext2 *p256knext.Signer
compBenchSigP256K1 []byte
compBenchSigBtcec []byte
compBenchSigNext []byte
)
func initComparisonBenchData() {
// Generate a fixed secret key for benchmarks
if benchSeckey == nil {
benchSeckey = []byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
}
// Ensure it's valid (non-zero and less than order)
// We'll validate by trying to create a signer
for {
testSigner := signer.NewP256K1Signer()
if err := testSigner.InitSec(benchSeckey); err == nil {
break
}
if _, err := rand.Read(benchSeckey); err != nil {
panic(err)
}
}
// Create message hash
benchMsghash = make([]byte, 32)
if _, err := rand.Read(benchMsghash); err != nil {
panic(err)
}
}
// Setup P256K1Signer (this repo's implementation)
signer1 := signer.NewP256K1Signer()
if err := signer1.InitSec(benchSeckey); err != nil {
panic(err)
}
compBenchSignerP256K1 = signer1
var err error
compBenchSigP256K1, err = signer1.Sign(benchMsghash)
if err != nil {
panic(err)
}
// Setup BtcecSigner (pure Go)
signer2 := signer.NewBtcecSigner()
if err := signer2.InitSec(benchSeckey); err != nil {
panic(err)
}
compBenchSignerBtcec = signer2
compBenchSigBtcec, err = signer2.Sign(benchMsghash)
if err != nil {
panic(err)
}
// Setup NextP256K Signer (CGO version)
signer3 := &p256knext.Signer{}
if err := signer3.InitSec(benchSeckey); err != nil {
panic(err)
}
compBenchSignerNext = signer3
compBenchSigNext, err = signer3.Sign(benchMsghash)
if err != nil {
panic(err)
}
// Generate second key pair for ECDH
seckey2 := make([]byte, 32)
for {
if _, err := rand.Read(seckey2); err != nil {
panic(err)
}
// Validate by trying to create a signer
testSigner := signer.NewP256K1Signer()
if err := testSigner.InitSec(seckey2); err == nil {
break
}
}
// P256K1Signer second key pair
signer12 := signer.NewP256K1Signer()
if err := signer12.InitSec(seckey2); err != nil {
panic(err)
}
compBenchSignerP256K12 = signer12
// BtcecSigner second key pair
signer22 := signer.NewBtcecSigner()
if err := signer22.InitSec(seckey2); err != nil {
panic(err)
}
compBenchSignerBtcec2 = signer22
// NextP256K Signer second key pair
signer32 := &p256knext.Signer{}
if err := signer32.InitSec(seckey2); err != nil {
panic(err)
}
compBenchSignerNext2 = signer32
}
// BenchmarkPubkeyDerivation compares public key derivation from private key
func BenchmarkPubkeyDerivation_P256K1(b *testing.B) {
if benchSeckey == nil {
initComparisonBenchData()
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
s := signer.NewP256K1Signer()
if err := s.InitSec(benchSeckey); err != nil {
b.Fatalf("failed to create signer: %v", err)
}
_ = s.Pub()
}
}
func BenchmarkPubkeyDerivation_Btcec(b *testing.B) {
if benchSeckey == nil {
initComparisonBenchData()
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
s := signer.NewBtcecSigner()
if err := s.InitSec(benchSeckey); err != nil {
b.Fatalf("failed to create signer: %v", err)
}
_ = s.Pub()
}
}
func BenchmarkPubkeyDerivation_NextP256K(b *testing.B) {
if benchSeckey == nil {
initComparisonBenchData()
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
s := &p256knext.Signer{}
if err := s.InitSec(benchSeckey); err != nil {
b.Fatalf("failed to create signer: %v", err)
}
_ = s.Pub()
}
}
// BenchmarkSign compares Schnorr signing
func BenchmarkSign_P256K1(b *testing.B) {
if benchSeckey == nil {
initComparisonBenchData()
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
if compBenchSignerP256K1 == nil {
initComparisonBenchData()
}
_, err := compBenchSignerP256K1.Sign(benchMsghash)
if err != nil {
b.Fatalf("failed to sign: %v", err)
}
}
}
func BenchmarkSign_Btcec(b *testing.B) {
if benchSeckey == nil {
initComparisonBenchData()
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
if compBenchSignerBtcec == nil {
initComparisonBenchData()
}
_, err := compBenchSignerBtcec.Sign(benchMsghash)
if err != nil {
b.Fatalf("failed to sign: %v", err)
}
}
}
func BenchmarkSign_NextP256K(b *testing.B) {
if benchSeckey == nil {
initComparisonBenchData()
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
if compBenchSignerNext == nil {
initComparisonBenchData()
}
_, err := compBenchSignerNext.Sign(benchMsghash)
if err != nil {
b.Fatalf("failed to sign: %v", err)
}
}
}
// BenchmarkVerify compares Schnorr verification
func BenchmarkVerify_P256K1(b *testing.B) {
if benchSeckey == nil {
initComparisonBenchData()
}
if compBenchSignerP256K1 == nil || compBenchSigP256K1 == nil {
initComparisonBenchData()
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
verifier := signer.NewP256K1Signer()
if err := verifier.InitPub(compBenchSignerP256K1.Pub()); err != nil {
b.Fatalf("failed to create verifier: %v", err)
}
valid, err := verifier.Verify(benchMsghash, compBenchSigP256K1)
if err != nil {
b.Fatalf("verification error: %v", err)
}
if !valid {
b.Fatalf("verification failed")
}
}
}
func BenchmarkVerify_Btcec(b *testing.B) {
if benchSeckey == nil {
initComparisonBenchData()
}
if compBenchSignerBtcec == nil || compBenchSigBtcec == nil {
initComparisonBenchData()
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
verifier := signer.NewBtcecSigner()
if err := verifier.InitPub(compBenchSignerBtcec.Pub()); err != nil {
b.Fatalf("failed to create verifier: %v", err)
}
valid, err := verifier.Verify(benchMsghash, compBenchSigBtcec)
if err != nil {
b.Fatalf("verification error: %v", err)
}
if !valid {
b.Fatalf("verification failed")
}
}
}
func BenchmarkVerify_NextP256K(b *testing.B) {
if benchSeckey == nil {
initComparisonBenchData()
}
if compBenchSignerNext == nil || compBenchSigNext == nil {
initComparisonBenchData()
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
verifier := &p256knext.Signer{}
if err := verifier.InitPub(compBenchSignerNext.Pub()); err != nil {
b.Fatalf("failed to create verifier: %v", err)
}
valid, err := verifier.Verify(benchMsghash, compBenchSigNext)
if err != nil {
b.Fatalf("verification error: %v", err)
}
if !valid {
b.Fatalf("verification failed")
}
}
}
// BenchmarkECDH compares ECDH shared secret generation
func BenchmarkECDH_P256K1(b *testing.B) {
if benchSeckey == nil {
initComparisonBenchData()
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
if compBenchSignerP256K1 == nil || compBenchSignerP256K12 == nil {
initComparisonBenchData()
}
_, err := compBenchSignerP256K1.ECDH(compBenchSignerP256K12.Pub())
if err != nil {
b.Fatalf("ECDH failed: %v", err)
}
}
}
func BenchmarkECDH_Btcec(b *testing.B) {
if benchSeckey == nil {
initComparisonBenchData()
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
if compBenchSignerBtcec == nil || compBenchSignerBtcec2 == nil {
initComparisonBenchData()
}
_, err := compBenchSignerBtcec.ECDH(compBenchSignerBtcec2.Pub())
if err != nil {
b.Fatalf("ECDH failed: %v", err)
}
}
}
func BenchmarkECDH_NextP256K(b *testing.B) {
if benchSeckey == nil {
initComparisonBenchData()
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
if compBenchSignerNext == nil || compBenchSignerNext2 == nil {
initComparisonBenchData()
}
_, err := compBenchSignerNext.ECDH(compBenchSignerNext2.Pub())
if err != nil {
b.Fatalf("ECDH failed: %v", err)
}
}
}