summaryrefslogtreecommitdiff
path: root/bip-0341.mediawiki
diff options
context:
space:
mode:
Diffstat (limited to 'bip-0341.mediawiki')
-rw-r--r--bip-0341.mediawiki16
1 files changed, 7 insertions, 9 deletions
diff --git a/bip-0341.mediawiki b/bip-0341.mediawiki
index 6472430..564071f 100644
--- a/bip-0341.mediawiki
+++ b/bip-0341.mediawiki
@@ -59,7 +59,7 @@ 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-0340.mediawiki#design|BIP340]].
* 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<ref>'''Why is the first byte of the annex <code>0x50</code>?''' The <code>0x50</code> 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 oddness, each leaf version needs an even byte value and the immediately following odd byte value that are both not yet used in P2WPKH or P2WSH spending. To indicate the annex, only an "unpaired" available byte is necessary like <code>0x50</code>. This choice maximizes the available options for future script versions.</ref>, this last element is called ''annex'' ''a''<ref>'''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 <code>annex</code> in transactions, or it may lead to PERMANENT FUND LOSS.</ref> and is removed from the witness stack. The annex (or the lack of thereof) is always covered by the signature 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<ref>'''Why is the first byte of the annex <code>0x50</code>?''' The <code>0x50</code> 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 parity of the public key's Y coordinate, each leaf version needs an even byte value and the immediately following odd byte value that are both not yet used in P2WPKH or P2WSH spending. To indicate the annex, only an "unpaired" available byte is necessary like <code>0x50</code>. This choice maximizes the available options for future script versions.</ref>, this last element is called ''annex'' ''a''<ref>'''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 <code>annex</code> in transactions, or it may lead to PERMANENT FUND LOSS.</ref> and is removed from the witness stack. The annex (or the lack of thereof) is always covered by the signature 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'' (see the next subsection).
* If there are at least two witness elements left, script path spending is used:
@@ -168,8 +168,8 @@ Alice will not be able to notice the script path, but Mallory can unilaterally s
'''Computing the output script''' Once the spending conditions are split into an internal key <code>internal_pubkey</code> and a binary tree whose leaves are (leaf_version, script) tuples, the output script can be computed using the Python3 algorithms below. These algorithms take advantage of helper functions from the [bip-0340/referency.py BIP340 reference code] for integer conversion, point multiplication, and tagged hashes.
First, we define <code>taproot_tweak_pubkey</code> for 32-byte [[bip-0340.mediawiki|BIP340]] public key arrays.
-In addition to the tweaked public key byte array, the function returns a boolean indicating whether the public key represents the tweaked point or its negation.
-This will be required for spending the output with a script path.
+The function returns a bit indicating the tweaked public key's Y coordinate as well as the public key byte array.
+The parity bit will be required for spending the output with a script path.
In order to allow spending with the key path, we define <code>taproot_tweak_seckey</code> to compute the secret key for a tweaked public key.
For any byte string <code>h</code> it holds that <code>taproot_tweak_pubkey(pubkey_gen(seckey), h)[0] == pubkey_gen(taproot_tweak_seckey(seckey, h))</code>.
@@ -179,8 +179,7 @@ def taproot_tweak_pubkey(pubkey, h):
if t >= SECP256K1_ORDER:
raise ValueError
Q = point_add(lift_x_even_y(int_from_bytes(pubkey)), point_mul(G, t))
- is_negated = not has_even_y(Q)
- return bytes_from_int(x(Q)), is_negated
+ return 0 if has_even_y(Q) else 1, bytes_from_int(x(Q))
def taproot_tweak_seckey(seckey0, h):
P = point_mul(G, int_from_bytes(seckey0))
@@ -226,7 +225,7 @@ def taproot_output_script(internal_pubkey, script_tree):
To spend this output using script ''D'', the control block would contain the following data in this order:
- <control byte with leaf version and negation bit> <internal key p> <C> <E> <AB>
+ <control byte with leaf version and parity bit> <internal key p> <C> <E> <AB>
The TapTweak would then be computed as described [[bip-0341.mediawiki#script-validation-rules|above]] like so:
@@ -258,9 +257,8 @@ This function returns the witness stack necessary and a <code>sighash</code> fun
def taproot_sign_script(internal_pubkey, script_tree, script_num, inputs):
info, h = taproot_tree_helper(script_tree)
(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
+ output_pubkey_y_parity, _ = taproot_tweak_pubkey(internal_pubkey, h)
+ pubkey_data = bytes([output_pubkey_y_parity + leaf_version]) + internal_pubkey
return inputs + [script, pubkey_data + path]
</source>