diff options
Diffstat (limited to 'bip-tapscript.mediawiki')
-rw-r--r-- | bip-tapscript.mediawiki | 32 |
1 files changed, 13 insertions, 19 deletions
diff --git a/bip-tapscript.mediawiki b/bip-tapscript.mediawiki index ed729c7..3bbe8f3 100644 --- a/bip-tapscript.mediawiki +++ b/bip-tapscript.mediawiki @@ -92,7 +92,7 @@ The following rules apply to <code>OP_CHECKSIG</code>, <code>OP_CHECKSIGVERIFY</ ** If <code>n</code> is larger than 4 bytes, the script MUST fail and terminate immediately. * If the public key size is zero, the script MUST fail and terminate immediately. * If the public key size is 32 bytes, it is considered to be a public key as described in bip-schnorr: -** If the signature is not the empty vector, the signature is validated according to the bip-taproot signature validation rules against the public key and the tapscript transaction digest (to be defined hereinafter) as message. Validation failure MUST cause the script to fail and terminate immediately. +** If the signature is not the empty vector, the signature is validated against the public key (see the next subsection). * If the public key size is not zero and not 32 bytes, the public key is of an ''unknown public key type''<ref>'''Unknown public key types''' allow adding new signature validation rules through softforks. A softfork could add actual signature validation which either passes or makes the script fail and terminate immediately. This way, new <code>SIGHASH</code> modes can be added, as well as [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-December/016549.html NOINPUT-tagged public keys] and a public key constant which is replaced by the taproot internal key for signature validation.</ref> and no actual signature verification is applied. During script execution of signature opcodes they behave exactly as known public key types except that signature validation is considered to be successful. * If the script did not fail and terminate before this step, regardless of the public key type: ** If the signature is the empty vector: @@ -104,26 +104,20 @@ The following rules apply to <code>OP_CHECKSIG</code>, <code>OP_CHECKSIGVERIFY</ *** For <code>OP_CHECKSIG</code>, a 1-byte value <code>0x01</code> is pushed onto the stack. *** For <code>OP_CHECKSIGADD</code>, a <code>CScriptNum</code> with value of <code>n + 1</code> is pushed onto the stack. -===Transaction digest=== +===Signature validation=== -As the message for signature opcodes signature verification, transaction digest has the same definition as in bip-taproot, except the following: +To validate a signature ''sig'' with public key ''p'': +* Compute the tapscript message extension ''ext'', consisting of: +** ''tapleaf_hash'' (32): the tapleaf hash as defined in bip-taproot +** ''key_version'' (1): a constant value ''0x00'' representing the current version of public keys in the tapscript signature opcode execution. +** ''codesep_pos'' (4): the opcode position of the last executed <code>OP_CODESEPARATOR</code> before the currently executed signature opcode, with the value in little endian (or ''0xffffffff'' if none executed). The first opcode in a script has a position of 0. A multi-byte push opcode is counted as one opcode, regardless of the size of data being pushed. +* If the ''sig'' is 64 bytes long, return ''Verify(q, hash<sub>TapSigHash</sub>(0x00 || SigMsg(0x00, 1) || ext), sig)'', where ''Verify'' is defined in bip-schnorr. +* If the ''sig'' is 65 bytes long, return ''sig[64] ≠ 0x00 and Verify(q, hash<sub>TapSighash</sub>(0x00 || SigMsg(sig[64], 0) || ext), sig[0:64])''. +* Otherwise, fail. -The one-byte <code>spend_type</code> has a different value, specifically at bit 1: -* Bit 0 is set if an annex is present (the original witness stack has at least two witness elements, and the first byte of the last element is <code>0x50</code>). -* Bit 1 is set. -* The other bits are unset. - -As additional pieces of data, added at the end of the input to the ''hash<sub>TapSighash</sub>'' function: -* <code>tapleaf_hash</code> (32): the tapleaf hash as defined in bip-taproot -* <code>key_version</code> (1): a constant value <code>0x00</code> representing the current version of public keys in the tapscript signature opcode execution. -* <code>codeseparator_position</code> (4): the opcode position of the last executed <code>OP_CODESEPARATOR</code> before the currently executed signature opcode, with the value in little endian (or <code>0xffffffff</code> if none executed). The first opcode in a script has a position of 0. A multi-byte push opcode is counted as one opcode, regardless of the size of data being pushed. - -The total number of bytes hashed is at most ''247''<ref>'''What is the number of bytes hashed for the signature hash?''' The total size of the input to ''hash<sub>TapSighash</sub>'' (excluding the initial 64-byte hash tag) can be computed using the following formula: ''215 - is_anyonecanpay * 52 - is_none * 32 + has_annex * 32''.</ref>. - -In summary, the semantics of the [https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki BIP143] sighash types remain unchanged, except the following: -# The exceptions mentioned in bip-taproot. -# The digest commits to taproot-specific data <code>key_version</code>.<ref>'''Why does the transaction digest commit to the <code>key_version</code>?''' This is for future extensions that define unknown public key types, making sure signatures can't be moved from one key type to another.</ref> -# The digest commits to the executed script through the <code>tapleaf_hash</code> which includes the leaf version and script instead of <code>scriptCode</code>. This implies that this commitment is unaffected by <code>OP_CODESEPARATOR</code>. +In summary, the semantics of signature validation is identical to bip-taproot, except the following: +# The digest commits to tapscript-specific data ''key_version''.<ref>'''Why does the transaction digest commit to the ''key_version''?''' This is for future extensions that define unknown public key types, making sure signatures can't be moved from one key type to another.</ref> +# The digest commits to the executed script through the ''tapleaf_hash'' which includes the leaf version and script instead of ''scriptCode''. This implies that this commitment is unaffected by <code>OP_CODESEPARATOR</code>. # The digest commits to the opcode position of the last executed <code>OP_CODESEPARATOR</code>.<ref>'''Why does the transaction digest commit to the position of the last executed <code>OP_CODESEPARATOR</code>?''' This allows continuing to use <code>OP_CODESEPARATOR</code> to sign the executed path of the script. Because the <code>codeseparator_position</code> is the last input to the digest, the SHA256 midstate can be efficiently cached for multiple <code>OP_CODESEPARATOR</code>s in a single script. In contrast, the BIP143 handling of <code>OP_CODESEPARATOR</code> is to commit to the executed script only from the last executed <code>OP_CODESEPARATOR</code> onwards which requires unnecessary rehashing of the script. It should be noted that the one known <code>OP_CODESEPARATOR</code> use case of saving a second public key push in a script by sharing the first one between two code branches can be most likely expressed even cheaper by moving each branch into a separate taproot leaf.</ref> ===Resource limits=== |