Skip to content

Commit 4824220

Browse files
committed
musig-spec: describe NonceGen, NonceAgg, Sign,PartialSig{Verify,Agg}
1 parent 3c122d0 commit 4824220

1 file changed

Lines changed: 135 additions & 4 deletions

File tree

doc/musig-spec.mediawiki

Lines changed: 135 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ This document is licensed under the 2-clause BSD license.
2727
* The KeyAgg coefficient is computed by hashing the key instead of key index. Otherwise, if the pubkey list gets sorted, the signer needs to translate between key indices pre- and post-sorting.
2828
* The second unique key in the pubkey list given to ''KeyAgg'' (as well as any keys identical to this key) gets the constant KeyAgg coefficient 1 which saves an exponentiation (see the MuSig2* appendix in the [https://eprint.iacr.org/2020/1261 MuSig2 paper]).
2929
* The public key inputs are serialized using x-only (32 byte) instead of compressed (33 byte) serialization. The reason for this is that as x-only keys are becoming more common, the full key may not be available.
30+
* The public nonces are serialized in compressed format (33 bytes). We accept the small overhead compared to x-only serialization to avoid complicating the specification.
3031
3132
=== Specification ===
3233

@@ -46,7 +47,7 @@ The following conventions are used, with constants as defined for [https://www.s
4647
** The function ''bytes(x)'', where ''x'' is an integer, returns the 32-byte encoding of ''x'', most significant byte first.
4748
** The function ''bytes(P)'', where ''P'' is a point, returns ''bytes(x(P))''.
4849
** The function ''has_even_y(P)'', where ''P'' is a point for which ''not is_infinite(P)'', returns ''y(P) mod 2 = 0''.
49-
** The function ''cbytes(P)'', where ''P'' is a point, returns ''a || bytes(P)'' where ''a'' is ''2'' if ''has_even_y(P)'' and ''3'' otherwise.
50+
** The function ''cbytes(P)'', where ''P'' is a point, returns ''a || bytes(P)'' where ''a'' is a byte that is ''2'' if ''has_even_y(P)'' and ''3'' otherwise.
5051
** The function ''int(x)'', where ''x'' is a 32-byte array, returns the 256-bit unsigned integer whose most significant byte first encoding is ''x''.
5152
** The function ''lift_x(x)'', where ''x'' is an integer in range ''0..2<sup>256</sup>-1'', returns the point ''P'' for which ''x(P) = x''<ref>
5253
Given a candidate X coordinate ''x'' in the range ''0..p-1'', there exist either exactly two or exactly zero valid Y coordinates. If no valid Y coordinate exists, then ''x'' is not a valid X coordinate either, i.e., no point ''P'' exists for which ''x(P) = x''. The valid Y coordinates for a given candidate ''x'' are the square roots of ''c = x<sup>3</sup> + 7 mod p'' and they can be computed as ''y = &plusmn;c<sup>(p+1)/4</sup> mod p'' (see [https://en.wikipedia.org/wiki/Quadratic_residue#Prime_or_prime_power_modulus Quadratic residue]) if they exist, which can be checked by squaring and comparing with ''c''.</ref> and ''has_even_y(P)'', or fails if ''x'' is greater than ''p-1'' or no such point exists. The function ''lift_x(x)'' is equivalent to the following pseudocode:
@@ -56,6 +57,8 @@ The following conventions are used, with constants as defined for [https://www.s
5657
*** Fail if ''c &ne; y'<sup>2</sup> mod p''.
5758
*** Let ''y = y' '' if ''y' mod 2 = 0'', otherwise let ''y = p - y' ''.
5859
*** Return the unique point ''P'' such that ''x(P) = x'' and ''y(P) = y''.
60+
** The function ''point(x)'', where ''x'' is a 32-byte array ("x-only" serialization), returns ''lift_x(int(x))''. Fail if ''lift_x'' fails.
61+
** The function ''pointc(x)'', where ''x'' is a 33-byte array (compressed serialization), sets ''P = lift_x(int(x[1:33]))'' and fails if that fails. If ''x[0] = 2'' it returns ''P'' and if ''x[0] = 3'' it returns ''-P''. Otherwise, it fails.
5962
** The function ''hash<sub>tag</sub>(x)'' where ''tag'' is a UTF-8 encoded tag name and ''x'' is a byte array returns the 32-byte hash ''SHA256(SHA256(tag) || SHA256(tag) || x)''.
6063
6164
@@ -75,12 +78,16 @@ Input:
7578
* The public keys ''pk<sub>1..u</sub>'': ''u'' 32-byte arrays
7679
7780
The algorithm ''KeyAgg(pk<sub>1..u</sub>)'' is defined as:
81+
* Let ''Q = KeyAggInternal(pk<sub>1..u</sub>)''; fail if that fails.
82+
* Return ''bytes(Q)''.
83+
84+
The algorithm ''KeyAggInternal(pk<sub>1..u</sub>)'' is defined as:
7885
* For ''i = 1 .. u'':
7986
** Let ''a<sub>i</sub> = KeyAggCoeff(pk<sub>1..u</sub>, pk<sub>i</sub>)''.
80-
** Let ''P<sub>i</sub> = lift_x(int(pk<sub>i</sub>))''; fail if it fails.
87+
** Let ''P<sub>i</sub> = point(pk<sub>i</sub>)''; fail if that fails.
8188
* Let ''Q = a<sub>1</sub>⋅P<sub>1</sub> + a<sub>2</sub>⋅P<sub>1</sub> + ... + a<sub>u</sub>⋅P<sub>u</sub>''
8289
* Fail if ''is_infinite(Q)''.
83-
* Return ''bytes(Q)''.
90+
* Return ''Q''.
8491
8592
The algorithm ''HashKeys(pk<sub>1..u</sub>)'' is defined as:
8693
* Return ''hash<sub>KeyAgg list</sub>(pk<sub>1</sub> || pk<sub>2</sub> || ... || pk<sub>u</sub>)''
@@ -97,12 +104,136 @@ The algorithm ''KeyAggCoeff(pk<sub>1..u</sub>, pk')'' is defined as:
97104
** Return 1
98105
* Return ''int(hash<sub>KeyAgg coefficient</sub>(L || pk')) mod n''
99106
107+
==== Nonce Generation ====
108+
109+
The algorithm ''NonceGen()'' is defined as:
110+
* Generate two random integers ''k<sub>1</sub>, k<sub>2</sub>'' in the range ''1...n-1''
111+
* Let ''R<sup>*</sup><sub>1</sub> = k<sub>1</sub>⋅G, R<sup>*</sup><sub>2</sub> = k<sub>2</sub>⋅G''
112+
* Let ''pubnonce = cbytes(R<sup>*</sup><sub>1</sub>) || cbytes(R<sup>*</sup><sub>2</sub>)''
113+
* Let ''secnonce = bytes(k<sub>1</sub>) || bytes(k<sub>2</sub>)''
114+
* Return ''secnonce'' and ''pubnonce''
115+
116+
==== Nonce Aggregation ====
117+
118+
* The number ''u'' of ''pubnonces'' with ''0 < u < 2^32''
119+
* The public nonces ''pubnonce<sub>1..u</sub>'': ''u'' 66-byte arrays
120+
121+
The algorithm ''NonceAgg(pubnonce<sub>1..u</sub>)'' is defined as:
122+
* For ''i = 1 .. 2'':
123+
** For ''j = 1 .. u'':
124+
*** Let ''R<sub>i,j</sub> = pointc(pubnonce<sub>j</sub>[(i-1)*33:i*33])''; fail if that fails
125+
** Let ''R'<sub>i</sub> = R<sub>i,1</sub> + R<sub>i,2</sub> + ... + R<sub>i,u</sub>''
126+
** Let ''R<sub>i</sub> = R'<sub>i</sub>'' if not ''is_infinite(R'<sub>i</sub>)'', otherwise let R<sub>i</sub> = G''
127+
* Return ''aggnonce = cbytes(R<sub>1</sub>) || cbytes(R<sub>2</sub>)''
128+
129+
==== Signing ====
130+
131+
Input:
132+
* The secret nonce ''secnonce'' that has never been used as input to ''Sign'' before: a 64-byte array
133+
* The secret key ''sk'': a 32-byte array
134+
* The aggregate public nonce ''aggnonce'': a 66-byte array
135+
* The number ''u'' of public keys with ''0 < u < 2^32''
136+
* The public keys ''pk<sub>1..u</sub>'': ''u'' 32-byte arrays
137+
* The message ''m'': a 32-byte array
138+
139+
The algorithm ''Sign(secnonce, sk, aggnonce, pk<sub>1..u</sub>, m)'' is defined as:
140+
* Let ''R<sub>1</sub> = pointc(aggnonce[0:33]), R<sub>2</sub> = pointc(aggnonce[33:66])''; fail if that fails
141+
* Let ''Q = KeyAggInternal(pk<sub>1..u</sub>)''; fail if that fails
142+
* Let ''b = int(hash<sub>MuSig/noncecoef</sub>(aggnonce || bytes(Q) || m)) mod n''
143+
* Let ''R = R<sub>1</sub> + b⋅R<sub>2</sub>''
144+
* Fail if ''is_infinite(R)''
145+
* Let ''k'<sub>1</sub> = int(secnonce[0:32]), k'<sub>2</sub> = int(secnonce[32:64])''
146+
* Fail if ''k'<sub>i</sub> = 0'' or ''k'<sub>i</sub> &ge; n'' for ''i = 1..2''
147+
* Let ''k<sub>1</sub> = k'<sub>1</sub>, k<sub>2</sub> = k'<sub>2</sub> '' if ''has_even_y(R)'', otherwise let ''k<sub>1</sub> = n - k'<sub>1</sub>, k<sub>2</sub> = n - k<sub>2</sub>''
148+
* Let ''d' = int(sk)''
149+
* Fail if ''d' = 0'' or ''d' &ge; n''
150+
* Let ''P = d'⋅G''
151+
* Let ''d = n - d' '' if ''has_even_y(P) `XOR` has_even_y(Q)'', otherwise let ''d = d' ''
152+
* Let ''e = int(hash<sub>BIP0340/challenge</sub>(bytes(R) || bytes(Q) || m)) mod n''
153+
* Let ''mu = KeyAggCoeff(pk<sub>1..u</sub>, bytes(P))''
154+
* Let ''s = (k<sub>1</sub> + b⋅k<sub>2</sub> + e⋅mu⋅d) mod n''
155+
* Let ''psig = bytes(s)''
156+
* Let ''pubnonce = cbytes(k'<sub>1</sub>⋅G) || cbytes(k'<sub>2</sub>⋅G)''
157+
* If ''PartialSigVerifyInternal(psig, pubnonce, aggnonce, pk<sub>1..u</sub>, bytes(P), m)'' (see below) returns failure, abort<ref>Verifying the signature before leaving the signer prevents random or attacker provoked computation errors. This prevents publishing invalid signatures which may leak information about the secret key. It is recommended, but can be omitted if the computation cost is prohibitive.</ref>.
158+
* Return partial signature ''psig
159+
160+
==== Partial Signature Verification ====
161+
162+
Input:
163+
* The partial signature ''psig'': a 32-byte array
164+
* The number ''u'' of public nonces and public keys with ''0 < u < 2^32''
165+
* The public nonces ''pubnonce<sub>1..u</sub>'': ''u'' 66-byte arrays
166+
* The public keys ''pk<sub>1..u</sub>'': ''u'' 32-byte arrays
167+
* The message ''m'': a 32-byte array
168+
* The index of the signer ''i'' in the public nonces and public keys with ''0 < i <= u''
169+
170+
The algorithm ''PartialSigVerify(psig, pubnonce<sub>1..u</sub>, pk<sub>1..u</sub>, m, i)'' is defined as:
171+
* Let ''aggnonce = NonceAgg(pubnonce<sub>1..u</sub>)''; fail if that fails
172+
* Run ''PartialSigVerifyInternal(psig, pubnonce<sub>i</sub>, aggnonce, pk<sub>1..u</sub>, pk<sub>i</sub>, m)''
173+
* Return success iff no failure occurred before reaching this point.
174+
175+
===== PartialSigVerifyInternal =====
176+
177+
Input:
178+
* The partial signature ''psig'': a 32-byte array
179+
* The public nonce of the signer ''pubnonce'': a 66-byte array
180+
* The aggregate public nonce ''aggnonce'': a 66-byte array
181+
* The number ''u'' of public keys with ''0 < u < 2^32''
182+
* The public keys ''pk<sub>1..u</sub>'': ''u'' 32-byte arrays
183+
* The public key of the signer ''pk<sup>*</sup>'' (in ''pk<sub>1..u</sub>''): a 32-byte array
184+
* The message ''m'': a 32-byte array
185+
186+
The algorithm ''PartialSigVerifyInternal(psig, pubnonce, aggnonce, pk<sub>1..u</sub>, pk<sup>*</sup>, m)'' is defined as:
187+
* Let ''s = int(psig)''; fail if ''s &ge; n''
188+
* Let ''R<sub>1</sub> = pointc(aggnonce[0:33]), R<sub>2</sub> = pointc(aggnonce[33:66])''; fail if that fails
189+
* Let ''Q = KeyAggInternal(pk<sub>1..u</sub>)''; fail if that fails
190+
* Let ''b = int(hash<sub>MuSig/noncecoef</sub>(aggnonce || bytes(Q) || m)) mod n''
191+
* Let ''R = R<sub>1</sub> + b⋅R<sub>2</sub>''
192+
* Let ''R<sup>*</sup><sub>1</sub> = pointc(pubnonce[0:33]), R<sup>*</sup><sub>2</sub> = pointc(pubnonce[33:66])''
193+
* Let ''R<sup>*</sup>' = R<sup>*</sup><sub>1</sub> + b⋅R<sup>*</sup><sub>2</sub>''
194+
* Let ''R<sup>*</sup> = R<sup>*</sup>' '' if ''has_even_y(R)'', otherwise let ''R<sup>*</sup> = -R<sup>*</sup>' ''
195+
* Let ''e = int(hash<sub>BIP0340/challenge</sub>(bytes(R) || bytes(Q) || m)) mod n''
196+
* Let ''mu = KeyAggCoeff(pk<sub>1..u</sub>, pk<sup>*</sup>)''
197+
* Let ''P' = point(pk<sup>*</sup>)''; fail if that fails
198+
* Let ''P = P' '' if ''has_even_y(Q)'', otherwise let ''P = -P' ''
199+
* Fail if ''s⋅G &ne; R<sup>*</sup> + e⋅mu⋅P''
200+
* Return success iff no failure occurred before reaching this point.
201+
202+
==== Partial Signature Aggregation ====
203+
204+
Input:
205+
* The final nonce ''R'' as created during ''Sign'' or ''PartialSigVerify'': a point
206+
* The number ''u'' of signatures with ''0 < u < 2^32''
207+
* The partial signatures ''sig<sub>1..u</sub>'': ''u'' 32-byte arrays
208+
209+
The algorithm ''SigAgg(R, sig<sub>1..u</sub>)'' is defined as:
210+
* For ''i = 1 .. u'':
211+
** Let ''s<sub>i</sub> = int(sig<sub>i</sub>)''; fail if ''s<sub>i</sub> &ge; n''.
212+
* Let ''s = s<sub>1</sub> + ... + s<sub>u</sub> mod n''
213+
* Return ''sig = ''bytes(R) || bytes(s)''
214+
215+
=== Signing Flow ===
216+
217+
Note that this specification unnecessarily recomputes intermediary values (such as the aggregate public key) that can be cached in real implementations.
218+
219+
There are multiple ways to use above algorithms and arrive at a final Schnorr signature.
220+
One of them can be described as follows:
221+
The signers ''1'' to ''n'' each run ''NonceGen'' to compute ''secnonce'' and ''pubnonce''.
222+
Every signer sends its public key and ''pubnonce'' to every other signer and all signers agree on a single message to sign.
223+
Then, the signers run ''NonceAgg'' and ''Sign'' with their secret signing key and ''secnonce''.
224+
They send the resulting partial signature to every other signer and combine them with the ''SigAgg'' algorithm.
225+
226+
''IMPORTANT'': The ''Sign'' algorithm must '''not''' be executed twice with the same ''secnonce''.
227+
Otherwise, it is possible to extract the secret signing key from the partial signatures.
228+
An implementation may invalidate the secnonce argument after ''Sign'' to avoid any reuse.
229+
Avoiding reuse also implies that the ''NonceGen'' algorithm must compute unbiased, uniformly random values ''k<sub>1</sub>'' and ''k<sub>2</sub>''.
230+
100231
== Applications ==
101232

102233
== Test Vectors and Reference Code ==
103234

104235
There are some vectors in libsecp256k1's [https://github.com/ElementsProject/secp256k1-zkp/blob/master/src/modules/musig/tests_impl.h MuSig test file].
105-
Search for the ''musig_test_vectors_keyagg'' function.
236+
Search for the ''musig_test_vectors_keyagg'' and ''musig_test_vectors_sign'' functions.
106237

107238
== Footnotes ==
108239

0 commit comments

Comments
 (0)