<p>The Tapscript would look like this:</p>
<pre><code>&lt;32-byte pubkey1&gt; OP_CHECKSIG &lt;32-byte pubkey2&gt; OP_CHECKSIGADD 1 OP_NUMEQUAL
</code></pre>
<p>Note: Unlike in P2SH/P2WSH, pubkeys should be 32-byte x-only pubkeys in tapscript.</p>
<p>This tapscript would go in the Tapscript tree. Assuming this is the only script you'd like to lock the bitcoin to, the tree would be a single leaf with this script and the BIP342 Leaf Version.</p>
<p>Next, you must define an internal pubkey. Assuming you want the 1-of-2 script to be the only way to spend the bitcoin, you can follow BIP341's recommendation for how to generate a private but provably unsolvable internal key.</p>
<blockquote>
<p>...pick as internal key a point with unknown discrete logarithm. One example of such a point is <code>H = lift_x(0x0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0) </code>which is constructed by taking the hash of the standard uncompressed encoding of the secp256k1 base point <code>G</code> as X coordinate. In order to avoid leaking the information that key path spending is not possible it is recommended to pick a fresh integer <code>r</code> in the range <code>0...n-1</code> uniformly at random and use <code>H + rG</code> as internal key. It is possible to prove that this internal key does not have a known discrete logarithm with respect to <code>G</code> by revealing <code>r</code> to a verifier who can then reconstruct how the internal key was created.</p>
</blockquote>
<p>From there, you must merkelize the script tree (a single leaf in your case) and use the result to tweak the internal pubkey, resulting in Q, the Taproot output key. BIP341 explains this process and provides sample python code to do so:</p>
<p><a href="https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#constructing-and-spending-taproot-outputs" rel="nofollow noreferrer">https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#constructing-and-spending-taproot-outputs</a></p>

CC BY-SA 4.0
2023-03-08T17:55:36.797Z
That seems a bit silly; you can instead pick one of the keys as internal key, and use the other one in a "<key> OP_CHECKSIG" script. That's strictly cheaper to spend.
Pieter Wuille
CC BY-SA 4.0
2023-03-11T15:50:06.863Z
Yes this is definitely the better way to go if the only spend option you want is a 1-of-2. I think my answer is still valuable in the case that someone wants a 1-of-2 multisig as only 1 in a set of possible spend conditions.
Sachin Meier
CC BY-SA 4.0
2023-03-11T17:58:22.007Z
Even then it's better to split the options up into two individual single key options, and either turn both into leaves, or one into a leaf and the other into a key path. But fair enough, in that case it's less clear cut.
Pieter Wuille
CC BY-SA 4.0
2023-05-13T15:44:50.097Z
@sachin To clarify, the unlocking script for this would be either [00] [sig] or [sig] [00], and the script would fail if [sig0] [sig1] is provided (regardless if one or both signatures were valid). Correct?
Peter
CC BY-SA 4.0
2023-05-23T17:20:52.343Z
To be clear, the 0x00 byte indicates an empty vector. It's the length byte, not actual data. so the unlocking part of the stack would be [sig] [] or [] [sig]. And yes, [sig] [sig] should fail. You could easily change the script to accept >= N signatures but why waste data.
Sachin Meier
CC BY-SA 4.0
2023-03-08T17:38:22.170Z
2023-03-08T17:38:22.170Z
Sachin Meier
<p>We have two companies and we want to spend funds with 1-of-2 multisig. We successfully did such a multisig with P2SH. How can I do this in P2TR? Can any give me a detailed instruction step by step?
Thanks.</p>

CC BY-SA 4.0
2023-03-01T23:29:33.440Z
Hi Wei, do you have any requirements regarding the software, programming language or library you are using?
Murch
<multi-signature><address-generation><p2tr>
How to create a 1-of-2 multisig with P2TR?
Wei
# How to create a 1-of-2 multisig with P2TR?

(Asked by: username_0 on 2023-03-01)

We have two companies and we want to spend funds with 1-of-2 multisig. We successfully did such a multisig with P2SH. How can I do this in P2TR? Can any give me a detailed instruction step by step?
Thanks.

**Tags:** multi-signature, address-generation, p2tr

> **Comments:**
> **username_1**: Hi Wei, do you have any requirements regarding the software, programming language or library you are using?  

---

## 1 answers

### Answer by username_2 on 2023-03-08. Score: 2

The Tapscript would look like this:

```
<32-byte pubkey1> OP_CHECKSIG <32-byte pubkey2> OP_CHECKSIGADD 1 OP_NUMEQUAL

```

Note: Unlike in P2SH/P2WSH, pubkeys should be 32-byte x-only pubkeys in tapscript.

This tapscript would go in the Tapscript tree. Assuming this is the only script you'd like to lock the bitcoin to, the tree would be a single leaf with this script and the BIP342 Leaf Version.

Next, you must define an internal pubkey. Assuming you want the 1-of-2 script to be the only way to spend the bitcoin, you can follow BIP341's recommendation for how to generate a private but provably unsolvable internal key.

> ...pick as internal key a point with unknown discrete logarithm. One example of such a point is `H = lift_x(0x0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0)` which is constructed by taking the hash of the standard uncompressed encoding of the secp256k1 base point `G` as X coordinate. In order to avoid leaking the information that key path spending is not possible it is recommended to pick a fresh integer `r` in the range `0...n-1` uniformly at random and use `H + rG` as internal key. It is possible to prove that this internal key does not have a known discrete logarithm with respect to `G` by revealing `r` to a verifier who can then reconstruct how the internal key was created.

From there, you must merkelize the script tree (a single leaf in your case) and use the result to tweak the internal pubkey, resulting in Q, the Taproot output key. BIP341 explains this process and provides sample python code to do so:

<https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#constructing-and-spending-taproot-outputs>

> **Comments:**
> **username_3**: That seems a bit silly; you can instead pick one of the keys as internal key, and use the other one in a "<key> OP_CHECKSIG" script. That's strictly cheaper to spend.  
> **username_2**: Yes this is definitely the better way to go if the only spend option you want is a 1-of-2. I think my answer is still valuable in the case that someone wants a 1-of-2 multisig as only 1 in a set of possible spend conditions.  
> **username_3**: Even then it's better to split the options up into two individual single key options, and either turn both into leaves, or one into a leaf and the other into a key path. But fair enough, in that case it's less clear cut.  
> **username_4**: @username_2 To clarify, the unlocking script for this would be either [00] [sig] or [sig] [00], and the script would fail if [sig0] [sig1] is provided (regardless if one or both signatures were valid). Correct?  
> **username_2**: To be clear, the 0x00 byte indicates an empty vector. It's the length byte, not actual data. so the unlocking part of the stack would be [sig] [] or [] [sig]. And yes, [sig] [sig] should fail. You could easily change the script to accept >= N signatures but why waste data.  

---

