Taproot
Last updated
Last updated
The core of Taproot is composed of Schnorr signatures and MAST abstract syntax trees.
We'll focus on the creation of Taproot public keys and the spending pattern.
To create a Taproot public key, it is important to understand the process of generating aggregated public keys and aggregated signatures.
The related research focus on MuSig1 and MuSig2, it says MuSig1 is more complicated because it requires three rounds of communication to create a signature, with each round consisting of back-and-forth message exchanges.
From the above diagram, we can see that the generation process of aggregated public keys can be divided into three steps:
Public keys are exchanged between parties, and all the public keys are concatenated and hashed once to generate c_all.
c_all is concatenated with the public key i and hashed to generate the factor c_i.
The aggregated public key P_agg is obtained by linearly combining the public keys using the factor c_i.
The generation process of aggregated signatures, as shown in the diagram, requires three rounds of communication and can be divided into two main steps:
Nonces are generated and linearly aggregated to obtain R_agg.
Each party uses their private key to generate Schnorr signatures and then aggregates them to obtain the final aggregated signature (R_agg, s1+s2+s3).
As shown in the above diagram, a Taproot public key consists of two main components: the aggregated public key P and the public key formed by the MAST structure, denoted as tG.
Assuming P is the aggregated public key of Alice, Bob, and Charlie, and script_A, script_B, and script_C are the scripts related to Alice, Bob, and Charlie, respectively. Then the
Taproot public key creation process is as follows:
1)Generate public and private keys for each one.
2)The public key is aggregated into pubkey_agg and the private key is adjusted for later signing.
3)Create scripts script_A, script_B, script_C
4)Build the MAST abstract syntax tree
Calculate the private key taptweak corresponding to the MAST structure. In the figure above, TaggedHash represents a hash with a label, with a fixed length of 32 bytes, it calculated as:
TaggedHash(tag, x) = sha256(sha256(tag) + sha256(tag) + x)
ver represents the Tapscript version number, which is currently 0xc0;
size represents the number of bytes of the scirpt;
A&B means A, and the B dictionary is sorted and spliced by bytes.
5)According to the formula Q=P+tG to generate the taproot public key and segwit_address for the following transaction.
6)Transfer 50 BTC to the Taproot address.
To complete the transfer to Bob, there are two payment options:
i. Fill in all data like the original text of the transaction, the recipient's address, the amount, etc.
If we follow the first option, we need Alice, Bob, and Charlie to sign the transaction respectively and then generate their own nonce to aggregate them.
Finally, aggregating the signatures. As a result, the witness script for this option is a single signature with a fixed length of 64 bytes.
ii. Test whether the original of the transaction formed by the first cost is legitimate and send the transaction.
To perform the second method, where Alice uses script_A, the witness script should include the following components:
[Stack element(s) satisfying TapScript_A]
[TapScript_A] [Controlblock c]
Here, [Controlblock c] represents the proof associated with TapScript_A, with a length of 33 + 32n.
The first byte of the 33-byte sequence is calculated based on the aggregate public key and the Taproot version number.
The remaining 32 bytes represent the x-coordinate of the aggregate public key. 32n represents the proof for TapScript_A, and in this example, n is equal to 2, indicating taggedhash_leafB and taggedhash_leafC.
Test the second type of transaction formed by spending the original text and send the transaction.