mirror of
https://github.com/bitcoin/bips.git
synced 2026-03-23 16:05:41 +00:00
Abstract out common signature message calculation
This commit is contained in:
@@ -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===
|
||||
|
||||
Reference in New Issue
Block a user