bench_test.go raw

   1  // Copyright 2013-2016 The btcsuite developers
   2  // Copyright (c) 2015-2021 The Decred developers
   3  // Use of this source code is governed by an ISC
   4  // license that can be found in the LICENSE file.
   5  
   6  package schnorr
   7  
   8  import (
   9  	"math/big"
  10  	"testing"
  11  
  12  	"next.orly.dev/pkg/nostr/crypto/ec"
  13  	"next.orly.dev/pkg/nostr/crypto/ec/secp256k1"
  14  	"next.orly.dev/pkg/nostr/encoders/hex"
  15  	"github.com/minio/sha256-simd"
  16  )
  17  
  18  // hexToBytes converts the passed hex string into bytes and will panic if there
  19  // is an error. This is only provided for the hard-coded constants, so errors in
  20  // the source code can be detected. It will only (and must only) be called with
  21  // hard-coded values.
  22  func hexToBytes(s string) []byte {
  23  	b, err := hex.Dec(s)
  24  	if err != nil {
  25  		panic("invalid hex in source file: " + s)
  26  	}
  27  	return b
  28  }
  29  
  30  // hexToModNScalar converts the passed hex string into a ModNScalar and will
  31  // panic if there is an error. This is only provided for the hard-coded
  32  //
  33  //	constants, so errors in the source code can be detected. It will only (and
  34  //
  35  // must only) be called with hard-coded values.
  36  func hexToModNScalar(s string) *btcec.ModNScalar {
  37  	b, err := hex.Dec(s)
  38  	if err != nil {
  39  		panic("invalid hex in source file: " + s)
  40  	}
  41  	var scalar btcec.ModNScalar
  42  	if overflow := scalar.SetByteSlice(b); overflow {
  43  		panic("hex in source file overflows mod N scalar: " + s)
  44  	}
  45  	return &scalar
  46  }
  47  
  48  // hexToFieldVal converts the passed hex string into a FieldVal and will panic
  49  // if there is an error. This is only provided for the hard-coded constants, so
  50  // errors in the source code can be detected. It will only (and must only) be
  51  // called with hard-coded values.
  52  func hexToFieldVal(s string) *btcec.FieldVal {
  53  	b, err := hex.Dec(s)
  54  	if err != nil {
  55  		panic("invalid hex in source file: " + s)
  56  	}
  57  	var f btcec.FieldVal
  58  	if overflow := f.SetByteSlice(b); overflow {
  59  		panic("hex in source file overflows mod P: " + s)
  60  	}
  61  	return &f
  62  }
  63  
  64  // fromHex converts the passed hex string into a big integer pointer and will
  65  // panic if there is an error. This is only provided for the hard-coded
  66  // constants, so errors in the source code can be detected. It will only (and
  67  // must only) be called for initialization purposes.
  68  func fromHex(s string) *big.Int {
  69  	if s == "" {
  70  		return big.NewInt(0)
  71  	}
  72  	r, ok := new(big.Int).SetString(s, 16)
  73  	if !ok {
  74  		panic("invalid hex in source file: " + s)
  75  	}
  76  	return r
  77  }
  78  
  79  var testOk bool
  80  
  81  // BenchmarkSign benchmarks how long it takes to sign a message.
  82  func BenchmarkSign(b *testing.B) {
  83  	// Randomly generated keypair.
  84  	d := hexToModNScalar("9e0699c91ca1e3b7e3c9ba71eb71c89890872be97576010fe593fbf3fd57e66d")
  85  	privKey := secp256k1.NewSecretKey(d)
  86  	// blake256 of by{0x01, 0x02, 0x03, 0x04}.
  87  	msgHash := hexToBytes("c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7")
  88  	var auxBytes [32]byte
  89  	copy(auxBytes[:], msgHash)
  90  	auxBytes[0] ^= 1
  91  	var (
  92  		sig *Signature
  93  		err error
  94  	)
  95  	b.ReportAllocs()
  96  	b.ResetTimer()
  97  	for i := 0; i < b.N; i++ {
  98  		sig, err = Sign(
  99  			privKey, msgHash, CustomNonce(auxBytes), FastSign(),
 100  		)
 101  	}
 102  	testSig = sig
 103  	testErr = err
 104  }
 105  
 106  // BenchmarkSigVerify benchmarks how long it takes the secp256k1 curve to
 107  // verify signatures.
 108  func BenchmarkSigVerify(b *testing.B) {
 109  	// Randomly generated keypair.
 110  	d := hexToModNScalar("9e0699c91ca1e3b7e3c9ba71eb71c89890872be97576010fe593fbf3fd57e66d")
 111  	privKey := secp256k1.NewSecretKey(d)
 112  	pubKey := privKey.PubKey()
 113  	// Double sha256 of by{0x01, 0x02, 0x03, 0x04}
 114  	msgHash := sha256.Sum256([]byte("benchmark"))
 115  	sig, err := Sign(privKey, msgHash[:])
 116  	if err != nil {
 117  		b.Fatalf("unable to sign: %v", err)
 118  	}
 119  	if !sig.Verify(msgHash[:], pubKey) {
 120  		b.Errorf("Signature failed to verify")
 121  		return
 122  	}
 123  	var ok bool
 124  	b.ReportAllocs()
 125  	b.ResetTimer()
 126  	for i := 0; i < b.N; i++ {
 127  		ok = sig.Verify(msgHash[:], pubKey)
 128  	}
 129  	testOk = ok
 130  }
 131  
 132  // Used to ensure the compiler doesn't optimize away the benchmark.
 133  var (
 134  	testSig *Signature
 135  	testErr error
 136  )
 137  
 138  // BenchmarkSignRfc6979 benchmarks how long it takes to sign a message.
 139  func BenchmarkSignRfc6979(b *testing.B) {
 140  	// Randomly generated keypair.
 141  	d := hexToModNScalar("9e0699c91ca1e3b7e3c9ba71eb71c89890872be97576010fe593fbf3fd57e66d")
 142  	privKey := secp256k1.NewSecretKey(d)
 143  	// blake256 of by{0x01, 0x02, 0x03, 0x04}.
 144  	msgHash := hexToBytes("c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7")
 145  	var (
 146  		sig *Signature
 147  		err error
 148  	)
 149  	b.ReportAllocs()
 150  	b.ResetTimer()
 151  	for i := 0; i < b.N; i++ {
 152  		sig, err = Sign(privKey, msgHash, FastSign())
 153  	}
 154  	testSig = sig
 155  	testErr = err
 156  }
 157  
 158  // BenchmarkSigSerialize benchmarks how long it takes to serialize Schnorr
 159  // signatures.
 160  func BenchmarkSigSerialize(b *testing.B) {
 161  	// From randomly generated keypair.
 162  	d := hexToModNScalar("9e0699c91ca1e3b7e3c9ba71eb71c89890872be97576010fe593fbf3fd57e66d")
 163  	secKey := secp256k1.NewSecretKey(d)
 164  	// blake256 of by{0x01, 0x02, 0x03, 0x04}.
 165  	msgHash := hexToBytes("c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7")
 166  	// Generate the signature.
 167  	sig, _ := Sign(secKey, msgHash)
 168  	b.ReportAllocs()
 169  	b.ResetTimer()
 170  	for i := 0; i < b.N; i++ {
 171  		sig.Serialize()
 172  	}
 173  }
 174