From 11533d137966561ce0fb05f1a9beecd32ad7ec9f Mon Sep 17 00:00:00 2001 From: Yuval Kogman Date: Thu, 7 May 2026 05:52:39 +0200 Subject: [PATCH 1/2] add outline of psbt privacy considerations doc --- psbt-privacy.md | 65 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 psbt-privacy.md diff --git a/psbt-privacy.md b/psbt-privacy.md new file mode 100644 index 0000000..8f7fc42 --- /dev/null +++ b/psbt-privacy.md @@ -0,0 +1,65 @@ +### meta/TODO + +The immediate goal of this document is just to be a minimal list of fields that +are necessary and safe to share. + +Ideally this document should comprehensively categorize fields by privacy +implications wrt different kinds of peers, for all BIP 174 & 370 roles. + +--- + +There should be clear diagrams showing how the different roles interact around +the privacy boundary. For example, Creator role can already add a bunch of +private information in single party setting (`createfundedpsbt`) and this is +appropriate. (nested) Multisig may involve multiple privacy boundaries, and the +udpater role may interact in complicated ways with this. + +--- + +## Abstract + +PSBT creation, construction, updating, and signing may all add privacy +sensitive information to PSBTs. + +When exchanging (modifiable) PSBTs during construction (BIP 370 or otherwise) +or signing with semi-trusted or untrusted counterparties, only some fields are +necessary to share, and privacy can be harmed significantly if certain fields +that are required for a signing device for example are leaked to an untrusted +party. + +## Specification + +### Input fields + +All data that eventually winds up in the chain is fine: + +- construction +- prev txid and spent output index +- nsequence +- combiner (signing) +- witness or non witness utxo +- finalized witnesses/scriptSigs + +Non-finalized signature data:: this is a bit more naunced and needs evaluation +of the other BIPs, in particular tapscript stuff, because not all data comitted +in the script needs to make it to the chain, depending on the spend paths. + +All other fields should only be shared with trusted parties (e.g. own devices, +within an organization, etc) + +### Output fields + +Consensus fields: + +- value +- script +- depending on the situation bip 375 silent payments info field may or may not be appropriate to share + +Derivation paths etc definitely need to be scrubbed. + +### Global fields + +Most BIP 174 or 370 global fields are fine but anything related to BIP 32 paths +or keys, multisig, miniscript etc should not be included. + + From 046247d5dabdba5ec374829882550fecf3daa5e6 Mon Sep 17 00:00:00 2001 From: Armin Sabouri Date: Wed, 13 May 2026 14:52:43 -0400 Subject: [PATCH 2/2] WIP - Draft psbt privacy scrubbing bip --- psbt-privacy.md | 356 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 325 insertions(+), 31 deletions(-) diff --git a/psbt-privacy.md b/psbt-privacy.md index 8f7fc42..1ae8fc7 100644 --- a/psbt-privacy.md +++ b/psbt-privacy.md @@ -1,4 +1,4 @@ -### meta/TODO + + +# BIP: XXX Privacy PSBT ## Abstract -PSBT creation, construction, updating, and signing may all add privacy -sensitive information to PSBTs. +PSBT creation, construction, updating, and signing may all add privacy sensitive information to PSBTs. + +When exchanging (modifiable) PSBTs during construction (BIP 370 or otherwise) or signing with untrusted counterparties, only some fields are necessary to share, and privacy can be harmed significantly if certain fields that are required for a signing device for example are leaked to an untrusted party. + +This document specifies what fields can be shared with trusted and untrusted parties such that privacy is preserved. + +## Rationale + +Historically, PSBTs were exchanged only with trusted peers. For example, one owner, one organization, or mutually trusting cosigners. Interactive protocols now pass PSBTs across trust boundaries (payjoin, coordinator-less coinjoin, external combiners). Some protocols, such as BIP77, explicity mention what fields should be removed. However, other interactive tx construction bips either assume always a trusted enviorment or tacitly assume the clients will remove sensative information. Without proper specification clients will diverge. + +## Trust Domain (find better name TODO) + +Model the trust domain as a single authorization boundary: every PSBT role inside it may observe the full PSBT, including signing material and wallet-internal metadata. You rely on those parties not to relay that data outside the domain. When a PSBT leaves the domain, hand off only the entries the external role needs for its next step. Scrub every privacy-sensitive field listed below at each trust-boundary crossing unless policy explicitly documents an exception. + +If a PSBT re-enters the trust domain, it may regain the fields that were stripped. + +### Motivating examples + +TODO: remove this section and integrate into parts of this doc + + -When exchanging (modifiable) PSBTs during construction (BIP 370 or otherwise) -or signing with semi-trusted or untrusted counterparties, only some fields are -necessary to share, and privacy can be harmed significantly if certain fields -that are required for a signing device for example are leaked to an untrusted -party. +multisig example 2:3 with central coordinator and untrusting independent signers: +Psbt gets created, coins are selected and ouputs are created. The change output includes enough informatoin s.t each signer can verify the change is created correctly. +The updater creates 3 different PSBT with signing fields specific to a signer. Signers strips signing fields before distributing back to combiner -- they only include +a partial sig. +Signers do not learn each others derivations paths. In case a signer is replaced, they will not be able to identify the wallets future outputs based on onchain information. + +BIP174 Manual CoinJoin Workflow: +This is a example of an interactive tx construction between three untrusting wallets. Alice creates the PSBT, adds her inputs. At this point the PSBT should only contain public fields. Bob similarly does the same thing. Carol adds inputs, but signs them. This is not explictly notes but this may mean signing fields were present. Carol (and the other signers) must strip siging fields before returning PSBT ## Specification -### Input fields +### Scrubber Role + +Run the scrubber at the trust boundary on the sending side. It reads the in-domain PSBT, copies only the non-sensitive fields defined below into a fresh outbound PSBT, and drops everything else before handoff. The scrubber must sit inside the wallet trust domain: it needs the full PSBT to scrub correctly, and only the scrubbed copy crosses the trust domain. + + + +## Fields + +We categorize PSBT fields from the [BIP 174 type registry](https://github.com/bitcoin/bips/blob/master/bip-0174/type-registry.mediawiki) by privacy sensitivity. Each table lists the registry name, key type, minimum PSBT version, and the BIP that introduces the field. + +### Insensative Fields + +These include public fields that the final transaction reveals onchain. + +Some of these fields will always be available on-chain. Others are conditional based on the output type and/or the wallet policy. Ones that are optional should not be shared with other signing parties or the combiner. If they are non-optional they can be shared unconditionally. If a field is non-optional but may not end up on chain (providing witness for multiple spending condition) the peer before the trust boundary must make a judgment call and remove fields that are unliekly to be used as witness before handoff. + +Some of these fields will always be available on-chain. Others are conditional based on the output type and/or the wallet policy. Optional ones should not be shared with other signing parties or the combiner; non-optional ones can be shared unconditionally. + +For example, the combiner does not need witness scripts (only a signing party does). `PSBT_IN_SEQUENCE` is fine to share and is necessary when merge conflicts arise. + +#### Global + +`` | PSBT version | BIP | +--- | --- | --- | +`PSBT_GLOBAL_UNSIGNED_TX = 0x00` | 0, 2 | [174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) | +`PSBT_GLOBAL_TX_VERSION = 0x02` | 2 | [370](https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki) | +`PSBT_GLOBAL_FALLBACK_LOCKTIME = 0x03` | 2 | [370](https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki) | +`PSBT_GLOBAL_INPUT_COUNT = 0x04` | 2 | [370](https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki) | +`PSBT_GLOBAL_OUTPUT_COUNT = 0x05` | 2 | [370](https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki) | + +#### Input + +`` | PSBT version | BIP | +--- | --- | --- | +`PSBT_IN_NON_WITNESS_UTXO = 0x00` | 0, 2 | [174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) | +`PSBT_IN_WITNESS_UTXO = 0x01` | 0, 2 | [174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) | +`PSBT_IN_SIGHASH_TYPE = 0x03` | 0, 2 | [174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) | +`PSBT_IN_REDEEM_SCRIPT = 0x04` | 0, 2 | [174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) | +`PSBT_IN_WITNESS_SCRIPT = 0x05` | 0, 2 | [174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) | +`PSBT_IN_FINAL_SCRIPTSIG = 0x07` | 0, 2 | [174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) | +`PSBT_IN_FINAL_SCRIPTWITNESS = 0x08` | 0, 2 | [174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) | +`PSBT_IN_PREVIOUS_TXID = 0x0e` | 2 | [370](https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki) | +`PSBT_IN_OUTPUT_INDEX = 0x0f` | 2 | [370](https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki) | +`PSBT_IN_SEQUENCE = 0x10` | 2 | [370](https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki) | +`PSBT_IN_REQUIRED_TIME_LOCKTIME = 0x11` | 2 | [370](https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki) | +`PSBT_IN_REQUIRED_HEIGHT_LOCKTIME = 0x12` | 2 | [370](https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki) | +`PSBT_IN_TAP_KEY_SIG = 0x13` | 2 | [371](https://github.com/bitcoin/bips/blob/master/bip-0371.mediawiki) | +`PSBT_IN_TAP_SCRIPT_SIG = 0x14` | 2 | [371](https://github.com/bitcoin/bips/blob/master/bip-0371.mediawiki) | +`PSBT_IN_TAP_LEAF_SCRIPT = 0x15` | 2 | [371](https://github.com/bitcoin/bips/blob/master/bip-0371.mediawiki) | + +/// Tapscript sig must be treated as sensative if it may not end up on chain. i.e the PSBT can be finalized in > 1 way. +/// Contrived: example: you have both a keyspend sig and a tapscript sig. Some other party decides to broadcast one. That other party learns of your taptree strucutre. + +// Same reasoning as above fir tap script sig + +#### Output + +`` | PSBT version | BIP | +--- | --- | --- | +`PSBT_OUT_AMOUNT = 0x03` | 2 | [370](https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki) | +`PSBT_OUT_SCRIPT = 0x04` | 2 | [370](https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki), [375](https://github.com/bitcoin/bips/blob/master/bip-0375.mediawiki) | + +#### Internal PSBT Fields + +These fields govern internal PSBT logic and can be shared without loss of privacy. + +`` | PSBT version | BIP | +--- | --- | --- | +`PSBT_GLOBAL_TX_MODIFIABLE = 0x06` | 2 | [370](https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki) | +`PSBT_GLOBAL_VERSION = 0xFB` | 0, 2 | [174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) | + +### Sensitive Fields + +These include signing fields and metadata a signing party needs to derive keys, identify wallet-controlled outputs, verify wallet policy, or verify protocol-specific rules. + +Air-gapped cold signing parties need these fields explicitly because they may not maintain wallet state or derive the required context from another source. + +#### Partial Signatures + +`` | PSBT version | BIP | +--- | --- | --- | +`PSBT_IN_PARTIAL_SIG = 0x02` | 0, 2 | [174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) | + +#### Derivation Fields + +Untrusted parties can derive future and previous (unhardened) addresses. + +`` | PSBT version | BIP | +--- | --- | --- | +`PSBT_GLOBAL_XPUB = 0x01` | 0, 2 | [174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) | +`PSBT_IN_BIP32_DERIVATION = 0x06` | 0, 2 | [174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) | +`PSBT_OUT_BIP32_DERIVATION = 0x02` | 0, 2 | [174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) | +`PSBT_IN_TAP_BIP32_DERIVATION = 0x16` | 2 | [371](https://github.com/bitcoin/bips/blob/master/bip-0371.mediawiki) | +`PSBT_OUT_TAP_BIP32_DERIVATION = 0x07` | 2 | [371](https://github.com/bitcoin/bips/blob/master/bip-0371.mediawiki) | +`PSBT_IN_SP_SPEND_BIP32_DERIVATION = 0x1f` | 2 | [376](https://github.com/bitcoin/bips/blob/master/bip-0376.mediawiki) | + +#### Proprietary and Unknown Fields + +Global, input, and output proprietary and unknown fields are application-defined: their meaning is not specified by the PSBT standards, so a scrubber cannot classify them as safe to retain. **By default, remove them** before any handoff to an untrusted party. + +`` | PSBT version | BIP | +--- | --- | --- | +`PSBT_GLOBAL_PROPRIETARY = 0xFC` | 0, 2 | [174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) | +`PSBT_IN_PROPRIETARY = 0xFC` | 0, 2 | [174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) | +`PSBT_OUT_PROPRIETARY = 0xFC` | 0, 2 | [174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) | +`(any unregistered keytype)` | 0, 2 | — | + +#### Pre-images + +These fields supply preimages for hash-lock conditions in scripts (HTLCs). TODO: expand rationale. + +`` | PSBT version | BIP | +--- | --- | --- | +`PSBT_IN_RIPEMD160 = 0x0a` | 0, 2 | [174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) | +`PSBT_IN_SHA256 = 0x0b` | 0, 2 | [174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) | +`PSBT_IN_HASH160 = 0x0c` | 0, 2 | [174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) | +`PSBT_IN_HASH256 = 0x0d` | 0, 2 | [174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) | + +#### Taptree Fields + +Taproot hides optional script paths from untrusted parties. Internal key and related fields reveal whether script paths exist. + +`` | PSBT version | BIP | +--- | --- | --- | +`PSBT_IN_TAP_INTERNAL_KEY = 0x17` | 2 | [371](https://github.com/bitcoin/bips/blob/master/bip-0371.mediawiki) | +`PSBT_IN_TAP_MERKLE_ROOT = 0x18` | 2 | [371](https://github.com/bitcoin/bips/blob/master/bip-0371.mediawiki) | +`PSBT_OUT_TAP_INTERNAL_KEY = 0x05` | 2 | [371](https://github.com/bitcoin/bips/blob/master/bip-0371.mediawiki) | +`PSBT_OUT_TAP_TREE = 0x06` | 2 | [371](https://github.com/bitcoin/bips/blob/master/bip-0371.mediawiki) | + +#### Output Redeem Script / Witness Script + +This data may eventually appear on-chain; revealing it early leaks the spending condition ppre. + +`` | PSBT version | BIP | +--- | --- | --- | +`PSBT_OUT_REDEEM_SCRIPT = 0x00` | 0, 2 | [174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) | +`PSBT_OUT_WITNESS_SCRIPT = 0x01` | 0, 2 | [174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) | + +#### MuSig Fields + +MuSig2 signing parties usually sit in the same trust domain. An untrusted party that learns the other signing parties’ keys can correlate them with the aggregate key and weaken MuSig’s single-key-spend obfuscation. + +`` | PSBT version | BIP | +--- | --- | --- | +`PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS = 0x1a` | 2 | [373](https://github.com/bitcoin/bips/blob/master/bip-0373.mediawiki) | +`PSBT_IN_MUSIG2_PUB_NONCE = 0x1b` | 2 | [373](https://github.com/bitcoin/bips/blob/master/bip-0373.mediawiki) | +`PSBT_IN_MUSIG2_PARTIAL_SIG = 0x1c` | 2 | [373](https://github.com/bitcoin/) + +/// I dont think musig2 keys are sensative the same pks in a OP_CHECKMULTISIG are. During setup to generate the aggregate key you nececarily need to know the entire key set to commit to it. So the signers are neccecarily in the same trust domain but what about the combiner? + +Generally, in musig2 the signing parties are within the same trust domain. However, if an untrusted party learns the other signing parties’ keys they can correlate the aggregate key with individual signing parties in that multisig. Or worse it defeats the whole point of musig: to obfuscate a multisig behind a single key spend. + +// Partial sig added for hte same reason as above. + +#### Silent Payment Fields + +Silent payment outputs should look like ordinary P2TR key spends. Reveal silent-payment fields only across a trust boundary when the protocol requires it. + +`` | PSBT version | BIP | +--- | --- | --- | +`PSBT_GLOBAL_SP_ECDH_SHARE = 0x07` | 2 | [375](https://github.com/bitcoin/bips/blob/master/bip-0375.mediawiki) | +`PSBT_GLOBAL_SP_DLEQ = 0x08` | 2 | [375](https://github.com/bitcoin/bips/blob/master/bip-0375.mediawiki) | +`PSBT_IN_SP_ECDH_SHARE = 0x1d` | 2 | [375](https://github.com/bitcoin/bips/blob/master/bip-0375.mediawiki) | +`PSBT_IN_SP_DLEQ = 0x1e` | 2 | [375](https://github.com/bitcoin/bips/blob/master/bip-0375.mediawiki) | +`PSBT_IN_SP_TWEAK = 0x20` | 2 | [376](https://github.com/bitcoin/bips/blob/master/bip-0376.mediawiki) | +`PSBT_OUT_SP_V0_INFO = 0x09` | 2 | [375](https://github.com/bitcoin/bips/blob/master/bip-0375.mediawiki) | +`PSBT_OUT_SP_V0_LABEL = 0x0a` | 2 | [375](https://github.com/bitcoin/bips/blob/master/bip-0375.mediawiki) | + +// Tweak the input s.t it can spend the output. +// If you reveal your tweak, a untrusting participant and link your input to a sp output. And verify the output is a sp output + +// TODO: are these sensative: yes just bc they label an output as sp when untrusting parties wouldnt otherwise know. +// Created when input set is not unilateral +// Created and shared when all inputs are owned by same owner +// This neccecarily implies common input owner. +// TODO: maybe this is sensative because of the CIH reasoning but the per input ones are not? + +#### Misc + +`` | PSBT version | BIP | +--- | --- | --- | +`PSBT_GLOBAL_GENERIC_SIGNED_MESSAGE = 0x09` | 2 | [322](https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki) | +`PSBT_IN_POR_COMMITMENT = 0x09` | 0, 2 | [127](https://github.com/bitcoin/bips/blob/master/bip-0127.mediawiki) | +`PSBT_OUT_DNSSEC_PROOF = 0x35` | 2 | [353](https://github.com/bitcoin/bips/blob/master/bip-0353.mediawiki) | + +PSBT_GLOBAL_GENERIC_SIGNED_MESSAGE falls into a similar catagory as proprietarty and unknown. Depending on what the message contents are they may be appropriate to be shared with untrusted parties. But by default should be removed. + +PSBT_IN_POR_COMMITMENT is neccecarily mean to be shared with trusted parties. Signing parties must only share their commitment with trusted parties. + +PSBT_OUT_DNSSEC_PROOF creates an "identity" to output mapping and should only be shared with trusted parties. + +### Modifiable Flag Note + +If the inputs or outputs modifiable flags are set the scrubber [can still remove individual fields](https://github.com/bitcoin/bips/pull/1059#discussion_r593537694). + +### Updater - multi signer case + +In cases where multiple untrusting signers are participating in the signing process, the updater must build a separate PSBT per signer and attach only that signer's required signing fields on each copy. + +### Field transfer sequence + +Example: wallet trust domain versus an external combiner. Creator through Scrubber sit in one domain and may handle signing metadata under your internal policy. Scrubber to Combiner is the trust-boundary crossing: the scrubber builds the outbound PSBT copy that keeps only what merge needs (typically the public transaction skeleton plus that signing party’s partial witness material) and drops every other privacy-sensitive field listed below. + +```mermaid +sequenceDiagram + box rgba(230,242,255,0.55) Wallet trust domain + participant Creator + participant Constructor + participant Updater + participant Signer + participant Scrubber + end + box rgba(255,235,235,0.45) External to wallet trust domain + participant Combiner + participant Finalizer + participant Extractor + end + + Creator->>Constructor: Empty PSBT + Constructor->>Updater: Public transaction fields + + Updater->>Signer: Public transaction fields + Updater->>Signer: Signing fields scoped to this signer + + Signer->>Scrubber: PSBT with signing metadata and partial witness + Note over Signer,Scrubber: Scrubber stays inside the wallet trust domain and may read the full PSBT. + + Scrubber->>Combiner: Public transaction fields + Scrubber->>Combiner: Partial witness fields for merge + Note over Scrubber,Combiner: Trust boundary. Outbound copy omits sensitive fields. + + Combiner->>Finalizer: Public transaction fields + Combiner->>Finalizer: Combined partial witness fields + + Finalizer->>Extractor: Finalization fields + Note over Extractor: Extract broadcast-ready transaction +``` + +Example: **2-of-3** with two co-owner signing parties in the wallet trust domain and a third **recovery signing party** outside it, as in [BIP 89](https://github.com/bitcoin/bips/blob/master/bip-0089.mediawiki) chain-code delegation. Co-owners receive full signing metadata inside the domain. The recovery party acts as **delegator** and must not receive other parties’ derivation paths, public keys, or partial signatures. The updater builds a separate PSBT copy per signing party. -All data that eventually winds up in the chain is fine: +```mermaid +sequenceDiagram + box rgba(230,242,255,0.55) Wallet trust domain + participant Creator + participant Constructor + participant Updater + participant SignerA + participant SignerB + participant Scrubber + participant Combiner + end + box rgba(255,235,235,0.45) BIP 89 delegator outside domain + participant SignerC + end -- construction -- prev txid and spent output index -- nsequence -- combiner (signing) -- witness or non witness utxo -- finalized witnesses/scriptSigs + Creator->>Constructor: Empty PSBT + Constructor->>Updater: Public transaction fields -Non-finalized signature data:: this is a bit more naunced and needs evaluation -of the other BIPs, in particular tapscript stuff, because not all data comitted -in the script needs to make it to the chain, depending on the spend paths. + Updater->>SignerA: PSBT copy, public fields and signing metadata + Updater->>SignerB: PSBT copy, public fields and signing metadata + Note over Updater,SignerB: Co-owners stay in domain. One party may act as BIP 89 delegatee. -All other fields should only be shared with trusted parties (e.g. own devices, -within an organization, etc) + Updater->>Scrubber: PSBT copy scoped to SignerC + Note over Updater,Scrubber: Omit other signing parties derivations and partial sigs. -### Output fields + Scrubber->>SignerC: Scrubbed PSBT and CCD tweak bundle + Note over Scrubber,SignerC: Trust boundary. Delegator sees only per-spend signing context. -Consensus fields: + SignerC->>Combiner: Partial witness from SignerC -- value -- script -- depending on the situation bip 375 silent payments info field may or may not be appropriate to share + SignerA->>Combiner: Partial witness from SignerA + SignerB->>Combiner: Partial witness from SignerB + Note over SignerA,Combiner: Combiner is trusted. Co-owners need not scrub for merge. -Derivation paths etc definitely need to be scrubbed. + Combiner->>Combiner: Merge partial witnesses +``` -### Global fields +### Refrence Implementation -Most BIP 174 or 370 global fields are fine but anything related to BIP 32 paths -or keys, multisig, miniscript etc should not be included. + +### Test Vectors +TODO