1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
use ;
/// A [multisig scheme](crate::MultisigScheme) based on [Schnorr
/// signatures](crate::Schnorr).
///
/// Using Schnorr signatures has multiple advantages over the simple approach
/// to multisig, where the signatures from each private key are concatenated.
/// Most importantly, the resulting multisig is indistinguishable from a
/// regular Schnorr signature created by a single private key. Consequently,
/// this scheme is also more efficient: the size of the signature is the same no
/// matter the number of signers.
///
/// Before signing, $n$ signers with private keys $p_i$ and public keys $P_i =
/// p_iG$ each pick random secret numbers $r_i$ in a [secure collaborative
/// manner](SchnorrRandomness). They share the public counterparts of the secret
/// numbers $R_i = r_iG$, where $G$ is the [generator
/// point](crate::ecc::Curve::g) of the underlying [elliptic
/// curve](crate::ecc::Curve), and calculate $R = \sum_{i=1}^{n} R_i$.
///
/// They start with $s = 0$. When it's $p_i$'s turn to sign, s is updated as
/// follows:
///
/// $$
/// c_i = H_{agg}(\langle L \rangle \parallel P_i) \cdot H_{sig}(\tilde P
/// \parallel R \parallel m) \\
/// s_i = r_i - p_ic_i \\
/// s \gets s + s_i
/// $$
///
/// Where $H_{agg}$ and $H_{sig}$ are hash functions returning numbers in the
/// range $[1, N-1]$ (which don't have to be the same, but in this
/// implementation they are), $\langle L \rangle$ is a unique encoding of the
/// pubkeys $P_1, P_2, \dotsc, P_n$, and $c_i$ is called the "challenge" for
/// $p_i$. $\tilde P$ is the combined pubkey:
///
/// $$
/// \tilde P = \sum_{i = 1}^{n} P_i \cdot H_{agg}(\langle L \rangle \parallel
/// P_i) $$
///
/// The resulting signature is $(s, e)$ where $e = H_{sig}(\tilde P \parallel R
/// \parallel m)$.
///
/// A [regular Schnorr signature](crate::Schnorr) $(s, e)$ is verified using
/// the following formula, where $e$ is the hash $H(P \parallel R
/// \parallel m)$ and $P$ is the public key:
///
/// $$
/// R = sG + eP \\
/// R = sG + H(P \parallel R \parallel m)P \\
/// H(P \parallel R \parallel m) \stackrel{?}{=} e
/// $$
///
/// A Schnorr multisig is verified the exact same way, using $\tilde P$ as the
/// pubkey and $H_{sig}$ as the hash function:
///
/// $$
/// R = sG + e\tilde P \\
/// R = sG + H_{sig}(\tilde P \parallel R \parallel m)\tilde P \\
/// H_{sig}(\tilde P \parallel R \parallel m) \stackrel{?}{=} e
/// $$
///
/// After every actor has signed, the signature $s$ will be $s = \sum_{i =
/// 1}^{n} s_i$. Substituting this into the equation for $R$:
///
/// $$
/// R = \Big(\sum_{i = 1}^{n} s_i\Big)G + e\tilde P \\
/// R = \Big(\sum_{i = 1}^{n} r_i - p_ic_i\Big)G + e\tilde P \\
/// R = \Big(\sum_{i = 1}^{n} r_i - p_iH_{agg}(\langle L \rangle \parallel P_i)
/// H_{sig}(\tilde P \parallel R \parallel m)\Big)G + e\tilde P \\
/// $$
///
/// Since in this case $e = H_{sig}(\tilde P \parallel R \parallel m)$, the
/// equation can be made slightly shorter:
///
/// $$
/// R = \Big(\sum_{i = 1}^{n} r_i - p_iH_{agg}(\langle L \rangle \parallel P_i)
/// e\Big)G + e\tilde P \\
/// $$
///
/// The sum can be split around the subtraction operation and multiplied by $G$:
///
/// $$
/// R = \Big(\sum_{i = 1}^{n} r_i - \sum_{i = 1}^{n} p_iH_{agg}(\langle L
/// \rangle \parallel P_i) e\Big)G + e\tilde P \\
/// R = \Big(\sum_{i = 1}^{n} r_iG - \sum_{i = 1}^{n} p_iGH_{agg}(\langle L
/// \rangle \parallel P_i) e\Big) + e\tilde P \\
/// R = \Big(R - \sum_{i = 1}^{n} P_iH_{agg}(\langle L
/// \rangle \parallel P_i) e\Big) + e\tilde P \\
/// $$
///
/// Every element in the remaining sum is multiplied by $e = H_{sig}(\tilde P
/// \parallel R \parallel m)$ which doesn't depend on $i$, so it can be factored
/// out:
///
/// $$
/// R = \Big(R - e\sum_{i = 1}^{n} P_iH_{agg}(\langle L
/// \rangle \parallel P_i)\Big) + e\tilde P \\
/// $$
///
/// Finally since $\tilde P = \sum_{i = 1}^{n} P_iH_{agg}(\langle L \rangle
/// \parallel P_i)$:
///
/// $$
/// R = R - e\tilde P + e\tilde P \\
/// R = R
/// $$
///
/// Which shows that Schnorr multisigs can be verified the same way as regular
/// Schnorr signatures, so long as they use the same hash function. Note that
/// the key reason why this works is because the expression for $s$ has the same
/// form for multisigs as it does for regular signatures, except for summation
/// over $r_i$ and $p_i$. Compare the form of a regular Schnorr signature:
///
/// $$
/// s = {\color{red}r} - \color{yellow}e\color{green}p
/// $$
///
/// with the form of a Schnorr multisig:
///
/// $$
/// s = \sum_{i = 1}^n r_i - ep_iH_{agg}(\langle L \rangle \parallel P_i) \\
/// s = {\color{red}\sum_{i = 1}^n r_i} - \color{yellow}e\color{green}\sum_{i =
/// 1}^np_iH_{agg}(\langle L \rangle \parallel P_i) $$
///
/// The private keys $p_i$ are multiplied by $H_{agg}(\langle L \rangle
/// \parallel P_i)$ for two reasons:
///
/// 1. $H_{agg}$ hashes over $\langle L \rangle$ so that no actor accidentally
/// signs a multisig for the wrong group of pubkeys.
/// 2. $H_{agg}$ hashes over $P_i$ so that no actor can maliciously fake his
/// public key. For example, if $p_i$ was not multiplied by $H_{agg}(P_i)$
/// then the formula for the combined pubkey would be simply $\tilde P =
/// \sum_{i = 1}^n P_i$, allowing a malicious actor to set his pubkey to $P_1
/// = P_1' - P_2 - P_3 - \dots - P_n$, where $P_1' = p_1'G$ is the actor's
/// actual pubkey. This results in $\tilde P = P_1'$ which allows him to make
/// signatures for the whole group using his private key $p_i'$ alone.
/// Multiplying private keys with the hash of their corresponding public keys
/// prevents this problem, since the malicious actor would end up multiplying
/// $p_1'$ with the hash of $P_1$ resulting in an invalid signature.
;
/// Before creating a [Schnorr multisig](MultiSchnorr), the actors must each
/// commit to a secret random number $r_i$. They proceed in two rounds:
///
/// 1. Each actor generates his secret random number $r_i$ and the public
/// counterpart $R_i = r_iG$, where $G$ is the [generator
/// point](crate::ecc::Curve::g) of the underlying [elliptic
/// curve](crate::ecc::Curve). He reveals his commitment $t_i = H(R_i)$ to
/// the other actors, where $H$ is a hash function.
/// 2. After all commitments $t_i$ have been revealed, each actor shares his
/// value of $R_i$ and verifies the $R_i$ values of other actors against
/// their corresponding commitments $t_i$.
///
/// This two-round protocol serves to prevent any actor from maliciously
/// changing his secret number $r_i$ based on the $R_i$ values of other actors.
// Explicit implementation because `derive` adds the requirement `C: Clone`,
// which is unnecessary.
/// Combine multiple pubkeys into a single multisig pubkey.
/// Encode multiple pubkeys into a unique binary representation.
;