2024-11-14 16:26:55 -05:00
|
|
|
<pre>
|
|
|
|
BIP: 349
|
|
|
|
Layer: Consensus (soft fork)
|
|
|
|
Title: OP_INTERNALKEY
|
|
|
|
Author: Brandon Black <freedom@reardencode.com>
|
|
|
|
Jeremy Rubin <j@rubin.io>
|
|
|
|
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0349
|
|
|
|
Status: Draft
|
|
|
|
Type: Standards Track
|
2024-11-14 16:28:11 -05:00
|
|
|
Created: 2024-11-14
|
2024-11-14 16:26:55 -05:00
|
|
|
License: BSD-3-Clause
|
|
|
|
</pre>
|
2024-04-24 14:34:29 -07:00
|
|
|
|
|
|
|
## Abstract
|
|
|
|
|
|
|
|
This BIP describes a new tapscript opcode (`OP_INTERNALKEY`) which
|
2024-11-12 23:46:22 +01:00
|
|
|
pushes the _taproot internal key_ to the stack.
|
2024-04-24 14:34:29 -07:00
|
|
|
|
|
|
|
## Specification
|
|
|
|
|
2024-11-12 23:46:22 +01:00
|
|
|
When verifying taproot script path spends having leaf version `0xc0` (as
|
|
|
|
defined in [BIP 342]), `OP_INTERNALKEY` replaces `OP_SUCCESS203` (0xcb).
|
2024-11-14 18:10:42 +01:00
|
|
|
`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.
|
2024-04-24 14:34:29 -07:00
|
|
|
|
|
|
|
## 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
|
2024-11-12 23:46:22 +01:00
|
|
|
signing with the _taproot internal key_, but only with additional script
|
2024-04-24 14:34:29 -07:00
|
|
|
restrictions. In this case, `OP_INTERNALKEY` saves 8 vBytes.
|
|
|
|
|
|
|
|
### Mitigated control block overhead for scripts using hash locks
|
|
|
|
|
2024-11-12 23:46:22 +01:00
|
|
|
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.
|
2024-04-24 14:34:29 -07:00
|
|
|
|
|
|
|
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.
|
|
|
|
|
2024-12-21 14:43:40 -05:00
|
|
|
### 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.
|
|
|
|
|
2024-04-24 14:34:29 -07:00
|
|
|
## 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
|
|
|
|
|
2024-12-21 12:39:05 -05:00
|
|
|
The concept for INTERNALKEY first arose in a [discussion](https://gnusha.org/bitcoin-wizards/2022-01-05.log) between Russell O'Connor
|
2024-12-19 23:52:11 -05:00
|
|
|
and Jeremy Rubin in Bitcoin Wizards IRC, inspired by BIP-0118's key punning technique
|
2024-12-21 12:39:05 -05:00
|
|
|
for the internal key. It was later
|
2024-12-19 23:52:11 -05:00
|
|
|
drafted into this BIP by Brandon Black.
|
|
|
|
|
2024-04-24 14:34:29 -07:00
|
|
|
|
|
|
|
## Copyright
|
|
|
|
|
|
|
|
This document is licensed under the 3-clause BSD license.
|
|
|
|
|
|
|
|
[BIP 341]: https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki
|
|
|
|
|
|
|
|
[BIP 342]: https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki
|