<p>Yes, that looks correct.</p>
<p>I suppose you are correct that <code>PSBT_IN_TAP_INTERNAL_KEY</code> is not strictly necessary, but one of the main ideas with PSBTs is to include as much information as possible, and to be explicit what the information included is. So instead of inferring the internal key from <code>PSBT_IN_TAP_BIP32_DERIVATION</code>, we explicitly say what it is with <code>PSBT_IN_TAP_INTERNAL_KEY</code>.</p>
<p>It is also possible to have the internal key also be a key inside of a script (dunno why you'd want that, but it could happen). In that case, it would not be possible to infer which key is the internal key from just <code>PSBT_IN_TAP_BIP32_DERIVATION</code>.</p>

CC BY-SA 4.0
2022-04-28T07:29:10.117Z
Thank you for your answer! It makes sense to me to add as much information as possible. But when implementing the signer role it's useful to know what the minimum required fields are in order to perform some validation.
guggero
CC BY-SA 4.0
2022-04-28T07:30:13.807Z
In your example, I assume that the same key would appear in the PSBT_IN_TAP_BIP32_DERIVATION field twice? Once with no leaf hashes and once with a leaf hash?
guggero
CC BY-SA 4.0
2022-04-28T14:37:02.167Z
@guggero no, it would be there once with one leaf hash. A PSBT cannot have duplicate keys.
Ava Chow
CC BY-SA 4.0
2022-04-28T14:41:44.533Z
Ah, right, I mixed it up in my head with PSBT_IN_TAP_SCRIPT_SIG where the leaf hash is in the key along with the pubkey. Now it all makes sense to me, thanks a lot!
guggero
CC BY-SA 4.0
2022-04-27T22:50:26.577Z
2022-04-27T22:50:26.577Z
Ava Chow
<p>As far as I can tell there are three ways you can produce a valid Schnorr signature in a Taproot environment:</p>
<ol>
<li>For a p2tr output that uses a <a href="https://github.com/bitcoin/bips/blob/master/bip-0086.mediawiki" rel="nofollow noreferrer">BIP-0086</a> commitment (key spend, sign with internal key, tweak with <code>h_tapTweak(internalKey)*G</code>)</li>
<li>For a p2tr output that commits to a script tree root hash (key spend, sign with internal key, tweak with <code>h_tapTweak(internalKey || scriptRoot)*G</code>)</li>
<li>For a p2tr output that commits to a script merkle tree root hash (script spend, sign with any key to satisfy leaf script)</li>
</ol>
<p>How do I find out which of the above signature &quot;methods&quot; is expected to be produced by a PSBT signer?</p>
<p>The updated <a href="https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki" rel="nofollow noreferrer">BIP-0174</a> 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.</p>
<p>I found some test vectors in <a href="https://github.com/bitcoin/bitcoin/pull/22558" rel="nofollow noreferrer">https://github.com/bitcoin/bitcoin/pull/22558</a> 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?</p>
<p>This is what I was able to scrape together so far:</p>
<ol>
<li>(p2tr BIP-0086 key spend): Set <code>PSBT_IN_TAP_BIP32_DERIVATION</code> with internal key and <strong>zero/empty leaf hashes</strong>.</li>
<li>(p2tr script root hash key spend): Set <code>PSBT_IN_TAP_BIP32_DERIVATION</code> with internal key <strong>zero/empty leaf hashes</strong>, set <code>PSBT_IN_TAP_MERKLE_ROOT</code> to merkle root hash.</li>
<li>(p2tr script spend): Set <code>PSBT_IN_TAP_BIP32_DERIVATION</code> with internal key and the leaf hash of the leaf that is being executed. Also set <code>PSBT_IN_TAP_LEAF_SCRIPT</code> with the control block and the script of the executed leaf.</li>
</ol>
<p>Does that look correct?</p>
<p>If yes, then what is the significance of the <code>PSBT_IN_TAP_INTERNAL_KEY</code> field compared to using the internal key in the <code>PSBT_IN_TAP_BIP32_DERIVATION</code> field? It feels like I'm missing something here.</p>

<taproot><bip174-psbt><p2tr>
Taproot signing with PSBT: How to determine signing method?
guggero
# Taproot signing with PSBT: How to determine signing method?

(Asked by: username_0 on 2022-04-27)

As far as I can tell there are three ways you can produce a valid Schnorr signature in a Taproot environment:

1. For a p2tr output that uses a [BIP-0086](https://github.com/bitcoin/bips/blob/master/bip-0086.mediawiki) commitment (key spend, sign with internal key, tweak with `h_tapTweak(internalKey)*G`)
2. 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`)
3. 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](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) 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:

1. (p2tr BIP-0086 key spend): Set `PSBT_IN_TAP_BIP32_DERIVATION` with internal key and **zero/empty leaf hashes**.
2. (p2tr script root hash key spend): Set `PSBT_IN_TAP_BIP32_DERIVATION` with internal key **zero/empty leaf hashes**, set `PSBT_IN_TAP_MERKLE_ROOT` to merkle root hash.
3. (p2tr script spend): Set `PSBT_IN_TAP_BIP32_DERIVATION` with internal key and the leaf hash of the leaf that is being executed. Also set `PSBT_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.

**Tags:** taproot, bip174-psbt, p2tr


---

## 1 answers

### Answer by username_1 on 2022-04-27. Score: 2 | Accepted answer

Yes, that looks correct.

I suppose you are correct that `PSBT_IN_TAP_INTERNAL_KEY` is not strictly necessary, but one of the main ideas with PSBTs is to include as much information as possible, and to be explicit what the information included is. So instead of inferring the internal key from `PSBT_IN_TAP_BIP32_DERIVATION`, we explicitly say what it is with `PSBT_IN_TAP_INTERNAL_KEY`.

It is also possible to have the internal key also be a key inside of a script (dunno why you'd want that, but it could happen). In that case, it would not be possible to infer which key is the internal key from just `PSBT_IN_TAP_BIP32_DERIVATION`.

> **Comments:**
> **username_0**: Thank you for your answer! It makes sense to me to add as much information as possible. But when implementing the signer role it's useful to know what the minimum required fields are in order to perform some validation.  
> **username_0**: In your example, I assume that the same key would appear in the PSBT_IN_TAP_BIP32_DERIVATION field twice? Once with no leaf hashes and once with a leaf hash?  
> **username_1**: @username_0 no, it would be there once with one leaf hash. A PSBT cannot have duplicate keys.  
> **username_0**: Ah, right, I mixed it up in my head with PSBT_IN_TAP_SCRIPT_SIG where the leaf hash is in the key along with the pubkey. Now it all makes sense to me, thanks a lot!  

---

