Alternative Signed Scripts?

The soon-to-be live Taproot upgrade introduces the possibility of associating a collection of ‘alternative’ scripts to a Bitcoin address. These allow coins to be locked into a contract containing a collection of different clauses by which they can be unlocked and, when spending, we only reveal the script corresponding to the specific clause being activated. So long as all parties to the address authorise the transaction, a standard Taproot spend can be used simply by providing the digital signature, in which case, none of the alternative scripts need to be used or represented on the blockchain at all. As I described in an earlier post, the scripts are represented by a Merkelized Alternative Script Tree (MAST, for short). The Merkle root is used to modify the public key and, when activating a particular script for spending, it, along with its Merkle proof, is included in the spending transaction’s witness field.

There is another, simpler, way in which alternative scripts could have been incorporated, which I will refer to as Alternative Signed Scripts (or ASS, if you prefer…). This is a suggestion as to how it could easily have been done, and not a description of the actual Taproot implementation as it is. Hence the question mark in the post title — why did Bitcoin devs not implement the method which I will describe here? Is there a particular reason, or was it just not considered?

First, recall that a Taproot address contains a public key in the scriptPubKey of the sending transaction, and the corresponding Schnorr signature in the witness field of the spending transaction.

P2TR — Pay to Taproot
witness <signature>
scriptPubKey OP_1 <pubKey>

To be a valid spend, the signature needs to be valid for the provided public key and with the transaction as the message. To spend using an alternative signed script, we would have exactly the same Taproot format for the scriptPubKey associated with the Bitcoin address. The only difference is in the witness field of the transaction spending the coins.

P2TR — Pay to Taproot
witness <sig_1> … <sig_n><script><signature>
scriptPubKey OP_1 <pubKey>

Here, <script> is a serialization of the alternative spend script to be used, and <signature> is a Schnorr signature for the spend script. When validating the spend, we first use the public key to check that the signature is valid using the specified script as the message. Next, the items <sig_1> through <sig_n> are pushed onto the stack. Finally, <script> is deserialized and executed. As usual, if the value at the top of the stack is True then the spend is valid, otherwise it is invalid.

That is all there is to my hypothetical ASS upgrade. It is simple, but should allow all the same flexibility as the standard Taproot MAST implementation. Recall that, by aggregation, Schnorr signatures can handle multisig accounts in the same way as for single sig. Hence, the public key for a Taproot address could represent a single signatory or multiple parties. In either case, all parties could agree beforehand to sign a set of scripts defining different methods of spending from the address, and share these signatures. When spending, if they are all present, they can cooperate to sign the spending transaction and initiate a standard Taproot spend. On the other hand, any party can use one of the prepared scripts along with its signature to enforce an alternative spend. This achieves the same result as the usual Taproot where, instead, they build a Merkle tree. As alternative signed scripts can only be used for spending if all parties to the address have cooperated to create a valid Schnorr signature, it is secure. Only allowed spend scripts can be used. The suggested method in this post does seem to have several advantages over MAST.

  • It is simpler. For alternative signed scripts, we do not modify the public key in any way, unlike with MAST where the public key has to be merged with the Merkle root and the signing algorithm similarly modified.
  • It is more private. Spending using a signed script is not affected in any way by the existence of any other alternative signed scripts. With MAST, the Merkle tree has to be contructed by combining all scripts. When spending, the Merkle proof is sent in the witness field of the transaction, revealing the depth of the tree, and giving an indication as to the total number of alternative scripts.
  • It is more flexible. For example, it is possible for the signatories to the Taproot address to agree to additional signed scripts after it has already been funded. With MAST, this is not possible since it requires rebuilding the Merkle tree and creating a new Merkle root, which changes the public key. Admittedly, no-one has asked for this functionality as far as I am aware, but it is interesting that the simplicity of using signed scripts allows such flexibility.
  • It is more space-efficient in many cases. For a Merkle tree of depth n, MAST requires providing a control string of length 33 + 32n bytes, whereas an alternative signed script would instead require a single 64 byte signature. Hence, signed scripts would use up less space on the blockchain except for the case where there is only a single alternative script so that the Merkle tree has depth n = 0.

I end the post by re-iterating the questions from above. Why did Bitcoin devs not implement the method of signed scripts described here? Is there a particular reason, or was it just not considered? Maybe there are benefits to the existing MAST implementation that I did not consider but, by my arguments above, using signed scripts would seem to offer some improvements over MAST while also being simpler to implement and use.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s