github.com/palcoin-project/palcd@v1.0.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/palcoin-project/palcd/btcec" 13 "github.com/palcoin-project/palcd/chaincfg" 14 "github.com/palcoin-project/palcd/chaincfg/chainhash" 15 "github.com/palcoin-project/palcd/wire" 16 "github.com/palcoin-project/palcutil" 17 ) 18 19 type addressToKey struct { 20 key *btcec.PrivateKey 21 compressed bool 22 } 23 24 func mkGetKey(keys map[string]addressToKey) KeyDB { 25 if keys == nil { 26 return KeyClosure(func(addr palcutil.Address) (*btcec.PrivateKey, 27 bool, error) { 28 return nil, false, errors.New("nope") 29 }) 30 } 31 return KeyClosure(func(addr palcutil.Address) (*btcec.PrivateKey, 32 bool, error) { 33 a2k, ok := keys[addr.EncodeAddress()] 34 if !ok { 35 return nil, false, errors.New("nope") 36 } 37 return a2k.key, a2k.compressed, nil 38 }) 39 } 40 41 func mkGetScript(scripts map[string][]byte) ScriptDB { 42 if scripts == nil { 43 return ScriptClosure(func(addr palcutil.Address) ([]byte, error) { 44 return nil, errors.New("nope") 45 }) 46 } 47 return ScriptClosure(func(addr palcutil.Address) ([]byte, error) { 48 script, ok := scripts[addr.EncodeAddress()] 49 if !ok { 50 return nil, errors.New("nope") 51 } 52 return script, nil 53 }) 54 } 55 56 func checkScripts(msg string, tx *wire.MsgTx, idx int, inputAmt int64, sigScript, pkScript []byte) error { 57 tx.TxIn[idx].SignatureScript = sigScript 58 vm, err := NewEngine(pkScript, tx, idx, 59 ScriptBip16|ScriptVerifyDERSignatures, nil, nil, inputAmt) 60 if err != nil { 61 return fmt.Errorf("failed to make script engine for %s: %v", 62 msg, err) 63 } 64 65 err = vm.Execute() 66 if err != nil { 67 return fmt.Errorf("invalid script signature for %s: %v", msg, 68 err) 69 } 70 71 return nil 72 } 73 74 func signAndCheck(msg string, tx *wire.MsgTx, idx int, inputAmt int64, pkScript []byte, 75 hashType SigHashType, kdb KeyDB, sdb ScriptDB, 76 previousScript []byte) error { 77 78 sigScript, err := SignTxOutput(&chaincfg.TestNet3Params, tx, idx, 79 pkScript, hashType, kdb, sdb, nil) 80 if err != nil { 81 return fmt.Errorf("failed to sign output %s: %v", msg, err) 82 } 83 84 return checkScripts(msg, tx, idx, inputAmt, sigScript, pkScript) 85 } 86 87 func TestSignTxOutput(t *testing.T) { 88 t.Parallel() 89 90 // make key 91 // make script based on key. 92 // sign with magic pixie dust. 93 hashTypes := []SigHashType{ 94 SigHashOld, // no longer used but should act like all 95 SigHashAll, 96 SigHashNone, 97 SigHashSingle, 98 SigHashAll | SigHashAnyOneCanPay, 99 SigHashNone | SigHashAnyOneCanPay, 100 SigHashSingle | SigHashAnyOneCanPay, 101 } 102 inputAmounts := []int64{5, 10, 15} 103 tx := &wire.MsgTx{ 104 Version: 1, 105 TxIn: []*wire.TxIn{ 106 { 107 PreviousOutPoint: wire.OutPoint{ 108 Hash: chainhash.Hash{}, 109 Index: 0, 110 }, 111 Sequence: 4294967295, 112 }, 113 { 114 PreviousOutPoint: wire.OutPoint{ 115 Hash: chainhash.Hash{}, 116 Index: 1, 117 }, 118 Sequence: 4294967295, 119 }, 120 { 121 PreviousOutPoint: wire.OutPoint{ 122 Hash: chainhash.Hash{}, 123 Index: 2, 124 }, 125 Sequence: 4294967295, 126 }, 127 }, 128 TxOut: []*wire.TxOut{ 129 { 130 Value: 1, 131 }, 132 { 133 Value: 2, 134 }, 135 { 136 Value: 3, 137 }, 138 }, 139 LockTime: 0, 140 } 141 142 // Pay to Pubkey Hash (uncompressed) 143 for _, hashType := range hashTypes { 144 for i := range tx.TxIn { 145 msg := fmt.Sprintf("%d:%d", hashType, i) 146 key, err := btcec.NewPrivateKey(btcec.S256()) 147 if err != nil { 148 t.Errorf("failed to make privKey for %s: %v", 149 msg, err) 150 break 151 } 152 153 pk := (*btcec.PublicKey)(&key.PublicKey). 154 SerializeUncompressed() 155 address, err := palcutil.NewAddressPubKeyHash( 156 palcutil.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 := palcutil.NewAddressPubKeyHash( 193 palcutil.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 := palcutil.NewAddressPubKeyHash( 254 palcutil.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 := palcutil.NewAddressPubKeyHash( 293 palcutil.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 := palcutil.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 := palcutil.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 := palcutil.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 := palcutil.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 := palcutil.NewAddressPubKeyHash( 556 palcutil.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 := palcutil.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 := palcutil.NewAddressPubKeyHash( 613 palcutil.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 := palcutil.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 := palcutil.NewAddressPubKeyHash( 696 palcutil.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 := palcutil.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 := palcutil.NewAddressPubKeyHash( 753 palcutil.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 := palcutil.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 := palcutil.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 := palcutil.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 := palcutil.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 := palcutil.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 := palcutil.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 := palcutil.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 := palcutil.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 := palcutil.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 := palcutil.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 := palcutil.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 []*palcutil.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 := palcutil.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 := palcutil.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 := palcutil.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 []*palcutil.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 := palcutil.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 := palcutil.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 := palcutil.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 []*palcutil.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 := palcutil.NewAddressScriptHash( 1325 pkScript, &chaincfg.TestNet3Params) 1326 if err != nil { 1327 t.Errorf("failed to make p2sh addr for %s: %v", 1328 msg, err) 1329 break 1330 } 1331 1332 scriptPkScript, err := PayToAddrScript(scriptAddr) 1333 if err != nil { 1334 t.Errorf("failed to make script pkscript for "+ 1335 "%s: %v", msg, err) 1336 break 1337 } 1338 1339 sigScript, err := SignTxOutput(&chaincfg.TestNet3Params, 1340 tx, i, scriptPkScript, hashType, 1341 mkGetKey(map[string]addressToKey{ 1342 address1.EncodeAddress(): {key1, true}, 1343 }), mkGetScript(map[string][]byte{ 1344 scriptAddr.EncodeAddress(): pkScript, 1345 }), nil) 1346 if err != nil { 1347 t.Errorf("failed to sign output %s: %v", msg, 1348 err) 1349 break 1350 } 1351 1352 // Only 1 out of 2 signed, this *should* fail. 1353 if checkScripts(msg, tx, i, inputAmounts[i], sigScript, 1354 scriptPkScript) == nil { 1355 t.Errorf("part signed script valid for %s", msg) 1356 break 1357 } 1358 1359 // Sign with the other key and merge 1360 sigScript, err = SignTxOutput(&chaincfg.TestNet3Params, 1361 tx, i, scriptPkScript, hashType, 1362 mkGetKey(map[string]addressToKey{ 1363 address1.EncodeAddress(): {key1, true}, 1364 address2.EncodeAddress(): {key2, true}, 1365 }), mkGetScript(map[string][]byte{ 1366 scriptAddr.EncodeAddress(): pkScript, 1367 }), sigScript) 1368 if err != nil { 1369 t.Errorf("failed to sign output %s: %v", msg, err) 1370 break 1371 } 1372 1373 // Now we should pass. 1374 err = checkScripts(msg, tx, i, inputAmounts[i], 1375 sigScript, scriptPkScript) 1376 if err != nil { 1377 t.Errorf("fully signed script invalid for "+ 1378 "%s: %v", msg, err) 1379 break 1380 } 1381 } 1382 } 1383 } 1384 1385 type tstInput struct { 1386 txout *wire.TxOut 1387 sigscriptGenerates bool 1388 inputValidates bool 1389 indexOutOfRange bool 1390 } 1391 1392 type tstSigScript struct { 1393 name string 1394 inputs []tstInput 1395 hashType SigHashType 1396 compress bool 1397 scriptAtWrongIndex bool 1398 } 1399 1400 var coinbaseOutPoint = &wire.OutPoint{ 1401 Index: (1 << 32) - 1, 1402 } 1403 1404 // Pregenerated private key, with associated public key and pkScripts 1405 // for the uncompressed and compressed hash160. 1406 var ( 1407 privKeyD = []byte{0x6b, 0x0f, 0xd8, 0xda, 0x54, 0x22, 0xd0, 0xb7, 1408 0xb4, 0xfc, 0x4e, 0x55, 0xd4, 0x88, 0x42, 0xb3, 0xa1, 0x65, 1409 0xac, 0x70, 0x7f, 0x3d, 0xa4, 0x39, 0x5e, 0xcb, 0x3b, 0xb0, 1410 0xd6, 0x0e, 0x06, 0x92} 1411 pubkeyX = []byte{0xb2, 0x52, 0xf0, 0x49, 0x85, 0x78, 0x03, 0x03, 0xc8, 1412 0x7d, 0xce, 0x51, 0x7f, 0xa8, 0x69, 0x0b, 0x91, 0x95, 0xf4, 1413 0xf3, 0x5c, 0x26, 0x73, 0x05, 0x05, 0xa2, 0xee, 0xbc, 0x09, 1414 0x38, 0x34, 0x3a} 1415 pubkeyY = []byte{0xb7, 0xc6, 0x7d, 0xb2, 0xe1, 0xff, 0xc8, 0x43, 0x1f, 1416 0x63, 0x32, 0x62, 0xaa, 0x60, 0xc6, 0x83, 0x30, 0xbd, 0x24, 1417 0x7e, 0xef, 0xdb, 0x6f, 0x2e, 0x8d, 0x56, 0xf0, 0x3c, 0x9f, 1418 0x6d, 0xb6, 0xf8} 1419 uncompressedPkScript = []byte{0x76, 0xa9, 0x14, 0xd1, 0x7c, 0xb5, 1420 0xeb, 0xa4, 0x02, 0xcb, 0x68, 0xe0, 0x69, 0x56, 0xbf, 0x32, 1421 0x53, 0x90, 0x0e, 0x0a, 0x86, 0xc9, 0xfa, 0x88, 0xac} 1422 compressedPkScript = []byte{0x76, 0xa9, 0x14, 0x27, 0x4d, 0x9f, 0x7f, 1423 0x61, 0x7e, 0x7c, 0x7a, 0x1c, 0x1f, 0xb2, 0x75, 0x79, 0x10, 1424 0x43, 0x65, 0x68, 0x27, 0x9d, 0x86, 0x88, 0xac} 1425 shortPkScript = []byte{0x76, 0xa9, 0x14, 0xd1, 0x7c, 0xb5, 1426 0xeb, 0xa4, 0x02, 0xcb, 0x68, 0xe0, 0x69, 0x56, 0xbf, 0x32, 1427 0x53, 0x90, 0x0e, 0x0a, 0x88, 0xac} 1428 uncompressedAddrStr = "1L6fd93zGmtzkK6CsZFVVoCwzZV3MUtJ4F" 1429 compressedAddrStr = "14apLppt9zTq6cNw8SDfiJhk9PhkZrQtYZ" 1430 ) 1431 1432 // Pretend output amounts. 1433 const coinbaseVal = 2500000000 1434 const fee = 5000000 1435 1436 var sigScriptTests = []tstSigScript{ 1437 { 1438 name: "one input uncompressed", 1439 inputs: []tstInput{ 1440 { 1441 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript), 1442 sigscriptGenerates: true, 1443 inputValidates: true, 1444 indexOutOfRange: false, 1445 }, 1446 }, 1447 hashType: SigHashAll, 1448 compress: false, 1449 scriptAtWrongIndex: false, 1450 }, 1451 { 1452 name: "two inputs uncompressed", 1453 inputs: []tstInput{ 1454 { 1455 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript), 1456 sigscriptGenerates: true, 1457 inputValidates: true, 1458 indexOutOfRange: false, 1459 }, 1460 { 1461 txout: wire.NewTxOut(coinbaseVal+fee, uncompressedPkScript), 1462 sigscriptGenerates: true, 1463 inputValidates: true, 1464 indexOutOfRange: false, 1465 }, 1466 }, 1467 hashType: SigHashAll, 1468 compress: false, 1469 scriptAtWrongIndex: false, 1470 }, 1471 { 1472 name: "one input compressed", 1473 inputs: []tstInput{ 1474 { 1475 txout: wire.NewTxOut(coinbaseVal, compressedPkScript), 1476 sigscriptGenerates: true, 1477 inputValidates: true, 1478 indexOutOfRange: false, 1479 }, 1480 }, 1481 hashType: SigHashAll, 1482 compress: true, 1483 scriptAtWrongIndex: false, 1484 }, 1485 { 1486 name: "two inputs compressed", 1487 inputs: []tstInput{ 1488 { 1489 txout: wire.NewTxOut(coinbaseVal, compressedPkScript), 1490 sigscriptGenerates: true, 1491 inputValidates: true, 1492 indexOutOfRange: false, 1493 }, 1494 { 1495 txout: wire.NewTxOut(coinbaseVal+fee, compressedPkScript), 1496 sigscriptGenerates: true, 1497 inputValidates: true, 1498 indexOutOfRange: false, 1499 }, 1500 }, 1501 hashType: SigHashAll, 1502 compress: true, 1503 scriptAtWrongIndex: false, 1504 }, 1505 { 1506 name: "hashType SigHashNone", 1507 inputs: []tstInput{ 1508 { 1509 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript), 1510 sigscriptGenerates: true, 1511 inputValidates: true, 1512 indexOutOfRange: false, 1513 }, 1514 }, 1515 hashType: SigHashNone, 1516 compress: false, 1517 scriptAtWrongIndex: false, 1518 }, 1519 { 1520 name: "hashType SigHashSingle", 1521 inputs: []tstInput{ 1522 { 1523 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript), 1524 sigscriptGenerates: true, 1525 inputValidates: true, 1526 indexOutOfRange: false, 1527 }, 1528 }, 1529 hashType: SigHashSingle, 1530 compress: false, 1531 scriptAtWrongIndex: false, 1532 }, 1533 { 1534 name: "hashType SigHashAnyoneCanPay", 1535 inputs: []tstInput{ 1536 { 1537 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript), 1538 sigscriptGenerates: true, 1539 inputValidates: true, 1540 indexOutOfRange: false, 1541 }, 1542 }, 1543 hashType: SigHashAnyOneCanPay, 1544 compress: false, 1545 scriptAtWrongIndex: false, 1546 }, 1547 { 1548 name: "hashType non-standard", 1549 inputs: []tstInput{ 1550 { 1551 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript), 1552 sigscriptGenerates: true, 1553 inputValidates: true, 1554 indexOutOfRange: false, 1555 }, 1556 }, 1557 hashType: 0x04, 1558 compress: false, 1559 scriptAtWrongIndex: false, 1560 }, 1561 { 1562 name: "invalid compression", 1563 inputs: []tstInput{ 1564 { 1565 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript), 1566 sigscriptGenerates: true, 1567 inputValidates: false, 1568 indexOutOfRange: false, 1569 }, 1570 }, 1571 hashType: SigHashAll, 1572 compress: true, 1573 scriptAtWrongIndex: false, 1574 }, 1575 { 1576 name: "short PkScript", 1577 inputs: []tstInput{ 1578 { 1579 txout: wire.NewTxOut(coinbaseVal, shortPkScript), 1580 sigscriptGenerates: false, 1581 indexOutOfRange: false, 1582 }, 1583 }, 1584 hashType: SigHashAll, 1585 compress: false, 1586 scriptAtWrongIndex: false, 1587 }, 1588 { 1589 name: "valid script at wrong index", 1590 inputs: []tstInput{ 1591 { 1592 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript), 1593 sigscriptGenerates: true, 1594 inputValidates: true, 1595 indexOutOfRange: false, 1596 }, 1597 { 1598 txout: wire.NewTxOut(coinbaseVal+fee, uncompressedPkScript), 1599 sigscriptGenerates: true, 1600 inputValidates: true, 1601 indexOutOfRange: false, 1602 }, 1603 }, 1604 hashType: SigHashAll, 1605 compress: false, 1606 scriptAtWrongIndex: true, 1607 }, 1608 { 1609 name: "index out of range", 1610 inputs: []tstInput{ 1611 { 1612 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript), 1613 sigscriptGenerates: true, 1614 inputValidates: true, 1615 indexOutOfRange: false, 1616 }, 1617 { 1618 txout: wire.NewTxOut(coinbaseVal+fee, uncompressedPkScript), 1619 sigscriptGenerates: true, 1620 inputValidates: true, 1621 indexOutOfRange: false, 1622 }, 1623 }, 1624 hashType: SigHashAll, 1625 compress: false, 1626 scriptAtWrongIndex: true, 1627 }, 1628 } 1629 1630 // Test the sigscript generation for valid and invalid inputs, all 1631 // hashTypes, and with and without compression. This test creates 1632 // sigscripts to spend fake coinbase inputs, as sigscripts cannot be 1633 // created for the MsgTxs in txTests, since they come from the blockchain 1634 // and we don't have the private keys. 1635 func TestSignatureScript(t *testing.T) { 1636 t.Parallel() 1637 1638 privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), privKeyD) 1639 1640 nexttest: 1641 for i := range sigScriptTests { 1642 tx := wire.NewMsgTx(wire.TxVersion) 1643 1644 output := wire.NewTxOut(500, []byte{OP_RETURN}) 1645 tx.AddTxOut(output) 1646 1647 for range sigScriptTests[i].inputs { 1648 txin := wire.NewTxIn(coinbaseOutPoint, nil, nil) 1649 tx.AddTxIn(txin) 1650 } 1651 1652 var script []byte 1653 var err error 1654 for j := range tx.TxIn { 1655 var idx int 1656 if sigScriptTests[i].inputs[j].indexOutOfRange { 1657 t.Errorf("at test %v", sigScriptTests[i].name) 1658 idx = len(sigScriptTests[i].inputs) 1659 } else { 1660 idx = j 1661 } 1662 script, err = SignatureScript(tx, idx, 1663 sigScriptTests[i].inputs[j].txout.PkScript, 1664 sigScriptTests[i].hashType, privKey, 1665 sigScriptTests[i].compress) 1666 1667 if (err == nil) != sigScriptTests[i].inputs[j].sigscriptGenerates { 1668 if err == nil { 1669 t.Errorf("passed test '%v' incorrectly", 1670 sigScriptTests[i].name) 1671 } else { 1672 t.Errorf("failed test '%v': %v", 1673 sigScriptTests[i].name, err) 1674 } 1675 continue nexttest 1676 } 1677 if !sigScriptTests[i].inputs[j].sigscriptGenerates { 1678 // done with this test 1679 continue nexttest 1680 } 1681 1682 tx.TxIn[j].SignatureScript = script 1683 } 1684 1685 // If testing using a correct sigscript but for an incorrect 1686 // index, use last input script for first input. Requires > 0 1687 // inputs for test. 1688 if sigScriptTests[i].scriptAtWrongIndex { 1689 tx.TxIn[0].SignatureScript = script 1690 sigScriptTests[i].inputs[0].inputValidates = false 1691 } 1692 1693 // Validate tx input scripts 1694 scriptFlags := ScriptBip16 | ScriptVerifyDERSignatures 1695 for j := range tx.TxIn { 1696 vm, err := NewEngine(sigScriptTests[i]. 1697 inputs[j].txout.PkScript, tx, j, scriptFlags, nil, nil, 0) 1698 if err != nil { 1699 t.Errorf("cannot create script vm for test %v: %v", 1700 sigScriptTests[i].name, err) 1701 continue nexttest 1702 } 1703 err = vm.Execute() 1704 if (err == nil) != sigScriptTests[i].inputs[j].inputValidates { 1705 if err == nil { 1706 t.Errorf("passed test '%v' validation incorrectly: %v", 1707 sigScriptTests[i].name, err) 1708 } else { 1709 t.Errorf("failed test '%v' validation: %v", 1710 sigScriptTests[i].name, err) 1711 } 1712 continue nexttest 1713 } 1714 } 1715 } 1716 }