Home › Topics › Wallets › BIP 349

BIP 349: OP_INTERNALKEY

Also known as: BIP349, BIP-0349.

In plain English: Adds a small script instruction that places a Taproot output's 'internal key', the main key behind the output, onto the script's working data. It saves space by avoiding repeating that key inside scripts, and is designed to complement other proposed instructions for advanced contracts.

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

Full specification

Abstract

This BIP describes a new tapscript opcode (OP_INTERNALKEY) which pushes the taproot internal key to the stack.

Specification

When verifying taproot script path spends having leaf version 0xc0 (as defined in BIP 342), OP_INTERNALKEY replaces OP_SUCCESS203 (0xcb). OP_INTERNALKEY pushes the 32-byte x-only representation of the taproot internal key (referred to as p), as defined in BIP 341, to the stack.

Motivation

Key spend with additional conditions

When building taproot outputs, especially those secured by an aggregate key representing more than one signer, the parties may wish to collaborate on signing with the taproot internal key, but only with additional script restrictions. In this case, OP_INTERNALKEY saves 8 vBytes.

Mitigated control block overhead for scripts using hash locks

In cases where key path spending is not desired, the internal key may be set to a NUMS point whose bytes would otherwise be required in a tapscript. This could be used with any hash locked transaction, for example, to save 8 vBytes.

Note: The internal key must be the X coordinate of a point on the SECP256K1 curve, so any such hash must be checked and modified until it is such an X coordinate. This will typically take approximately 2 attempts.

Re-Keying with Merkle Root Preservation

Consider a program such CTV <X> CSFS <S+1> CLTV. Such fragments are useful for LN-Symmetry applications.

Such a program would be embedded within a Taproot script path, such as TR(X, {CTV <X> CSFS <S+1> CLTV}).

Were the internal key to be updated from X to Y, the resulting program would be: TR(Y, {CTV <X> CSFS <S+1> CLTV}).

The key in the leaf and the key-path would be mismatched. Were OP_INTERNALKEY to be used, the leaf would automatically re-key. E.g., TR(X, {CTV OP_INTERNALKEY CSFS <S+1> CLTV}) is equivalent to TR(X, {CTV <X> CSFS <S+1> CLTV}) and TR(Y, {CTV OP_INTERNALKEY CSFS <S+1> CLTV}) is equivalent to TR(Y, {CTV <Y> CSFS <S+1> CLTV}).

While this particular example is contrived, the general technique of using OP_INTERNALKEY as updatable across an entire script tree is a helpful covenant primitive when it is desirable to invalidate signatures from prior states. For example, the theoretical OP_TAPLEAFUPDATEVERIFY opcode modifies the internal key directly to remove or add a participant, and OP_INTERNALKEY would ensure that the tweaked key is used from all script paths where desired.

Reference Implementation

A reference implementation is provided here:

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

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_SUCCESS203, OP_INTERNALKEY would invalidate their spend.

Deployment

TBD

Credits

The concept for INTERNALKEY first arose in a discussion between Russell O'Connor and Jeremy Rubin in Bitcoin Wizards IRC, inspired by BIP-0118's key punning technique for the internal key. It was later drafted into this BIP by Brandon Black.

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

Questions about BIP 349

What is BIP 349?

BIP 349, “OP_INTERNALKEY”, is a specification Bitcoin Improvement Proposal written by Brandon Black and Jeremy Rubin and assigned in November 2024. Adds a small script instruction that places a Taproot output's 'internal key', the main key behind the output, onto the script's working data. It saves space by avoiding repeating that key inside scripts, and is designed to complement other proposed instructions for advanced contracts.

Is BIP 349 active?

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

Who wrote BIP 349?

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

Which BIPs build on BIP 349?

1 other BIP references BIP 349: BIP 448 (Taproot-native (Re)bindable Transactions).

Where can I read the full BIP 349 specification?

The complete text of BIP 349 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 349

  • 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

Related proposals