|
37 | 37 | #define TXIO_SHA_OUTPUT_WITNESSES_D (TXIO_SHA_OUTPUTS | TXIO_SHA256_D) |
38 | 38 | /* ... end of segwit cached data */ |
39 | 39 |
|
| 40 | +static const unsigned char zero_hash[SHA256_LEN]; |
| 41 | + |
40 | 42 | /* SHA256(TapSighash) */ |
41 | 43 | static const unsigned char TAPSIGHASH_SHA256[SHA256_LEN] = { |
42 | 44 | 0xf4, 0x0a, 0x48, 0xdf, 0x4b, 0x2a, 0x70, 0xc8, 0xb4, 0x92, 0x4b, 0xf2, 0x65, 0x46, 0x61, 0xed, |
@@ -555,6 +557,107 @@ static void txio_hash_tapleaf_hash(cursor_io *io, |
555 | 557 | } |
556 | 558 | } |
557 | 559 |
|
| 560 | +/* BIP 143 */ |
| 561 | +static int bip143_signature_hash( |
| 562 | + const struct wally_tx *tx, size_t index, |
| 563 | + const struct wally_map *values, |
| 564 | + const unsigned char *scriptcode, size_t scriptcode_len, |
| 565 | + uint32_t sighash, |
| 566 | + struct wally_map *cache, |
| 567 | + bool is_elements, |
| 568 | + unsigned char *bytes_out, size_t len) |
| 569 | +{ |
| 570 | + const struct wally_tx_input *txin = tx ? tx->inputs + index : NULL; |
| 571 | + const struct wally_tx_output *txout = tx ? tx->outputs + index : NULL; |
| 572 | + const bool sh_anyonecanpay = sighash & WALLY_SIGHASH_ANYONECANPAY; |
| 573 | +#ifdef BUILD_ELEMENTS |
| 574 | + const bool sh_rangeproof = sighash & WALLY_SIGHASH_RANGEPROOF; |
| 575 | +#endif |
| 576 | + const bool sh_none = (sighash & WALLY_SIGHASH_MASK) == WALLY_SIGHASH_NONE; |
| 577 | + const bool sh_single = (sighash & WALLY_SIGHASH_MASK) == WALLY_SIGHASH_SINGLE; |
| 578 | + cursor_io io; |
| 579 | + |
| 580 | + /* Note that scriptcode can be empty, so we don't check it here */ |
| 581 | + if (!tx || !values || BYTES_INVALID(scriptcode, scriptcode_len) || |
| 582 | + sighash & 0xffffff00) |
| 583 | + return WALLY_EINVAL; |
| 584 | + |
| 585 | + { |
| 586 | + /* Validate input values: We must have the value at 'index'. */ |
| 587 | + bool (*value_len_fn)(size_t) = is_elements ? value_len_ok : satoshi_len_ok; |
| 588 | + if (!map_has_one(values, index, value_len_fn)) |
| 589 | + return WALLY_EINVAL; |
| 590 | + } |
| 591 | + |
| 592 | + /* Init */ |
| 593 | + io.cache = cache; |
| 594 | + io.cursor = bytes_out; |
| 595 | + io.max = len; |
| 596 | + sha256_init(&io.ctx); |
| 597 | + /* Tx data */ |
| 598 | + hash_le32(&io.ctx, tx->version); |
| 599 | + if (sh_anyonecanpay) |
| 600 | + hash_bytes(&io.ctx, zero_hash, sizeof(zero_hash)); |
| 601 | + else |
| 602 | + txio_hash_sha_prevouts(&io, tx, TXIO_SHA_PREVOUTS_D); |
| 603 | + if (sh_anyonecanpay || sh_single || sh_none) |
| 604 | + hash_bytes(&io.ctx, zero_hash, sizeof(zero_hash)); |
| 605 | + else |
| 606 | + txio_hash_sha_sequences(&io, tx, TXIO_SHA_SEQUENCES_D); |
| 607 | +#ifdef BUILD_ELEMENTS |
| 608 | + if (is_elements) { |
| 609 | + if (sh_anyonecanpay) |
| 610 | + hash_bytes(&io.ctx, zero_hash, sizeof(zero_hash)); |
| 611 | + else |
| 612 | + txio_hash_sha_issuances(&io, tx, TXIO_SHA_ISSUANCES_D); |
| 613 | + } |
| 614 | +#endif |
| 615 | + /* Input data */ |
| 616 | + txio_hash_outpoint(&io, txin); |
| 617 | +#ifdef BUILD_ELEMENTS |
| 618 | + if (is_elements) |
| 619 | + txio_hash_input_elements(&io, tx, index, NULL, NULL, values, |
| 620 | + scriptcode, scriptcode_len, WALLY_SIGTYPE_SW_V0); |
| 621 | + else |
| 622 | +#endif |
| 623 | + txio_hash_input(&io, tx, index, NULL, values, |
| 624 | + scriptcode, scriptcode_len, WALLY_SIGTYPE_SW_V0); |
| 625 | + |
| 626 | + /* Output data */ |
| 627 | + if (sh_none || (sh_single && index >= tx->num_outputs)) |
| 628 | + hash_bytes(&io.ctx, zero_hash, sizeof(zero_hash)); |
| 629 | + else if (sh_single) { |
| 630 | +#ifdef BUILD_ELEMENTS |
| 631 | + if (is_elements) |
| 632 | + txio_hash_sha_single_output_elements(&io, txout, TXIO_UNCACHED_D); |
| 633 | + else |
| 634 | +#endif |
| 635 | + txio_hash_sha_single_output(&io, txout, TXIO_UNCACHED_D); |
| 636 | + } else { |
| 637 | +#ifdef BUILD_ELEMENTS |
| 638 | + if (is_elements) |
| 639 | + txio_hash_sha_outputs_elements(&io, tx, TXIO_SHA_OUTPUTS_D); |
| 640 | + else |
| 641 | +#endif |
| 642 | + txio_hash_sha_outputs(&io, tx, TXIO_SHA_OUTPUTS_D); |
| 643 | + } |
| 644 | + |
| 645 | +#ifdef BUILD_ELEMENTS |
| 646 | + if (sh_rangeproof) { |
| 647 | + if (sh_none || (sh_single && index >= tx->num_outputs)) |
| 648 | + hash_bytes(&io.ctx, zero_hash, sizeof(zero_hash)); |
| 649 | + else if (sh_single) |
| 650 | + txio_hash_sha_single_output_witness(&io, txout, TXIO_UNCACHED_D); |
| 651 | + else |
| 652 | + txio_hash_sha_output_witnesses(&io, tx, TXIO_SHA_OUTPUT_WITNESSES_D); |
| 653 | + } |
| 654 | +#endif |
| 655 | + |
| 656 | + hash_le32(&io.ctx, tx->locktime); |
| 657 | + hash_le32(&io.ctx, sighash); |
| 658 | + return txio_done(&io, TXIO_SHA256_D); |
| 659 | +} |
| 660 | + |
558 | 661 | /* BIP 341 */ |
559 | 662 | static void txio_bip341_init(cursor_io *io, |
560 | 663 | const unsigned char *genesis_blockhash, size_t genesis_blockhash_len) |
@@ -612,18 +715,12 @@ static int bip341_signature_hash( |
612 | 715 | const bool sh_anyprevout_anyscript = bip341_is_input_hash_type(sighash, WALLY_SIGHASH_ANYPREVOUTANYSCRIPT); |
613 | 716 | cursor_io io; |
614 | 717 |
|
615 | | - if (!tx || index >= tx->num_inputs || |
616 | | - !values || |
617 | | - BYTES_INVALID(tapleaf_script, tapleaf_script_len) || |
618 | | - key_version > 1 || |
619 | | - codesep_position != WALLY_NO_CODESEPARATOR || /* TODO: Add support */ |
620 | | - BYTES_INVALID(annex, annex_len) || (annex && *annex != 0x50) || |
621 | | - BYTES_INVALID_N(genesis_blockhash, genesis_blockhash_len, SHA256_LEN) || |
622 | | - !bytes_out || len != SHA256_LEN) |
623 | | - return WALLY_EINVAL; |
| 718 | + if (index >= tx->num_inputs || (annex && *annex != 0x50)) |
| 719 | + return WALLY_EINVAL; |
624 | 720 |
|
625 | 721 | if (is_elements) { |
626 | | - if (!genesis_blockhash) |
| 722 | + if (!genesis_blockhash || |
| 723 | + mem_is_zero(genesis_blockhash, genesis_blockhash_len)) |
627 | 724 | return WALLY_EINVAL; |
628 | 725 | } else { |
629 | 726 | genesis_blockhash = NULL; |
@@ -653,30 +750,6 @@ static int bip341_signature_hash( |
653 | 750 | return WALLY_EINVAL; |
654 | 751 | } |
655 | 752 |
|
656 | | - switch (sighash) { |
657 | | - case WALLY_SIGHASH_DEFAULT: |
658 | | - case WALLY_SIGHASH_ALL: |
659 | | - case WALLY_SIGHASH_NONE: |
660 | | - case WALLY_SIGHASH_SINGLE: |
661 | | - case WALLY_SIGHASH_ALL | WALLY_SIGHASH_ANYONECANPAY: |
662 | | - case WALLY_SIGHASH_NONE | WALLY_SIGHASH_ANYONECANPAY: |
663 | | - case WALLY_SIGHASH_SINGLE | WALLY_SIGHASH_ANYONECANPAY: |
664 | | - break; /* Always valid */ |
665 | | - case WALLY_SIGHASH_ALL | WALLY_SIGHASH_ANYPREVOUT: |
666 | | - case WALLY_SIGHASH_NONE | WALLY_SIGHASH_ANYPREVOUT: |
667 | | - case WALLY_SIGHASH_SINGLE | WALLY_SIGHASH_ANYPREVOUT: |
668 | | - case WALLY_SIGHASH_ALL | WALLY_SIGHASH_ANYPREVOUT | WALLY_SIGHASH_ANYONECANPAY: |
669 | | - case WALLY_SIGHASH_NONE | WALLY_SIGHASH_ANYPREVOUT | WALLY_SIGHASH_ANYONECANPAY: |
670 | | - case WALLY_SIGHASH_SINGLE | WALLY_SIGHASH_ANYPREVOUT | WALLY_SIGHASH_ANYONECANPAY: |
671 | | - if (key_version != 1) |
672 | | - return WALLY_EINVAL; /* Only valid for key_version 1 */ |
673 | | - if (is_elements) |
674 | | - return WALLY_ERROR; /* Elements: unsure of Activation status/no ELIP */ |
675 | | - break; |
676 | | - default: |
677 | | - return WALLY_EINVAL; /* Unknown sighash type */ |
678 | | - } |
679 | | - |
680 | 753 | /* Init */ |
681 | 754 | io.cache = cache; |
682 | 755 | io.cursor = bytes_out; |
@@ -782,15 +855,60 @@ int wally_tx_get_input_signature_hash( |
782 | 855 | uint32_t sighash_type = flags & WALLY_SIGTYPE_MASK; |
783 | 856 | int ret = WALLY_EINVAL; |
784 | 857 |
|
785 | | - if (!flags || (flags & ~SIGTYPE_ALL)) |
| 858 | + if (!tx || !tx->num_inputs || !tx->num_outputs || !values || |
| 859 | + BYTES_INVALID(tapleaf_script, tapleaf_script_len) || |
| 860 | + key_version > 1 || |
| 861 | + codesep_position != WALLY_NO_CODESEPARATOR || /* TODO: Add support */ |
| 862 | + BYTES_INVALID(annex, annex_len) || |
| 863 | + BYTES_INVALID_N(genesis_blockhash, genesis_blockhash_len, SHA256_LEN) || |
| 864 | + !flags || (flags & ~SIGTYPE_ALL) || !bytes_out || len != SHA256_LEN) |
786 | 865 | return WALLY_EINVAL; |
787 | 866 |
|
788 | 867 | #ifdef BUILD_ELEMENTS |
789 | 868 | if ((ret = wally_tx_is_elements(tx, &is_elements)) != WALLY_OK) |
790 | 869 | return ret; |
791 | 870 | #endif |
792 | 871 |
|
793 | | - /* FIXME: Support segwit/pre-segwit hashing */ |
| 872 | + switch (sighash) { |
| 873 | + case WALLY_SIGHASH_DEFAULT: |
| 874 | +#if 0 |
| 875 | + /* TODO: The previous impl allows a sighash of 0 for |
| 876 | + * pre-segwit/segwit v0 txs. We should probably disallow this. |
| 877 | + */ |
| 878 | + if (sighash_type != WALLY_SIGTYPE_SW_V1) |
| 879 | + return WALLY_EINVAL; /* Only valid for taproot */ |
| 880 | + break; |
| 881 | +#endif |
| 882 | + case WALLY_SIGHASH_ALL: |
| 883 | + case WALLY_SIGHASH_NONE: |
| 884 | + case WALLY_SIGHASH_SINGLE: |
| 885 | + case WALLY_SIGHASH_ALL | WALLY_SIGHASH_ANYONECANPAY: |
| 886 | + case WALLY_SIGHASH_NONE | WALLY_SIGHASH_ANYONECANPAY: |
| 887 | + case WALLY_SIGHASH_SINGLE | WALLY_SIGHASH_ANYONECANPAY: |
| 888 | + break; /* Always valid */ |
| 889 | + case WALLY_SIGHASH_ALL | WALLY_SIGHASH_ANYPREVOUT: |
| 890 | + case WALLY_SIGHASH_NONE | WALLY_SIGHASH_ANYPREVOUT: |
| 891 | + case WALLY_SIGHASH_SINGLE | WALLY_SIGHASH_ANYPREVOUT: |
| 892 | + case WALLY_SIGHASH_ALL | WALLY_SIGHASH_ANYPREVOUT | WALLY_SIGHASH_ANYONECANPAY: |
| 893 | + case WALLY_SIGHASH_NONE | WALLY_SIGHASH_ANYPREVOUT | WALLY_SIGHASH_ANYONECANPAY: |
| 894 | + case WALLY_SIGHASH_SINGLE | WALLY_SIGHASH_ANYPREVOUT | WALLY_SIGHASH_ANYONECANPAY: |
| 895 | + if (sighash_type != WALLY_SIGTYPE_SW_V1 || key_version != 1) |
| 896 | + return WALLY_EINVAL; /* Only valid for taproot key version 1 */ |
| 897 | + if (is_elements) { |
| 898 | + /* Activation status unclear and no ELIP: disallow for now */ |
| 899 | + return WALLY_ERROR; |
| 900 | + } |
| 901 | + break; |
| 902 | + default: |
| 903 | + return WALLY_EINVAL; /* Unknown sighash type */ |
| 904 | + } |
| 905 | + |
| 906 | + /* FIXME: Support pre-segwit hashing */ |
| 907 | + if (sighash_type == WALLY_SIGTYPE_SW_V0) |
| 908 | + return bip143_signature_hash(tx, index, values, |
| 909 | + tapleaf_script, tapleaf_script_len, |
| 910 | + sighash, cache, is_elements, |
| 911 | + bytes_out, len); |
794 | 912 | if (sighash_type == WALLY_SIGTYPE_SW_V1) |
795 | 913 | return bip341_signature_hash(tx, index, scripts, assets, values, |
796 | 914 | tapleaf_script, tapleaf_script_len, |
|
0 commit comments