Home › Topics › Consensus › BIP 348

BIP 348 (OP_CHECKSIGFROMSTACK): CHECKSIGFROMSTACK

Also known as: OP_CHECKSIGFROMSTACK, CSFS, BIP348, BIP-0348.

In plain English: Adds an instruction letting Bitcoin scripts verify a signature over any piece of data, not just over the spending transaction itself. That opens the door to things like delegating spending rights, using signed messages from outside parties (oracles), and building more efficient second-layer protocols.

Status
Draft
Type
Specification
Layer
Consensus (soft fork)
Authors
Brandon Black, Jeremy Rubin
Assigned
Last changed
Topics
Consensus
Source
bip-0348.md on GitHub · Markdown

Full specification

Abstract

This BIP describes a new opcode for the purpose of checking cryptographic signatures in bitcoin scripts against data from the stack.

Summary

When verifying taproot script spends having leaf version 0xc0 (as defined in BIP 342), we propose OP_CHECKSIGFROMSTACK to replace OP_SUCCESS204 (0xcc).

OP_CHECKSIGFROMSTACK has semantics similar to OP_CHECKSIG, as specified below. Briefly, it pops 3 elements from the stack: a 32-byte public key, a message, and a signature. If the signature is valid for that public key and message, 1 is pushed to the stack. If the signature is the empty vector, 0 is pushed to the stack, and otherwise script execution fails.

Only 32-byte keys are constrained. Similar to BIP 342 unknown key types, for other key lengths no signature verification is performed and it is considered successful.

Specification

  • If fewer than 3 elements are on the stack, the script MUST fail and terminate immediately.
  • The public key (top element), message (second to top element), and signature (third from top element) are read from the stack.
  • The top three elements are popped from the stack.
  • 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 340:
    • If the signature is not the empty vector, the signature is validated against the public key and message according to BIP 340. Validation failure in this case immediately terminates script execution with failure.
  • If the public key size is not zero and not 32 bytes; the public key is of an unknown public key type. Signature verification for unknown public key types succeeds as if signature verification for a known public key type had succeeded.
  • If the script did not fail and terminate before this step, regardless of the public key type:
    • If the signature is the empty vector: An empty vector is pushed onto the stack, and execution continues with the next opcode.
    • If the signature is not the empty vector:
      • The opcode is counted towards the sigops budget as described in BIP 342.
      • A 1-byte value 0x01 is pushed onto the stack.

Design Considerations

  1. Message hashing: BIP 340 is compatible with any size of message and does not require it to be a securely hashed input, so the message is not hashed prior to BIP 340 verification.
  2. Lack of verify semantics: Adding a single opcode for this purpose keeps the implementation and design simple. An earlier draft had a verify variant as a NOP upgrade, and if this functionality is later brought to legacy scripts, that would be a good time to add a verify variant.
  3. Add/multisig: No concession is made to OP_CHECKMULTISIG or OP_CHECKSIGADD semantics with OP_CHECKSIGFROMSTACK. In Tapscript, add semantics can be implemented with 1 additional vByte per key (OP_TOALTSTACK OP_CHECKSIGFROMSTACK OP_FROMALTSTACK OP_ADD).
  4. Splitting R/S on the stack: Implementing split/separate signatures is left as an exercise for other bitcoin upgrades, such as BIP 347 (OP_CAT).
  5. APO-style (BIP 118) Taproot internal key: Rather than introducing an additional key type in this change, we suggest implementing OP_INTERNALKEY (BIP 349) or separately introducing that key type for all Tapscript signature checking operations in a separate change.

Resource Limits

These opcodes are treated identically to other signature checking opcodes and count against the sigops and budget.

Motivation

LN Symmetry

When combined with BIP 119 (OP_CHECKTEMPLATEVERIFY/CTV), OP_CHECKSIGFROMSTACK (CSFS) can be used to implement Lightning Symmetry channels. The construction OP_CHECKTEMPLATEVERIFY <pubkey> OP_CHECKSIGFROMSTACK with a spend stack containing the CTV hash and a signature for it is logically equivalent to <bip118_pubkey> OP_CHECKSIG and a signature over SIGHASH_ALL|SIGHASH_ANYPREVOUTANYSCRIPT. The OP_CHECKSIGFROMSTACK construction is 8 vBytes larger.

Summary of alternatives:

  • CTV+CSFS is the minimal functionality needed for Lightning Symmetry but requires the use of an OP_RETURN for data availability
  • APO is the original design for Lightning Symmetry and uses the taproot annex for data availability.
  • LNHANCE (CTV+CSFS+IKEY+PC) is the most efficient and direct way currently designed to implement Lightning Symmetry.

Delegation

Using a script like: <pubkey> SWAP IF 2 PICK SWAP CSFS VERIFY ENDIF CHECKSIG either direct verification or delegation can be achieved by the following unlock stacks: <sig> 0 or <dsig> <dpubkey> <sig> 1

Advanced delegation when combined with OP_PAIRCOMMIT or OP_CAT

Using a script like: CLTV OVER PAIRCOMMIT TOALT CHECKSIGVERIFY FROMALT <pubkey> CSFS or: CLTV SHA256 OVER CAT TOALT CHECKSIGVERIFY FROMALT <pubkey> CSFS with the unlock stack: <sig> <delegate_sig> <delegate_pubkey> <locktime>

Delegates to a public key after a lock time, enabling delegation to various keys after various associated times.

Reference Implementation

A reference implementation is provided here:

https://github.com/bitcoin/bitcoin/pull/29270

Backward Compatibility

By constraining the behavior of an OP_SUCCESS opcode, deployment of the BIP can be done in a backwards compatible, soft-fork manner. If anyone were to rely on the OP_SUCCESS behavior of OP_SUCCESS204, OP_CHECKSIGFROMSTACK would invalidate their spend.

Deployment

TBD

Credits

Reference implementation was made with reference to the implementation in Elements and started by moonsettler.

This document is licensed under the 3-clause BSD license.

Questions about BIP 348

What is BIP 348?

BIP 348, “CHECKSIGFROMSTACK”, also known as OP_CHECKSIGFROMSTACK, is a specification Bitcoin Improvement Proposal written by Brandon Black and Jeremy Rubin and assigned in November 2024. Adds an instruction letting Bitcoin scripts verify a signature over any piece of data, not just over the spending transaction itself. That opens the door to things like delegating spending rights, using signed messages from outside parties (oracles), and building more efficient second-layer protocols.

Is BIP 348 active?

No. BIP 348 is a Draft: it is still being written and discussed, so its details may change.

Who wrote BIP 348?

BIP 348 was written by Brandon Black and Jeremy Rubin. Its number was assigned on November 26, 2024.

Which BIPs build on BIP 348?

2 other BIPs reference BIP 348: BIP 346 (OP_TXHASH) and BIP 448 (Taproot-native (Re)bindable Transactions).

Where can I read the full BIP 348 specification?

The complete text of BIP 348 is on this page, taken unchanged from the official bitcoin/bips repository on GitHub. It is also available as Markdown and JSON.

BIPs that build on BIP 348

  • BIP 346: OP_TXHASH: Draft. Proposes a new script instruction, OP_TXHASH, that lets a script look at selected details of the transaction trying to spend it, such as its outputs or amounts. Combined with a way to check…
  • BIP 448: Taproot-native (Re)bindable Transactions: Draft. Bundles three small script instructions, OP_TEMPLATEHASH, OP_CHECKSIGFROMSTACK and OP_INTERNALKEY, into a single proposed upgrade. Together they would let transactions commit to specific future…

Learn more

Guides

Free tools

Glossary

Related proposals

  • BIP 30: Duplicate transactions: Deployed. Added a rule forbidding a block from including a transaction with the same ID as an earlier one whose outputs are not fully spent. Such duplicates can overwrite earlier coins and make them…
  • BIP 34 (block height in coinbase): Block v2, Height in Coinbase: Deployed. Upgraded blocks to version 2 and required each block's coinbase transaction (the one paying the miner) to include the block's height. This makes every coinbase unique, preventing duplicate…
  • BIP 42: A finite monetary supply for Bitcoin: Deployed. A tongue-in-cheek proposal fixing a software quirk that would have made the block reward reappear and coin issuance restart a couple of centuries from now. It ensures the roughly 21 million coin…
  • BIP 50: March 2013 Chain Fork Post-Mortem: Deployed. A post-mortem of the March 2013 incident in which a database limit in older Bitcoin software caused the blockchain to split temporarily. It explains what went wrong, how miners and developers…
  • BIP 54: Consensus Cleanup: Complete. Bundles fixes for several long-standing protocol weaknesses: the timewarp attack (manipulating block timestamps to speed up coin issuance), blocks that take extremely long to validate, Merkle tree…
  • BIP 62: Dealing with malleability: Closed. Proposed a set of rules to stop third parties from altering a transaction's ID without changing what it does, a problem called malleability. It was withdrawn after Segregated Witness (SegWit) solved…