P2PK (Pay-to-Public-Key) — simplest form
8. OP_CHECKSIG — The Core Signature Opcode
Overview
OP_CHECKSIG is the most fundamental authorization mechanism in Bitcoin Script. It verifies that a cryptographic signature is valid for the current transaction and the provided public key. It is used in virtually every Bitcoin transaction.
Opcode value: 0xac (decimal 172)
Stack input: <signature> <pubkey> (top of stack)
Stack output: 0x01 (success) or 0x00 (failure)
Basic Script Pattern
# P2PK (Pay-to-Public-Key) — simplest form
scriptPubKey: <pubkey> OP_CHECKSIG
scriptSig: <signature>
# Execution:
Stack: [
PUSH pubkey: [ <sig> | <pubkey> ]
OP_CHECKSIG: [ 0x01 ] (if sig valid)
What OP_CHECKSIG Consumes from the Stack
OP_CHECKSIG pops exactly two elements:
Stack before: [ ... | <signature> | <pubkey> ]
↑ top of stack
Pops: pubkey (first pop)
Pops: signature (second pop)
Processes: Validate sig against pubkey and transaction commitment
Pushes: 0x01 (valid) or 0x00 (invalid)
Historical Context
In the very first Bitcoin transactions (coinbase outputs in early blocks), Satoshi used P2PK scripts — the simplest form using OP_CHECKSIG:
# Satoshi's coinbase output (Block 0 — genesis block)
scriptPubKey:
04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb
649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f
OP_CHECKSIG
This is an uncompressed public key (65 bytes) with OP_CHECKSIG. The 50 BTC from the genesis block are unspendable due to a quirk in the original code, but the script format is the purest form of OP_CHECKSIG usage.
Elliptic Curve Digital Signature Algorithm (ECDSA)
Bitcoin uses ECDSA on the secp256k1 curve for signatures verified by OP_CHECKSIG:
# Key parameters
curve: secp256k1
p = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F
G = generator point (fixed by spec)
n = order of G (number of valid private keys)
# Signing
private_key = d (256-bit integer)
public_key = d * G (point on curve)
# Signature generation
k = random nonce (CRITICAL: must be unique per signature)
R = k * G
r = R.x mod n
s = k⁻¹ * (hash + r * d) mod n
signature = (r, s)
Taproot: Schnorr Signatures and OP_CHECKSIG
In Taproot (BIP 341, activated November 2021), OP_CHECKSIG in Tapscript validates Schnorr signatures instead of ECDSA:
# Tapscript OP_CHECKSIG context
# Signature is 64 bytes (Schnorr) instead of 71-73 bytes (DER ECDSA)
# Public key is 32 bytes (x-only) instead of 33 bytes (compressed)
scriptPubKey (Tapscript): <32-byte-x-only-pubkey> OP_CHECKSIG
witness: <64-byte-schnorr-signature>
Schnorr signatures have several advantages:
-
Linearity: Enables native key and signature aggregation.
-
Provable security: Tight security proof in the random oracle model.
-
Smaller: 64 bytes vs 71–73 bytes for DER ECDSA.
TeachMeBitcoin is an ad-free, open-source educational repository curated by a passionate team of Bitcoin researchers and educators for public benefit. If you found our articles helpful, please consider supporting our hosting and ongoing content updates with a clean donation: