Difference between revisions of "OP CHECKSIG"
Line 1: | Line 1: | ||
=DISCLAIMER= | =DISCLAIMER= | ||
− | This article | + | This article references the article at https://en.bitcoin.it/w/index.php?title=OP_CHECKSIG and the checking for correctness and editing is in progress. |
− | + | 23 Oct 2019 | |
− | Expected review by: | + | Expected review by: 6 Nov 2019 |
− | '''OP_CHECKSIG''' is an opcode | + | '''OP_CHECKSIG''' is an opcode that verifies an [[Digital Signatures (ECDSA) | ECDSA signature]]. It takes two inputs from the stack, a public key (on top of the stack) and an ECDSA signature in its DER_CANONISED format concatenated with sighash flags. It outputs true or false on the stack. |
− | |||
− | |||
− | |||
== Parameters == | == Parameters == | ||
− | In addition to the stack parameters | + | In addition to the stack parameters, OP_CHECKSIG needs to know the current transaction, the index of the transaction input in which the signature is checked, the scriptPubKey corresponding to the input, and the value the scriptPubKey represents. |
== How it works == | == How it works == | ||
− | + | In short, OP_CHECKSIG calls a function called "sighash" which produces a hash value of the serialised transaction. The hash value is the message on which the signature is verified. | |
+ | |||
[[File:Bitcoin_OpCheckSig_InDetail.png|thumb|right|Signature verification process of the default procedure]] | [[File:Bitcoin_OpCheckSig_InDetail.png|thumb|right|Signature verification process of the default procedure]] | ||
# the public key and the signature are popped from the stack, in that order. Signature format is [<DER signature> <1 byte hash-type>]. Hashtype value is last byte of the sig. | # the public key and the signature are popped from the stack, in that order. Signature format is [<DER signature> <1 byte hash-type>]. Hashtype value is last byte of the sig. | ||
− | # A new subScript is created from | + | # A new subScript is created from the scriptPubKey. The script from the immediately after the most recently parsed OP_CODESEPARATOR to the end of the scriptPub is the subScript. If there is no OP_CODESEPARATOR the entire scriptPubKey becomes the subScript. |
− | # Any occurrences of sig are deleted from subScript, if present (it is ''not standard'' to have a signature in | + | # Any occurrences of sig are deleted from subScript, if present. (it is ''not standard'' to have a signature in a locking script (scriptPubKey) of a transaction.) |
− | # Any remaining OP_CODESEPARATORS are removed from subScript | + | # Any remaining OP_CODESEPARATORS are removed from subScript. |
− | # The hashtype is removed from the last byte of the sig and stored | + | # The hashtype is removed from the last byte of the sig and stored. |
− | # A copy is made of the current transaction (hereby referred to txCopy) | + | # A copy is made of the current transaction (hereby referred to txCopy). |
− | # The scripts for all transaction inputs in txCopy are set to empty scripts (exactly 1 byte 0x00) | + | # The scripts for all transaction inputs in txCopy are set to empty scripts (exactly 1 byte 0x00). |
# The script for the current transaction input in txCopy is set to subScript (lead in by its length as a var-integer encoded!) | # The script for the current transaction input in txCopy is set to subScript (lead in by its length as a var-integer encoded!) | ||
Revision as of 16:35, 23 October 2019
DISCLAIMER
This article references the article at https://en.bitcoin.it/w/index.php?title=OP_CHECKSIG and the checking for correctness and editing is in progress. 23 Oct 2019 Expected review by: 6 Nov 2019
OP_CHECKSIG is an opcode that verifies an ECDSA signature. It takes two inputs from the stack, a public key (on top of the stack) and an ECDSA signature in its DER_CANONISED format concatenated with sighash flags. It outputs true or false on the stack.
Parameters
In addition to the stack parameters, OP_CHECKSIG needs to know the current transaction, the index of the transaction input in which the signature is checked, the scriptPubKey corresponding to the input, and the value the scriptPubKey represents.
How it works
In short, OP_CHECKSIG calls a function called "sighash" which produces a hash value of the serialised transaction. The hash value is the message on which the signature is verified.
- the public key and the signature are popped from the stack, in that order. Signature format is [<DER signature> <1 byte hash-type>]. Hashtype value is last byte of the sig.
- A new subScript is created from the scriptPubKey. The script from the immediately after the most recently parsed OP_CODESEPARATOR to the end of the scriptPub is the subScript. If there is no OP_CODESEPARATOR the entire scriptPubKey becomes the subScript.
- Any occurrences of sig are deleted from subScript, if present. (it is not standard to have a signature in a locking script (scriptPubKey) of a transaction.)
- Any remaining OP_CODESEPARATORS are removed from subScript.
- The hashtype is removed from the last byte of the sig and stored.
- A copy is made of the current transaction (hereby referred to txCopy).
- The scripts for all transaction inputs in txCopy are set to empty scripts (exactly 1 byte 0x00).
- The script for the current transaction input in txCopy is set to subScript (lead in by its length as a var-integer encoded!)
Now depending on the hashtype various things can happen to txCopy, these will be discussed individually.
Hashtype Values (from script.h):
Name | Value |
---|---|
SIGHASH_ALL | 0x00000001 |
SIGHASH_NONE | 0x00000002 |
SIGHASH_SINGLE | 0x00000003 |
SIGHASH_ANYONECANPAY | 0x00000080 |
- If (hashtype&31) = SIGHASH_NONE then apply the SIGHASH_NONE-procedure
- If (hashtype&31) = SIGHASH_SINGLE then apply the SIGHASH_SINGLE-procedure
- If hashtype & SIGHASH_ANYONECANPAY then apply the SIGHASH_ANYONECANPAY-procedure
Hence, hashtype SIGHASH_ANYONECANPAY may be applied also after any other hashtype-procedure<ref>file src/src/script.cpp in bitcoin-0.7.1</ref>. Besides the four listed hashtypes only a hashtype of value 0 appears a few times in the (main) block chain (and is handled like SIGHASH_ALL).
Hashtype SIGHASH_ALL (default)
No special further handling occurs in the default case. Think of this as "sign all of the outputs." Which is already done by the default procedure.
Procedure for Hashtype SIGHASH_NONE
- The output of txCopy is set to a vector of zero size.
- All other inputs aside from the current input in txCopy have their nSequence index set to zero
Think of this as "sign none of the outputs-- I don't care where the bitcoins go."
Procedure for Hashtype SIGHASH_SINGLE
- The output of txCopy is resized to the size of the current input index+1.
- All other txCopy outputs aside from the output that is the same as the current input index are set to a blank script and a value of (long) -1.
- All other txCopy inputs aside from the current input are set to have an nSequence index of zero.
Think of this as "sign one of the outputs-- I don't care where the other outputs go".
Note: The transaction that uses SIGHASH_SINGLE type of signature should not have more inputs than outputs. However if it does (because of the pre-existing implementation), it shall not be rejected, but instead for every "illegal" input (meaning: an input that has an index bigger than the maximum output index) the node should still verify it, though assuming the hash of 0000000000000000000000000000000000000000000000000000000000000001 [1]
Procedure for Hashtype SIGHASH_ANYONECANPAY
- The txCopy input vector is resized to a length of one.
- The current transaction input (with scriptPubKey modified to subScript) is set as the first and only member of this vector.
Think of this as "Let other people add inputs to this transaction, I don't care where the rest of the bitcoins come from."
Final signature check
An array of bytes is constructed from the serialized txCopy appended by four bytes for the hash type. This array is sha256 hashed twice, then the public key is used to check the supplied signature against the hash. The secp256k1 elliptic curve is used for the verification with the given public key.
Return values
OP_CHECKSIG will push true to the stack if the check passed, false otherwise. OP_CHECKSIG_VERIFY leaves nothing on the stack but will cause the script eval to fail immediately if the check does not pass.
References
<references/>