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