crypto_wasm_bench_test.go raw

   1  //go:build js || wasm || tinygo || wasm32
   2  
   3  package bench
   4  
   5  import (
   6  	"crypto/rand"
   7  	"testing"
   8  
   9  	"next.orly.dev/pkg/p256k1"
  10  )
  11  
  12  // WASM benchmarks for cryptographic operations using 32-bit arithmetic
  13  // This tests both ECDSA and Schnorr on WASM targets
  14  
  15  var (
  16  	wasmBenchSeckey   []byte
  17  	wasmBenchMsghash  []byte
  18  	wasmBenchPubkey   *p256k1.PublicKey
  19  	wasmBenchXonly    *p256k1.XOnlyPubkey
  20  	wasmBenchKeypair  *p256k1.KeyPair
  21  	wasmBenchECDSASig p256k1.ECDSASignature
  22  	wasmBenchSchnorrSig [64]byte
  23  )
  24  
  25  func initWASMBenchData(b *testing.B) {
  26  	if wasmBenchSeckey != nil {
  27  		return
  28  	}
  29  
  30  	// Generate a valid secret key
  31  	wasmBenchSeckey = make([]byte, 32)
  32  	for {
  33  		if _, err := rand.Read(wasmBenchSeckey); err != nil {
  34  			b.Fatal(err)
  35  		}
  36  		// Validate by creating a keypair
  37  		kp, err := p256k1.KeyPairCreate(wasmBenchSeckey)
  38  		if err == nil {
  39  			wasmBenchKeypair = kp
  40  			break
  41  		}
  42  	}
  43  
  44  	// Get public keys
  45  	wasmBenchPubkey = wasmBenchKeypair.Pubkey()
  46  	xonly, err := wasmBenchKeypair.XOnlyPubkey()
  47  	if err != nil {
  48  		b.Fatal(err)
  49  	}
  50  	wasmBenchXonly = xonly
  51  
  52  	// Generate message hash
  53  	wasmBenchMsghash = make([]byte, 32)
  54  	if _, err := rand.Read(wasmBenchMsghash); err != nil {
  55  		b.Fatal(err)
  56  	}
  57  
  58  	// Pre-compute ECDSA signature
  59  	if err := p256k1.ECDSASign(&wasmBenchECDSASig, wasmBenchMsghash, wasmBenchSeckey); err != nil {
  60  		b.Fatal(err)
  61  	}
  62  
  63  	// Pre-compute Schnorr signature
  64  	if err := p256k1.SchnorrSign(wasmBenchSchnorrSig[:], wasmBenchMsghash, wasmBenchKeypair, nil); err != nil {
  65  		b.Fatal(err)
  66  	}
  67  }
  68  
  69  // =============================================================================
  70  // WASM 32-bit - Schnorr Operations
  71  // =============================================================================
  72  
  73  func BenchmarkWASM_Schnorr_PubkeyDerivation(b *testing.B) {
  74  	initWASMBenchData(b)
  75  
  76  	b.ResetTimer()
  77  	b.ReportAllocs()
  78  	for i := 0; i < b.N; i++ {
  79  		kp, err := p256k1.KeyPairCreate(wasmBenchSeckey)
  80  		if err != nil {
  81  			b.Fatal(err)
  82  		}
  83  		_, err = kp.XOnlyPubkey()
  84  		if err != nil {
  85  			b.Fatal(err)
  86  		}
  87  	}
  88  }
  89  
  90  func BenchmarkWASM_Schnorr_Sign(b *testing.B) {
  91  	initWASMBenchData(b)
  92  	var sig [64]byte
  93  
  94  	b.ResetTimer()
  95  	b.ReportAllocs()
  96  	for i := 0; i < b.N; i++ {
  97  		if err := p256k1.SchnorrSign(sig[:], wasmBenchMsghash, wasmBenchKeypair, nil); err != nil {
  98  			b.Fatal(err)
  99  		}
 100  	}
 101  }
 102  
 103  func BenchmarkWASM_Schnorr_Verify(b *testing.B) {
 104  	initWASMBenchData(b)
 105  
 106  	b.ResetTimer()
 107  	b.ReportAllocs()
 108  	for i := 0; i < b.N; i++ {
 109  		if !p256k1.SchnorrVerify(wasmBenchSchnorrSig[:], wasmBenchMsghash, wasmBenchXonly) {
 110  			b.Fatal("verification failed")
 111  		}
 112  	}
 113  }
 114  
 115  // =============================================================================
 116  // WASM 32-bit - ECDSA Operations
 117  // =============================================================================
 118  
 119  func BenchmarkWASM_ECDSA_PubkeyDerivation(b *testing.B) {
 120  	initWASMBenchData(b)
 121  	var pubkey p256k1.PublicKey
 122  
 123  	b.ResetTimer()
 124  	b.ReportAllocs()
 125  	for i := 0; i < b.N; i++ {
 126  		if err := p256k1.ECPubkeyCreate(&pubkey, wasmBenchSeckey); err != nil {
 127  			b.Fatal(err)
 128  		}
 129  	}
 130  }
 131  
 132  func BenchmarkWASM_ECDSA_Sign(b *testing.B) {
 133  	initWASMBenchData(b)
 134  	var sig p256k1.ECDSASignature
 135  
 136  	b.ResetTimer()
 137  	b.ReportAllocs()
 138  	for i := 0; i < b.N; i++ {
 139  		if err := p256k1.ECDSASign(&sig, wasmBenchMsghash, wasmBenchSeckey); err != nil {
 140  			b.Fatal(err)
 141  		}
 142  	}
 143  }
 144  
 145  func BenchmarkWASM_ECDSA_Verify(b *testing.B) {
 146  	initWASMBenchData(b)
 147  
 148  	b.ResetTimer()
 149  	b.ReportAllocs()
 150  	for i := 0; i < b.N; i++ {
 151  		if !p256k1.ECDSAVerify(&wasmBenchECDSASig, wasmBenchMsghash, wasmBenchPubkey) {
 152  			b.Fatal("verification failed")
 153  		}
 154  	}
 155  }
 156