bench_test.go raw

   1  // Copyright 2013-2016 The btcsuite developers
   2  // Use of this source code is governed by an ISC
   3  // license that can be found in the LICENSE file.
   4  
   5  package ecc
   6  
   7  import (
   8  	"encoding/hex"
   9  	"testing"
  10  )
  11  
  12  // BenchmarkAddJacobian benchmarks the secp256k1 curve addJacobian function with
  13  // Z values of 1 so that the associated optimizations are used.
  14  func BenchmarkAddJacobian(b *testing.B) {
  15  	b.StopTimer()
  16  	x1 := new(fieldVal).SetHex("34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6")
  17  	y1 := new(fieldVal).SetHex("0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232")
  18  	z1 := new(fieldVal).SetHex("1")
  19  	x2 := new(fieldVal).SetHex("34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6")
  20  	y2 := new(fieldVal).SetHex("0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232")
  21  	z2 := new(fieldVal).SetHex("1")
  22  	x3, y3, z3 := new(fieldVal), new(fieldVal), new(fieldVal)
  23  	curve := S256()
  24  	b.StartTimer()
  25  	for i := 0; i < b.N; i++ {
  26  		curve.addJacobian(x1, y1, z1, x2, y2, z2, x3, y3, z3)
  27  	}
  28  }
  29  
  30  // BenchmarkAddJacobianNotZOne benchmarks the secp256k1 curve addJacobian
  31  // function with Z values other than one so the optimizations associated with
  32  // Z=1 aren't used.
  33  func BenchmarkAddJacobianNotZOne(b *testing.B) {
  34  	b.StopTimer()
  35  	x1 := new(fieldVal).SetHex("d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718")
  36  	y1 := new(fieldVal).SetHex("5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190")
  37  	z1 := new(fieldVal).SetHex("2")
  38  	x2 := new(fieldVal).SetHex("91abba6a34b7481d922a4bd6a04899d5a686f6cf6da4e66a0cb427fb25c04bd4")
  39  	y2 := new(fieldVal).SetHex("03fede65e30b4e7576a2abefc963ddbf9fdccbf791b77c29beadefe49951f7d1")
  40  	z2 := new(fieldVal).SetHex("3")
  41  	x3, y3, z3 := new(fieldVal), new(fieldVal), new(fieldVal)
  42  	curve := S256()
  43  	b.StartTimer()
  44  	for i := 0; i < b.N; i++ {
  45  		curve.addJacobian(x1, y1, z1, x2, y2, z2, x3, y3, z3)
  46  	}
  47  }
  48  
  49  // BenchmarkScalarBaseMult benchmarks the secp256k1 curve ScalarBaseMult
  50  // function.
  51  func BenchmarkScalarBaseMult(b *testing.B) {
  52  	k := fromHex("d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575")
  53  	curve := S256()
  54  	for i := 0; i < b.N; i++ {
  55  		curve.ScalarBaseMult(k.Bytes())
  56  	}
  57  }
  58  
  59  // BenchmarkScalarBaseMultLarge benchmarks the secp256k1 curve ScalarBaseMult
  60  // function with abnormally large k values.
  61  func BenchmarkScalarBaseMultLarge(b *testing.B) {
  62  	k := fromHex("d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c005751111111011111110")
  63  	curve := S256()
  64  	for i := 0; i < b.N; i++ {
  65  		curve.ScalarBaseMult(k.Bytes())
  66  	}
  67  }
  68  
  69  // BenchmarkScalarMult benchmarks the secp256k1 curve ScalarMult function.
  70  func BenchmarkScalarMult(b *testing.B) {
  71  	x := fromHex("34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6")
  72  	y := fromHex("0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232")
  73  	k := fromHex("d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575")
  74  	curve := S256()
  75  	for i := 0; i < b.N; i++ {
  76  		curve.ScalarMult(x, y, k.Bytes())
  77  	}
  78  }
  79  
  80  // BenchmarkNAF benchmarks the NAF function.
  81  func BenchmarkNAF(b *testing.B) {
  82  	k := fromHex("d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575")
  83  	for i := 0; i < b.N; i++ {
  84  		NAF(k.Bytes())
  85  	}
  86  }
  87  
  88  // BenchmarkSigVerify benchmarks how long it takes the secp256k1 curve to
  89  // verify signatures.
  90  func BenchmarkSigVerify(b *testing.B) {
  91  	b.StopTimer()
  92  	// Randomly generated keypair.
  93  	// Private key: 9e0699c91ca1e3b7e3c9ba71eb71c89890872be97576010fe593fbf3fd57e66d
  94  	pubKey := PublicKey{
  95  		Curve: S256(),
  96  		X:     fromHex("d2e670a19c6d753d1a6d8b20bd045df8a08fb162cf508956c31268c6d81ffdab"),
  97  		Y:     fromHex("ab65528eefbb8057aa85d597258a3fbd481a24633bc9b47a9aa045c91371de52"),
  98  	}
  99  
 100  	// Double sha256 of []byte{0x01, 0x02, 0x03, 0x04}
 101  	msgHash := fromHex("8de472e2399610baaa7f84840547cd409434e31f5d3bd71e4d947f283874f9c0")
 102  	sig := Signature{
 103  		R: fromHex("fef45d2892953aa5bbcdb057b5e98b208f1617a7498af7eb765574e29b5d9c2c"),
 104  		S: fromHex("d47563f52aac6b04b55de236b7c515eb9311757db01e02cff079c3ca6efb063f"),
 105  	}
 106  
 107  	if !sig.Verify(msgHash.Bytes(), &pubKey) {
 108  		b.Errorf("Signature failed to verify")
 109  		return
 110  	}
 111  	b.StartTimer()
 112  
 113  	for i := 0; i < b.N; i++ {
 114  		sig.Verify(msgHash.Bytes(), &pubKey)
 115  	}
 116  }
 117  
 118  // BenchmarkFieldNormalize benchmarks how long it takes the internal field
 119  // to perform normalization (which includes modular reduction).
 120  func BenchmarkFieldNormalize(b *testing.B) {
 121  	// The normalize function is constant time so default value is fine.
 122  	f := new(fieldVal)
 123  	for i := 0; i < b.N; i++ {
 124  		f.Normalize()
 125  	}
 126  }
 127  
 128  // BenchmarkParseCompressedPubKey benchmarks how long it takes to decompress and
 129  // validate a compressed public key from a byte array.
 130  func BenchmarkParseCompressedPubKey(b *testing.B) {
 131  	rawPk, _ := hex.DecodeString("0234f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6")
 132  
 133  	var (
 134  		pk  *PublicKey
 135  		err error
 136  	)
 137  
 138  	b.ReportAllocs()
 139  	b.ResetTimer()
 140  	for i := 0; i < b.N; i++ {
 141  		pk, err = ParsePubKey(rawPk, S256())
 142  	}
 143  	_ = pk
 144  	_ = err
 145  }
 146