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.
17 type signatureTest struct {
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)
30 panic("invalid hex string in test source: err " + err.Error() +
37 var signatureTests = []signatureTest{
38 // signatures from bitcoin blockchain tx
39 // 0437cd7f8525ceed2324359c2d0ba26006d92d85
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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
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,
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,
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,
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,
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,
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,
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,
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,
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.
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,
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,
329 func TestSignatures(t *testing.T) {
330 for _, test := range signatureTests {
333 _, err = ParseDERSignature(test.sig, S256())
335 _, err = ParseSignature(test.sig, S256())
339 t.Errorf("%s signature failed when shouldn't %v",
342 t.Errorf("%s got error %v", test.name, err)
347 t.Errorf("%s counted as valid when it should fail",
353 // TestSignatureSerialize ensures that serializing signatures works as expected.
354 func TestSignatureSerialize(t *testing.T) {
360 // signature from bitcoin blockchain tx
361 // 0437cd7f8525ceed2324359c2d0ba26006d92d85
363 "valid 1 - r and s most significant bits are zero",
365 R: fromHex("4e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd41"),
366 S: fromHex("181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d09"),
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,
380 // signature from bitcoin blockchain tx
381 // cb00f8a0573b18faa8c4f467b049f5d202bf1101d9ef2633bc611be70376a4b4
383 "valid 2 - r most significant bit is one",
385 R: fromHex("0082235e21a2300022738dabb8e1bbd9d19cfb1e7ab8c30a23b0afbb8d178abcf3"),
386 S: fromHex("24bf68e256c534ddfaf966bf908deb944305596f7bdcc38d69acad7f9c868724"),
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,
400 // signature from bitcoin blockchain tx
401 // fda204502a3345e08afd6af27377c052e77f1fefeaeb31bdd45f1e1237ca5470
403 "valid 3 - s most significant bit is one",
405 R: fromHex("1cadddc2838598fee7dc35a12b340c6bde8b389f7bfd19a1252a17c4b5ed2d71"),
406 S: new(big.Int).Add(fromHex("00c1a251bbecb14b058a8bd77f65de87e51c47e95904f4c0e9d52eddc21c1415ac"), S256().N),
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,
426 []byte{0x30, 0x06, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00},
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,
440 func testSignCompact(t *testing.T, tag string, curve *KoblitzCurve,
441 data []byte, isCompressed bool) {
442 tmp, _ := NewPrivateKey(curve)
443 priv := (*PrivateKey)(tmp)
445 hashed := []byte("testing")
446 sig, err := SignCompact(curve, priv, hashed, isCompressed)
448 t.Errorf("%s: error signing: %s", tag, err)
452 pk, wasCompressed, err := RecoverCompact(curve, sig, hashed)
454 t.Errorf("%s: error recovering: %s", tag, err)
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)
462 if wasCompressed != isCompressed {
463 t.Errorf("%s: recovered pubkey doesn't match compressed state "+
464 "(%v vs %v)", tag, isCompressed, wasCompressed)
468 // If we change the compressed bit we should get the same key back,
469 // but the compressed flag should be reversed.
476 pk, wasCompressed, err = RecoverCompact(curve, sig, hashed)
478 t.Errorf("%s: error recovering (2): %s", tag, err)
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)
486 if wasCompressed == isCompressed {
487 t.Errorf("%s: recovered pubkey doesn't match reversed "+
488 "compressed state (%v vs %v)", tag, isCompressed,
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)
500 t.Errorf("failed to read random data for %s", name)
503 compressed := i%2 != 0
504 testSignCompact(t, name, S256(), data, compressed)
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
519 "cca9fbcc1b41e5a95d369eaa6ddcff73b61a4efaa279cfc6567e8daa39cbaf50",
521 "2df40ca70e639d89528a6b670d9d48d9165fdc0febc0974056bdce192b8e16a3",
522 "3045022100af340daf02cc15c8d5d08d7735dfe6b98a474ed373bdb5fbecf7571be52b384202205009fb27f37034a9b24b707b7c6b79ca23ddef9e25f7282e8a797efe53a8f124",
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",
529 "8f8a276c19f4149656b280621e358cce24f5f52542772691ee69063b74f15d15",
530 "3045022100934b1ea10a4b3c1757e2b0c017d0b6143ce3c9a7e6a4a49860d7a6ab210ee3d802202442ce9d2b916064108014783e923ec36b49743e2ffa1c4496f01a512aafd9e5",
533 "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
535 "33a19b60e25fb6f4435af53a3d42d493644827367e6453928554f43e49aa6f90",
536 "3045022100fd567d121db66e382991534ada77a6bd3106f0a1098c231e47993447cd6af2d002206b39cd0eb1bc8603e159ef5c20a5c8ad685a45b06ce9bebed3f153d10d93bed5",
539 "f8b8af8ce3c7cca5e300d33939540c10d45ce001b8f252bfbc57ba0342904181",
541 "525a82b70e67874398067543fd84c83d30c175fdc45fdeee082fe13b1d7cfdf1",
542 "304402207063ae83e7f62bbb171798131b4a0564b956930092b33b07b395615d9ec7e15c022058dfcc1e00a35e1572f366ffe34ba0fc47db1e7189759b9fb233c5b05ab388ea",
545 "0000000000000000000000000000000000000000000000000000000000000001",
546 "All those moments will be lost in time, like tears in rain. Time to die...",
547 "38aa22d72376b4dbc472e06c3ba403ee0a394da63fc58d88686c611aba98d6b3",
548 "30450221008600dbd41e348fe5c9465ab92d23e3db8b98b873beecd930736488696438cb6b0220547fe64427496db33bf66019dacbf0039c04199abb0122918601db38a72cfc21",
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",
558 for i, test := range tests {
559 privKey, _ := PrivKeyFromBytes(S256(), decodeHex(test.key))
560 hash := sha256.Sum256([]byte(test.msg))
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,
572 // Ensure deterministically generated signature is the expected value.
573 gotSig, err := privKey.Sign(hash[:])
575 t.Errorf("Sign #%d (%s): unexpected error: %v", i,
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,
590 func TestSignatureIsEqual(t *testing.T) {
592 R: fromHex("0082235e21a2300022738dabb8e1bbd9d19cfb1e7ab8c30a23b0afbb8d178abcf3"),
593 S: fromHex("24bf68e256c534ddfaf966bf908deb944305596f7bdcc38d69acad7f9c868724"),
596 R: fromHex("4e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd41"),
597 S: fromHex("181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d09"),
600 if !sig1.IsEqual(sig1) {
601 t.Fatalf("value of IsEqual is incorrect, %v is "+
602 "equal to %v", sig1, sig1)
605 if sig1.IsEqual(sig2) {
606 t.Fatalf("value of IsEqual is incorrect, %v is not "+
607 "equal to %v", sig1, sig2)