Pay to Taproot

So far, we've seen many types of scriptPubKey in the previous modules: P2PKH, P2WPKH, P2SH, and P2WSH.

Reminder of the previous scripts

P2PKHOP_DUP OP_HASH160 <20B pubkey hash> OP_EQUALVERIFY OP_CHECKSIGP2WPKHOP_0 <20B pubkey hash>P2SHOP_HASH160 <20B script hash> OP_EQUALP2WSHOP_0 <32B script hash>

In this lesson, we will learn about a new type of scriptPubKey called P2TR.

P2TR has the following format:

OP_1 <32B tweaked key>
  • OP_1 means segwit version 1
  • <32B tweaked key> is what we are going to spend the next lessons explaining

Segwit v0 vs v1

Segwit v0 is used in P2WPKH and P2WSH:

P2WPKHOP_0 <20B pubkey hash>P2WSHOP_0 <32B script hash>

Both start with OP_0, and that is what marks them as segwit v0.

Segwit v1 is used in P2TR, and it is the one we are going to learn about in this module:

P2TROP_1 <32B tweaked key>

So far, P2TR looks like a simple script.

One way to spend it is with the private key corresponding to the <32B tweaked key>. This is called a key-path spend.

But the tweaked key is built in a way that makes it interesting. Let's see how.

Tweaking a public key

The term "tweak" means we start with an original public key and make a change to it to get a tweaked public key.

And that's exactly what we are going to do here.

Let's say we have an original public key PP.

Tweaking it means altering it with a value, which we call the tweak tt, to get a new tweaked public key QQ:

Q=P+tGQ = P + t \cdot G

There's a lot going on here, so let's break this equation into two parts: PP, the original public key, and tGt \cdot G.

Part 1: PP

PP is our original public key. Let's call its private key dd.

P=dGP = d \cdot G

That's just scalar multiplication, the operation that turns a private key dd into a public key PP. We can think of it as adding the generator point GG to itself dd times.

PP is also a point on the secp256k1 curve.

Part 2: tGt \cdot G

Now notice the second part of the equation: tGt \cdot G.

Doesn't this also look like a normal point on the secp256k1 curve, with tt acting like a private key?

That's exactly what it is mathematically. tGt \cdot G is a point made by adding GG to itself tt times.

We are going to call this point TT, so it is easier to reference:

  • TT is the tweak point
  • tt is the tweak value
T=tGT = t \cdot G

Putting it back together

So QQ, the tweaked public key, is just the addition of two points: PP, the original public key, and TT, the tweak point.

Q=P+T=dG+tG=(d+t)G\begin{aligned} Q &= P + T \\ &= d \cdot G + t \cdot G \\ &= (d + t) \cdot G \end{aligned}

Adding the two curve points dGd \cdot G and tGt \cdot G gives us a point whose private key is the sum of dd and tt.

The tweaked private key is therefore:

q=(d+t)modnq = (d + t) \bmod n

Here, nn is the order of the secp256k1 generator point.

That means if we have funds locked to the tweaked public key QQ, one way to spend them is by signing with the tweaked private key qq.

This works because QQ is just another point on the curve, created through point addition.

The P2TR output

Remember the scriptPubKey we saw at the beginning:

OP_1 <32B tweaked key>

That <32B tweaked key> is the QQ we just computed.

OP_1 <32B tweaked key> = OP_1 <Q> = OP_1 <P + T> = OP_1 <d·G + t·G>

A tweaked key looks like any other public key

From the outside, QQ looks like any other public key.

Someone looking at it cannot tell whether it was created by tweaking another key or generated directly from a private key. The original key PP and the tweak tt remain hidden.

This is one of Taproot's privacy properties.

Right now, the tweak tt looks like just an arbitrary value. In the next lessons, we will see how we make it commit to data.

That is where Taproot gets interesting.

Optional

Signing with a tweaked keypair

Prove in code that the tweaked private key signs for the tweaked public key. Skip it if you only want the theory.

We said that funds locked to QQ can be spent using the tweaked private key (d+t)modn(d+t) \bmod n.

Let's prove it in code.

Fill in the two tweaked values, then press Run.

Hints
  • T is already t*G. Add the two points with add(P, T).
  • The tweaked private key is the sum of the scalars, reduced mod n: (d + t) % n.

Solution code

In this example, the verifier only sees QQ. It has no idea that the key was built by adding a tweak.

In the next lessons, we will make that tweak commit to data, which is where Taproot gets powerful.

Suggest Edits