OP_CHECKSIG

Revision as of 11:00, 4 November 2019 by Wei (talk | contribs)

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 done. Please review and update this disclaimer. 04 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 signature and the public involved in the verification are obtained from the stack.

In detail,

File:Bitcoin OpCheckSig InDetail.png
Signature verification process of the default procedure
  1. the public key and the signature are popped from the top of the stack, in that order. Signature format is [<DER signature> <1 byte hash-type>]. Hashtype value is last byte of the signature.
  2. A new subScript is created from the previous scriptPubKey identified by the input in which the signature is verified. The partial script from the immediately after the most recently parsed OP_CODESEPARATOR to the end of the scriptPubKey is the subScript. If there is no OP_CODESEPARATOR the entire scriptPubKey becomes the subScript.
  3. Any occurrences of signatures are deleted from subScript, if present. (It is not standard to have a signature in a scriptPubKey (locking script) of a transaction.)
  4. Any remaining OP_CODESEPARATORS are removed from the subScript.
  5. The hashtype is removed from the last byte of the signature and stored.
  6. A copy is made from the current transaction (hereby referred to txCopy).
  7. The scripts for all transaction inputs in txCopy are set to empty scripts (exactly 1 byte 0x00).
  8. The scriptSig in 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. See SIGHASH flags for more detail.


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

https://github.com/bitcoin-sv/bitcoin-sv/blob/master/src/script/interpreter.cpp