<p>Salts are used for things like password storage where multiple users may be using the same password. By using a salt it obfuscates to an observer of the database which users are using the same password because of different salts. The only motivation for using a salt on Taproot scripts would be if users were using the same Taproot scripts. But at the very least users' public keys will be different (unless they are using the same private key) and so no Taproot scripts will be the same unless they are controlled by the same user.</p>
<p>To state the obvious users shouldn't be using the same password (terrible password hygiene) for non-Bitcoin services but it is even more serious for Bitcoin. If users don't generate a Bitcoin private key with sufficient entropy their Bitcoin will likely be stolen.</p>
<blockquote>
<p>For the observation, it is possible to guess the unused script from the hash.</p>
</blockquote>
<p>Guessing the preimage of a secure hash function is infeasible. It can only be done through brute force (trying lots of possible preimages) but there are so many possible preimages it is like looking for a needle in a haystack.</p>

CC BY-SA 4.0
2021-07-19T07:53:07.460Z
Yes, it would be very difficult to find hash collisions, but would it be easier if there were some qualifications? For example, the three unlocking conditions in a MAST are

1. sig from A && sig B && timelock 10 Blocks 
2. sig from A && timelock 100 Blocks
3. sig from B && timelock 200 Blocks

They then eventually unlocked with condition 1. The observer then tries A's public key + time lock to collide. I know this is a rare example, but it still works, right? And if you add salt to the script it seems to stop it?
sphpmp
CC BY-SA 4.0
2021-07-19T08:09:26.367Z
Just checking I understand your question. In your scenario a script is revealed and a blockchain observer uses the details of that script to try to work out through (informed) brute force the other scripts in the Taproot tree (MAST) that weren't revealed and used to spend? Or uses the details of that script to try to work out the other scripts in other Taproot trees? Because obviously the observer/attacker doesn't know the private key(s) and so can't steal the funds even if he/she succeeds in brute forcing a particular script from a hash.
Michael Folkson
CC BY-SA 4.0
2021-07-19T08:15:22.463Z
No, I don't want to discuss here whether an attacker could spend this UTXO, but only whether this would lead to a leak of unused scripts, as this seems to defeat the original purpose of Taproot?  

And by adding salt to the script, for an observer, even if he knows some information, he cannot know the script corresponding to the hash (because of the presence of the salt).
sphpmp
CC BY-SA 4.0
2021-07-19T08:44:55.017Z
I think the answer to your question then is that tagged hashes are used throughout Taproot and this performs a similar role to a salt. https://github.com/bitcoinops/taproot-workshop/blob/b5a84402dde6a52dfdd979b8b1703ce8a8f3480f/0.3-tagged-hashes.ipynb
Michael Folkson
CC BY-SA 4.0
2021-07-19T09:00:33.577Z
Tagged Hash seems to prevent a branch node from being able to be interpreted as a leaf node. And all the tags for leaf nodes when I read BIP 341 were **Tapleaf**. So I guess it's still different from what salt means.
sphpmp
CC BY-SA 4.0
2021-07-19T09:02:39.187Z
If each leaf node has a different tag, then indeed that would be my answer, but I don't see that they are different at the moment (correct me if I'm wrong). And, thank you very much for your answer!
sphpmp
CC BY-SA 4.0
2021-07-19T15:19:39.747Z
@MichaelFolkson As the tagged hash is predictable it can't function as a salt. It prevents the data being hashed from accidentally matching a hash used in a different context, but it cannot provide privacy as the tag isn't secret.
Pieter Wuille
CC BY-SA 4.0
2021-07-19T07:31:47.777Z
2021-07-19T07:40:14.883Z
2021-07-19T07:40:14.883Z
Michael Folkson
<p>In general this shouldn't be a concern, as every script almost certainly contains at least a public key, and you can use fresh public keys in every branch.</p>
<p>If you're still concerned about privacy of the revealed script, you can tweak the public keys in it manually with some secret that's shared between all participants (e.g. the hash of concatenation of all scripts in it, before tweaking). Or you can even add extra data to one using a push opcode and OP_DROP.</p>

CC BY-SA 4.0
2021-07-19T15:13:26.873Z
2021-07-19T15:13:26.873Z
Pieter Wuille
<p>The corresponding Merkle proof needs to be given when unlocking UTXO using MAST, where the hash of an unused script will be included. For the observation, it seems possible to guess the unused script from the hash. For example, I might be able to get some public keys from the script that is actually being executed, and then I combine one of them with some time locks to try to do hash collisions.</p>
<p>Adding salt to the script would seem to easily prevent this, so why hasn't Taproot done this? Is this because the hash collision described above is basically infeasible, and adding salt takes up extra witness space?</p>

<privacy><taproot><key-tweaking>
Why don't add salt to the tapscript in Taproot?
sphpmp
# Why don't add salt to the tapscript in Taproot?

(Asked by: username_0 on 2021-07-19)

The corresponding Merkle proof needs to be given when unlocking UTXO using MAST, where the hash of an unused script will be included. For the observation, it seems possible to guess the unused script from the hash. For example, I might be able to get some public keys from the script that is actually being executed, and then I combine one of them with some time locks to try to do hash collisions.

Adding salt to the script would seem to easily prevent this, so why hasn't Taproot done this? Is this because the hash collision described above is basically infeasible, and adding salt takes up extra witness space?

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


---

## 2 answers

### Answer by username_2 on 2021-07-19. Score: 4 | Accepted answer

In general this shouldn't be a concern, as every script almost certainly contains at least a public key, and you can use fresh public keys in every branch.

If you're still concerned about privacy of the revealed script, you can tweak the public keys in it manually with some secret that's shared between all participants (e.g. the hash of concatenation of all scripts in it, before tweaking). Or you can even add extra data to one using a push opcode and OP\_DROP.


---

### Answer by username_1 on 2021-07-19. Score: 2

Salts are used for things like password storage where multiple users may be using the same password. By using a salt it obfuscates to an observer of the database which users are using the same password because of different salts. The only motivation for using a salt on Taproot scripts would be if users were using the same Taproot scripts. But at the very least users' public keys will be different (unless they are using the same private key) and so no Taproot scripts will be the same unless they are controlled by the same user.

To state the obvious users shouldn't be using the same password (terrible password hygiene) for non-Bitcoin services but it is even more serious for Bitcoin. If users don't generate a Bitcoin private key with sufficient entropy their Bitcoin will likely be stolen.

> For the observation, it is possible to guess the unused script from the hash.

Guessing the preimage of a secure hash function is infeasible. It can only be done through brute force (trying lots of possible preimages) but there are so many possible preimages it is like looking for a needle in a haystack.

> **Comments:**
> **username_0**: Yes, it would be very difficult to find hash collisions, but would it be easier if there were some qualifications? For example, the three unlocking conditions in a MAST are  1. sig from A && sig B && timelock 10 Blocks  2. sig from A && timelock 100 Blocks 3. sig from B && timelock 200 Blocks  They then eventually unlocked with condition 1. The observer then tries A's public key + time lock to collide. I know this is a rare example, but it still works, right? And if you add salt to the script it seems to stop it?  
> **username_1**: Just checking I understand your question. In your scenario a script is revealed and a blockchain observer uses the details of that script to try to work out through (informed) brute force the other scripts in the Taproot tree (MAST) that weren't revealed and used to spend? Or uses the details of that script to try to work out the other scripts in other Taproot trees? Because obviously the observer/attacker doesn't know the private key(s) and so can't steal the funds even if he/she succeeds in brute forcing a particular script from a hash.  
> **username_0**: No, I don't want to discuss here whether an attacker could spend this UTXO, but only whether this would lead to a leak of unused scripts, as this seems to defeat the original purpose of Taproot?    And by adding salt to the script, for an observer, even if he knows some information, he cannot know the script corresponding to the hash (because of the presence of the salt).  
> **username_1**: I think the answer to your question then is that tagged hashes are used throughout Taproot and this performs a similar role to a salt. https://github.com/bitcoinops/taproot-workshop/blob/b5a84402dde6a52dfdd979b8b1703ce8a8f3480f/0.3-tagged-hashes.ipynb  
> **username_0**: Tagged Hash seems to prevent a branch node from being able to be interpreted as a leaf node. And all the tags for leaf nodes when I read BIP 341 were **Tapleaf**. So I guess it's still different from what salt means.  
> **username_0**: If each leaf node has a different tag, then indeed that would be my answer, but I don't see that they are different at the moment (correct me if I'm wrong). And, thank you very much for your answer!  
> **username_2**: @username_1 As the tagged hash is predictable it can't function as a salt. It prevents the data being hashed from accidentally matching a hash used in a different context, but it cannot provide privacy as the tag isn't secret.  

---

