<p>You perform tweaking at signing time if the key you're signing for was tweaked. That's a decision that was made when the output was constructed, not when it is spent.</p>
<p>Taproot outputs can consist of:</p>
<ul>
<li>Just a raw public key directly, with no tweaking. In this case only a key path spend is available, by signing with the corresponding private key. It's just a pay-to-pubkey now, and there is no tweaking at any point. This approach is not advisable for reasons I won't go into, but it is perfectly legal.</li>
<li>Just an internal public key, with no script tree, which is tweaked to construct the output key using <code>H_TapTweak(pubkey)</code> as tweak. In this case again only a key path spend is available, but at spending time the private key needs to be tweaked by the same amount or it wouldn't match the published public key. This is what most single-party taproot wallets use.</li>
<li>The full construction with an internal public key, and a tree of one or more scripts. The output now consists of the internal key tweaked using <code>H_TapTweak(internal_pubkey || merkleroot)</code>, where <code>merkleroot</code> is the Merkle root of the script tree. Such outputs can be spent in one of two ways:
<ul>
<li>The key path spend, which involves signing with the tweaked private key, corresponding to the tweaked public key that was published in the output.</li>
<li>A script path spend, where one of the script leaves, the internal (untweaked) key, and a Merkle path proving that script occurred in the tree, are revealed, together with whatever that script needs to satisfy it. If that script involves CHECKSIG operations, signatures must be provided for the public keys in the script. If those public keys are tweaked, the signin step will need to tweak the corresponding private keys too, but this is not necessary or advisable. Typical constructions use untweaked keys inside taproot scripts.</li>
</ul>
</li>
</ul>
<p>So to summarize: you need to tweak private keys at spending time when the public key you're signing for was tweaked. Whether that is the case depends on how the output was constructed. The internal public key (the one intended for key path spends) is usually tweaked (and must be, if scripts are present). The public keys <em>inside</em> those scripts usually aren't tweaked (but in theory they could be).</p>
<blockquote>
<p>the privkey_a is used to sign the sighash to use TapScript_A, but nothing involves a tweak when constructing the witness <code>[signatureA, TapLeafA.script, control_map[TapLeafA.script]]</code>.</p>
</blockquote>
<p>The control block (taken from the <code>control_map</code> in the code you cite) contains the tweak that was used. It's just not used to sign the private keys, because the public keys in the script were not tweaked either. But the tweak must still be revealed, or verifiers cannot tell that the script you're revealed actually contributed to the published public key in the output.</p>
<blockquote>
<p>My question is, if I want to construct a taproot output just with script spend, what's the point of using tweak?</p>
</blockquote>
<p>You can't, really. Every taproot output that permits script path spending is constructed by taking an internal public key and tweaking it with the Merkle root, and you must know what that internal public key and tweak are to spend it, as you need to convince the verifier &quot;wait! that public key you saw in the output, it's actually tweaked using my script here, so I can spend with that instead!&quot;. If you don't want the ability to spend with any internal key using a key path, you'll need to use an internal key that nobody knows the private key to; but there still must be one.</p>
<p>The philosophy behind Taproot is that nearly always, outputs can have an internal public key corresponding to some or all of the participants' consent, and heavily optimizes for being able to sign using the key path as a result. If you have a use case with just a script, the result may feel unnatural due to the need for a dummy internal public key, and tweak.</p>

CC BY-SA 4.0
2023-04-20T06:01:33.290Z
Awesome, thank for clarifying.
pxr_64
CC BY-SA 4.0
2023-02-20T16:53:04.740Z
2023-02-20T17:33:24.717Z
2023-02-20T17:33:24.717Z
Pieter Wuille
<p>The taptweak is defined as <code>t = TAGGED_HASH(P | s)</code> where <code>P</code> is the internal public key and <code>s</code> is the Merkle Root with all tapleaves. You provide both <code>P</code> and <code>s</code>, so the tweak is computed using the mentioned formula. To get the external public key (the one in the spk) you just compute <code>P + tG</code></p>

CC BY-SA 4.0
2023-02-20T16:18:32.610Z
2023-02-20T16:18:32.610Z
Davidson Souza
<p>I understand that a taproot output can be either spent using key path or script path.</p>
<p>With key path, a tweak is applied to the private key and then sign the sighash. The signature is provided as a witness.</p>
<p>However with script path, I do not see the tweak being used anywhere. For example, in 2.4.8 in
<a href="https://github.com/bitcoinops/taproot-workshop/blob/master/solutions/2.4-taptree-solutions.ipynb" rel="nofollow noreferrer">https://github.com/bitcoinops/taproot-workshop/blob/master/solutions/2.4-taptree-solutions.ipynb</a>, the privkey_a is used to sign the sighash to use TapScript_A, but nothing involves a tweak when constructing the witness <code>[signatureA, TapLeafA.script, control_map[TapLeafA.script]]</code>.</p>
<p>My question is, if I want to construct a taproot output just with script spend, what's the point of using tweak?</p>

CC BY-SA 4.0
2023-02-20T16:22:21.057Z
Related question: https://bitcoin.stackexchange.com/questions/99722/taproot-eliminating-key-path
Michael Folkson
<taproot><p2tr><key-tweaking>
Is tweak used when spending from script path for Taproot?
Joy Wang
# Is tweak used when spending from script path for Taproot?

(Asked by: username_0 on 2023-02-20)

I understand that a taproot output can be either spent using key path or script path.

With key path, a tweak is applied to the private key and then sign the sighash. The signature is provided as a witness.

However with script path, I do not see the tweak being used anywhere. For example, in 2.4.8 in
<https://github.com/bitcoinops/taproot-workshop/blob/master/solutions/2.4-taptree-solutions.ipynb>, the privkey\_a is used to sign the sighash to use TapScript\_A, but nothing involves a tweak when constructing the witness `[signatureA, TapLeafA.script, control_map[TapLeafA.script]]`.

My question is, if I want to construct a taproot output just with script spend, what's the point of using tweak?

**Tags:** taproot, p2tr, key-tweaking

> **Comments:**
> **username_1**: Related question: https://bitcoin.stackexchange.com/questions/99722/taproot-eliminating-key-path  

---

## 2 answers

### Answer by username_2 on 2023-02-20. Score: 5

You perform tweaking at signing time if the key you're signing for was tweaked. That's a decision that was made when the output was constructed, not when it is spent.

Taproot outputs can consist of:

* Just a raw public key directly, with no tweaking. In this case only a key path spend is available, by signing with the corresponding private key. It's just a pay-to-pubkey now, and there is no tweaking at any point. This approach is not advisable for reasons I won't go into, but it is perfectly legal.
* Just an internal public key, with no script tree, which is tweaked to construct the output key using `H_TapTweak(pubkey)` as tweak. In this case again only a key path spend is available, but at spending time the private key needs to be tweaked by the same amount or it wouldn't match the published public key. This is what most single-party taproot wallets use.
* The full construction with an internal public key, and a tree of one or more scripts. The output now consists of the internal key tweaked using `H_TapTweak(internal_pubkey || merkleroot)`, where `merkleroot` is the Merkle root of the script tree. Such outputs can be spent in one of two ways:
  + The key path spend, which involves signing with the tweaked private key, corresponding to the tweaked public key that was published in the output.
  + A script path spend, where one of the script leaves, the internal (untweaked) key, and a Merkle path proving that script occurred in the tree, are revealed, together with whatever that script needs to satisfy it. If that script involves CHECKSIG operations, signatures must be provided for the public keys in the script. If those public keys are tweaked, the signin step will need to tweak the corresponding private keys too, but this is not necessary or advisable. Typical constructions use untweaked keys inside taproot scripts.

So to summarize: you need to tweak private keys at spending time when the public key you're signing for was tweaked. Whether that is the case depends on how the output was constructed. The internal public key (the one intended for key path spends) is usually tweaked (and must be, if scripts are present). The public keys *inside* those scripts usually aren't tweaked (but in theory they could be).

> the privkey\_a is used to sign the sighash to use TapScript\_A, but nothing involves a tweak when constructing the witness `[signatureA, TapLeafA.script, control_map[TapLeafA.script]]`.

The control block (taken from the `control_map` in the code you cite) contains the tweak that was used. It's just not used to sign the private keys, because the public keys in the script were not tweaked either. But the tweak must still be revealed, or verifiers cannot tell that the script you're revealed actually contributed to the published public key in the output.

> My question is, if I want to construct a taproot output just with script spend, what's the point of using tweak?

You can't, really. Every taproot output that permits script path spending is constructed by taking an internal public key and tweaking it with the Merkle root, and you must know what that internal public key and tweak are to spend it, as you need to convince the verifier "wait! that public key you saw in the output, it's actually tweaked using my script here, so I can spend with that instead!". If you don't want the ability to spend with any internal key using a key path, you'll need to use an internal key that nobody knows the private key to; but there still must be one.

The philosophy behind Taproot is that nearly always, outputs can have an internal public key corresponding to some or all of the participants' consent, and heavily optimizes for being able to sign using the key path as a result. If you have a use case with just a script, the result may feel unnatural due to the need for a dummy internal public key, and tweak.

> **Comments:**
> **username_3**: Awesome, thank for clarifying.  

---

### Answer by username_4 on 2023-02-20. Score: 0

The taptweak is defined as `t = TAGGED_HASH(P | s)` where `P` is the internal public key and `s` is the Merkle Root with all tapleaves. You provide both `P` and `s`, so the tweak is computed using the mentioned formula. To get the external public key (the one in the spk) you just compute `P + tG`


---

