diff --git a/bip-taproot.mediawiki b/bip-taproot.mediawiki index 6090a711..2b91da82 100644 --- a/bip-taproot.mediawiki +++ b/bip-taproot.mediawiki @@ -59,19 +59,19 @@ The following rules only apply when such an output is being spent. Any other out * Let ''q'' be the 32-byte array containing the witness program (the second push in the scriptPubKey) which represents a public key according to bip-schnorr. * Fail if the witness stack has 0 elements. -* If there are at least two witness elements, and the first byte of the last element is 0x50'''Why is the first byte of the annex 0x50?''' Like the 0xc0 constant, 0x50 is chosen as it could not be confused with a valid P2WPKH or P2WSH spending. As the control block's initial byte's lowest bit is used to indicate the public key's Y squareness, each script version needs two subsequence byte values that are both not yet used in P2WPKH or P2WSH spending. To indicate the annex, only an "unpaired" available byte is necessary like 0x50. This choice maximizes the available options for future script versions., this last element is called ''annex'' ''a'''''What is the purpose of the annex?''' The annex is a reserved space for future extensions, such as indicating the validation costs of computationally expensive new opcodes in a way that is recognizable without knowing the outputs being spent. Until the meaning of this field is defined by another softfork, users SHOULD NOT include annex in transactions, or it may lead to PERMANENT FUND LOSS. and is removed from the witness stack. The annex (or the lack of thereof) is always covered by the transaction digest and contributes to transaction weight, but is otherwise ignored during taproot validation. +* If there are at least two witness elements, and the first byte of the last element is 0x50'''Why is the first byte of the annex 0x50?''' Like the choice to always set the top two bits of the control block's first byte the, 0x50 is chosen as it could not be confused with a valid P2WPKH or P2WSH spending. As the control block's initial byte's lowest bit is used to indicate the public key's Y squareness, each leaf version needs two subsequent byte values that are both not yet used in P2WPKH or P2WSH spending. To indicate the annex, only an "unpaired" available byte is necessary like 0x50. This choice maximizes the available options for future script versions., this last element is called ''annex'' ''a'''''What is the purpose of the annex?''' The annex is a reserved space for future extensions, such as indicating the validation costs of computationally expensive new opcodes in a way that is recognizable without knowing the scriptPubKey of the output being spent. Until the meaning of this field is defined by another softfork, users SHOULD NOT include annex in transactions, or it may lead to PERMANENT FUND LOSS. and is removed from the witness stack. The annex (or the lack of thereof) is always covered by the transaction digest and contributes to transaction weight, but is otherwise ignored during taproot validation. * If there is exactly one element left in the witness stack, key path spending is used: ** The single witness stack element is interpreted as the signature and must be valid (see the next section) for the public key ''q'' and taproot transaction digest (to be defined hereinafter) as message. Fail if it is not. Otherwise pass. * If there are at least two witness elements left, script path spending is used: ** Call the second-to-last stack element ''s'', the script. ** The last stack element is called the control block ''c'', and must have length ''33 + 32m'', for a value of ''m'' that is an integer between 0 and 128'''Why is the Merkle path length limited to 128?''' The optimally space-efficient Merkle tree can be constructed based on the probabilities of the scripts in the leaves, using the Huffman algorithm. This algorithm will construct branches with lengths approximately equal to ''log2(1/probability)'', but to have branches longer than 128 you would need to have scripts with an execution chance below 1 in ''2128''. As that is our security bound, scripts that truly have such a low chance can probably be removed entirely., inclusive. Fail if it does not have such a length. ** Let ''p = c[1:33]'' and let ''P = point(p)'' where ''point'' and ''[:]'' are defined as in bip-schnorr. Fail if this point is not on the curve. -** Let ''l = c[0] & 0xfe'', the leaf version'''What is the purpose of the first byte of the control block?''' The first byte of the control block has three distinct functions: +** Call ''(c[0] ^ 0xc0) >> 1'' the leaf version'''What is the purpose of the first byte of the control block?''' The first byte of the control block has three distinct functions: * The low bit is used to denote whether the point represented by public key ''q'' is negated before verifying the taproot tweak.'''Why is it necessary to reveal a bit to indicate if the point represented by the output public key is negated in a script path spend?''' The ''point'' function (defined in bip-schnorr) always constructs a point with a square Y coordinate, but because ''Q'' is constructed by adding the taproot tweak to the internal public key ''P'', it cannot easily be guaranteed that ''Q'' in fact has such a Y coordinate. Therefore, before verifying the taproot tweak the original point is restored by negating if necessary. We can not ignore the Y coordinate because it would prevent batch verification. Trying out multiple internal keys until there's such a ''Q'' is possible but undesirable and unnecessary since this information about the Y coordinate only consumes an unused bit. -* By keeping the top two bits set to true, it can be guaranteed that scripts can be recognized without knowledge of the UTXO being spent, simplifying analysis. This is because such values cannot occur as first byte of the final stack element in either P2WPKH or P2WSH spends. -* The remaining five bits are used for introducing new script versions that are not observable unless actually executed. +* Some types of static analysis may benefit from the ability to analyse spends without access to the output being spent. We achieve that for leaf versions 0 to 31 via flipping the top two bits of the first byte of the control block and observing that this ensures they can be distinguished from P2WPKH and P2WSH spends -- as for P2WPKH, the last witness stack item is a public key, whose first byte is either 0x02 or 0x03, and for P2WSH, the last item is a script, and scripts must contain valid opcodes, but no value ≥ 0xc0 is a valid opcode. +* The remaining five bits encode the leaf version, which can be used for introducing new script versions that are not observable unless actually executed. . -** Let ''k0 = hashTapLeaf(l || compact_size(size of s) || s)''; also call it the ''tapleaf hash''. +** Let ''k0 = hashTapLeaf(c[0] & 0xfe || compact_size(size of s) || s)''; also call it the ''tapleaf hash''. ** For ''j'' in ''[0,1,...,m-1]'': *** Let ''ej = c[33+32j:65+32j]''. *** Let ''kj+1 depend on whether ''kj < ej'' (lexicographically)'''Why are child elements sorted before hashing in the Merkle tree?''' By doing so, it is not necessary to reveal the left/right directions along with the hashes in revealed Merkle branches. This is possible because we do not actually care about the position of specific scripts in the tree; only that they are actually committed to.: @@ -81,7 +81,7 @@ The following rules only apply when such an output is being spent. Any other out ** If ''t ≥ 0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141'' (order of secp256k1), fail. ** Let ''Q = point(q) if (c[0] & 1) = 1 and -point(q) otherwise''. Fail if this point is not on the curve. ** If ''Q ≠ P + int(t)G'', fail. -** Execute the script, according to the applicable script rules'''What are the applicable script rules in script path spends?''' Bip-tapscript specifies validity rules that apply if the leaf version is ''0xc0'', but future proposals can introduce rules for other leaf versions., using the witness stack elements excluding the script ''s'', the control block ''c'', and the annex ''a'' if present, as initial stack. +** Execute the script, according to the applicable script rules'''What are the applicable script rules in script path spends?''' Bip-tapscript specifies validity rules that apply if the leaf version is 0, but future proposals can introduce rules for other leaf versions., using the witness stack elements excluding the script ''s'', the control block ''c'', and the annex ''a'' if present, as initial stack. ''q'' is referred to as ''taproot output key'' and ''p'' as ''taproot internal key''. @@ -209,7 +209,7 @@ The following function, taproot_output_script, returns a byte array def taproot_tree_helper(script_tree): if isinstance(script_tree, tuple): leaf_version, script = script_tree - h = tagged_hash("TapLeaf", bytes([leaf_version]) + ser_script(script)) + h = tagged_hash("TapLeaf", bytes([(2 * leaf_version) ^ 0xc0]) + ser_script(script)) return ([((leaf_version, script), bytes())], h) left, left_h = taproot_tree_helper(script_tree[0]) right, right_h = taproot_tree_helper(script_tree[1]) @@ -221,8 +221,8 @@ def taproot_tree_helper(script_tree): def taproot_output_script(internal_pubkey, script_tree): """Given a internal public key and a tree of scripts, compute the output script. script_tree is either: - - a (leaf_version, script) tuple (leaf_version is 0xc0 for bip-tapscript scripts) - - a list of two elements, each with the same structure as script_tree itself + - a (leaf_version, script) tuple (leaf_version is 0 for bip-tapscript scripts) + - a list of two elements, each with the same structure as script_tree itself""" - None """ if script_tree is None: @@ -271,7 +271,7 @@ def taproot_sign_script(internal_pubkey, script_tree, script_num, inputs): (leaf_version, script), path = info[script_num] _, is_negated = taproot_tweak_pubkey(internal_pubkey, h) output_pubkey_tag = 0 if is_negated else 1 - pubkey_data = bytes([output_pubkey_tag + leaf_version]) + internal_pubkey + pubkey_data = bytes([output_pubkey_tag ^ (2 * leaf_version) ^ 0xc0]) + internal_pubkey return inputs + [script, pubkey_data + path] diff --git a/bip-tapscript.mediawiki b/bip-tapscript.mediawiki index 759d0d85..120a6178 100644 --- a/bip-tapscript.mediawiki +++ b/bip-tapscript.mediawiki @@ -51,7 +51,7 @@ The rules below only apply when validating a transaction input for which all of * The transaction input is a '''segregated witness spend''' (i.e., the scriptPubKey contains a witness program as defined in [https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki BIP141]). * It is a '''taproot spend''' as defined in bip-taproot (i.e., the witness version is 1, the witness program is 32 bytes, and it is not P2SH wrapped). * It is a '''script path spend''' as defined in bip-taproot (i.e., after removing the optional annex from the witness stack, two or more stack elements remain). -* The leaf version is ''0xc0'' (i.e. the first byte of the last witness element after removing the optional annex is ''0xc0'' or ''0xc1'')'''How is the ''0xc0'' constant chosen?''' Following the guidelines in bip-taproot, by choosing a value having the two top bits set, tapscript spends are identifiable even without access to the UTXO being spent., marking it as a '''tapscript spend'''. +* The leaf version is 0 (i.e. the first byte of the last witness element after removing the optional annex is ''0xc0'' or ''0xc1''), marking it as a '''tapscript spend'''. Validation of such inputs must be equivalent to performing the following steps in the specified order. # If the input is invalid due to BIP141 or bip-taproot, fail.