OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / btcsuite / btcd / txscript / sign_test.go
1 // Copyright (c) 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 txscript
6
7 import (
8         "errors"
9         "fmt"
10         "testing"
11
12         "github.com/btcsuite/btcd/btcec"
13         "github.com/btcsuite/btcd/chaincfg"
14         "github.com/btcsuite/btcd/chaincfg/chainhash"
15         "github.com/btcsuite/btcd/wire"
16         "github.com/btcsuite/btcutil"
17 )
18
19 type addressToKey struct {
20         key        *btcec.PrivateKey
21         compressed bool
22 }
23
24 func mkGetKey(keys map[string]addressToKey) KeyDB {
25         if keys == nil {
26                 return KeyClosure(func(addr btcutil.Address) (*btcec.PrivateKey,
27                         bool, error) {
28                         return nil, false, errors.New("nope")
29                 })
30         }
31         return KeyClosure(func(addr btcutil.Address) (*btcec.PrivateKey,
32                 bool, error) {
33                 a2k, ok := keys[addr.EncodeAddress()]
34                 if !ok {
35                         return nil, false, errors.New("nope")
36                 }
37                 return a2k.key, a2k.compressed, nil
38         })
39 }
40
41 func mkGetScript(scripts map[string][]byte) ScriptDB {
42         if scripts == nil {
43                 return ScriptClosure(func(addr btcutil.Address) ([]byte, error) {
44                         return nil, errors.New("nope")
45                 })
46         }
47         return ScriptClosure(func(addr btcutil.Address) ([]byte, error) {
48                 script, ok := scripts[addr.EncodeAddress()]
49                 if !ok {
50                         return nil, errors.New("nope")
51                 }
52                 return script, nil
53         })
54 }
55
56 func checkScripts(msg string, tx *wire.MsgTx, idx int, inputAmt int64, sigScript, pkScript []byte) error {
57         tx.TxIn[idx].SignatureScript = sigScript
58         vm, err := NewEngine(pkScript, tx, idx,
59                 ScriptBip16|ScriptVerifyDERSignatures, nil, nil, inputAmt)
60         if err != nil {
61                 return fmt.Errorf("failed to make script engine for %s: %v",
62                         msg, err)
63         }
64
65         err = vm.Execute()
66         if err != nil {
67                 return fmt.Errorf("invalid script signature for %s: %v", msg,
68                         err)
69         }
70
71         return nil
72 }
73
74 func signAndCheck(msg string, tx *wire.MsgTx, idx int, inputAmt int64, pkScript []byte,
75         hashType SigHashType, kdb KeyDB, sdb ScriptDB,
76         previousScript []byte) error {
77
78         sigScript, err := SignTxOutput(&chaincfg.TestNet3Params, tx, idx,
79                 pkScript, hashType, kdb, sdb, nil)
80         if err != nil {
81                 return fmt.Errorf("failed to sign output %s: %v", msg, err)
82         }
83
84         return checkScripts(msg, tx, idx, inputAmt, sigScript, pkScript)
85 }
86
87 func TestSignTxOutput(t *testing.T) {
88         t.Parallel()
89
90         // make key
91         // make script based on key.
92         // sign with magic pixie dust.
93         hashTypes := []SigHashType{
94                 SigHashOld, // no longer used but should act like all
95                 SigHashAll,
96                 SigHashNone,
97                 SigHashSingle,
98                 SigHashAll | SigHashAnyOneCanPay,
99                 SigHashNone | SigHashAnyOneCanPay,
100                 SigHashSingle | SigHashAnyOneCanPay,
101         }
102         inputAmounts := []int64{5, 10, 15}
103         tx := &wire.MsgTx{
104                 Version: 1,
105                 TxIn: []*wire.TxIn{
106                         {
107                                 PreviousOutPoint: wire.OutPoint{
108                                         Hash:  chainhash.Hash{},
109                                         Index: 0,
110                                 },
111                                 Sequence: 4294967295,
112                         },
113                         {
114                                 PreviousOutPoint: wire.OutPoint{
115                                         Hash:  chainhash.Hash{},
116                                         Index: 1,
117                                 },
118                                 Sequence: 4294967295,
119                         },
120                         {
121                                 PreviousOutPoint: wire.OutPoint{
122                                         Hash:  chainhash.Hash{},
123                                         Index: 2,
124                                 },
125                                 Sequence: 4294967295,
126                         },
127                 },
128                 TxOut: []*wire.TxOut{
129                         {
130                                 Value: 1,
131                         },
132                         {
133                                 Value: 2,
134                         },
135                         {
136                                 Value: 3,
137                         },
138                 },
139                 LockTime: 0,
140         }
141
142         // Pay to Pubkey Hash (uncompressed)
143         for _, hashType := range hashTypes {
144                 for i := range tx.TxIn {
145                         msg := fmt.Sprintf("%d:%d", hashType, i)
146                         key, err := btcec.NewPrivateKey(btcec.S256())
147                         if err != nil {
148                                 t.Errorf("failed to make privKey for %s: %v",
149                                         msg, err)
150                                 break
151                         }
152
153                         pk := (*btcec.PublicKey)(&key.PublicKey).
154                                 SerializeUncompressed()
155                         address, err := btcutil.NewAddressPubKeyHash(
156                                 btcutil.Hash160(pk), &chaincfg.TestNet3Params)
157                         if err != nil {
158                                 t.Errorf("failed to make address for %s: %v",
159                                         msg, err)
160                                 break
161                         }
162
163                         pkScript, err := PayToAddrScript(address)
164                         if err != nil {
165                                 t.Errorf("failed to make pkscript "+
166                                         "for %s: %v", msg, err)
167                         }
168
169                         if err := signAndCheck(msg, tx, i, inputAmounts[i], pkScript, hashType,
170                                 mkGetKey(map[string]addressToKey{
171                                         address.EncodeAddress(): {key, false},
172                                 }), mkGetScript(nil), nil); err != nil {
173                                 t.Error(err)
174                                 break
175                         }
176                 }
177         }
178
179         // Pay to Pubkey Hash (uncompressed) (merging with correct)
180         for _, hashType := range hashTypes {
181                 for i := range tx.TxIn {
182                         msg := fmt.Sprintf("%d:%d", hashType, i)
183                         key, err := btcec.NewPrivateKey(btcec.S256())
184                         if err != nil {
185                                 t.Errorf("failed to make privKey for %s: %v",
186                                         msg, err)
187                                 break
188                         }
189
190                         pk := (*btcec.PublicKey)(&key.PublicKey).
191                                 SerializeUncompressed()
192                         address, err := btcutil.NewAddressPubKeyHash(
193                                 btcutil.Hash160(pk), &chaincfg.TestNet3Params)
194                         if err != nil {
195                                 t.Errorf("failed to make address for %s: %v",
196                                         msg, err)
197                                 break
198                         }
199
200                         pkScript, err := PayToAddrScript(address)
201                         if err != nil {
202                                 t.Errorf("failed to make pkscript "+
203                                         "for %s: %v", msg, err)
204                         }
205
206                         sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
207                                 tx, i, pkScript, hashType,
208                                 mkGetKey(map[string]addressToKey{
209                                         address.EncodeAddress(): {key, false},
210                                 }), mkGetScript(nil), nil)
211                         if err != nil {
212                                 t.Errorf("failed to sign output %s: %v", msg,
213                                         err)
214                                 break
215                         }
216
217                         // by the above loop, this should be valid, now sign
218                         // again and merge.
219                         sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
220                                 tx, i, pkScript, hashType,
221                                 mkGetKey(map[string]addressToKey{
222                                         address.EncodeAddress(): {key, false},
223                                 }), mkGetScript(nil), sigScript)
224                         if err != nil {
225                                 t.Errorf("failed to sign output %s a "+
226                                         "second time: %v", msg, err)
227                                 break
228                         }
229
230                         err = checkScripts(msg, tx, i, inputAmounts[i], sigScript, pkScript)
231                         if err != nil {
232                                 t.Errorf("twice signed script invalid for "+
233                                         "%s: %v", msg, err)
234                                 break
235                         }
236                 }
237         }
238
239         // Pay to Pubkey Hash (compressed)
240         for _, hashType := range hashTypes {
241                 for i := range tx.TxIn {
242                         msg := fmt.Sprintf("%d:%d", hashType, i)
243
244                         key, err := btcec.NewPrivateKey(btcec.S256())
245                         if err != nil {
246                                 t.Errorf("failed to make privKey for %s: %v",
247                                         msg, err)
248                                 break
249                         }
250
251                         pk := (*btcec.PublicKey)(&key.PublicKey).
252                                 SerializeCompressed()
253                         address, err := btcutil.NewAddressPubKeyHash(
254                                 btcutil.Hash160(pk), &chaincfg.TestNet3Params)
255                         if err != nil {
256                                 t.Errorf("failed to make address for %s: %v",
257                                         msg, err)
258                                 break
259                         }
260
261                         pkScript, err := PayToAddrScript(address)
262                         if err != nil {
263                                 t.Errorf("failed to make pkscript "+
264                                         "for %s: %v", msg, err)
265                         }
266
267                         if err := signAndCheck(msg, tx, i, inputAmounts[i],
268                                 pkScript, hashType,
269                                 mkGetKey(map[string]addressToKey{
270                                         address.EncodeAddress(): {key, true},
271                                 }), mkGetScript(nil), nil); err != nil {
272                                 t.Error(err)
273                                 break
274                         }
275                 }
276         }
277
278         // Pay to Pubkey Hash (compressed) with duplicate merge
279         for _, hashType := range hashTypes {
280                 for i := range tx.TxIn {
281                         msg := fmt.Sprintf("%d:%d", hashType, i)
282
283                         key, err := btcec.NewPrivateKey(btcec.S256())
284                         if err != nil {
285                                 t.Errorf("failed to make privKey for %s: %v",
286                                         msg, err)
287                                 break
288                         }
289
290                         pk := (*btcec.PublicKey)(&key.PublicKey).
291                                 SerializeCompressed()
292                         address, err := btcutil.NewAddressPubKeyHash(
293                                 btcutil.Hash160(pk), &chaincfg.TestNet3Params)
294                         if err != nil {
295                                 t.Errorf("failed to make address for %s: %v",
296                                         msg, err)
297                                 break
298                         }
299
300                         pkScript, err := PayToAddrScript(address)
301                         if err != nil {
302                                 t.Errorf("failed to make pkscript "+
303                                         "for %s: %v", msg, err)
304                         }
305
306                         sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
307                                 tx, i, pkScript, hashType,
308                                 mkGetKey(map[string]addressToKey{
309                                         address.EncodeAddress(): {key, true},
310                                 }), mkGetScript(nil), nil)
311                         if err != nil {
312                                 t.Errorf("failed to sign output %s: %v", msg,
313                                         err)
314                                 break
315                         }
316
317                         // by the above loop, this should be valid, now sign
318                         // again and merge.
319                         sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
320                                 tx, i, pkScript, hashType,
321                                 mkGetKey(map[string]addressToKey{
322                                         address.EncodeAddress(): {key, true},
323                                 }), mkGetScript(nil), sigScript)
324                         if err != nil {
325                                 t.Errorf("failed to sign output %s a "+
326                                         "second time: %v", msg, err)
327                                 break
328                         }
329
330                         err = checkScripts(msg, tx, i, inputAmounts[i],
331                                 sigScript, pkScript)
332                         if err != nil {
333                                 t.Errorf("twice signed script invalid for "+
334                                         "%s: %v", msg, err)
335                                 break
336                         }
337                 }
338         }
339
340         // Pay to PubKey (uncompressed)
341         for _, hashType := range hashTypes {
342                 for i := range tx.TxIn {
343                         msg := fmt.Sprintf("%d:%d", hashType, i)
344
345                         key, err := btcec.NewPrivateKey(btcec.S256())
346                         if err != nil {
347                                 t.Errorf("failed to make privKey for %s: %v",
348                                         msg, err)
349                                 break
350                         }
351
352                         pk := (*btcec.PublicKey)(&key.PublicKey).
353                                 SerializeUncompressed()
354                         address, err := btcutil.NewAddressPubKey(pk,
355                                 &chaincfg.TestNet3Params)
356                         if err != nil {
357                                 t.Errorf("failed to make address for %s: %v",
358                                         msg, err)
359                                 break
360                         }
361
362                         pkScript, err := PayToAddrScript(address)
363                         if err != nil {
364                                 t.Errorf("failed to make pkscript "+
365                                         "for %s: %v", msg, err)
366                         }
367
368                         if err := signAndCheck(msg, tx, i, inputAmounts[i],
369                                 pkScript, hashType,
370                                 mkGetKey(map[string]addressToKey{
371                                         address.EncodeAddress(): {key, false},
372                                 }), mkGetScript(nil), nil); err != nil {
373                                 t.Error(err)
374                                 break
375                         }
376                 }
377         }
378
379         // Pay to PubKey (uncompressed)
380         for _, hashType := range hashTypes {
381                 for i := range tx.TxIn {
382                         msg := fmt.Sprintf("%d:%d", hashType, i)
383
384                         key, err := btcec.NewPrivateKey(btcec.S256())
385                         if err != nil {
386                                 t.Errorf("failed to make privKey for %s: %v",
387                                         msg, err)
388                                 break
389                         }
390
391                         pk := (*btcec.PublicKey)(&key.PublicKey).
392                                 SerializeUncompressed()
393                         address, err := btcutil.NewAddressPubKey(pk,
394                                 &chaincfg.TestNet3Params)
395                         if err != nil {
396                                 t.Errorf("failed to make address for %s: %v",
397                                         msg, err)
398                                 break
399                         }
400
401                         pkScript, err := PayToAddrScript(address)
402                         if err != nil {
403                                 t.Errorf("failed to make pkscript "+
404                                         "for %s: %v", msg, err)
405                         }
406
407                         sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
408                                 tx, i, pkScript, hashType,
409                                 mkGetKey(map[string]addressToKey{
410                                         address.EncodeAddress(): {key, false},
411                                 }), mkGetScript(nil), nil)
412                         if err != nil {
413                                 t.Errorf("failed to sign output %s: %v", msg,
414                                         err)
415                                 break
416                         }
417
418                         // by the above loop, this should be valid, now sign
419                         // again and merge.
420                         sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
421                                 tx, i, pkScript, hashType,
422                                 mkGetKey(map[string]addressToKey{
423                                         address.EncodeAddress(): {key, false},
424                                 }), mkGetScript(nil), sigScript)
425                         if err != nil {
426                                 t.Errorf("failed to sign output %s a "+
427                                         "second time: %v", msg, err)
428                                 break
429                         }
430
431                         err = checkScripts(msg, tx, i, inputAmounts[i], sigScript, pkScript)
432                         if err != nil {
433                                 t.Errorf("twice signed script invalid for "+
434                                         "%s: %v", msg, err)
435                                 break
436                         }
437                 }
438         }
439
440         // Pay to PubKey (compressed)
441         for _, hashType := range hashTypes {
442                 for i := range tx.TxIn {
443                         msg := fmt.Sprintf("%d:%d", hashType, i)
444
445                         key, err := btcec.NewPrivateKey(btcec.S256())
446                         if err != nil {
447                                 t.Errorf("failed to make privKey for %s: %v",
448                                         msg, err)
449                                 break
450                         }
451
452                         pk := (*btcec.PublicKey)(&key.PublicKey).
453                                 SerializeCompressed()
454                         address, err := btcutil.NewAddressPubKey(pk,
455                                 &chaincfg.TestNet3Params)
456                         if err != nil {
457                                 t.Errorf("failed to make address for %s: %v",
458                                         msg, err)
459                                 break
460                         }
461
462                         pkScript, err := PayToAddrScript(address)
463                         if err != nil {
464                                 t.Errorf("failed to make pkscript "+
465                                         "for %s: %v", msg, err)
466                         }
467
468                         if err := signAndCheck(msg, tx, i, inputAmounts[i],
469                                 pkScript, hashType,
470                                 mkGetKey(map[string]addressToKey{
471                                         address.EncodeAddress(): {key, true},
472                                 }), mkGetScript(nil), nil); err != nil {
473                                 t.Error(err)
474                                 break
475                         }
476                 }
477         }
478
479         // Pay to PubKey (compressed) with duplicate merge
480         for _, hashType := range hashTypes {
481                 for i := range tx.TxIn {
482                         msg := fmt.Sprintf("%d:%d", hashType, i)
483
484                         key, err := btcec.NewPrivateKey(btcec.S256())
485                         if err != nil {
486                                 t.Errorf("failed to make privKey for %s: %v",
487                                         msg, err)
488                                 break
489                         }
490
491                         pk := (*btcec.PublicKey)(&key.PublicKey).
492                                 SerializeCompressed()
493                         address, err := btcutil.NewAddressPubKey(pk,
494                                 &chaincfg.TestNet3Params)
495                         if err != nil {
496                                 t.Errorf("failed to make address for %s: %v",
497                                         msg, err)
498                                 break
499                         }
500
501                         pkScript, err := PayToAddrScript(address)
502                         if err != nil {
503                                 t.Errorf("failed to make pkscript "+
504                                         "for %s: %v", msg, err)
505                         }
506
507                         sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
508                                 tx, i, pkScript, hashType,
509                                 mkGetKey(map[string]addressToKey{
510                                         address.EncodeAddress(): {key, true},
511                                 }), mkGetScript(nil), nil)
512                         if err != nil {
513                                 t.Errorf("failed to sign output %s: %v", msg,
514                                         err)
515                                 break
516                         }
517
518                         // by the above loop, this should be valid, now sign
519                         // again and merge.
520                         sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
521                                 tx, i, pkScript, hashType,
522                                 mkGetKey(map[string]addressToKey{
523                                         address.EncodeAddress(): {key, true},
524                                 }), mkGetScript(nil), sigScript)
525                         if err != nil {
526                                 t.Errorf("failed to sign output %s a "+
527                                         "second time: %v", msg, err)
528                                 break
529                         }
530
531                         err = checkScripts(msg, tx, i, inputAmounts[i],
532                                 sigScript, pkScript)
533                         if err != nil {
534                                 t.Errorf("twice signed script invalid for "+
535                                         "%s: %v", msg, err)
536                                 break
537                         }
538                 }
539         }
540
541         // As before, but with p2sh now.
542         // Pay to Pubkey Hash (uncompressed)
543         for _, hashType := range hashTypes {
544                 for i := range tx.TxIn {
545                         msg := fmt.Sprintf("%d:%d", hashType, i)
546                         key, err := btcec.NewPrivateKey(btcec.S256())
547                         if err != nil {
548                                 t.Errorf("failed to make privKey for %s: %v",
549                                         msg, err)
550                                 break
551                         }
552
553                         pk := (*btcec.PublicKey)(&key.PublicKey).
554                                 SerializeUncompressed()
555                         address, err := btcutil.NewAddressPubKeyHash(
556                                 btcutil.Hash160(pk), &chaincfg.TestNet3Params)
557                         if err != nil {
558                                 t.Errorf("failed to make address for %s: %v",
559                                         msg, err)
560                                 break
561                         }
562
563                         pkScript, err := PayToAddrScript(address)
564                         if err != nil {
565                                 t.Errorf("failed to make pkscript "+
566                                         "for %s: %v", msg, err)
567                                 break
568                         }
569
570                         scriptAddr, err := btcutil.NewAddressScriptHash(
571                                 pkScript, &chaincfg.TestNet3Params)
572                         if err != nil {
573                                 t.Errorf("failed to make p2sh addr for %s: %v",
574                                         msg, err)
575                                 break
576                         }
577
578                         scriptPkScript, err := PayToAddrScript(
579                                 scriptAddr)
580                         if err != nil {
581                                 t.Errorf("failed to make script pkscript for "+
582                                         "%s: %v", msg, err)
583                                 break
584                         }
585
586                         if err := signAndCheck(msg, tx, i, inputAmounts[i],
587                                 scriptPkScript, hashType,
588                                 mkGetKey(map[string]addressToKey{
589                                         address.EncodeAddress(): {key, false},
590                                 }), mkGetScript(map[string][]byte{
591                                         scriptAddr.EncodeAddress(): pkScript,
592                                 }), nil); err != nil {
593                                 t.Error(err)
594                                 break
595                         }
596                 }
597         }
598
599         // Pay to Pubkey Hash (uncompressed) with duplicate merge
600         for _, hashType := range hashTypes {
601                 for i := range tx.TxIn {
602                         msg := fmt.Sprintf("%d:%d", hashType, i)
603                         key, err := btcec.NewPrivateKey(btcec.S256())
604                         if err != nil {
605                                 t.Errorf("failed to make privKey for %s: %v",
606                                         msg, err)
607                                 break
608                         }
609
610                         pk := (*btcec.PublicKey)(&key.PublicKey).
611                                 SerializeUncompressed()
612                         address, err := btcutil.NewAddressPubKeyHash(
613                                 btcutil.Hash160(pk), &chaincfg.TestNet3Params)
614                         if err != nil {
615                                 t.Errorf("failed to make address for %s: %v",
616                                         msg, err)
617                                 break
618                         }
619
620                         pkScript, err := PayToAddrScript(address)
621                         if err != nil {
622                                 t.Errorf("failed to make pkscript "+
623                                         "for %s: %v", msg, err)
624                                 break
625                         }
626
627                         scriptAddr, err := btcutil.NewAddressScriptHash(
628                                 pkScript, &chaincfg.TestNet3Params)
629                         if err != nil {
630                                 t.Errorf("failed to make p2sh addr for %s: %v",
631                                         msg, err)
632                                 break
633                         }
634
635                         scriptPkScript, err := PayToAddrScript(
636                                 scriptAddr)
637                         if err != nil {
638                                 t.Errorf("failed to make script pkscript for "+
639                                         "%s: %v", msg, err)
640                                 break
641                         }
642
643                         sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
644                                 tx, i, scriptPkScript, hashType,
645                                 mkGetKey(map[string]addressToKey{
646                                         address.EncodeAddress(): {key, false},
647                                 }), mkGetScript(map[string][]byte{
648                                         scriptAddr.EncodeAddress(): pkScript,
649                                 }), nil)
650                         if err != nil {
651                                 t.Errorf("failed to sign output %s: %v", msg,
652                                         err)
653                                 break
654                         }
655
656                         // by the above loop, this should be valid, now sign
657                         // again and merge.
658                         sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
659                                 tx, i, scriptPkScript, hashType,
660                                 mkGetKey(map[string]addressToKey{
661                                         address.EncodeAddress(): {key, false},
662                                 }), mkGetScript(map[string][]byte{
663                                         scriptAddr.EncodeAddress(): pkScript,
664                                 }), nil)
665                         if err != nil {
666                                 t.Errorf("failed to sign output %s a "+
667                                         "second time: %v", msg, err)
668                                 break
669                         }
670
671                         err = checkScripts(msg, tx, i, inputAmounts[i],
672                                 sigScript, scriptPkScript)
673                         if err != nil {
674                                 t.Errorf("twice signed script invalid for "+
675                                         "%s: %v", msg, err)
676                                 break
677                         }
678                 }
679         }
680
681         // Pay to Pubkey Hash (compressed)
682         for _, hashType := range hashTypes {
683                 for i := range tx.TxIn {
684                         msg := fmt.Sprintf("%d:%d", hashType, i)
685
686                         key, err := btcec.NewPrivateKey(btcec.S256())
687                         if err != nil {
688                                 t.Errorf("failed to make privKey for %s: %v",
689                                         msg, err)
690                                 break
691                         }
692
693                         pk := (*btcec.PublicKey)(&key.PublicKey).
694                                 SerializeCompressed()
695                         address, err := btcutil.NewAddressPubKeyHash(
696                                 btcutil.Hash160(pk), &chaincfg.TestNet3Params)
697                         if err != nil {
698                                 t.Errorf("failed to make address for %s: %v",
699                                         msg, err)
700                                 break
701                         }
702
703                         pkScript, err := PayToAddrScript(address)
704                         if err != nil {
705                                 t.Errorf("failed to make pkscript "+
706                                         "for %s: %v", msg, err)
707                         }
708
709                         scriptAddr, err := btcutil.NewAddressScriptHash(
710                                 pkScript, &chaincfg.TestNet3Params)
711                         if err != nil {
712                                 t.Errorf("failed to make p2sh addr for %s: %v",
713                                         msg, err)
714                                 break
715                         }
716
717                         scriptPkScript, err := PayToAddrScript(
718                                 scriptAddr)
719                         if err != nil {
720                                 t.Errorf("failed to make script pkscript for "+
721                                         "%s: %v", msg, err)
722                                 break
723                         }
724
725                         if err := signAndCheck(msg, tx, i, inputAmounts[i],
726                                 scriptPkScript, hashType,
727                                 mkGetKey(map[string]addressToKey{
728                                         address.EncodeAddress(): {key, true},
729                                 }), mkGetScript(map[string][]byte{
730                                         scriptAddr.EncodeAddress(): pkScript,
731                                 }), nil); err != nil {
732                                 t.Error(err)
733                                 break
734                         }
735                 }
736         }
737
738         // Pay to Pubkey Hash (compressed) with duplicate merge
739         for _, hashType := range hashTypes {
740                 for i := range tx.TxIn {
741                         msg := fmt.Sprintf("%d:%d", hashType, i)
742
743                         key, err := btcec.NewPrivateKey(btcec.S256())
744                         if err != nil {
745                                 t.Errorf("failed to make privKey for %s: %v",
746                                         msg, err)
747                                 break
748                         }
749
750                         pk := (*btcec.PublicKey)(&key.PublicKey).
751                                 SerializeCompressed()
752                         address, err := btcutil.NewAddressPubKeyHash(
753                                 btcutil.Hash160(pk), &chaincfg.TestNet3Params)
754                         if err != nil {
755                                 t.Errorf("failed to make address for %s: %v",
756                                         msg, err)
757                                 break
758                         }
759
760                         pkScript, err := PayToAddrScript(address)
761                         if err != nil {
762                                 t.Errorf("failed to make pkscript "+
763                                         "for %s: %v", msg, err)
764                         }
765
766                         scriptAddr, err := btcutil.NewAddressScriptHash(
767                                 pkScript, &chaincfg.TestNet3Params)
768                         if err != nil {
769                                 t.Errorf("failed to make p2sh addr for %s: %v",
770                                         msg, err)
771                                 break
772                         }
773
774                         scriptPkScript, err := PayToAddrScript(
775                                 scriptAddr)
776                         if err != nil {
777                                 t.Errorf("failed to make script pkscript for "+
778                                         "%s: %v", msg, err)
779                                 break
780                         }
781
782                         sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
783                                 tx, i, scriptPkScript, hashType,
784                                 mkGetKey(map[string]addressToKey{
785                                         address.EncodeAddress(): {key, true},
786                                 }), mkGetScript(map[string][]byte{
787                                         scriptAddr.EncodeAddress(): pkScript,
788                                 }), nil)
789                         if err != nil {
790                                 t.Errorf("failed to sign output %s: %v", msg,
791                                         err)
792                                 break
793                         }
794
795                         // by the above loop, this should be valid, now sign
796                         // again and merge.
797                         sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
798                                 tx, i, scriptPkScript, hashType,
799                                 mkGetKey(map[string]addressToKey{
800                                         address.EncodeAddress(): {key, true},
801                                 }), mkGetScript(map[string][]byte{
802                                         scriptAddr.EncodeAddress(): pkScript,
803                                 }), nil)
804                         if err != nil {
805                                 t.Errorf("failed to sign output %s a "+
806                                         "second time: %v", msg, err)
807                                 break
808                         }
809
810                         err = checkScripts(msg, tx, i, inputAmounts[i],
811                                 sigScript, scriptPkScript)
812                         if err != nil {
813                                 t.Errorf("twice signed script invalid for "+
814                                         "%s: %v", msg, err)
815                                 break
816                         }
817                 }
818         }
819
820         // Pay to PubKey (uncompressed)
821         for _, hashType := range hashTypes {
822                 for i := range tx.TxIn {
823                         msg := fmt.Sprintf("%d:%d", hashType, i)
824
825                         key, err := btcec.NewPrivateKey(btcec.S256())
826                         if err != nil {
827                                 t.Errorf("failed to make privKey for %s: %v",
828                                         msg, err)
829                                 break
830                         }
831
832                         pk := (*btcec.PublicKey)(&key.PublicKey).
833                                 SerializeUncompressed()
834                         address, err := btcutil.NewAddressPubKey(pk,
835                                 &chaincfg.TestNet3Params)
836                         if err != nil {
837                                 t.Errorf("failed to make address for %s: %v",
838                                         msg, err)
839                                 break
840                         }
841
842                         pkScript, err := PayToAddrScript(address)
843                         if err != nil {
844                                 t.Errorf("failed to make pkscript "+
845                                         "for %s: %v", msg, err)
846                         }
847
848                         scriptAddr, err := btcutil.NewAddressScriptHash(
849                                 pkScript, &chaincfg.TestNet3Params)
850                         if err != nil {
851                                 t.Errorf("failed to make p2sh addr for %s: %v",
852                                         msg, err)
853                                 break
854                         }
855
856                         scriptPkScript, err := PayToAddrScript(
857                                 scriptAddr)
858                         if err != nil {
859                                 t.Errorf("failed to make script pkscript for "+
860                                         "%s: %v", msg, err)
861                                 break
862                         }
863
864                         if err := signAndCheck(msg, tx, i, inputAmounts[i],
865                                 scriptPkScript, hashType,
866                                 mkGetKey(map[string]addressToKey{
867                                         address.EncodeAddress(): {key, false},
868                                 }), mkGetScript(map[string][]byte{
869                                         scriptAddr.EncodeAddress(): pkScript,
870                                 }), nil); err != nil {
871                                 t.Error(err)
872                                 break
873                         }
874                 }
875         }
876
877         // Pay to PubKey (uncompressed) with duplicate merge
878         for _, hashType := range hashTypes {
879                 for i := range tx.TxIn {
880                         msg := fmt.Sprintf("%d:%d", hashType, i)
881
882                         key, err := btcec.NewPrivateKey(btcec.S256())
883                         if err != nil {
884                                 t.Errorf("failed to make privKey for %s: %v",
885                                         msg, err)
886                                 break
887                         }
888
889                         pk := (*btcec.PublicKey)(&key.PublicKey).
890                                 SerializeUncompressed()
891                         address, err := btcutil.NewAddressPubKey(pk,
892                                 &chaincfg.TestNet3Params)
893                         if err != nil {
894                                 t.Errorf("failed to make address for %s: %v",
895                                         msg, err)
896                                 break
897                         }
898
899                         pkScript, err := PayToAddrScript(address)
900                         if err != nil {
901                                 t.Errorf("failed to make pkscript "+
902                                         "for %s: %v", msg, err)
903                         }
904
905                         scriptAddr, err := btcutil.NewAddressScriptHash(
906                                 pkScript, &chaincfg.TestNet3Params)
907                         if err != nil {
908                                 t.Errorf("failed to make p2sh addr for %s: %v",
909                                         msg, err)
910                                 break
911                         }
912
913                         scriptPkScript, err := PayToAddrScript(scriptAddr)
914                         if err != nil {
915                                 t.Errorf("failed to make script pkscript for "+
916                                         "%s: %v", msg, err)
917                                 break
918                         }
919
920                         sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
921                                 tx, i, scriptPkScript, hashType,
922                                 mkGetKey(map[string]addressToKey{
923                                         address.EncodeAddress(): {key, false},
924                                 }), mkGetScript(map[string][]byte{
925                                         scriptAddr.EncodeAddress(): pkScript,
926                                 }), nil)
927                         if err != nil {
928                                 t.Errorf("failed to sign output %s: %v", msg,
929                                         err)
930                                 break
931                         }
932
933                         // by the above loop, this should be valid, now sign
934                         // again and merge.
935                         sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
936                                 tx, i, scriptPkScript, hashType,
937                                 mkGetKey(map[string]addressToKey{
938                                         address.EncodeAddress(): {key, false},
939                                 }), mkGetScript(map[string][]byte{
940                                         scriptAddr.EncodeAddress(): pkScript,
941                                 }), nil)
942                         if err != nil {
943                                 t.Errorf("failed to sign output %s a "+
944                                         "second time: %v", msg, err)
945                                 break
946                         }
947
948                         err = checkScripts(msg, tx, i, inputAmounts[i],
949                                 sigScript, scriptPkScript)
950                         if err != nil {
951                                 t.Errorf("twice signed script invalid for "+
952                                         "%s: %v", msg, err)
953                                 break
954                         }
955                 }
956         }
957
958         // Pay to PubKey (compressed)
959         for _, hashType := range hashTypes {
960                 for i := range tx.TxIn {
961                         msg := fmt.Sprintf("%d:%d", hashType, i)
962
963                         key, err := btcec.NewPrivateKey(btcec.S256())
964                         if err != nil {
965                                 t.Errorf("failed to make privKey for %s: %v",
966                                         msg, err)
967                                 break
968                         }
969
970                         pk := (*btcec.PublicKey)(&key.PublicKey).
971                                 SerializeCompressed()
972                         address, err := btcutil.NewAddressPubKey(pk,
973                                 &chaincfg.TestNet3Params)
974                         if err != nil {
975                                 t.Errorf("failed to make address for %s: %v",
976                                         msg, err)
977                                 break
978                         }
979
980                         pkScript, err := PayToAddrScript(address)
981                         if err != nil {
982                                 t.Errorf("failed to make pkscript "+
983                                         "for %s: %v", msg, err)
984                         }
985
986                         scriptAddr, err := btcutil.NewAddressScriptHash(
987                                 pkScript, &chaincfg.TestNet3Params)
988                         if err != nil {
989                                 t.Errorf("failed to make p2sh addr for %s: %v",
990                                         msg, err)
991                                 break
992                         }
993
994                         scriptPkScript, err := PayToAddrScript(scriptAddr)
995                         if err != nil {
996                                 t.Errorf("failed to make script pkscript for "+
997                                         "%s: %v", msg, err)
998                                 break
999                         }
1000
1001                         if err := signAndCheck(msg, tx, i, inputAmounts[i],
1002                                 scriptPkScript, hashType,
1003                                 mkGetKey(map[string]addressToKey{
1004                                         address.EncodeAddress(): {key, true},
1005                                 }), mkGetScript(map[string][]byte{
1006                                         scriptAddr.EncodeAddress(): pkScript,
1007                                 }), nil); err != nil {
1008                                 t.Error(err)
1009                                 break
1010                         }
1011                 }
1012         }
1013
1014         // Pay to PubKey (compressed)
1015         for _, hashType := range hashTypes {
1016                 for i := range tx.TxIn {
1017                         msg := fmt.Sprintf("%d:%d", hashType, i)
1018
1019                         key, err := btcec.NewPrivateKey(btcec.S256())
1020                         if err != nil {
1021                                 t.Errorf("failed to make privKey for %s: %v",
1022                                         msg, err)
1023                                 break
1024                         }
1025
1026                         pk := (*btcec.PublicKey)(&key.PublicKey).
1027                                 SerializeCompressed()
1028                         address, err := btcutil.NewAddressPubKey(pk,
1029                                 &chaincfg.TestNet3Params)
1030                         if err != nil {
1031                                 t.Errorf("failed to make address for %s: %v",
1032                                         msg, err)
1033                                 break
1034                         }
1035
1036                         pkScript, err := PayToAddrScript(address)
1037                         if err != nil {
1038                                 t.Errorf("failed to make pkscript "+
1039                                         "for %s: %v", msg, err)
1040                         }
1041
1042                         scriptAddr, err := btcutil.NewAddressScriptHash(
1043                                 pkScript, &chaincfg.TestNet3Params)
1044                         if err != nil {
1045                                 t.Errorf("failed to make p2sh addr for %s: %v",
1046                                         msg, err)
1047                                 break
1048                         }
1049
1050                         scriptPkScript, err := PayToAddrScript(scriptAddr)
1051                         if err != nil {
1052                                 t.Errorf("failed to make script pkscript for "+
1053                                         "%s: %v", msg, err)
1054                                 break
1055                         }
1056
1057                         sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
1058                                 tx, i, scriptPkScript, hashType,
1059                                 mkGetKey(map[string]addressToKey{
1060                                         address.EncodeAddress(): {key, true},
1061                                 }), mkGetScript(map[string][]byte{
1062                                         scriptAddr.EncodeAddress(): pkScript,
1063                                 }), nil)
1064                         if err != nil {
1065                                 t.Errorf("failed to sign output %s: %v", msg,
1066                                         err)
1067                                 break
1068                         }
1069
1070                         // by the above loop, this should be valid, now sign
1071                         // again and merge.
1072                         sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
1073                                 tx, i, scriptPkScript, hashType,
1074                                 mkGetKey(map[string]addressToKey{
1075                                         address.EncodeAddress(): {key, true},
1076                                 }), mkGetScript(map[string][]byte{
1077                                         scriptAddr.EncodeAddress(): pkScript,
1078                                 }), nil)
1079                         if err != nil {
1080                                 t.Errorf("failed to sign output %s a "+
1081                                         "second time: %v", msg, err)
1082                                 break
1083                         }
1084
1085                         err = checkScripts(msg, tx, i, inputAmounts[i],
1086                                 sigScript, scriptPkScript)
1087                         if err != nil {
1088                                 t.Errorf("twice signed script invalid for "+
1089                                         "%s: %v", msg, err)
1090                                 break
1091                         }
1092                 }
1093         }
1094
1095         // Basic Multisig
1096         for _, hashType := range hashTypes {
1097                 for i := range tx.TxIn {
1098                         msg := fmt.Sprintf("%d:%d", hashType, i)
1099
1100                         key1, err := btcec.NewPrivateKey(btcec.S256())
1101                         if err != nil {
1102                                 t.Errorf("failed to make privKey for %s: %v",
1103                                         msg, err)
1104                                 break
1105                         }
1106
1107                         pk1 := (*btcec.PublicKey)(&key1.PublicKey).
1108                                 SerializeCompressed()
1109                         address1, err := btcutil.NewAddressPubKey(pk1,
1110                                 &chaincfg.TestNet3Params)
1111                         if err != nil {
1112                                 t.Errorf("failed to make address for %s: %v",
1113                                         msg, err)
1114                                 break
1115                         }
1116
1117                         key2, err := btcec.NewPrivateKey(btcec.S256())
1118                         if err != nil {
1119                                 t.Errorf("failed to make privKey 2 for %s: %v",
1120                                         msg, err)
1121                                 break
1122                         }
1123
1124                         pk2 := (*btcec.PublicKey)(&key2.PublicKey).
1125                                 SerializeCompressed()
1126                         address2, err := btcutil.NewAddressPubKey(pk2,
1127                                 &chaincfg.TestNet3Params)
1128                         if err != nil {
1129                                 t.Errorf("failed to make address 2 for %s: %v",
1130                                         msg, err)
1131                                 break
1132                         }
1133
1134                         pkScript, err := MultiSigScript(
1135                                 []*btcutil.AddressPubKey{address1, address2},
1136                                 2)
1137                         if err != nil {
1138                                 t.Errorf("failed to make pkscript "+
1139                                         "for %s: %v", msg, err)
1140                         }
1141
1142                         scriptAddr, err := btcutil.NewAddressScriptHash(
1143                                 pkScript, &chaincfg.TestNet3Params)
1144                         if err != nil {
1145                                 t.Errorf("failed to make p2sh addr for %s: %v",
1146                                         msg, err)
1147                                 break
1148                         }
1149
1150                         scriptPkScript, err := PayToAddrScript(scriptAddr)
1151                         if err != nil {
1152                                 t.Errorf("failed to make script pkscript for "+
1153                                         "%s: %v", msg, err)
1154                                 break
1155                         }
1156
1157                         if err := signAndCheck(msg, tx, i, inputAmounts[i],
1158                                 scriptPkScript, hashType,
1159                                 mkGetKey(map[string]addressToKey{
1160                                         address1.EncodeAddress(): {key1, true},
1161                                         address2.EncodeAddress(): {key2, true},
1162                                 }), mkGetScript(map[string][]byte{
1163                                         scriptAddr.EncodeAddress(): pkScript,
1164                                 }), nil); err != nil {
1165                                 t.Error(err)
1166                                 break
1167                         }
1168                 }
1169         }
1170
1171         // Two part multisig, sign with one key then the other.
1172         for _, hashType := range hashTypes {
1173                 for i := range tx.TxIn {
1174                         msg := fmt.Sprintf("%d:%d", hashType, i)
1175
1176                         key1, err := btcec.NewPrivateKey(btcec.S256())
1177                         if err != nil {
1178                                 t.Errorf("failed to make privKey for %s: %v",
1179                                         msg, err)
1180                                 break
1181                         }
1182
1183                         pk1 := (*btcec.PublicKey)(&key1.PublicKey).
1184                                 SerializeCompressed()
1185                         address1, err := btcutil.NewAddressPubKey(pk1,
1186                                 &chaincfg.TestNet3Params)
1187                         if err != nil {
1188                                 t.Errorf("failed to make address for %s: %v",
1189                                         msg, err)
1190                                 break
1191                         }
1192
1193                         key2, err := btcec.NewPrivateKey(btcec.S256())
1194                         if err != nil {
1195                                 t.Errorf("failed to make privKey 2 for %s: %v",
1196                                         msg, err)
1197                                 break
1198                         }
1199
1200                         pk2 := (*btcec.PublicKey)(&key2.PublicKey).
1201                                 SerializeCompressed()
1202                         address2, err := btcutil.NewAddressPubKey(pk2,
1203                                 &chaincfg.TestNet3Params)
1204                         if err != nil {
1205                                 t.Errorf("failed to make address 2 for %s: %v",
1206                                         msg, err)
1207                                 break
1208                         }
1209
1210                         pkScript, err := MultiSigScript(
1211                                 []*btcutil.AddressPubKey{address1, address2},
1212                                 2)
1213                         if err != nil {
1214                                 t.Errorf("failed to make pkscript "+
1215                                         "for %s: %v", msg, err)
1216                         }
1217
1218                         scriptAddr, err := btcutil.NewAddressScriptHash(
1219                                 pkScript, &chaincfg.TestNet3Params)
1220                         if err != nil {
1221                                 t.Errorf("failed to make p2sh addr for %s: %v",
1222                                         msg, err)
1223                                 break
1224                         }
1225
1226                         scriptPkScript, err := PayToAddrScript(scriptAddr)
1227                         if err != nil {
1228                                 t.Errorf("failed to make script pkscript for "+
1229                                         "%s: %v", msg, err)
1230                                 break
1231                         }
1232
1233                         sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
1234                                 tx, i, scriptPkScript, hashType,
1235                                 mkGetKey(map[string]addressToKey{
1236                                         address1.EncodeAddress(): {key1, true},
1237                                 }), mkGetScript(map[string][]byte{
1238                                         scriptAddr.EncodeAddress(): pkScript,
1239                                 }), nil)
1240                         if err != nil {
1241                                 t.Errorf("failed to sign output %s: %v", msg,
1242                                         err)
1243                                 break
1244                         }
1245
1246                         // Only 1 out of 2 signed, this *should* fail.
1247                         if checkScripts(msg, tx, i, inputAmounts[i], sigScript,
1248                                 scriptPkScript) == nil {
1249                                 t.Errorf("part signed script valid for %s", msg)
1250                                 break
1251                         }
1252
1253                         // Sign with the other key and merge
1254                         sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
1255                                 tx, i, scriptPkScript, hashType,
1256                                 mkGetKey(map[string]addressToKey{
1257                                         address2.EncodeAddress(): {key2, true},
1258                                 }), mkGetScript(map[string][]byte{
1259                                         scriptAddr.EncodeAddress(): pkScript,
1260                                 }), sigScript)
1261                         if err != nil {
1262                                 t.Errorf("failed to sign output %s: %v", msg, err)
1263                                 break
1264                         }
1265
1266                         err = checkScripts(msg, tx, i, inputAmounts[i], sigScript,
1267                                 scriptPkScript)
1268                         if err != nil {
1269                                 t.Errorf("fully signed script invalid for "+
1270                                         "%s: %v", msg, err)
1271                                 break
1272                         }
1273                 }
1274         }
1275
1276         // Two part multisig, sign with one key then both, check key dedup
1277         // correctly.
1278         for _, hashType := range hashTypes {
1279                 for i := range tx.TxIn {
1280                         msg := fmt.Sprintf("%d:%d", hashType, i)
1281
1282                         key1, err := btcec.NewPrivateKey(btcec.S256())
1283                         if err != nil {
1284                                 t.Errorf("failed to make privKey for %s: %v",
1285                                         msg, err)
1286                                 break
1287                         }
1288
1289                         pk1 := (*btcec.PublicKey)(&key1.PublicKey).
1290                                 SerializeCompressed()
1291                         address1, err := btcutil.NewAddressPubKey(pk1,
1292                                 &chaincfg.TestNet3Params)
1293                         if err != nil {
1294                                 t.Errorf("failed to make address for %s: %v",
1295                                         msg, err)
1296                                 break
1297                         }
1298
1299                         key2, err := btcec.NewPrivateKey(btcec.S256())
1300                         if err != nil {
1301                                 t.Errorf("failed to make privKey 2 for %s: %v",
1302                                         msg, err)
1303                                 break
1304                         }
1305
1306                         pk2 := (*btcec.PublicKey)(&key2.PublicKey).
1307                                 SerializeCompressed()
1308                         address2, err := btcutil.NewAddressPubKey(pk2,
1309                                 &chaincfg.TestNet3Params)
1310                         if err != nil {
1311                                 t.Errorf("failed to make address 2 for %s: %v",
1312                                         msg, err)
1313                                 break
1314                         }
1315
1316                         pkScript, err := MultiSigScript(
1317                                 []*btcutil.AddressPubKey{address1, address2},
1318                                 2)
1319                         if err != nil {
1320                                 t.Errorf("failed to make pkscript "+
1321                                         "for %s: %v", msg, err)
1322                         }
1323
1324                         scriptAddr, err := btcutil.NewAddressScriptHash(
1325                                 pkScript, &chaincfg.TestNet3Params)
1326                         if err != nil {
1327                                 t.Errorf("failed to make p2sh addr for %s: %v",
1328                                         msg, err)
1329                                 break
1330                         }
1331
1332                         scriptPkScript, err := PayToAddrScript(scriptAddr)
1333                         if err != nil {
1334                                 t.Errorf("failed to make script pkscript for "+
1335                                         "%s: %v", msg, err)
1336                                 break
1337                         }
1338
1339                         sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
1340                                 tx, i, scriptPkScript, hashType,
1341                                 mkGetKey(map[string]addressToKey{
1342                                         address1.EncodeAddress(): {key1, true},
1343                                 }), mkGetScript(map[string][]byte{
1344                                         scriptAddr.EncodeAddress(): pkScript,
1345                                 }), nil)
1346                         if err != nil {
1347                                 t.Errorf("failed to sign output %s: %v", msg,
1348                                         err)
1349                                 break
1350                         }
1351
1352                         // Only 1 out of 2 signed, this *should* fail.
1353                         if checkScripts(msg, tx, i, inputAmounts[i], sigScript,
1354                                 scriptPkScript) == nil {
1355                                 t.Errorf("part signed script valid for %s", msg)
1356                                 break
1357                         }
1358
1359                         // Sign with the other key and merge
1360                         sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
1361                                 tx, i, scriptPkScript, hashType,
1362                                 mkGetKey(map[string]addressToKey{
1363                                         address1.EncodeAddress(): {key1, true},
1364                                         address2.EncodeAddress(): {key2, true},
1365                                 }), mkGetScript(map[string][]byte{
1366                                         scriptAddr.EncodeAddress(): pkScript,
1367                                 }), sigScript)
1368                         if err != nil {
1369                                 t.Errorf("failed to sign output %s: %v", msg, err)
1370                                 break
1371                         }
1372
1373                         // Now we should pass.
1374                         err = checkScripts(msg, tx, i, inputAmounts[i],
1375                                 sigScript, scriptPkScript)
1376                         if err != nil {
1377                                 t.Errorf("fully signed script invalid for "+
1378                                         "%s: %v", msg, err)
1379                                 break
1380                         }
1381                 }
1382         }
1383 }
1384
1385 type tstInput struct {
1386         txout              *wire.TxOut
1387         sigscriptGenerates bool
1388         inputValidates     bool
1389         indexOutOfRange    bool
1390 }
1391
1392 type tstSigScript struct {
1393         name               string
1394         inputs             []tstInput
1395         hashType           SigHashType
1396         compress           bool
1397         scriptAtWrongIndex bool
1398 }
1399
1400 var coinbaseOutPoint = &wire.OutPoint{
1401         Index: (1 << 32) - 1,
1402 }
1403
1404 // Pregenerated private key, with associated public key and pkScripts
1405 // for the uncompressed and compressed hash160.
1406 var (
1407         privKeyD = []byte{0x6b, 0x0f, 0xd8, 0xda, 0x54, 0x22, 0xd0, 0xb7,
1408                 0xb4, 0xfc, 0x4e, 0x55, 0xd4, 0x88, 0x42, 0xb3, 0xa1, 0x65,
1409                 0xac, 0x70, 0x7f, 0x3d, 0xa4, 0x39, 0x5e, 0xcb, 0x3b, 0xb0,
1410                 0xd6, 0x0e, 0x06, 0x92}
1411         pubkeyX = []byte{0xb2, 0x52, 0xf0, 0x49, 0x85, 0x78, 0x03, 0x03, 0xc8,
1412                 0x7d, 0xce, 0x51, 0x7f, 0xa8, 0x69, 0x0b, 0x91, 0x95, 0xf4,
1413                 0xf3, 0x5c, 0x26, 0x73, 0x05, 0x05, 0xa2, 0xee, 0xbc, 0x09,
1414                 0x38, 0x34, 0x3a}
1415         pubkeyY = []byte{0xb7, 0xc6, 0x7d, 0xb2, 0xe1, 0xff, 0xc8, 0x43, 0x1f,
1416                 0x63, 0x32, 0x62, 0xaa, 0x60, 0xc6, 0x83, 0x30, 0xbd, 0x24,
1417                 0x7e, 0xef, 0xdb, 0x6f, 0x2e, 0x8d, 0x56, 0xf0, 0x3c, 0x9f,
1418                 0x6d, 0xb6, 0xf8}
1419         uncompressedPkScript = []byte{0x76, 0xa9, 0x14, 0xd1, 0x7c, 0xb5,
1420                 0xeb, 0xa4, 0x02, 0xcb, 0x68, 0xe0, 0x69, 0x56, 0xbf, 0x32,
1421                 0x53, 0x90, 0x0e, 0x0a, 0x86, 0xc9, 0xfa, 0x88, 0xac}
1422         compressedPkScript = []byte{0x76, 0xa9, 0x14, 0x27, 0x4d, 0x9f, 0x7f,
1423                 0x61, 0x7e, 0x7c, 0x7a, 0x1c, 0x1f, 0xb2, 0x75, 0x79, 0x10,
1424                 0x43, 0x65, 0x68, 0x27, 0x9d, 0x86, 0x88, 0xac}
1425         shortPkScript = []byte{0x76, 0xa9, 0x14, 0xd1, 0x7c, 0xb5,
1426                 0xeb, 0xa4, 0x02, 0xcb, 0x68, 0xe0, 0x69, 0x56, 0xbf, 0x32,
1427                 0x53, 0x90, 0x0e, 0x0a, 0x88, 0xac}
1428         uncompressedAddrStr = "1L6fd93zGmtzkK6CsZFVVoCwzZV3MUtJ4F"
1429         compressedAddrStr   = "14apLppt9zTq6cNw8SDfiJhk9PhkZrQtYZ"
1430 )
1431
1432 // Pretend output amounts.
1433 const coinbaseVal = 2500000000
1434 const fee = 5000000
1435
1436 var sigScriptTests = []tstSigScript{
1437         {
1438                 name: "one input uncompressed",
1439                 inputs: []tstInput{
1440                         {
1441                                 txout:              wire.NewTxOut(coinbaseVal, uncompressedPkScript),
1442                                 sigscriptGenerates: true,
1443                                 inputValidates:     true,
1444                                 indexOutOfRange:    false,
1445                         },
1446                 },
1447                 hashType:           SigHashAll,
1448                 compress:           false,
1449                 scriptAtWrongIndex: false,
1450         },
1451         {
1452                 name: "two inputs uncompressed",
1453                 inputs: []tstInput{
1454                         {
1455                                 txout:              wire.NewTxOut(coinbaseVal, uncompressedPkScript),
1456                                 sigscriptGenerates: true,
1457                                 inputValidates:     true,
1458                                 indexOutOfRange:    false,
1459                         },
1460                         {
1461                                 txout:              wire.NewTxOut(coinbaseVal+fee, uncompressedPkScript),
1462                                 sigscriptGenerates: true,
1463                                 inputValidates:     true,
1464                                 indexOutOfRange:    false,
1465                         },
1466                 },
1467                 hashType:           SigHashAll,
1468                 compress:           false,
1469                 scriptAtWrongIndex: false,
1470         },
1471         {
1472                 name: "one input compressed",
1473                 inputs: []tstInput{
1474                         {
1475                                 txout:              wire.NewTxOut(coinbaseVal, compressedPkScript),
1476                                 sigscriptGenerates: true,
1477                                 inputValidates:     true,
1478                                 indexOutOfRange:    false,
1479                         },
1480                 },
1481                 hashType:           SigHashAll,
1482                 compress:           true,
1483                 scriptAtWrongIndex: false,
1484         },
1485         {
1486                 name: "two inputs compressed",
1487                 inputs: []tstInput{
1488                         {
1489                                 txout:              wire.NewTxOut(coinbaseVal, compressedPkScript),
1490                                 sigscriptGenerates: true,
1491                                 inputValidates:     true,
1492                                 indexOutOfRange:    false,
1493                         },
1494                         {
1495                                 txout:              wire.NewTxOut(coinbaseVal+fee, compressedPkScript),
1496                                 sigscriptGenerates: true,
1497                                 inputValidates:     true,
1498                                 indexOutOfRange:    false,
1499                         },
1500                 },
1501                 hashType:           SigHashAll,
1502                 compress:           true,
1503                 scriptAtWrongIndex: false,
1504         },
1505         {
1506                 name: "hashType SigHashNone",
1507                 inputs: []tstInput{
1508                         {
1509                                 txout:              wire.NewTxOut(coinbaseVal, uncompressedPkScript),
1510                                 sigscriptGenerates: true,
1511                                 inputValidates:     true,
1512                                 indexOutOfRange:    false,
1513                         },
1514                 },
1515                 hashType:           SigHashNone,
1516                 compress:           false,
1517                 scriptAtWrongIndex: false,
1518         },
1519         {
1520                 name: "hashType SigHashSingle",
1521                 inputs: []tstInput{
1522                         {
1523                                 txout:              wire.NewTxOut(coinbaseVal, uncompressedPkScript),
1524                                 sigscriptGenerates: true,
1525                                 inputValidates:     true,
1526                                 indexOutOfRange:    false,
1527                         },
1528                 },
1529                 hashType:           SigHashSingle,
1530                 compress:           false,
1531                 scriptAtWrongIndex: false,
1532         },
1533         {
1534                 name: "hashType SigHashAnyoneCanPay",
1535                 inputs: []tstInput{
1536                         {
1537                                 txout:              wire.NewTxOut(coinbaseVal, uncompressedPkScript),
1538                                 sigscriptGenerates: true,
1539                                 inputValidates:     true,
1540                                 indexOutOfRange:    false,
1541                         },
1542                 },
1543                 hashType:           SigHashAnyOneCanPay,
1544                 compress:           false,
1545                 scriptAtWrongIndex: false,
1546         },
1547         {
1548                 name: "hashType non-standard",
1549                 inputs: []tstInput{
1550                         {
1551                                 txout:              wire.NewTxOut(coinbaseVal, uncompressedPkScript),
1552                                 sigscriptGenerates: true,
1553                                 inputValidates:     true,
1554                                 indexOutOfRange:    false,
1555                         },
1556                 },
1557                 hashType:           0x04,
1558                 compress:           false,
1559                 scriptAtWrongIndex: false,
1560         },
1561         {
1562                 name: "invalid compression",
1563                 inputs: []tstInput{
1564                         {
1565                                 txout:              wire.NewTxOut(coinbaseVal, uncompressedPkScript),
1566                                 sigscriptGenerates: true,
1567                                 inputValidates:     false,
1568                                 indexOutOfRange:    false,
1569                         },
1570                 },
1571                 hashType:           SigHashAll,
1572                 compress:           true,
1573                 scriptAtWrongIndex: false,
1574         },
1575         {
1576                 name: "short PkScript",
1577                 inputs: []tstInput{
1578                         {
1579                                 txout:              wire.NewTxOut(coinbaseVal, shortPkScript),
1580                                 sigscriptGenerates: false,
1581                                 indexOutOfRange:    false,
1582                         },
1583                 },
1584                 hashType:           SigHashAll,
1585                 compress:           false,
1586                 scriptAtWrongIndex: false,
1587         },
1588         {
1589                 name: "valid script at wrong index",
1590                 inputs: []tstInput{
1591                         {
1592                                 txout:              wire.NewTxOut(coinbaseVal, uncompressedPkScript),
1593                                 sigscriptGenerates: true,
1594                                 inputValidates:     true,
1595                                 indexOutOfRange:    false,
1596                         },
1597                         {
1598                                 txout:              wire.NewTxOut(coinbaseVal+fee, uncompressedPkScript),
1599                                 sigscriptGenerates: true,
1600                                 inputValidates:     true,
1601                                 indexOutOfRange:    false,
1602                         },
1603                 },
1604                 hashType:           SigHashAll,
1605                 compress:           false,
1606                 scriptAtWrongIndex: true,
1607         },
1608         {
1609                 name: "index out of range",
1610                 inputs: []tstInput{
1611                         {
1612                                 txout:              wire.NewTxOut(coinbaseVal, uncompressedPkScript),
1613                                 sigscriptGenerates: true,
1614                                 inputValidates:     true,
1615                                 indexOutOfRange:    false,
1616                         },
1617                         {
1618                                 txout:              wire.NewTxOut(coinbaseVal+fee, uncompressedPkScript),
1619                                 sigscriptGenerates: true,
1620                                 inputValidates:     true,
1621                                 indexOutOfRange:    false,
1622                         },
1623                 },
1624                 hashType:           SigHashAll,
1625                 compress:           false,
1626                 scriptAtWrongIndex: true,
1627         },
1628 }
1629
1630 // Test the sigscript generation for valid and invalid inputs, all
1631 // hashTypes, and with and without compression.  This test creates
1632 // sigscripts to spend fake coinbase inputs, as sigscripts cannot be
1633 // created for the MsgTxs in txTests, since they come from the blockchain
1634 // and we don't have the private keys.
1635 func TestSignatureScript(t *testing.T) {
1636         t.Parallel()
1637
1638         privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), privKeyD)
1639
1640 nexttest:
1641         for i := range sigScriptTests {
1642                 tx := wire.NewMsgTx(wire.TxVersion)
1643
1644                 output := wire.NewTxOut(500, []byte{OP_RETURN})
1645                 tx.AddTxOut(output)
1646
1647                 for range sigScriptTests[i].inputs {
1648                         txin := wire.NewTxIn(coinbaseOutPoint, nil, nil)
1649                         tx.AddTxIn(txin)
1650                 }
1651
1652                 var script []byte
1653                 var err error
1654                 for j := range tx.TxIn {
1655                         var idx int
1656                         if sigScriptTests[i].inputs[j].indexOutOfRange {
1657                                 t.Errorf("at test %v", sigScriptTests[i].name)
1658                                 idx = len(sigScriptTests[i].inputs)
1659                         } else {
1660                                 idx = j
1661                         }
1662                         script, err = SignatureScript(tx, idx,
1663                                 sigScriptTests[i].inputs[j].txout.PkScript,
1664                                 sigScriptTests[i].hashType, privKey,
1665                                 sigScriptTests[i].compress)
1666
1667                         if (err == nil) != sigScriptTests[i].inputs[j].sigscriptGenerates {
1668                                 if err == nil {
1669                                         t.Errorf("passed test '%v' incorrectly",
1670                                                 sigScriptTests[i].name)
1671                                 } else {
1672                                         t.Errorf("failed test '%v': %v",
1673                                                 sigScriptTests[i].name, err)
1674                                 }
1675                                 continue nexttest
1676                         }
1677                         if !sigScriptTests[i].inputs[j].sigscriptGenerates {
1678                                 // done with this test
1679                                 continue nexttest
1680                         }
1681
1682                         tx.TxIn[j].SignatureScript = script
1683                 }
1684
1685                 // If testing using a correct sigscript but for an incorrect
1686                 // index, use last input script for first input.  Requires > 0
1687                 // inputs for test.
1688                 if sigScriptTests[i].scriptAtWrongIndex {
1689                         tx.TxIn[0].SignatureScript = script
1690                         sigScriptTests[i].inputs[0].inputValidates = false
1691                 }
1692
1693                 // Validate tx input scripts
1694                 scriptFlags := ScriptBip16 | ScriptVerifyDERSignatures
1695                 for j := range tx.TxIn {
1696                         vm, err := NewEngine(sigScriptTests[i].
1697                                 inputs[j].txout.PkScript, tx, j, scriptFlags, nil, nil, 0)
1698                         if err != nil {
1699                                 t.Errorf("cannot create script vm for test %v: %v",
1700                                         sigScriptTests[i].name, err)
1701                                 continue nexttest
1702                         }
1703                         err = vm.Execute()
1704                         if (err == nil) != sigScriptTests[i].inputs[j].inputValidates {
1705                                 if err == nil {
1706                                         t.Errorf("passed test '%v' validation incorrectly: %v",
1707                                                 sigScriptTests[i].name, err)
1708                                 } else {
1709                                         t.Errorf("failed test '%v' validation: %v",
1710                                                 sigScriptTests[i].name, err)
1711                                 }
1712                                 continue nexttest
1713                         }
1714                 }
1715         }
1716 }