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
5package txscript
6
7import (
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
19type addressToKey struct {
20	key        *btcec.PrivateKey
21	compressed bool
22}
23
24func 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
41func 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
56func 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
74func 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
87func 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
1385type tstInput struct {
1386	txout              *wire.TxOut
1387	sigscriptGenerates bool
1388	inputValidates     bool
1389	indexOutOfRange    bool
1390}
1391
1392type tstSigScript struct {
1393	name               string
1394	inputs             []tstInput
1395	hashType           SigHashType
1396	compress           bool
1397	scriptAtWrongIndex bool
1398}
1399
1400var 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.
1406var (
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.
1433const coinbaseVal = 2500000000
1434const fee = 5000000
1435
1436var 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.
1635func TestSignatureScript(t *testing.T) {
1636	t.Parallel()
1637
1638	privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), privKeyD)
1639
1640nexttest:
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}
1717