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.
360 lines
8.1 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|
|
|