From: Matias Monteagudo <omatimonteagudov@gmail•com>
To: Bitcoin Development Mailing List <bitcoindev@googlegroups.com>
Subject: [bitcoindev] BIP Booby Trapped Wallets - Covenant-Only Taproot Outputs
Date: Thu, 21 Aug 2025 10:46:31 -0700 (PDT) [thread overview]
Message-ID: <6778d5ec-91dc-4c3b-9718-581ec2cf7be6n@googlegroups.com> (raw)
[-- Attachment #1.1: Type: text/plain, Size: 15994 bytes --]
<pre>
BIP: ?
Layer: Consensus (soft fork)
Title: Booby Trapped Wallets
Author: Matias Monteagudo <omatimonteagudov@gmail•com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-XXXX
Status: Draft
Type: Standards Track
Created: 2025-08-21
License: BSD-2-Clause
Requires: 341, 342
</pre>
== Abstract ==
This BIP proposes covenant-only Taproot outputs, an optional but
irrevocable wallet-level security mechanism. When activated by wallet
owners, covenant-only mode disables key-path spending and mandates
script-path spending, creating invisible transaction restrictions that only
become apparent when violated. This mechanism provides an optional security
layer for high-value institutional Bitcoin holdings against unauthorized
access while maintaining transaction privacy until restrictions are
triggered.
== Copyright ==
This BIP is licensed under the BSD 2-clause license.
== Motivation ==
High-profile Bitcoin holders, particularly institutional entities such as
exchanges, face significant security risks. When attackers gain access to
private keys, they can drain wallets with varying degrees of difficulty but
ultimately succeed. Current security measures are visible and can be
circumvented by sophisticated attackers.
This proposal creates an optional but irrevocable security mechanism where:
# Wallet owners can voluntarily and irrevocably restrict future
transactions to predefined destination addresses
# Once activated, unauthorized transfer attempts are automatically
redirected to arbitration wallets
# The restrictions remain completely invisible until triggered
# Protected wallets appear identical to unprotected ones, preventing
attacker preparation
# The mechanism is entirely opt-in and cannot be forced upon any wallet
== Specification ==
=== Covenant-Only Taproot Output ===
A covenant-only Taproot output extends standard Taproot (BIP 341) by
mandating script-path spending through the use of an invalidated internal
key:
<pre>
scriptPubKey: OP_1 <32-byte-covenant-taproot-output>
</pre>
The output commitment follows standard Taproot construction:
<pre>
covenant_taproot_output = internal_pubkey + tagged_hash("TapTweak",
internal_pubkey || merkle_root)
</pre>
Where internal_pubkey is set to an unspendable value, making key-path
spending impossible.
=== Key Components ===
==== 1. Internal Key Invalidation ====
The internal public key MUST be set to the following unspendable point:
<pre>
internal_pubkey = lift_x(tagged_hash("CovenantOnly/InvalidKey", b""))
</pre>
This point has no known discrete logarithm, ensuring key-path spending is
cryptographically impossible while maintaining compatibility with existing
Taproot validation rules.
==== 2. Covenant Script Template ====
The covenant script enforces destination restrictions through conditional
execution:
<pre>
# Check if destination is whitelisted
OP_DUP OP_HASH160 <destination_hash> OP_EQUAL
OP_IF
# Validate whitelist membership with Merkle proof
OP_SWAP <whitelist_merkle_root> OP_CHECKTEMPLATEVERIFY
<destination_pubkey> OP_CHECKSIG
OP_ELSE
# Enforce arbitration for unauthorized destinations
<arbitration_wallet_script>
OP_ENDIF
</pre>
Note: This script assumes a hypothetical OP_CHECKTEMPLATEVERIFY opcode for
Merkle proof validation. Actual implementation would use existing opcodes
for Merkle tree verification. The arbitration_wallet_script can be any
valid script (single-sig, multisig, or other) as determined by the
institution and arbitrator.
==== 3. Whitelist Construction ====
Allowed destinations are hashed into a Merkle tree:
<pre>
whitelist_hash = merkle_root(destination_1, destination_2, ...,
destination_n)
</pre>
=== Transaction Validation ===
==== Normal Operation ====
When spending to a whitelisted destination:
# Transaction appears as standard Taproot spend
# Script-path reveals the covenant logic
# Whitelist proof validates the destination
# Transaction proceeds normally
==== Unauthorized Attempt ====
When attempting to spend to non-whitelisted destination:
# Script-path execution fails whitelist check
# Automatic fallback to arbitration wallet
# Funds are locked pending arbitration resolution
=== Activation and Deployment ===
This soft fork follows the deployment mechanism specified in BIP 9 (Version
bits with timeout and delay):
<pre>
name: covenant-taproot
bit: TBD (to be assigned by BIP editors)
starttime: TBD (6 months after BIP Final status)
timeout: TBD (2 years after starttime)
threshold: 1815 (90% of 2016 blocks)
</pre>
The soft fork activates when 90% of blocks in a difficulty period signal
readiness, ensuring broad miner consensus before enforcement begins.
=== New Consensus Rules ===
After activation, nodes MUST enforce the following rules for covenant-only
Taproot outputs:
# '''Internal Key Validation''': Outputs using the covenant-only internal
key (as defined in section 1) MUST be validated as covenant-only outputs
# '''Mandatory Script-Path''': Covenant-only outputs MUST be spent using
script-path spending; key-path spending attempts are INVALID
# '''Script Execution''': The covenant script MUST successfully execute and
validate destination restrictions
# '''Merkle Proof Verification''': Whitelisted destinations MUST provide
valid Merkle inclusion proofs
# '''Arbitration Fallback''': Non-whitelisted destinations MUST redirect to
the specified arbitration wallet
These rules only apply to outputs created after activation and do not
affect existing Taproot outputs.
== Backwards Compatibility ==
This proposal maintains full backwards compatibility through careful soft
fork design:
# '''Pre-existing Outputs''': All existing Taproot outputs continue to
function unchanged with their original semantics
# '''Node Compatibility''': Non-upgraded nodes validate covenant-only
outputs as standard Taproot without additional restrictions
# '''Wallet Compatibility''': Existing wallet software continues to work;
covenant functionality is purely additive
# '''Transaction Relay''': All transactions remain compatible with existing
relay policies and fee estimation
# '''Mining Compatibility''': No changes required to mining software or
pool configurations
The soft fork nature ensures that old software never sees invalid
transactions, maintaining network cohesion during the upgrade period.
== Rationale ==
=== Why Extend Taproot? ===
Taproot provides the perfect foundation because:
# '''Privacy''': Scripts remain hidden until execution
# '''Flexibility''': Merkle tree structure supports complex covenants
# '''Efficiency''': Minimal on-chain footprint
# '''Adoption''': Building on existing, activated technology
=== Why Disable Key-Path Spending? ===
Key-path spending would allow attackers to bypass covenant restrictions
entirely. By making the internal key unspendable, we ensure that all
spending must go through the covenant script validation.
=== Arbitration Mechanism ===
The automatic arbitration fallback provides:
# '''Recovery path''': Legitimate users can recover funds through
arbitration
# '''Deterrent effect''': Attackers know stolen funds will be locked
# '''Institutional security''': Professional arbitration services can be
integrated with any wallet type
Institutions can choose from existing specialized services such as the
Blockchain Arbitration & Commerce Society (https://bacsociety.com) or any
other arbitrator they trust, providing flexibility in arbitration provider
selection.
=== Privacy Benefits ===
# Protected wallets are indistinguishable from regular Taproot addresses
# Covenant restrictions only become visible when violated
# Normal operations remain completely private
# Attackers cannot identify targets in advance
== Reference Implementation ==
=== Core Validation Logic ===
<pre>
def validate_covenant_taproot(scriptPubKey, witness_stack, tx_outputs):
"""Validate a Covenant-Only Taproot spend"""
# Extract the covenant output
if len(scriptPubKey) != 34 or scriptPubKey[0] != 0x51:
return False
covenant_output = scriptPubKey[2:]
# Verify script-path spending (key-path is invalid)
if len(witness_stack) < 3:
return False
script = witness_stack[-2]
control_block = witness_stack[-1]
# Validate Taproot script-path
if not validate_taproot_script_path(script, control_block,
covenant_output):
return False
# Execute covenant script
return execute_covenant_script(script, witness_stack[:-2], tx_outputs)
def execute_covenant_script(script, witness_stack, tx_outputs):
"""Execute the covenant validation script"""
# Parse script to extract whitelist and arbitration keys
whitelist_hash, destination_key, arbitration_keys =
parse_covenant_script(script)
# Check if spending to whitelisted destination
for output in tx_outputs:
dest_hash = hash160(output.scriptPubKey)
if validate_whitelist_inclusion(dest_hash, whitelist_hash,
witness_stack):
# Spending to authorized destination
return validate_signature(destination_key, witness_stack)
# No whitelisted destination found - enforce arbitration
return validate_arbitration_wallet(arbitration_keys, witness_stack)
</pre>
=== Wallet Integration ===
<pre>
class CovenantWallet:
def create_covenant_output(self, whitelist_destinations,
arbitrator_pubkey):
"""Create a new Covenant-Only Taproot output"""
# Create whitelist Merkle tree
whitelist_hash =
self.build_whitelist_merkle_tree(whitelist_destinations)
# Build covenant script
covenant_script = self.build_covenant_script(
whitelist_hash,
self.institution_pubkey,
arbitrator_pubkey
)
# Create Taproot commitment with invalid internal key
invalid_internal_key = tagged_hash("CovenantOnly/InvalidKey", b"")
taproot_output = self.compute_taproot_output(invalid_internal_key,
covenant_script)
return taproot_output
def spend_covenant_output(self, utxo, destination, whitelist_proof):
"""Spend from a covenant-protected output"""
# Build witness stack
witness_stack = []
witness_stack.extend(self.create_signature_data())
witness_stack.append(whitelist_proof)
witness_stack.append(self.covenant_script)
witness_stack.append(self.control_block)
return self.create_transaction(utxo, destination, witness_stack)
</pre>
== Security Considerations ==
=== Cryptographic Security ===
# '''Internal Key Security''': The covenant-only internal key is derived
using a cryptographically secure hash function with no known preimage,
ensuring no party can compute the corresponding private key
# '''Script Hiding''': Covenant logic remains hidden until first execution,
preventing attackers from analyzing restrictions beforehand
# '''Merkle Tree Security''': Whitelist validation relies on
cryptographically secure Merkle tree inclusion proofs, preventing
unauthorized destination forgery
=== Attack Vectors and Mitigations ===
# '''Private Key Compromise''': Primary threat mitigated by mandatory
script-path spending that enforces covenant restrictions regardless of key
compromise
# '''Script Analysis Attack''': Covenant structure only revealed upon
violation attempt, limiting attacker intelligence gathering
# '''Arbitration Compromise''': Mitigated by using secure arbitration
wallet configurations and the ability to use multiple independent
arbitrators
# '''Implementation Vulnerabilities''': Reference implementation includes
comprehensive test vectors and edge case handling
# '''Social Engineering''': Attacks against arbitrators are mitigated
because the arbitrator's identity remains hidden until the covenant is
triggered, preventing targeted attacks during normal operations
=== Economic Security Model ===
# '''Attacker Economics''': Theft attempts face high probability of fund
seizure through arbitration, making attacks economically irrational
# '''Arbitrator Incentives''': Arbitrators have economic stake in fair
resolution to maintain reputation and future business
# '''Institution Benefits''': Legitimate institutions maintain full
operational control while gaining protection against unauthorized access
# '''Network Effects''': Widespread adoption increases overall ecosystem
security without degrading privacy or performance
=== Privacy Trade-offs ===
# Normal operations maintain full privacy
# Violation attempts reveal covenant structure
# Overall privacy significantly better than current multisig alternatives
== Test Vectors ==
=== Vector 1: Covenant-Only Output Creation ===
<pre>
Internal Key:
50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0
Merkle Root:
9a1c7d8f0e5b3a4c2d9f8e7b6a5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c
Script Tree: [covenant_script_leaf]
Expected Output: bc1p... (32-byte commitment)
</pre>
=== Vector 2: Valid Whitelisted Spend ===
<pre>
Input: Covenant-only Taproot UTXO from Vector 1
Destination: bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4 (whitelisted)
Witness Stack: [signature, merkle_proof, covenant_script, control_block]
Expected: VALID transaction
Privacy: Covenant script revealed but appears as normal Taproot spend
</pre>
=== Vector 3: Unauthorized Destination Attempt ===
<pre>
Input: Covenant-only Taproot UTXO from Vector 1
Destination: bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3
(not whitelisted)
Witness Stack: [arbitration_signatures, covenant_script, control_block]
Expected: Funds redirected to arbitration wallet
Privacy: Covenant structure fully revealed
</pre>
=== Vector 4: Key-Path Bypass Attempt ===
<pre>
Input: Covenant-only Taproot UTXO from Vector 1
Spend Type: Key-path (single signature, no script reveal)
Witness Stack: [invalid_signature]
Expected: INVALID (unspendable internal key)
Result: Transaction rejected by consensus rules
</pre>
== Implementation Timeline ==
# '''Phase 1''': Reference implementation and test suite
# '''Phase 2''': Community review and feedback incorporation
# '''Phase 3''': Testnet deployment and testing
# '''Phase 4''': Mainnet soft fork activation (if consensus achieved)
== Conclusion ==
This proposal introduces covenant-only Taproot outputs as an optional
security enhancement for Bitcoin. By leveraging existing Taproot
infrastructure with invalidated internal keys, we enable invisible
transaction restrictions that provide institutional-grade protection
without compromising privacy or usability.
The mechanism offers a balanced approach to high-value Bitcoin security,
maintaining compatibility with existing systems while providing powerful
deterrence against unauthorized access. The optional nature ensures no
impact on users who do not require this additional security layer.
== Acknowledgments ==
The author thanks the Bitcoin development community for their work on
Taproot (BIP 341) which provides the foundation for this proposal. Special
appreciation to the designers of the Taproot script commitment scheme that
enables covenant functionality.
== References ==
* [[bip-0341.mediawiki|BIP 341: Taproot: SegWit version 1 spending rules]]
* [[bip-0342.mediawiki|BIP 342: Validation of Taproot Scripts]]
* [https://github.com/bitcoin/bitcoin Bitcoin Core implementation]
* [[https://bacsociety.com Blockchain Arbitration & Commerce Society]]
--
You received this message because you are subscribed to the Google Groups "Bitcoin Development Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bitcoindev+unsubscribe@googlegroups•com.
To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/6778d5ec-91dc-4c3b-9718-581ec2cf7be6n%40googlegroups.com.
[-- Attachment #1.2: Type: text/html, Size: 18354 bytes --]
reply other threads:[~2025-08-21 18:16 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=6778d5ec-91dc-4c3b-9718-581ec2cf7be6n@googlegroups.com \
--to=omatimonteagudov@gmail$(echo .)com \
--cc=bitcoindev@googlegroups.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox