Script Path Spend in Taproot

Published by Mario Oettler on

Script paths are the really interesting part of Taproot. They allow for the creation and execution of various spending conditions. They do not replace the key path, but can be used alongside key paths.

Creating a script path in Taproot is a little more complex than creating a simple key path. But the input script still only contains the following information, which we already know from the key path above.

However, the public key Q is generated differently. It takes the public input key and tweaks it with a value T.

Let us look at how T is obtained.

Let’s say we have three spending conditions called script 1, script 2, and script 3. These scripts are contained into a Merkle tree. If you want to learn more about this, you can refer to MAST (Merkelized alternative script trees).

A tagged hash is a hash of an existing hash function (such as SHA256) and adds some information (tag) at the beginning of the message before hashing it.

Tagged hashes are a security measure to prevent the same hash being interpreted in different ways.

G is the generator point. (A generator point is a point in a group that can produce any other value in that group by multiplying it with an integer.

t is a positive scalar value in the range of 0 < t < SECP256K1_ORDER.

Here, we also learned where the tweak T comes from. If there were no script, T would simply be taggedHash(“TapTweak”, P).

The Merkle tree itself is not stored anywhere in the blockchain.

With this tweaking scheme, it is possible to encode a commitment (script) into a public key. The commitment is revealed by signing with the tweaked private key:

x’ = x + t

  • x’: tweaked private key
  • x: private key
  • t: tweak When signing, the user can reveal that the original keys have been tweaked by the commitment.

An observer cannot tell whether a public key is tweaked or untweaked.

In order to spend a script path, we need to provide:

  1. The valid spend script.
  2. A proof that the chosen spending script is part of the output Q.

Step 1 is easy. We just need to attach the script.

In step 2 we need to provide all the information necessary for the verifier to check that the script is part of the output Q. This includes:

  • Internal key P,
  • Merkle proof: The script is already provided in step 1, so we only need the remaining (tagged) hashes.

These information are included in the “control block” of the transaction. It is important not to reuse keys. This is also important for the leaf keys. So, for each taproot output, all leaves have to be recomputed. Reusing leaves is a major security risk.