|
| 1 | +--- |
| 2 | +title: "MuSig" |
| 3 | +date: 2024-01-25T15:32:14Z |
| 4 | +lastmod: "2024-07-26" |
| 5 | +draft: false |
| 6 | +category: Scripts |
| 7 | +layout: TopicBanner |
| 8 | +order: 7 |
| 9 | +icon: "FaUsers" |
| 10 | +parent: taproot |
| 11 | +--- |
| 12 | + |
| 13 | +# MuSig |
| 14 | + |
| 15 | +By the end of this article, we want Alice, Bob, and Carol to sign a transaction using MuSig. |
| 16 | + |
| 17 | +We will explain step by step using both theory and code. Your task by the end is to write the code for this signature generation. |
| 18 | + |
| 19 | +--- |
| 20 | + |
| 21 | +## 1. Theory |
| 22 | + |
| 23 | +To make this article simple to follow, we will answer three important questions that will help you understand the concept: **What? Why? How?** |
| 24 | + |
| 25 | +--- |
| 26 | + |
| 27 | +### What is MuSig? |
| 28 | + |
| 29 | +MuSig is simply a protocol for aggregating public keys and signatures. |
| 30 | + |
| 31 | +--- |
| 32 | + |
| 33 | +### Why do we need MuSig? |
| 34 | + |
| 35 | +The reasons we use MuSig are: |
| 36 | + |
| 37 | +- **Transaction Size/Fees:** Smaller transaction sizes lead to lower fees. |
| 38 | +- **Privacy:** We gain enhanced privacy. |
| 39 | + |
| 40 | +--- |
| 41 | + |
| 42 | +### How does MuSig work? |
| 43 | + |
| 44 | +Now we need your focus here, please. Grab a coffee, and let's dive in. |
| 45 | + |
| 46 | +Alice, Bob, and Carol want to create an aggregated signature such as: |
| 47 | +**s_agg = s_a + s_b + s_c** |
| 48 | + |
| 49 | +To create this signature, we need to go through three main steps: |
| 50 | + |
| 51 | +1. Aggregating public keys. |
| 52 | +2. Aggregating nonces. |
| 53 | +3. Aggregating the signature. |
| 54 | + |
| 55 | +Some of these steps require rounds of communication between participants: |
| 56 | + |
| 57 | +- Aggregating public keys does **not** require communication. |
| 58 | +- Aggregating nonces and signatures requires **three rounds of communication** (MuSig2 optimizes this to **two rounds**). |
| 59 | + |
| 60 | +--- |
| 61 | + |
| 62 | +## Step 1: Public Key Aggregation (Offline Process) |
| 63 | + |
| 64 | +A naive way to do public key aggregation is by summing up each participant's public key: |
| 65 | + |
| 66 | +**P_agg = P_a + P_b + P_c** |
| 67 | + |
| 68 | +However, this approach is vulnerable to a **key cancellation attack.** |
| 69 | + |
| 70 | +--- |
| 71 | + |
| 72 | +### What is a key cancellation attack? |
| 73 | + |
| 74 | +Imagine a scenario where Alice and Bob want to create a 2-of-2 aggregated signature. To achieve this, they need to: |
| 75 | + |
| 76 | +1. Exchange public keys. |
| 77 | +2. Exchange nonce commitments (needed for Schnorr signatures). |
| 78 | + |
| 79 | +But if Bob knows Alice’s public key (P_a) and nonce (R_a) beforehand, Bob can deceive Alice by sending modified values to her: |
| 80 | + |
| 81 | +- **P'_b = P_b - P_a** |
| 82 | +- **R'_b = R_b - R_a** |
| 83 | + |
| 84 | +When Alice calculates the signature, this manipulation causes issues. |
| 85 | + |
| 86 | +--- |
| 87 | + |
| 88 | +### Let’s break it down: |
| 89 | + |
| 90 | +The aggregated Schnorr signature equation is: |
| 91 | +**s_agg = s_a + s_b'** |
| 92 | + |
| 93 | +Expanding it: |
| 94 | + |
| 95 | +**s_agg * G = (R_a + h * P_a) + (R'_b + h * P'_b)** |
| 96 | +**= R_a + R'_b + h(P_a + P'_b)** |
| 97 | +**= R_a + (R_b - R_a) + h(P_a + P_b - P_a)** |
| 98 | +**= R_b + h(P_b)** |
| 99 | +**= s_b * G** |
| 100 | + |
| 101 | +--- |
| 102 | + |
| 103 | +**Did you catch it?** |
| 104 | +Bob can now sign the transaction alone without Alice's cooperation: **s_agg = s_b** |
| 105 | + |
| 106 | +--- |
| 107 | + |
| 108 | +### How do we counteract the key cancellation attack? |
| 109 | + |
| 110 | +To counteract this, we add a **challenge factor** to each participant's public key: |
| 111 | + |
| 112 | +**P'_i = c_i * P_i** |
| 113 | +(*c_i = challenge factor*) |
| 114 | + |
| 115 | +The challenge factor is generated based on the participants' aggregated public key. |
| 116 | + |
| 117 | +This ensures that no individual participant can create a public key that offsets the public keys of others. |
| 118 | + |
| 119 | +Here’s how we construct individual public keys and the aggregated public key: |
| 120 | +(*Remember, all of this happens offline. There’s no need for communication; public keys can be exchanged through offline channels.*) |
| 121 | + |
| 122 | +[Insert illustration here.] |
| 123 | + |
| 124 | +--- |
| 125 | + |
| 126 | +Now, let’s move to the next step: **Aggregate Nonce**. |
| 127 | + |
| 128 | +## Step 2: Aggregate nonces |
| 129 | + |
| 130 | +## Step 2: Aggregate Nonce (1st and 2nd Round of Communication) |
| 131 | + |
| 132 | +The process of aggregating nonces is as follows: |
| 133 | + |
| 134 | +1. Alice, Bob, and Carol each generate a random nonce **k_A**, **k_B**, and **k_C**. |
| 135 | +2. They calculate their respective nonce points: |
| 136 | + **R_A = k_A * G**, **R_B = k_B * G**, **R_C = k_C * G**. |
| 137 | +3. They exchange these nonce points (**R_A**, **R_B**, and **R_C**). |
| 138 | +4. Finally, they calculate the aggregated nonce: |
| 139 | + **R_agg = R_A + R_B + R_C** |
| 140 | + |
| 141 | +--- |
| 142 | + |
| 143 | +### Where do the rounds of communication happen in this process? |
| 144 | + |
| 145 | +Great question! The process of aggregating nonces is somewhat similar to aggregating public keys. |
| 146 | + |
| 147 | +**Except**: Public keys (e.g., **P_A**, **P_B**, and **P_C**) stay the same for every signature process, but random numbers (**k_A**, **k_B**, **k_C**) must change with every signature. |
| 148 | + |
| 149 | +Thus, in each signature process, we need a round of communication where Alice, Bob, and Carol exchange their **R_i** values to construct: |
| 150 | +**R_agg = R_A + R_B + R_C** |
| 151 | + |
| 152 | +However, before this step (where they exchange **R_i**), there is a **prior round of communication** to ensure none of them cheats by changing their **R_i** after seeing the others’ values. |
| 153 | + |
| 154 | +--- |
| 155 | + |
| 156 | +### How do we prevent cheating? |
| 157 | + |
| 158 | +To prevent cheating, Alice, Bob, and Carol must first exchange the **hashes** of their nonce points (e.g., **H(R_A)**, **H(R_B)**, **H(R_C)**) before revealing their actual **R_i** values. This ensures that once they reveal their **R_i**, they cannot modify their values after seeing others’. |
| 159 | + |
| 160 | +--- |
| 161 | + |
| 162 | +### Summary: Two Rounds of Communication for Nonce Aggregation |
| 163 | + |
| 164 | +1. **Exchange hash commitments:** |
| 165 | + Alice, Bob, and Carol share **H(R_A)**, **H(R_B)**, and **H(R_C)**. |
| 166 | + |
| 167 | +2. **Exchange nonce points:** |
| 168 | + They reveal **R_A**, **R_B**, and **R_C**. |
| 169 | + |
| 170 | +Once all **R_i** values are shared, they compute the aggregated nonce: |
| 171 | +**R_agg = R_A + R_B + R_C** |
| 172 | + |
| 173 | +--- |
| 174 | + |
| 175 | + |
| 176 | + |
| 177 | + |
| 178 | + |
| 179 | + |
| 180 | +## Step 3: Signature Aggregation (Final Step) |
| 181 | + |
| 182 | +After computing the **aggregate public key** (`P_agg`) and **aggregate nonce** (`R_agg`), each participant calculates their **partial signature**: |
| 183 | + |
| 184 | +`s_i = k_i + H(x(R_agg) | P_agg | m) * d_i` |
| 185 | + |
| 186 | + |
| 187 | +Where: |
| 188 | +- `k_i`: Participant's random nonce. |
| 189 | +- `d_i`: Participant's private key. |
| 190 | +- `H`: Hash function with `R_agg`, `P_agg`, and the message `m`. |
| 191 | + |
| 192 | +--- |
| 193 | + |
| 194 | +### Aggregating the Signatures |
| 195 | + |
| 196 | +Participants exchange their `s_i` values, and the **aggregate signature** is computed as: |
| 197 | + |
| 198 | +`s_agg = s_A + s_B + s_C` |
| 199 | + |
| 200 | + |
| 201 | +This simplifies to: |
| 202 | + |
| 203 | +`s_agg = k_agg + H(x(R_agg) | P_agg | m) * d_agg` |
| 204 | + |
| 205 | + |
| 206 | +Where: |
| 207 | +- `k_agg = k_A + k_B + k_C` (aggregate nonce scalar). |
| 208 | +- `d_agg = d_A + d_B + d_C` (aggregate private key scalar). |
| 209 | + |
| 210 | +--- |
| 211 | + |
| 212 | +### Final Signature |
| 213 | + |
| 214 | +The final aggregate signature is: |
| 215 | + |
| 216 | +`(R_agg, s_agg)` |
| 217 | + |
| 218 | + |
| 219 | +This pair can be verified using `P_agg` and the message `m`. |
0 commit comments