New fields required:
-
PSBT_IN_MUSIG_PARTICIPANT_PUBLIC_KEYS
:(<x_only_pk(agg_pk_to_sign)><x_only_pk(agg_pk)>)
-><[x_only_pk]*>
: For example,(a, b) -> [c]
whereb = Musig2_KeyAgg([c])
anda
is a tweaked(BIP32 tweak or x-only tweak or both) key derived fromb
where the tweaking information is present inPSBT_IN_TAP_BIP32_DERIVATION
in case of BIP32 tweak. In case,a
is the output key, an additional BIP341 tweak is applied. The tweak information is provided inPSBT_IN_TAP_INTERNAL_KEY
orPSBT_IN_TAP_MERKLE_ROOT
. The full xpub for the aggregatedagg_pk
can be provided inPBST_GLOBAL_XPUB
field -
PSBT_IN_TAP_MUSIG2_PUB_NONCE
:(<x_only_pk(participant_key), x_only_pk(agg_pk_to_sign), leaf_hash>)
-><pub_nonce>
(serialized pub_nonce includingR1
andR2
). -
PSBT_IN_TAP_PARTIAL_SIGNATURE
:(<x_only_pk(participant_key), x_only_pk(agg_pk_to_sign), leaf_hash>)
-><partial_sig>
(serialized partial_sig)
Q: How to compute the final tweak from the aggregated pubkey that is required for signing?
Note that the the key agg_xpk_tweaked
maybe different from the musig agg_pk
= KeyAgg(pki). In most cases, this would be obtained from applying a bip32 tweak to agg_pk
and another BIP341 taproot tweak. The signers and finalizers need to know this tweak to sign for agg_xkp_tweaked
. The BIP32 and x-only taproot tweaks can be computed recomputing agg_pk
= KeyAgg(pki) and looking at the PSBT_IN_TAP_BIP32_DERIVATION
for the agg_xkp_tweaked
. The derivation path, in this case, would be the non-hardened path agg_pk
. If the aggregated key being signed is the internal key, the additional taproot BIP341 tweak information is available in PSBT_IN_TAP_INTERNAL_KEY
or PSBT_IN_TAP_MERKLE_ROOT
.
- Wallet/users lookup psbt for all x-only public keys
PSBT_IN_TAP_INTERNAL_KEY
and in leaf (mini)scripts fromPSBT_IN_TAP_LEAF_SCRIPT
and lookup corresponding thePSBT_IN_TAP_BIP32_DERIVATION
for each key.- Non-aggregated pubkey case: If the derivation path is known to the wallet, sign with the corresponding key.
- Aggregated pubkey case: Lookup the key in
PSBT_IN_MUSIG_PARTICIPANT_PUBLIC_KEYS
(Map from<x_only_pk><x_only_pk>
->List[x_only_pks]
) and see we can sign for any of the constituent keys. To do this, we check thePSBT_IN_TAP_BIP32_DERIVATION
for each constituent key and check we have the key corresponding to the master fingerprint. If yes, we initiate in musig2 signing procedure for each of the keys that we can sign for.
- After figuring out which keys signers can sign for, each signer fills in
PSBT_IN_TAP_MUSIG2_PUB_NONCE
with key data as a tuple (partipant_pk
,agg_xpk_tweaked
,leaf_hash
) and value data as musig pub nonces(R1, R2)
.participant_pk
represents the public key of a participant in musig2 signing whileagg_xpk_tweaked
represents the final possibly multiple times tweaked public that the signers together want to sign.agg_xpk_tweaked
is included to indicate which key the signer is willing to sign for as the sameparticipant_pk
can be used multiple times in the different public keys in the same leaf script. (egmusig2(A, B, C)
andmusig2(A, D, E)
).leaf_hash
is also included for the signer to select which leaves they are willing to sign for. This nonce is not unique per signer, and the signer can add nonces to all keys that it is willing to sign for. If the key is an internal key, use[0u8; 32]
as leaf hash. - The signer should ensure that never even uses the same nonces again for any signing session regardless of the outcome of the session.
Remark: Musig2 has the benefit that we can proceed with round1 of signing without knowing the messages or keys! However a psbt workflow starts with an unsigned transaction, so it seems unlikely(?) that we can leverage this property to any use while signing bitcoin transactions. It may be possible to share these nonces out of the band before we engage in the psbt sign workflow, but that is outside of the scope of psbt.
- If all the participants have added nonces corresponding for
key, leaf_hash
pair, add a partial signature toPSBT_IN_TAP_PARTIAL_SIGNATURE
with key data(partipicant_pk, agg_pk_tweaked, leaf_hash)
and value aspartial-sig
which only contains thes
part of signature as per Musig partial sign spec.
- If there are enough signatures to produce a final signature, the finalizer can aggregate the partial signatures and add tweak*G and uses this as a final signature while satisfying the psbt.