As far as I can tell there are three ways you can produce a valid Schnorr signature in a Taproot environment:
- For a p2tr output that uses a BIP-0086 commitment (key spend, sign with internal key, tweak with
h_tapTweak(internalKey)*G
) - For a p2tr output that commits to a script tree root hash (key spend, sign with internal key, tweak with
h_tapTweak(internalKey || scriptRoot)*G
) - For a p2tr output that commits to a script merkle tree root hash (script spend, sign with any key to satisfy leaf script)
How do I find out which of the above signature "methods" is expected to be produced by a PSBT signer?
The updated BIP-0174 document only mentions all the new Taproot related fields for the inputs and outputs but does not mention how to interpret them and what combinations of values are valid.
I found some test vectors in https://github.com/bitcoin/bitcoin/pull/22558 that gave me some clues, but I'm not sure if I'm missing an important resource that describes the PSBT signing process in more detail?
This is what I was able to scrape together so far:
- (p2tr BIP-0086 key spend): Set
PSBT_IN_TAP_BIP32_DERIVATION
with internal key and zero/empty leaf hashes. - (p2tr script root hash key spend): Set
PSBT_IN_TAP_BIP32_DERIVATION
with internal key zero/empty leaf hashes, setPSBT_IN_TAP_MERKLE_ROOT
to merkle root hash. - (p2tr script spend): Set
PSBT_IN_TAP_BIP32_DERIVATION
with internal key and the leaf hash of the leaf that is being executed. Also setPSBT_IN_TAP_LEAF_SCRIPT
with the control block and the script of the executed leaf.
Does that look correct?
If yes, then what is the significance of the PSBT_IN_TAP_INTERNAL_KEY
field compared to using the internal key in the PSBT_IN_TAP_BIP32_DERIVATION
field? It feels like I'm missing something here.