Skip to content

Commit 16a9cbe

Browse files
authored
Merge pull request #31 from jrakibi/MuSig
add MuSig topic + exercises
2 parents ec08f4d + 71ce2b8 commit 16a9cbe

File tree

1 file changed

+219
-0
lines changed

1 file changed

+219
-0
lines changed

decoding/musig.mdx

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
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

Comments
 (0)