OSDN Git Service

Merge pull request #41 from Bytom/dev
[bytom/vapor.git] / vendor / github.com / btcsuite / btcd / btcec / signature_test.go
1 // Copyright (c) 2013-2017 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 btcec
6
7 import (
8         "bytes"
9         "crypto/rand"
10         "crypto/sha256"
11         "encoding/hex"
12         "fmt"
13         "math/big"
14         "testing"
15 )
16
17 type signatureTest struct {
18         name    string
19         sig     []byte
20         der     bool
21         isValid bool
22 }
23
24 // decodeHex decodes the passed hex string and returns the resulting bytes.  It
25 // panics if an error occurs.  This is only used in the tests as a helper since
26 // the only way it can fail is if there is an error in the test source code.
27 func decodeHex(hexStr string) []byte {
28         b, err := hex.DecodeString(hexStr)
29         if err != nil {
30                 panic("invalid hex string in test source: err " + err.Error() +
31                         ", hex: " + hexStr)
32         }
33
34         return b
35 }
36
37 var signatureTests = []signatureTest{
38         // signatures from bitcoin blockchain tx
39         // 0437cd7f8525ceed2324359c2d0ba26006d92d85
40         {
41                 name: "valid signature.",
42                 sig: []byte{0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
43                         0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
44                         0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
45                         0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
46                         0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
47                         0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
48                         0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
49                         0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
50                 },
51                 der:     true,
52                 isValid: true,
53         },
54         {
55                 name:    "empty.",
56                 sig:     []byte{},
57                 isValid: false,
58         },
59         {
60                 name: "bad magic.",
61                 sig: []byte{0x31, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
62                         0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
63                         0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
64                         0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
65                         0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
66                         0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
67                         0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
68                         0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
69                 },
70                 der:     true,
71                 isValid: false,
72         },
73         {
74                 name: "bad 1st int marker magic.",
75                 sig: []byte{0x30, 0x44, 0x03, 0x20, 0x4e, 0x45, 0xe1, 0x69,
76                         0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
77                         0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
78                         0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
79                         0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
80                         0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
81                         0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
82                         0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
83                 },
84                 der:     true,
85                 isValid: false,
86         },
87         {
88                 name: "bad 2nd int marker.",
89                 sig: []byte{0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
90                         0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
91                         0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
92                         0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
93                         0x41, 0x03, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
94                         0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
95                         0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
96                         0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
97                 },
98                 der:     true,
99                 isValid: false,
100         },
101         {
102                 name: "short len",
103                 sig: []byte{0x30, 0x43, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
104                         0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
105                         0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
106                         0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
107                         0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
108                         0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
109                         0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
110                         0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
111                 },
112                 der:     true,
113                 isValid: false,
114         },
115         {
116                 name: "long len",
117                 sig: []byte{0x30, 0x45, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
118                         0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
119                         0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
120                         0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
121                         0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
122                         0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
123                         0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
124                         0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
125                 },
126                 der:     true,
127                 isValid: false,
128         },
129         {
130                 name: "long X",
131                 sig: []byte{0x30, 0x44, 0x02, 0x42, 0x4e, 0x45, 0xe1, 0x69,
132                         0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
133                         0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
134                         0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
135                         0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
136                         0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
137                         0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
138                         0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
139                 },
140                 der:     true,
141                 isValid: false,
142         },
143         {
144                 name: "long Y",
145                 sig: []byte{0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
146                         0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
147                         0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
148                         0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
149                         0x41, 0x02, 0x21, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
150                         0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
151                         0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
152                         0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
153                 },
154                 der:     true,
155                 isValid: false,
156         },
157         {
158                 name: "short Y",
159                 sig: []byte{0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
160                         0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
161                         0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
162                         0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
163                         0x41, 0x02, 0x19, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
164                         0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
165                         0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
166                         0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
167                 },
168                 der:     true,
169                 isValid: false,
170         },
171         {
172                 name: "trailing crap.",
173                 sig: []byte{0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
174                         0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
175                         0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
176                         0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
177                         0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
178                         0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
179                         0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
180                         0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09, 0x01,
181                 },
182                 der: true,
183
184                 // This test is now passing (used to be failing) because there
185                 // are signatures in the blockchain that have trailing zero
186                 // bytes before the hashtype. So ParseSignature was fixed to
187                 // permit buffers with trailing nonsense after the actual
188                 // signature.
189                 isValid: true,
190         },
191         {
192                 name: "X == N ",
193                 sig: []byte{0x30, 0x44, 0x02, 0x20, 0xFF, 0xFF, 0xFF, 0xFF,
194                         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
195                         0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48,
196                         0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41,
197                         0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
198                         0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
199                         0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
200                         0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
201                 },
202                 der:     true,
203                 isValid: false,
204         },
205         {
206                 name: "X == N ",
207                 sig: []byte{0x30, 0x44, 0x02, 0x20, 0xFF, 0xFF, 0xFF, 0xFF,
208                         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
209                         0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48,
210                         0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41,
211                         0x42, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
212                         0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
213                         0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
214                         0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
215                 },
216                 der:     false,
217                 isValid: false,
218         },
219         {
220                 name: "Y == N",
221                 sig: []byte{0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
222                         0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
223                         0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
224                         0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
225                         0x41, 0x02, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
226                         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
227                         0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
228                         0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41,
229                 },
230                 der:     true,
231                 isValid: false,
232         },
233         {
234                 name: "Y > N",
235                 sig: []byte{0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
236                         0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
237                         0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
238                         0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
239                         0x41, 0x02, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
240                         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
241                         0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
242                         0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x42,
243                 },
244                 der:     false,
245                 isValid: false,
246         },
247         {
248                 name: "0 len X.",
249                 sig: []byte{0x30, 0x24, 0x02, 0x00, 0x02, 0x20, 0x18, 0x15,
250                         0x22, 0xec, 0x8e, 0xca, 0x07, 0xde, 0x48, 0x60, 0xa4,
251                         0xac, 0xdd, 0x12, 0x90, 0x9d, 0x83, 0x1c, 0xc5, 0x6c,
252                         0xbb, 0xac, 0x46, 0x22, 0x08, 0x22, 0x21, 0xa8, 0x76,
253                         0x8d, 0x1d, 0x09,
254                 },
255                 der:     true,
256                 isValid: false,
257         },
258         {
259                 name: "0 len Y.",
260                 sig: []byte{0x30, 0x24, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
261                         0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
262                         0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
263                         0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
264                         0x41, 0x02, 0x00,
265                 },
266                 der:     true,
267                 isValid: false,
268         },
269         {
270                 name: "extra R padding.",
271                 sig: []byte{0x30, 0x45, 0x02, 0x21, 0x00, 0x4e, 0x45, 0xe1, 0x69,
272                         0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
273                         0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
274                         0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
275                         0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
276                         0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
277                         0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
278                         0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
279                 },
280                 der:     true,
281                 isValid: false,
282         },
283         {
284                 name: "extra S padding.",
285                 sig: []byte{0x30, 0x45, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
286                         0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
287                         0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
288                         0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
289                         0x41, 0x02, 0x21, 0x00, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
290                         0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
291                         0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
292                         0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
293                 },
294                 der:     true,
295                 isValid: false,
296         },
297         // Standard checks (in BER format, without checking for 'canonical' DER
298         // signatures) don't test for negative numbers here because there isn't
299         // a way that is the same between openssl and go that will mark a number
300         // as negative. The Go ASN.1 parser marks numbers as negative when
301         // openssl does not (it doesn't handle negative numbers that I can tell
302         // at all. When not parsing DER signatures, which is done by by bitcoind
303         // when accepting transactions into its mempool, we otherwise only check
304         // for the coordinates being zero.
305         {
306                 name: "X == 0",
307                 sig: []byte{0x30, 0x25, 0x02, 0x01, 0x00, 0x02, 0x20, 0x18,
308                         0x15, 0x22, 0xec, 0x8e, 0xca, 0x07, 0xde, 0x48, 0x60,
309                         0xa4, 0xac, 0xdd, 0x12, 0x90, 0x9d, 0x83, 0x1c, 0xc5,
310                         0x6c, 0xbb, 0xac, 0x46, 0x22, 0x08, 0x22, 0x21, 0xa8,
311                         0x76, 0x8d, 0x1d, 0x09,
312                 },
313                 der:     false,
314                 isValid: false,
315         },
316         {
317                 name: "Y == 0.",
318                 sig: []byte{0x30, 0x25, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
319                         0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
320                         0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
321                         0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
322                         0x41, 0x02, 0x01, 0x00,
323                 },
324                 der:     false,
325                 isValid: false,
326         },
327 }
328
329 func TestSignatures(t *testing.T) {
330         for _, test := range signatureTests {
331                 var err error
332                 if test.der {
333                         _, err = ParseDERSignature(test.sig, S256())
334                 } else {
335                         _, err = ParseSignature(test.sig, S256())
336                 }
337                 if err != nil {
338                         if test.isValid {
339                                 t.Errorf("%s signature failed when shouldn't %v",
340                                         test.name, err)
341                         } /* else {
342                                 t.Errorf("%s got error %v", test.name, err)
343                         } */
344                         continue
345                 }
346                 if !test.isValid {
347                         t.Errorf("%s counted as valid when it should fail",
348                                 test.name)
349                 }
350         }
351 }
352
353 // TestSignatureSerialize ensures that serializing signatures works as expected.
354 func TestSignatureSerialize(t *testing.T) {
355         tests := []struct {
356                 name     string
357                 ecsig    *Signature
358                 expected []byte
359         }{
360                 // signature from bitcoin blockchain tx
361                 // 0437cd7f8525ceed2324359c2d0ba26006d92d85
362                 {
363                         "valid 1 - r and s most significant bits are zero",
364                         &Signature{
365                                 R: fromHex("4e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd41"),
366                                 S: fromHex("181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d09"),
367                         },
368                         []byte{
369                                 0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
370                                 0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3,
371                                 0xa1, 0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32,
372                                 0xe9, 0xd6, 0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab,
373                                 0x5f, 0xb8, 0xcd, 0x41, 0x02, 0x20, 0x18, 0x15,
374                                 0x22, 0xec, 0x8e, 0xca, 0x07, 0xde, 0x48, 0x60,
375                                 0xa4, 0xac, 0xdd, 0x12, 0x90, 0x9d, 0x83, 0x1c,
376                                 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22, 0x08, 0x22,
377                                 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
378                         },
379                 },
380                 // signature from bitcoin blockchain tx
381                 // cb00f8a0573b18faa8c4f467b049f5d202bf1101d9ef2633bc611be70376a4b4
382                 {
383                         "valid 2 - r most significant bit is one",
384                         &Signature{
385                                 R: fromHex("0082235e21a2300022738dabb8e1bbd9d19cfb1e7ab8c30a23b0afbb8d178abcf3"),
386                                 S: fromHex("24bf68e256c534ddfaf966bf908deb944305596f7bdcc38d69acad7f9c868724"),
387                         },
388                         []byte{
389                                 0x30, 0x45, 0x02, 0x21, 0x00, 0x82, 0x23, 0x5e,
390                                 0x21, 0xa2, 0x30, 0x00, 0x22, 0x73, 0x8d, 0xab,
391                                 0xb8, 0xe1, 0xbb, 0xd9, 0xd1, 0x9c, 0xfb, 0x1e,
392                                 0x7a, 0xb8, 0xc3, 0x0a, 0x23, 0xb0, 0xaf, 0xbb,
393                                 0x8d, 0x17, 0x8a, 0xbc, 0xf3, 0x02, 0x20, 0x24,
394                                 0xbf, 0x68, 0xe2, 0x56, 0xc5, 0x34, 0xdd, 0xfa,
395                                 0xf9, 0x66, 0xbf, 0x90, 0x8d, 0xeb, 0x94, 0x43,
396                                 0x05, 0x59, 0x6f, 0x7b, 0xdc, 0xc3, 0x8d, 0x69,
397                                 0xac, 0xad, 0x7f, 0x9c, 0x86, 0x87, 0x24,
398                         },
399                 },
400                 // signature from bitcoin blockchain tx
401                 // fda204502a3345e08afd6af27377c052e77f1fefeaeb31bdd45f1e1237ca5470
402                 {
403                         "valid 3 - s most significant bit is one",
404                         &Signature{
405                                 R: fromHex("1cadddc2838598fee7dc35a12b340c6bde8b389f7bfd19a1252a17c4b5ed2d71"),
406                                 S: new(big.Int).Add(fromHex("00c1a251bbecb14b058a8bd77f65de87e51c47e95904f4c0e9d52eddc21c1415ac"), S256().N),
407                         },
408                         []byte{
409                                 0x30, 0x45, 0x02, 0x20, 0x1c, 0xad, 0xdd, 0xc2,
410                                 0x83, 0x85, 0x98, 0xfe, 0xe7, 0xdc, 0x35, 0xa1,
411                                 0x2b, 0x34, 0x0c, 0x6b, 0xde, 0x8b, 0x38, 0x9f,
412                                 0x7b, 0xfd, 0x19, 0xa1, 0x25, 0x2a, 0x17, 0xc4,
413                                 0xb5, 0xed, 0x2d, 0x71, 0x02, 0x21, 0x00, 0xc1,
414                                 0xa2, 0x51, 0xbb, 0xec, 0xb1, 0x4b, 0x05, 0x8a,
415                                 0x8b, 0xd7, 0x7f, 0x65, 0xde, 0x87, 0xe5, 0x1c,
416                                 0x47, 0xe9, 0x59, 0x04, 0xf4, 0xc0, 0xe9, 0xd5,
417                                 0x2e, 0xdd, 0xc2, 0x1c, 0x14, 0x15, 0xac,
418                         },
419                 },
420                 {
421                         "zero signature",
422                         &Signature{
423                                 R: big.NewInt(0),
424                                 S: big.NewInt(0),
425                         },
426                         []byte{0x30, 0x06, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00},
427                 },
428         }
429
430         for i, test := range tests {
431                 result := test.ecsig.Serialize()
432                 if !bytes.Equal(result, test.expected) {
433                         t.Errorf("Serialize #%d (%s) unexpected result:\n"+
434                                 "got:  %x\nwant: %x", i, test.name, result,
435                                 test.expected)
436                 }
437         }
438 }
439
440 func testSignCompact(t *testing.T, tag string, curve *KoblitzCurve,
441         data []byte, isCompressed bool) {
442         tmp, _ := NewPrivateKey(curve)
443         priv := (*PrivateKey)(tmp)
444
445         hashed := []byte("testing")
446         sig, err := SignCompact(curve, priv, hashed, isCompressed)
447         if err != nil {
448                 t.Errorf("%s: error signing: %s", tag, err)
449                 return
450         }
451
452         pk, wasCompressed, err := RecoverCompact(curve, sig, hashed)
453         if err != nil {
454                 t.Errorf("%s: error recovering: %s", tag, err)
455                 return
456         }
457         if pk.X.Cmp(priv.X) != 0 || pk.Y.Cmp(priv.Y) != 0 {
458                 t.Errorf("%s: recovered pubkey doesn't match original "+
459                         "(%v,%v) vs (%v,%v) ", tag, pk.X, pk.Y, priv.X, priv.Y)
460                 return
461         }
462         if wasCompressed != isCompressed {
463                 t.Errorf("%s: recovered pubkey doesn't match compressed state "+
464                         "(%v vs %v)", tag, isCompressed, wasCompressed)
465                 return
466         }
467
468         // If we change the compressed bit we should get the same key back,
469         // but the compressed flag should be reversed.
470         if isCompressed {
471                 sig[0] -= 4
472         } else {
473                 sig[0] += 4
474         }
475
476         pk, wasCompressed, err = RecoverCompact(curve, sig, hashed)
477         if err != nil {
478                 t.Errorf("%s: error recovering (2): %s", tag, err)
479                 return
480         }
481         if pk.X.Cmp(priv.X) != 0 || pk.Y.Cmp(priv.Y) != 0 {
482                 t.Errorf("%s: recovered pubkey (2) doesn't match original "+
483                         "(%v,%v) vs (%v,%v) ", tag, pk.X, pk.Y, priv.X, priv.Y)
484                 return
485         }
486         if wasCompressed == isCompressed {
487                 t.Errorf("%s: recovered pubkey doesn't match reversed "+
488                         "compressed state (%v vs %v)", tag, isCompressed,
489                         wasCompressed)
490                 return
491         }
492 }
493
494 func TestSignCompact(t *testing.T) {
495         for i := 0; i < 256; i++ {
496                 name := fmt.Sprintf("test %d", i)
497                 data := make([]byte, 32)
498                 _, err := rand.Read(data)
499                 if err != nil {
500                         t.Errorf("failed to read random data for %s", name)
501                         continue
502                 }
503                 compressed := i%2 != 0
504                 testSignCompact(t, name, S256(), data, compressed)
505         }
506 }
507
508 func TestRFC6979(t *testing.T) {
509         // Test vectors matching Trezor and CoreBitcoin implementations.
510         // - https://github.com/trezor/trezor-crypto/blob/9fea8f8ab377dc514e40c6fd1f7c89a74c1d8dc6/tests.c#L432-L453
511         // - https://github.com/oleganza/CoreBitcoin/blob/e93dd71207861b5bf044415db5fa72405e7d8fbc/CoreBitcoin/BTCKey%2BTests.m#L23-L49
512         tests := []struct {
513                 key       string
514                 msg       string
515                 nonce     string
516                 signature string
517         }{
518                 {
519                         "cca9fbcc1b41e5a95d369eaa6ddcff73b61a4efaa279cfc6567e8daa39cbaf50",
520                         "sample",
521                         "2df40ca70e639d89528a6b670d9d48d9165fdc0febc0974056bdce192b8e16a3",
522                         "3045022100af340daf02cc15c8d5d08d7735dfe6b98a474ed373bdb5fbecf7571be52b384202205009fb27f37034a9b24b707b7c6b79ca23ddef9e25f7282e8a797efe53a8f124",
523                 },
524                 {
525                         // This signature hits the case when S is higher than halforder.
526                         // If S is not canonicalized (lowered by halforder), this test will fail.
527                         "0000000000000000000000000000000000000000000000000000000000000001",
528                         "Satoshi Nakamoto",
529                         "8f8a276c19f4149656b280621e358cce24f5f52542772691ee69063b74f15d15",
530                         "3045022100934b1ea10a4b3c1757e2b0c017d0b6143ce3c9a7e6a4a49860d7a6ab210ee3d802202442ce9d2b916064108014783e923ec36b49743e2ffa1c4496f01a512aafd9e5",
531                 },
532                 {
533                         "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
534                         "Satoshi Nakamoto",
535                         "33a19b60e25fb6f4435af53a3d42d493644827367e6453928554f43e49aa6f90",
536                         "3045022100fd567d121db66e382991534ada77a6bd3106f0a1098c231e47993447cd6af2d002206b39cd0eb1bc8603e159ef5c20a5c8ad685a45b06ce9bebed3f153d10d93bed5",
537                 },
538                 {
539                         "f8b8af8ce3c7cca5e300d33939540c10d45ce001b8f252bfbc57ba0342904181",
540                         "Alan Turing",
541                         "525a82b70e67874398067543fd84c83d30c175fdc45fdeee082fe13b1d7cfdf1",
542                         "304402207063ae83e7f62bbb171798131b4a0564b956930092b33b07b395615d9ec7e15c022058dfcc1e00a35e1572f366ffe34ba0fc47db1e7189759b9fb233c5b05ab388ea",
543                 },
544                 {
545                         "0000000000000000000000000000000000000000000000000000000000000001",
546                         "All those moments will be lost in time, like tears in rain. Time to die...",
547                         "38aa22d72376b4dbc472e06c3ba403ee0a394da63fc58d88686c611aba98d6b3",
548                         "30450221008600dbd41e348fe5c9465ab92d23e3db8b98b873beecd930736488696438cb6b0220547fe64427496db33bf66019dacbf0039c04199abb0122918601db38a72cfc21",
549                 },
550                 {
551                         "e91671c46231f833a6406ccbea0e3e392c76c167bac1cb013f6f1013980455c2",
552                         "There is a computer disease that anybody who works with computers knows about. It's a very serious disease and it interferes completely with the work. The trouble with computers is that you 'play' with them!",
553                         "1f4b84c23a86a221d233f2521be018d9318639d5b8bbd6374a8a59232d16ad3d",
554                         "3045022100b552edd27580141f3b2a5463048cb7cd3e047b97c9f98076c32dbdf85a68718b0220279fa72dd19bfae05577e06c7c0c1900c371fcd5893f7e1d56a37d30174671f6",
555                 },
556         }
557
558         for i, test := range tests {
559                 privKey, _ := PrivKeyFromBytes(S256(), decodeHex(test.key))
560                 hash := sha256.Sum256([]byte(test.msg))
561
562                 // Ensure deterministically generated nonce is the expected value.
563                 gotNonce := nonceRFC6979(privKey.D, hash[:]).Bytes()
564                 wantNonce := decodeHex(test.nonce)
565                 if !bytes.Equal(gotNonce, wantNonce) {
566                         t.Errorf("NonceRFC6979 #%d (%s): Nonce is incorrect: "+
567                                 "%x (expected %x)", i, test.msg, gotNonce,
568                                 wantNonce)
569                         continue
570                 }
571
572                 // Ensure deterministically generated signature is the expected value.
573                 gotSig, err := privKey.Sign(hash[:])
574                 if err != nil {
575                         t.Errorf("Sign #%d (%s): unexpected error: %v", i,
576                                 test.msg, err)
577                         continue
578                 }
579                 gotSigBytes := gotSig.Serialize()
580                 wantSigBytes := decodeHex(test.signature)
581                 if !bytes.Equal(gotSigBytes, wantSigBytes) {
582                         t.Errorf("Sign #%d (%s): mismatched signature: %x "+
583                                 "(expected %x)", i, test.msg, gotSigBytes,
584                                 wantSigBytes)
585                         continue
586                 }
587         }
588 }
589
590 func TestSignatureIsEqual(t *testing.T) {
591         sig1 := &Signature{
592                 R: fromHex("0082235e21a2300022738dabb8e1bbd9d19cfb1e7ab8c30a23b0afbb8d178abcf3"),
593                 S: fromHex("24bf68e256c534ddfaf966bf908deb944305596f7bdcc38d69acad7f9c868724"),
594         }
595         sig2 := &Signature{
596                 R: fromHex("4e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd41"),
597                 S: fromHex("181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d09"),
598         }
599
600         if !sig1.IsEqual(sig1) {
601                 t.Fatalf("value of IsEqual is incorrect, %v is "+
602                         "equal to %v", sig1, sig1)
603         }
604
605         if sig1.IsEqual(sig2) {
606                 t.Fatalf("value of IsEqual is incorrect, %v is not "+
607                         "equal to %v", sig1, sig2)
608         }
609 }