Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BIP-0341: Replace notion of is_negated with parity bit #203

Merged
merged 1 commit into from
Apr 7, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 7 additions & 9 deletions bip-0341.mediawiki
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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>.

Expand All @@ -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))
Expand Down Expand Up @@ -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:

Expand Down Expand Up @@ -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>

Expand Down