Files
p256k1/bench/comparison_bench_test.go

164 lines
3.7 KiB
Go

//go:build !nocgo
// +build !nocgo
package bench
import (
"crypto/rand"
"testing"
"p256k1.mleku.dev/signer"
)
// This file contains benchmarks for the P256K1Signer implementation
// (pure Go port from Bitcoin Core secp256k1)
var (
benchSeckey []byte
benchMsghash []byte
compBenchSignerP256K1 *signer.P256K1Signer
compBenchSignerP256K12 *signer.P256K1Signer
compBenchSigP256K1 []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)
}
// 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
}
// BenchmarkPubkeyDerivation benchmarks public key derivation from private key
func BenchmarkPubkeyDerivation(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()
}
}
// BenchmarkSign benchmarks Schnorr signing
func BenchmarkSign(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)
}
}
}
// BenchmarkVerify benchmarks Schnorr verification
func BenchmarkVerify(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")
}
}
}
// BenchmarkECDH benchmarks ECDH shared secret generation
func BenchmarkECDH(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)
}
}
}