user101033: I noticed this sentence in Taproot about the MAST build.

The remaining scripts should be organized into the leaves of a binary tree. This can be a balanced tree if each of the conditions these scripts correspond to are equally likely. If probabilities for each condition are known, consider constructing the tree as a Huffman tree.

But in the case of a balanced Merkle Tree, an observer can infer the number of layers in the tree by the Merkle proof and thus get an approximate number of leaves(scripts). For example, a P2TR ends up unlocked with a time lock, and I infer from the Merkle proof that there are 2 scripts in total. Then I can guess the other lock is a hash lock(since this is the most common script with two conditions and one of them is a time lock).
It seems that forcing the user to use an unbalanced Merkle Tree would also be an option (e.g. randomly initialising the coefficients and then constructing a Huffman tree)? Or maybe put in some fake leaves?

user47827: 
For example, a P2TR ends up unlocked with a time lock, and I infer from the Merkle proof that there are two scripts in total.

You can't infer this for certain. You know what layer of the Merkle tree the script was taken from (in this case the first layer) but there may be scripts present on the second, third, fourth layers etc that you don't know about. I agree that if a script is taken from the first layer it is possible (perhaps likely) there are two scripts.

Then I can guess that this is a MAST containing a hash time lock (since this is the most common script with two conditions and one of them is a time lock).

I'm not sure why you think having one leaf script with a timelock infers that another leaf script contains a hash timelock. If you are referring to Lightning, the most common channel closes are cooperative 2-of-2 closes where no alternative script paths need to be included in the output. In the case of rarer uncooperative closes it is obvious to a blockchain observer that it is an uncooperative Lightning channel close, you can't hide this.

It seems that forcing the user to use an unbalanced Merkle Tree would also be an option (e.g. randomly initialising the coefficients and then constructing a Huffman tree)? Or maybe put in some fake leaves?

You can definitely construct the Taproot tree however you wish. You can put scripts in lower layers than they need to be so it seems to a blockchain observer there are more script paths than there actually are. Typically to save on fees you will want to put the script you are most likely to use on a higher layer of the Merkle tree but if you are more concerned with privacy you may choose not to do this.

user121614: The answer is very simple, you can't independently verify that the user is using an unbalanced Merkle tree without knowing its structure in full – rendering all anonymity benefits pointless. But you are overestimating how much information about the Merkle tree can be inferred. Since during a Taproot spend only one Merkle path is revealed, unless the script is located right under the Merkle root – in which case it is provably the only script in the tree – there is no way to know for sure how many spending conditions were defined.
However, to prevent anyone from even making reasonable guesses, a wallet software could randomize the Merkle tree structure with every transaction, similarly to how some wallets randomly shuffle transaction outputs to disguise the change output.

101033: <p>I noticed this sentence in Taproot about the MAST build.</p>
<blockquote>
<p>The remaining scripts should be organized into the leaves of a binary tree. This can be a balanced tree if each of the conditions these scripts correspond to are equally likely. If probabilities for each condition are known, consider constructing the tree as a Huffman tree.</p>
</blockquote>
<p>But in the case of a balanced Merkle Tree, an observer can infer the number of layers in the tree by the Merkle proof and thus get an approximate number of leaves(scripts). For example, a P2TR ends up unlocked with a time lock, and I infer from the Merkle proof that there are 2 scripts in total. Then I can guess the other lock is a hash lock(since this is the most common script with two conditions and one of them is a time lock).</p>
<p>It seems that forcing the user to use an unbalanced Merkle Tree would also be an option (e.g. randomly initialising the coefficients and then constructing a Huffman tree)? Or maybe put in some fake leaves?</p>
 47827: <blockquote>
<p>For example, a P2TR ends up unlocked with a time lock, and I infer from the Merkle proof that there are two scripts in total.</p>
</blockquote>
<p>You can't infer this for certain. You know what layer of the Merkle tree the script was taken from (in this case the first layer) but there may be scripts present on the second, third, fourth layers etc that you don't know about. I agree that if a script is taken from the first layer it is possible (perhaps likely) there are two scripts.</p>
<blockquote>
<p>Then I can guess that this is a MAST containing a hash time lock (since this is the most common script with two conditions and one of them is a time lock).</p>
</blockquote>
<p>I'm not sure why you think having one leaf script with a timelock infers that another leaf script contains a hash timelock. If you are referring to Lightning, the most common channel closes are cooperative 2-of-2 closes where no alternative script paths need to be included in the output. In the case of rarer uncooperative closes it is obvious to a blockchain observer that it is an uncooperative Lightning channel close, you can't hide this.</p>
<blockquote>
<p>It seems that forcing the user to use an unbalanced Merkle Tree would also be an option (e.g. randomly initialising the coefficients and then constructing a Huffman tree)? Or maybe put in some fake leaves?</p>
</blockquote>
<p>You can definitely construct the Taproot tree however you wish. You can put scripts in lower layers than they need to be so it seems to a blockchain observer there are more script paths than there actually are. Typically to save on fees you will want to put the script you are most likely to use on a higher layer of the Merkle tree but if you are more concerned with privacy you may choose not to do this.</p>
 121614: <p>The answer is very simple, you can't independently verify that the user is using an unbalanced Merkle tree without knowing its structure in full – rendering all anonymity benefits pointless. But you are overestimating how much information about the Merkle tree can be inferred. Since during a Taproot spend only one Merkle path is revealed, unless the script is located right under the Merkle root – in which case it is provably the only script in the tree – there is no way to know for sure how many spending conditions were defined.</p>
<p>However, to prevent anyone from even making reasonable guesses, a wallet software could randomize the Merkle tree structure with every transaction, similarly to how some wallets randomly shuffle transaction outputs to disguise the change output.</p>
