comparison_bench_test.go raw

   1  //go:build !nocgo && !js && !wasm && !tinygo && !wasm32
   2  
   3  package bench
   4  
   5  import (
   6  	"crypto/rand"
   7  	"testing"
   8  
   9  	"next.orly.dev/pkg/p256k1/signer"
  10  )
  11  
  12  // This file contains benchmarks for the P256K1Signer implementation
  13  // (pure Go port from Bitcoin Core secp256k1)
  14  
  15  var (
  16  	benchSeckey            []byte
  17  	benchMsghash           []byte
  18  	compBenchSignerP256K1  *signer.P256K1Signer
  19  	compBenchSignerP256K12 *signer.P256K1Signer
  20  	compBenchSigP256K1     []byte
  21  )
  22  
  23  func initComparisonBenchData() {
  24  	// Generate a fixed secret key for benchmarks
  25  	if benchSeckey == nil {
  26  		benchSeckey = []byte{
  27  			0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  28  			0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  29  			0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  30  			0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  31  		}
  32  
  33  		// Ensure it's valid (non-zero and less than order)
  34  		// We'll validate by trying to create a signer
  35  		for {
  36  			testSigner := signer.NewP256K1Signer()
  37  			if err := testSigner.InitSec(benchSeckey); err == nil {
  38  				break
  39  			}
  40  			if _, err := rand.Read(benchSeckey); err != nil {
  41  				panic(err)
  42  			}
  43  		}
  44  
  45  		// Create message hash
  46  		benchMsghash = make([]byte, 32)
  47  		if _, err := rand.Read(benchMsghash); err != nil {
  48  			panic(err)
  49  		}
  50  	}
  51  
  52  	// Setup P256K1Signer (this repo's implementation)
  53  	signer1 := signer.NewP256K1Signer()
  54  	if err := signer1.InitSec(benchSeckey); err != nil {
  55  		panic(err)
  56  	}
  57  	compBenchSignerP256K1 = signer1
  58  
  59  	var err error
  60  	compBenchSigP256K1, err = signer1.Sign(benchMsghash)
  61  	if err != nil {
  62  		panic(err)
  63  	}
  64  
  65  	// Generate second key pair for ECDH
  66  	seckey2 := make([]byte, 32)
  67  	for {
  68  		if _, err := rand.Read(seckey2); err != nil {
  69  			panic(err)
  70  		}
  71  		// Validate by trying to create a signer
  72  		testSigner := signer.NewP256K1Signer()
  73  		if err := testSigner.InitSec(seckey2); err == nil {
  74  			break
  75  		}
  76  	}
  77  
  78  	// P256K1Signer second key pair
  79  	signer12 := signer.NewP256K1Signer()
  80  	if err := signer12.InitSec(seckey2); err != nil {
  81  		panic(err)
  82  	}
  83  	compBenchSignerP256K12 = signer12
  84  }
  85  
  86  // BenchmarkPubkeyDerivation benchmarks public key derivation from private key
  87  func BenchmarkPubkeyDerivation(b *testing.B) {
  88  	if benchSeckey == nil {
  89  		initComparisonBenchData()
  90  	}
  91  
  92  	b.ResetTimer()
  93  	for i := 0; i < b.N; i++ {
  94  		s := signer.NewP256K1Signer()
  95  		if err := s.InitSec(benchSeckey); err != nil {
  96  			b.Fatalf("failed to create signer: %v", err)
  97  		}
  98  		_ = s.Pub()
  99  	}
 100  }
 101  
 102  // BenchmarkSign benchmarks Schnorr signing
 103  func BenchmarkSign(b *testing.B) {
 104  	if benchSeckey == nil {
 105  		initComparisonBenchData()
 106  	}
 107  
 108  	b.ResetTimer()
 109  	for i := 0; i < b.N; i++ {
 110  		if compBenchSignerP256K1 == nil {
 111  			initComparisonBenchData()
 112  		}
 113  		_, err := compBenchSignerP256K1.Sign(benchMsghash)
 114  		if err != nil {
 115  			b.Fatalf("failed to sign: %v", err)
 116  		}
 117  	}
 118  }
 119  
 120  // BenchmarkVerify benchmarks Schnorr verification
 121  func BenchmarkVerify(b *testing.B) {
 122  	if benchSeckey == nil {
 123  		initComparisonBenchData()
 124  	}
 125  
 126  	if compBenchSignerP256K1 == nil || compBenchSigP256K1 == nil {
 127  		initComparisonBenchData()
 128  	}
 129  
 130  	b.ResetTimer()
 131  	for i := 0; i < b.N; i++ {
 132  		verifier := signer.NewP256K1Signer()
 133  		if err := verifier.InitPub(compBenchSignerP256K1.Pub()); err != nil {
 134  			b.Fatalf("failed to create verifier: %v", err)
 135  		}
 136  		valid, err := verifier.Verify(benchMsghash, compBenchSigP256K1)
 137  		if err != nil {
 138  			b.Fatalf("verification error: %v", err)
 139  		}
 140  		if !valid {
 141  			b.Fatalf("verification failed")
 142  		}
 143  	}
 144  }
 145  
 146  // BenchmarkECDH benchmarks ECDH shared secret generation
 147  func BenchmarkECDH(b *testing.B) {
 148  	if benchSeckey == nil {
 149  		initComparisonBenchData()
 150  	}
 151  
 152  	b.ResetTimer()
 153  	for i := 0; i < b.N; i++ {
 154  		if compBenchSignerP256K1 == nil || compBenchSignerP256K12 == nil {
 155  			initComparisonBenchData()
 156  		}
 157  		_, err := compBenchSignerP256K1.ECDH(compBenchSignerP256K12.Pub())
 158  		if err != nil {
 159  			b.Fatalf("ECDH failed: %v", err)
 160  		}
 161  	}
 162  }
 163