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