This document is a modified copy of BIP-0341 which describes the signature hash used for Taproot outputs in Elements. Items which differ from BIP-0341 are indicated with NEW.
In addition to the changes in this document, the four tagged hash tags TapLeaf, TapBranch, TapTweak and TapSighash in BIPs 341 and 342 are suffixed with /elements.
The function SigMsg(hash_type, ext_flag) computes the message being signed as a byte array. It is implicitly also a function of the spending transaction and the outputs it spends, but these are not listed to keep notation simple.
The parameter hash_type is an 8-bit unsigned value. The SIGHASH
encodings from the legacy script system are reused, including SIGHASH_ALL
, SIGHASH_NONE
, SIGHASH_SINGLE
, and SIGHASH_ANYONECANPAY
, plus the default hash_type value 0x00 which results in signing over the whole transaction just as for SIGHASH_ALL
. The following restrictions apply, which cause validation failure if violated:
- Using any undefined hash_type (not 0x00, 0x01, 0x02, 0x03, 0x81, 0x82, or 0x83).
- Using
SIGHASH_SINGLE
without a "corresponding output" (an output with the same index as the input being verified).
NEW The epoch field prepended before signature hash is completely dropped. If there are new updates to the taproot signature hashes in elements, they will use new tagged hashes instead of incrementing epochs
The parameter ext_flag is an integer in range 0-127, and is used for indicating (in the message) that extensions are added at the end of the message.
If the parameters take acceptable values, the message is the concatenation of the following data, in order (with byte size of each item listed in parentheses). Numerical values in 2, 4, or 8-byte are encoded in little-endian.
- NEW Blockchain data: (Rationale: Signatures cannot be reused across different Elements instances even if pubkeys are reused.)
- genesis_block (32): the hash of the blockchain's genesis block
- genesis_block (32): the genesis hash again
- Control:
- hash_type (1).
- Transaction data:
- nVersion (4): the nVersion of the transaction.
- nLockTime (4): the nLockTime of the transaction.
- If the hash_type & 0x80 does not equal
SIGHASH_ANYONECANPAY
:- NEW sha_outpoint_flags (32): the SHA256 of the serialization of the concatenation of one byte per input of the input's outpoint flags shifted right by 24 bits. (The byte for an pegin input would be 0x40. The byte for an issuance input would be 0x80. The byte for both a pegin and issuance would be 0xc0.)
- sha_prevouts (32): the SHA256 of the serialization of all input outpoints. Each prevout output index is the masked version excluding outpoint flags. As mentioned above, for pegin inputs these will be prevouts on the parent chain.
- NEW sha_asset_amounts (32): the SHA256 of the serialization of nAsset||nValue for each output. As mentioned above, for pegin inputs an explicit value (from the parent chain) and asset (the peg asset) will be used.
- sha_scriptpubkeys (32): the SHA256 of the serialization of all spent output scriptPubKeys.
- sha_sequences (32): the SHA256 of the serialization of all input nSequence.
- NEW sha_issuances (32): the SHA256 of the serialization of the concatenation of asset issuance data for inputs with an issuance or 0x00 for inputs with no issuance. (This matches the Segwit v0 encoding of this hash.)
- NEW sha_issuance_rangeproofs (32): the SHA256 of the serialization of the concatenation of issuanceAmountRangeproof||inflationKeysRangeproof for all inputs, where each field is encoded as 0x00 if absent (either if there is no issuance, or if there is an explicit issuance)
- If hash_type & 3 does not equal
SIGHASH_NONE
orSIGHASH_SINGLE
:- sha_outputs (32): the SHA256 of the serialization of all outputs in
CTxOut
format. - NEW sha_output_witnesses (32): the SHA256 of the serialization of all output witnesses (rangeproof and surjection proof) in
CTxOutWitness
format.
- sha_outputs (32): the SHA256 of the serialization of all outputs in
- Data about this input:
- spend_type (1): equal to (ext_flag * 2) + annex_present, where annex_present is 0 if no annex is present, or 1 otherwise (the original witness stack has two or more witness elements, and the first byte of the last element is 0x50)
- If hash_type & 0x80 equals
SIGHASH_ANYONECANPAY
:- NEW outpoint_flag (1): the input's outpoint flags shifted right by 24 bits. (Compare sha_outpoint_flags above.)
- outpoint (36): the
COutPoint
of this input (32-byte hash + 4-byte little-endian) where the output index excludes the outpoint flags. - NEW nAsset (33): (possibly confidential) assetID of the previous output spent by this input
- NEW nValue (9-33): (possibly confidential) amount of the previous output spent by this input
- scriptPubKey (35): scriptPubKey of the previous output spent by this input, serialized as script inside
CTxOut
. Its size is always 35 bytes. - nSequence (4): nSequence of this input.
- NEW asset_issuance (1-130): if outpoint_flag & 0x80 == 0x80: asset issuance data for this input, or 0x00 otherwise
- NEW sha_single_issuance_rangeproofs (0-32): if outpoint_flag & 0x80 == 0x80: the SHA256 of the serialization of the concatenation of issuanceAmountRangeproof||inflationKeysRangeproof for this input, where each field is encoded as 0x00 if absent
- If hash_type & 0x80 does not equal
SIGHASH_ANYONECANPAY
:- input_index (4): index of this input in the transaction input vector. Index of the first input is 0.
- If an annex is present (the lowest bit of spend_type is set):
- sha_annex (32): the SHA256 of (compact_size(size of annex) || annex), where annex includes the mandatory 0x50 prefix.
- Data about this output:
- If hash_type & 3 equals
SIGHASH_SINGLE
:- sha_single_output (32): the SHA256 of the corresponding output in
CTxOut
format. - NEW sha_single_output_witness (32): the SHA256 of the serialization of the corresponding output witnesses (rangeproof and surjection proof) in
CTxOutWitness
format.
- sha_single_output (32): the SHA256 of the corresponding output in
- If hash_type & 3 equals
ANYONECANPAY
sighashes, 366 bytes for non-ANYONECANPAY
sighashes, and both numbers are reduced by 64 bytes for SIGHASH_NONE
sighashes, and increased by 32 bytes if an annex is present. Note that this does not include the size of sub-hashes such as sha_prevouts, which may be cached across signatures of the same transaction.