Research/Bitcoin

Pay-to-Taproot Spend Paths: Key Path, Script Path, and Why It Matters

Technical deep dive into P2TR outputs: how key path and script path spending work, MAST tree construction, and real-world use cases.

bcSatoruJul 14, 2026

Every Pay-to-Taproot (P2TR) output encodes two distinct spending mechanisms into a single 34-byte output script. The first is a key path: a cooperative spend that looks identical to a single-key signature on chain. The second is a script path: a fallback that reveals one branch of a Merklized Alternative Script Tree (MAST), exposing only the spending condition actually used. Understanding how these two paths work at the byte level is essential for anyone building Bitcoin-native protocols, designing custody architectures, or reasoning about on-chain privacy.

This article walks through BIP-341 and BIP-342 from the ground up: how the tweaked public key is constructed, what witnesses look like for each path, how taptrees are built, and where the cost savings actually come from. We include byte-level breakdowns, concrete examples, and a comparison with P2WSH for equivalent scripts.

Anatomy of a P2TR Output

A P2TR output script is exactly 34 bytes: the opcode OP_1 (0x51), a push opcode (0x20), and a 32-byte x-only public key Q. The OP_1 identifies this as a SegWit version 1 witness program. Unlike P2WPKH or P2WSH (which commit to a hash), the output directly contains a public key, though one that has been mathematically tweaked.

ByteValueMeaning
0x51OP_1SegWit version 1
0x2032Push next 32 bytes
32 bytesQx-only tweaked public key

The Tweaked Public Key

The output key Q is derived from an internal public key P and an optional Merkle root k_m of the script tree. The formula uses a tagged hash for domain separation:

  • With a script tree: t = hash_TapTweak(bytes(P) || k_m), then Q = P + t·G
  • Without a script tree (per BIP-86): t = hash_TapTweak(bytes(P)), then Q = P + t·G

Here G is the secp256k1 generator point, and bytes(P) is the 32-byte x-only serialization of the internal key. The tweak t commits to both the internal key and any script tree, binding them cryptographically. Anyone who knows P and the Merkle root can verify the commitment, but an observer seeing only Q on chain cannot determine whether a script tree exists.

Provably unspendable key path: When a script tree should be the only spending mechanism, BIP-341 specifies a Nothing-Up-My-Sleeve (NUMS) point H = lift_x(0x50929b...03ac0) as the internal key. This point has no known discrete logarithm, making key path spending computationally infeasible while still allowing script path spends.

Tagged Hashes

BIP-341 uses tagged hashes throughout to prevent cross-protocol attacks. A tagged hash prepends two copies of SHA256(tag) before hashing the message: hash_tag(x) = SHA256(SHA256(tag) || SHA256(tag) || x). The 64-byte prefix aligns with one SHA-256 compression block, enabling implementations to precompute the midstate. Four tags are used: TapLeaf, TapBranch, TapTweak, and TapSighash.

Key Path Spending: The Cooperative Case

Key path spending is the optimal path: the one designers should aim for in the common case. The spender provides a single Schnorr signature in the witness, and that is all. No script is revealed, no Merkle proof is needed, and no information about any alternative spending conditions leaks on chain.

What Goes On Chain

The witness for a key path spend contains exactly one element: the BIP-340 Schnorr signature. When the sighash type is SIGHASH_DEFAULT (0x00, functionally identical to SIGHASH_ALL), the trailing byte is omitted, yielding a fixed 64-byte signature. With an explicit sighash type, the signature is 65 bytes.

The total input cost for a key path spend: 41 bytes of non-witness data (outpoint, scriptSig length, sequence) at 4 weight units per byte, plus 66 bytes of witness (items count + length prefix + 64-byte signature) at 1 WU per byte. That works out to 230 WU, or 57.5 vbytes. For context, a P2WPKH input costs 68 vbytes, and a P2WSH 2-of-3 multisig costs 104.5 vbytes.

Why Key Path Spending Is a Privacy Win

Every key path spend is structurally identical on chain: a 34-byte output and a witness containing a single signature. There is no public key in the witness (unlike P2WPKH, which reveals <sig> <pubkey>). An observer cannot distinguish whether Q represents:

  • A single private key
  • A MuSig2 aggregate of n keys (n-of-n)
  • A FROST threshold key (t-of-n)
  • A key with a hidden taptree containing dozens of fallback scripts

This uniformity breaks the common input heuristic that chain analysis firms rely on. Previously, a 2-of-3 multisig was trivially identifiable by its witness structure. With P2TR key path spending, the same setup is invisible. The privacy implications are significant: as P2TR adoption grows, the anonymity set expands for all users.

Script Path Spending: The Fallback

When the key path is unavailable (a signer is offline, keys are lost, a timelock condition must be enforced), the spender falls back to a script path. This reveals exactly one leaf of the taptree: the specific Tapscript being executed, along with a Merkle proof connecting it to the committed root. All other scripts in the tree remain hidden.

The Witness Stack

A script path witness has three groups of elements:

  1. Script inputs (signatures, preimages, or other data required by the script)
  2. The script itself (the raw Tapscript bytes)
  3. The control block (internal public key + Merkle path)

The node identifies a spend as script path (rather than key path) by checking whether the witness contains more than one element. If the last element begins with byte 0x50, it is treated as an annex (reserved for future use) and stripped before processing.

Control Block Structure

The control block is 33 + 32m bytes, where m is the depth of the leaf in the taptree (0 ≤ m ≤ 128):

OffsetSizeContent
c[0]1 byte(leaf_version & 0xfe) | (parity & 0x01)
c[1:33]32 bytesInternal public key P (x-only)
c[33:]32m bytesMerkle proof: m sibling hashes

The first byte encodes the leaf version (currently 0xc0 for Tapscript as defined in BIP-342) in the upper 7 bits, with the lowest bit carrying the Y-coordinate parity of the output key Q. The 32-byte internal key P is essential: the verifier needs it to reconstruct the tweaked key and confirm it matches the output.

Verifier Reconstruction

The validation algorithm proceeds in five steps:

  1. Compute the leaf hash: k_0 = hash_TapLeaf(v || compact_size(len(s)) || s), where v is the leaf version and s is the script
  2. Walk the Merkle proof: for each sibling hash e_j, combine it with the running hash k_j in lexicographic order: k_{j+1} = hash_TapBranch(sorted(k_j, e_j))
  3. Compute the tweak: t = hash_TapTweak(P || k_m)
  4. Derive the expected output key: Q' = P + t·G
  5. Verify that x(Q') matches the output key in the scriptPubKey, and that the parity matches c[0] & 1

If all checks pass, the node executes the revealed script with the remaining witness elements as inputs. The sorting rule in step 2 (smaller hash first) eliminates the need for direction bits in the proof, keeping the control block compact.

MAST: Organizing Multiple Spending Conditions

A MAST allows a P2TR output to commit to arbitrarily many spending conditions while revealing only the one actually used. The conditions are organized into a binary Merkle tree, and spending via any leaf requires only the script itself plus a logarithmic-sized proof.

Building the Taptree

Each leaf is hashed using the TapLeaf tag: hash_TapLeaf(0xc0 || compact_size(len(script)) || script). Internal nodes combine two children using the TapBranch tag, with the smaller hash always placed first: hash_TapBranch(sorted(left, right)). The root of this tree becomes the k_m in the tweak computation.

Proof sizes scale logarithmically with the number of leaves:

LeavesTree DepthMerkle PathControl Block
100 bytes33 bytes
2132 bytes65 bytes
4264 bytes97 bytes
8396 bytes129 bytes
164128 bytes161 bytes
2^kk32k bytes33 + 32k bytes

A tree with 128 leaves (the maximum depth) requires a control block of only 4,129 bytes. Compare this with P2WSH, where the entire witness script (containing all conditions) must be revealed regardless of which condition is satisfied.

Huffman Optimization

When spending conditions have unequal probabilities, the taptree should be structured as a Huffman tree: frequent conditions near the root (shorter proofs, lower fees), rare fallbacks deeper. BIP-341 explicitly recommends: “If one or more of the spending conditions consist of just a single key, the most likely one should be made the internal key.”

Consider three scripts A, B, and C, where B is the most likely:

  • Make B the shallowest leaf (depth 1, control block = 65 bytes)
  • Place A and C as children of a deeper branch (depth 2, control block = 97 bytes)
  • Or better: if B is a single-key condition, use it as the internal key for key path spending (control block = 0 bytes, just a 64-byte signature)

This design philosophy is central to efficient P2TR usage: optimize for the common case via the key path, and use the taptree for edge cases.

Tapscript: What Changed in BIP-342

Scripts executed inside a taptree leaf use Tapscript (BIP-342), a modified version of Bitcoin Script with several important changes from the legacy and SegWit v0 script systems.

OP_CHECKSIGADD Replaces OP_CHECKMULTISIG

The most visible change is the introduction of OP_CHECKSIGADD (opcode 0xba). Legacy OP_CHECKMULTISIG and OP_CHECKMULTISIGVERIFY are disabled in Tapscript (executing them immediately fails the script). The new opcode pops three stack elements: a signature, a counter n, and a public key. If the signature is empty, it pushes n unchanged. If the signature is valid, it pushes n + 1. If the signature is invalid and non-empty, the script fails.

A k-of-n multisig in Tapscript looks like:

<pk1> OP_CHECKSIG <pk2> OP_CHECKSIGADD ... <pkn> OP_CHECKSIGADD k OP_NUMEQUAL

The witness provides either a valid 64-byte Schnorr signature or an empty element for each key, in reverse order. This eliminates the off-by-one bug that plagued OP_CHECKMULTISIG (the infamous dummy OP_0 push) and enables batch verification, since each signature is independently validated against a specific key.

Removed Resource Limits

Tapscript removes two long-standing constraints:

  • The 10,000-byte script size limit (scripts are now bounded only by block weight)
  • The 201 non-push opcode limit per script

In their place, BIP-342 introduces a signature budget: budget = 50 + witness_size. Each non-empty signature consumes 50 units. This means roughly one signature operation per 50 bytes of witness data, plus one free operation. The budget scales naturally with the on-chain cost of the transaction, preventing abuse without imposing arbitrary caps.

OP_SUCCESS and Future Upgradability

Tapscript designates a range of currently undefined opcodes as OP_SUCCESS. If any of these opcodes appears in a script, validation succeeds unconditionally (the script is treated as anyone-can-spend). This enables future soft forks to redefine these opcodes with new semantics: proposals like OP_CAT and OP_CHECKTEMPLATEVERIFY would use this mechanism. Combined with leaf versioning (unknown versions also pass validation), Tapscript provides two independent upgrade paths without requiring new output types.

Concrete Example: 2-of-3 Multisig with Timelock Fallback

Consider a custody setup with three keyholders (Alice, Bob, Carol) where any two can spend cooperatively, but after 6 months Alice alone can recover the funds. A well-designed P2TR output for this scenario:

  • Internal key: MuSig2 aggregate of Alice and Bob (the two most likely signers)
  • Leaf 1: 2-of-2 MuSig2 of Alice and Carol
  • Leaf 2: 2-of-2 MuSig2 of Bob and Carol
  • Leaf 3: Alice's key + OP_CHECKSEQUENCEVERIFY with a ~6-month relative timelock

The taptree is structured with Huffman optimization: Leaves 1 and 2 (more likely fallbacks) at depth 1, Leaf 3 (rare recovery) at depth 2.

In the common case, Alice and Bob sign cooperatively via key path: 57.5 vbytes, indistinguishable from any other P2TR spend. If Bob is unavailable, Alice and Carol use Leaf 1 via script path: the witness reveals only their 2-of-2 script, not the existence of Leaf 2 or Leaf 3. If both Bob and Carol are permanently unavailable, Alice waits for the timelock and spends via Leaf 3.

Design principle: The most common spending condition should always be the key path. Reserve script paths for fallbacks, recovery, and enforcement of on-chain conditions like timelocks. This minimizes fees and maximizes privacy in the typical case.

Vault with Multiple Recovery Paths

A more complex scenario: a vault with graded security. The output commits to four conditions:

  • Key path: 3-of-5 FROST threshold of operational keys (daily operations)
  • Leaf 1: 2-of-5 FROST + 24-hour timelock (reduced quorum after delay)
  • Leaf 2: Hardware security module key + 7-day timelock (disaster recovery)
  • Leaf 3: Social recovery (3-of-5 trusted contacts) + 30-day timelock

With P2WSH, the entire witness script containing all four conditions would be revealed on every spend, leaking the vault's complete security architecture. With P2TR, the key path spend (daily case) reveals nothing. Even a script path spend only reveals the specific fallback used.

P2TR vs P2WSH: Byte-Level Cost Comparison

The real-world savings of P2TR depend on which spending path is used. Here is a byte-level comparison for a 2-of-3 multisig, the most common multi-party arrangement. All figures assume a single input.

P2WSH 2-of-3 Input Breakdown

Non-witness: 41 bytes (outpoint 36 + scriptSig length 1 + sequence 4) = 164 WU. Witness: items count (1) + OP_0 dummy (1) + two DER signatures with length prefixes (2 × 73) + witnessScript length prefix (1) + witnessScript itself (105 bytes: OP_2 <33-byte-pk> <33-byte-pk> <33-byte-pk> OP_3 OP_CHECKMULTISIG) = ~254 WU. Total: 418 WU = 104.5 vbytes.

Spend Path Comparison

Spend TypeNon-witness (WU)Witness (WU)Total (vbytes)vs P2WSH
P2WSH 2-of-3164254104.5baseline
P2TR key path (MuSig2/FROST)1646657.5-45%
P2TR script path (single-leaf 2-of-3)164271~109+4%
P2TR optimized (key path: 2 hot keys)1646657.5-45%
P2TR optimized (script fallback: hot + backup)164167~83-21%

The key takeaway: P2TR script path spending for a 2-of-3 is slightly more expensive than P2WSH (the script uses x-only keys but requires an additional control block). The massive savings come exclusively from key path spending, where MuSig2 or FROST collapses the multi-party signing into a single 64-byte Schnorr signature.

The optimized design, described by Bitcoin developer Murch, places a MuSig2 aggregate of the two most frequently used keys as the internal key, with fallback combinations in the taptree. The common case achieves a 45% size reduction; even the fallback paths outperform P2WSH.

P2TR and Threshold Signatures

The full value of P2TR key path spending is unlocked by threshold signature schemes that produce standard Schnorr signatures. Two protocols dominate this space:

MuSig2 (BIP-327) handles n-of-n key aggregation: all parties must sign, but the result is a single key and single signature. The protocol requires two rounds of communication and no trusted setup.

FROST (formalized in IETF RFC 9591, published June 2024) enables t-of-n threshold signing: any t signers from a group of n can produce a valid signature, with the remaining n-t signers uninvolved. The output is identical to MuSig2: a single Schnorr signature indistinguishable from a single-key spend.

PropertyMuSig2 (BIP-327)FROST (RFC 9591)
Thresholdn-of-n (all sign)t-of-n (any subset of t)
Signing rounds22 (or 1 with nonce preprocessing)
Key generationSimple aggregationRequires DKG or trusted dealer
On-chain footprintSingle key + single sigSingle key + single sig
Distinguishable from single-sigNoNo
Setup complexityLowerHigher

Both protocols produce output that is completely indistinguishable from a single-key Taproot spend on chain. An observer cannot determine the threshold, the number of participants, or whether key aggregation was used at all.

Spark and Taproot Key Path Spending

Spark leverages this property directly. The protocol uses a two-of-two signing model where the user holds one key share and the Spark operators collectively hold the other via FROST threshold signing. When funds move on chain (during deposits or exits), the cooperative signature is a standard Schnorr key path spend: 57.5 vbytes, indistinguishable from any other P2TR output. There is no on-chain fingerprint revealing that Spark was involved, which benefits both user privacy and block space efficiency.

For developers building on Spark, the Spark SDK abstracts the key management and signing coordination, handling FROST rounds and Taproot tweaking under the hood. The on-chain result is always a clean key path spend.

Adoption and the Path Forward

Taproot activated on November 14, 2021 at block 709,632. Adoption was initially slow (under 1% of transactions through most of 2022), then surged with Ordinals inscriptions in early 2023 and Runes in 2024. By April 2025, P2TR had become the largest UTXO type by count: approximately 59.3 million P2TR UTXOs (34.2% of all UTXOs), surpassing both P2PKH (28.8%) and P2WPKH (26.5%). However, the BTC value held is only about 0.75% of the total supply, reflecting the large number of small inscription-related outputs.

On the tooling side, Bitcoin Core v24.0+ defaults to P2TR for new descriptor wallets. Hardware wallet support is broadly available: Ledger (Bitcoin app v2.0.0+), Trezor (Safe 3, Safe 5, Model T), and BitBox02 all handle P2TR signing. LND v0.21 graduated simple Taproot channels to production, reducing on-chain channel footprints.

The remaining frontier is software adoption of key path spending with MuSig2 and FROST. Most current P2TR usage is single-key (BIP-86) or script path (inscriptions). As multisig wallets and custody providers migrate to aggregated-key P2TR, the fee savings and privacy improvements described in this article will compound across the network.

Tradeoffs and Limitations

P2TR is not universally superior to older output types. Several tradeoffs are worth understanding:

  • Key path requires interactive signing: MuSig2 and FROST both require multiple communication rounds between signers, unlike P2SH or P2WSH multisig where signatures can be collected independently
  • Script path is not always cheaper: for simple k-of-n multisig without key aggregation, P2TR script path witness is comparable to or slightly larger than P2WSH (the control block adds overhead)
  • x-only keys lose sign information: the 32-byte key serialization discards the Y-coordinate sign, requiring careful handling during key tweaking and signing (a source of subtle implementation bugs)
  • Backup complexity increases: a P2TR wallet must store the internal key, the complete taptree structure, and any key aggregation metadata, not just raw private keys or a seed phrase
  • Quantum considerations: P2TR reveals the public key in the output (unlike P2WSH/P2WPKH which commit to a hash), making it theoretically more exposed to future quantum attacks on elliptic curve cryptography, though this threat remains distant

Conclusion

P2TR outputs represent the most significant upgrade to Bitcoin's transaction format since SegWit. The dual-path design: key path for efficient cooperative spending and script path for flexible fallbacks, combined with MAST for condition privacy, gives protocol designers a powerful toolkit. The 45% fee reduction from key path spending with MuSig2 or FROST, the elimination of multisig fingerprinting, and the clean upgrade paths via Tapscript versioning make P2TR the preferred output type for new Bitcoin applications.

For a broader look at how Schnorr signatures enable Taproot, how Bitcoin address types have evolved, or how FROST threshold signing works in practice, explore the linked research. To build with Taproot key path spending in a production environment, the Spark developer documentation covers SDK integration and signing flows.

This article is for educational purposes only. It does not constitute financial or investment advice. Bitcoin and Layer 2 protocols involve technical and financial risk. Always do your own research and understand the tradeoffs before using any protocol.