Skip to content

Commit 1d0d60d

Browse files
Merge #178: musig-spec: expand on signing flow
fd51a62 musig-spec: add authors (Jonas Nick) f56e223 musig-spec: explain NonceGen and tweaking in signing flow context (Jonas Nick) e463ea4 musig-spec: mention stateless signing in signing flow (Jonas Nick) a29b961 musig-spec: add acknowledgements and improve abstract (Jonas Nick) 1a086ba musig-spec: add optional arguments to strengthen nonce function (Jonas Nick) 8d04ac3 musig-spec: remove unnecessary and inconsistent input paragraph (Jonas Nick) Pull request description: Based on #177 It's likely we're missing people in the acknowledgements. Ping me if you think you are. ACKs for top commit: real-or-random: ACK fd51a62 Tree-SHA512: 5240b783c15f76655b2593422dc7c76de1c5e298bbe2f39858daca4ee1b1877f1ff179b4043e6f1f75f8c804b734f4bb739d38a18a54b094d8640c57fd074ed9
2 parents 6c0aecf + fd51a62 commit 1d0d60d

File tree

1 file changed

+61
-15
lines changed

1 file changed

+61
-15
lines changed

doc/musig-spec.mediawiki

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
<pre>
22
BIP: ?
33
Title: MuSig2
4-
Author:
4+
Author: Jonas Nick <[email protected]>
5+
Tim Ruffing <[email protected]>
6+
Elliott Jin <[email protected]>
57
Status: Draft
68
License: BSD-3-Clause
79
Type: Informational
@@ -14,7 +16,7 @@
1416

1517
This document proposes a standard for the [https://eprint.iacr.org/2020/1261.pdf MuSig2] protocol.
1618
The standard is compatible with [https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki BIP340] public keys and signatures.
17-
It also supports ''tweaking'', which allows creating [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341] Taproot outputs with key and script paths.
19+
It supports ''tweaking'', which allows deriving [https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP32] child keys from aggregate keys and creating [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341] Taproot outputs with key and script paths.
1820

1921
=== Copyright ===
2022

@@ -71,14 +73,13 @@ If all signers behaved honestly, the result passes [https://github.com/bitcoin/b
7173
Otherwise, extracting the secret signing key from the partial signatures is possible.
7274
To avoid accidental reuse, an implementation may securely erase the ''secnonce'' argument by overwriting it with zeros after ''Sign'' has been run.
7375
A ''secnonce'' consisting of only zeros is invalid for ''Sign'' and will cause it to fail.
74-
The ''NonceGen'' algorithm '''must''' draw unbiased, uniformly random values ''k<sub>1</sub>'' and ''k<sub>2</sub>''.
75-
In particular, ''k<sub>1</sub>'' and ''k<sub>2</sub>'' must _not_ be derived deterministically from the session parameters (see [[#nonce-generation|Nonce Generation]]).
7676

7777
The output of ''KeyAgg'' is dependent on the order of the input public keys.
7878
If there is no common order of the signers already, the public keys can be sorted with the ''KeySort'' algorithm to ensure that the same aggregate key is calculated.
7979
Note that public keys are allowed to occur multiple times in the input of ''KeyAgg'' and ''KeySort'', and that it is possible to successfully complete a MuSig2 signing session with duplicated public keys.
8080

81-
In some applications, it is beneficial to generate and exchange ''pubnonces'' before the message to sign or the final set of signers is known.
81+
In some applications, it is beneficial to generate and exchange ''pubnonces'' before the signer's secret key, the final set of signers, or the message to sign is known.
82+
In this case, only the available arguments are provided to the ''NonceGen'' algorithm.
8283
After this preprocessing phase, the ''Sign'' algorithm can be run immediately when the message and set of signers is determined.
8384
This way, the final signature is created quicker and with fewer roundtrips.
8485
However, applications that use this method presumably store the nonces for a longer time and must therefore be even more careful not to reuse them.
@@ -89,6 +90,11 @@ This technique reduces the overall communication.
8990
The aggregator node does not need to be trusted for the scheme's security to hold.
9091
All the aggregator node can do is prevent the signing session from succeeding by sending out incorrect aggregate nonces.
9192

93+
In general, MuSig2 signers are stateful in the sense that they first generate ''secnonce'' and then need to store it until they receive the other signer's ''pubnonces'' or the ''aggnonce''.
94+
However, it is possible for one of the signers to be stateless.
95+
This signer waits until it receives the ''pubnonce'' of all the other signers and until session parameters such as a message to sign, public keys, and tweaks are determined.
96+
Then, the signer can run ''NonceGen'', ''NonceAgg'' and ''Sign'' in sequence and send out its ''pubnonce'' along with its partial signature.
97+
9298
If any signer sends an incorrect partial signature, i.e., one that has not then been created with ''Sign'' and the right arguments for the session, the MuSig2 protocol may fail to output a valid Schnorr signature.
9399
This standard provides the method ''PartialSigVerify'' to verify the correctness of partial signatures.
94100
If partial signatures are authenticated, this method can be used to identify disruptive signers and hold them accountable.
@@ -102,11 +108,43 @@ As a result, the [[#session-context|Session Context]] may look very different in
102108
103109
==== Nonce Generation ====
104110
105-
TODO
111+
'''IMPORTANT''': ''NonceGen'' must have access to a high-quality random generator to draw an unbiased, uniformly random value ''rand' ''.
112+
Additionally, implementors must avoid modifying the ''NonceGen'' algorithm without being fully aware of the implications.
113+
In contrast to BIP340 signing, the values ''k<sub>1</sub>'' and ''k<sub>2</sub>'' must _not_ be derived deterministically from the session parameters because otherwise active attackers can [https://medium.com/blockstream/musig-dn-schnorr-multisignatures-with-verifiably-deterministic-nonces-27424b5df9d6#e3b6 trick the victim into reusing a nonce].
114+
115+
The optional arguments to ''NonceGen'' enable a defense-in-depth mechanism that may prevent secret key exposure if ''rand' '' is accidentally not drawn uniformly at random.
116+
If the value ''rand' '' would be identical in two ''NonceGen'' invocations, but any optional argument is unequal, the values ''k<sub>1</sub>'' and ''k<sub>2</sub>'' are unequal as well (with overwhelming probability).
117+
In this case, accidentally using the same ''secnonce'' for ''Sign'' in both sessions would be avoided.
118+
Therefore, it is recommended to provide the optional arguments ''sk'', ''aggpk'', and ''m'' if these session parameters are already determined during nonce generation.
119+
The auxiliary input ''in'' can contain additional contextual data that has a chance of changing between ''NonceGen'' runs.
120+
However, the protection from the optional arguments should only be viewed as a last resort.
121+
In most conceivable scenarios, the assumption that the arguments are different between two executions of ''NonceGen'' is relatively strong, particularly when facing an active attacker.
122+
123+
On systems where obtaining uniformly random values is much harder than maintaining a global atomic counter, it can be beneficial to modify ''NonceGen''.
124+
Instead of drawing ''rand' '' uniformly at random, ''rand' '' can be the output of an atomic counter.
125+
With this modification, the secret signing key ''sk'' of the signer generating the nonce is _not_ an optional argument and must be provided to ''NonceGen''.
126+
The counter must never return the same output in two ''NonceGen'' invocations with the same ''sk''.
127+
128+
It is possible to modify ''NonceGen'' such that the ''secnonce'' of a single signer can be derived deterministically.
129+
For a deterministic nonce generation algorithm ''NonceGen' '', the arguments ''sk'', ''aggpk'' and ''m'' are not optional and must be set precisely to the signer's secret key and the aggregate public key and message of the session.
130+
In addition, ''NonceGen' '' requires the ''pubnonce'' value of _all_ other signers, which can be provided via the ''in'' argument.
131+
Hence, using ''NonceGen' '' is only possible for the last signer to generate a nonce and makes the signer stateless, similar to the signer mentioned in the [[#signing-flow|Signing Flow]] section.
132+
Lastly, to make ''NonceGen' '' deterministic, ''rand' '' is removed and ''rand'' is set to ''sk''.
133+
Note that failure to provide the correct arguments to ''NonceGen' '' will allow attackers to extract secret keys.
106134
107135
==== Tweaking ====
108136
109-
TODO
137+
In addition to public keys, the ''KeyAgg'' algorithm accepts tweaks, which modify the aggregate public key as defined in the [[#tweaking-definition|Tweaking Definition]] subsection.
138+
For example, if ''KeyAgg'' is run with ''v = 2'', ''is_xonly_t<sub>1</sub> = false'', ''is_xonly_t<sub>2</sub> = true'', then the aggregate key is first ordinarily tweaked with ''tweak<sub>1</sub>'' and then X-only tweaked with ''tweak<sub>2</sub>''.
139+
140+
The purpose of specifying tweaking is to ensure compatibility with existing uses of tweaking, i.e., that the result of signing is a valid signature for the tweaked public key.
141+
The MuSig2 algorithms take arbitrary tweaks as input but accepting arbitrary tweaks may negatively affect the protocol's security.
142+
Instead, signers should obtain the tweaks according to other specifications.
143+
This typically involves deriving the tweaks from a hash of the aggregate public key and some other information.
144+
145+
Ordinary tweaking can be used to derive child public keys from an aggregate public key using [https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP32].
146+
On the other hand, X-only tweaking is required for Taproot tweaking per [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341].
147+
A Taproot-tweaked public key commits to a ''script path'', allowing users to create transaction outputs that are spendable either with a MuSig2 multi-signature or by providing inputs that satisfy the script path.
110148
111149
=== Notation ===
112150
@@ -125,6 +163,7 @@ The following conventions are used, with constants as defined for [https://www.s
125163
** The function ''x[i:j]'', where ''x'' is a byte array and ''i, j &ge; 0'', returns a ''(j - i)''-byte array with a copy of the ''i''-th byte (inclusive) to the ''j''-th byte (exclusive) of ''x''.
126164
** The function ''bytes(x)'', where ''x'' is an integer, returns the 32-byte encoding of ''x'', most significant byte first.
127165
** The function ''bytes(P)'', where ''P'' is a point, returns ''bytes(x(P))''.
166+
** The function ''len(x)'' where ''x'' is a byte array returns the length of the array.
128167
** The function ''has_even_y(P)'', where ''P'' is a point for which ''not is_infinite(P)'', returns ''y(P) mod 2 = 0''.
129168
** The function ''with_even_y(P)'', where ''P'' is a point, returns ''P'' if ''is_infinite(P)'' or ''has_even_y(P)''. Otherwise, ''with_even_y(P)'' returns ''-P''.
130169
** 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.
@@ -212,8 +251,19 @@ Input:
212251
213252
==== Nonce Generation ====
214253
215-
'''''NonceGen()''''':
216-
* Generate two random integers ''k<sub>1</sub>, k<sub>2</sub>'' in the range ''1...n-1''
254+
Input:
255+
* The secret signing key ''sk'': a 32-byte array or 0-byte array (optional argument)
256+
* The aggregate public key ''aggpk'': a 32-byte array or 0-byte array (optional argument)
257+
* The message ''m'': a 32-byte array or 0-byte array (optional argument)
258+
* The auxiliary input ''in'': a byte array of length ''&ge; 0'' (optional argument)
259+
260+
'''''NonceGen(sk, aggpk, m, in)''''':
261+
* Let ''rand' '' be a 32-byte array freshly drawn uniformly at random
262+
* If ''len(sk) > 0'':
263+
** Let ''rand'' be the byte-wise xor of ''sk'' and ''hash<sub>MuSig/aux</sub>(rand')''<ref>The random data is hashed (with a unique tag) as a precaution against situations where the randomness may be correlated with the secret signing key itself. It is xored with the secret key (rather than combined with it in a hash) to reduce the number of operations exposed to the actual secret key.</ref>.
264+
* Else: let ''rand = rand' ''
265+
* Let ''k<sub>i</sub> = int(hash<sub>MuSig/nonce</sub>(rand || len(aggpk) || aggpk || i || len(m) || m || len(in) || in)) mod n'' for ''i = 1,2''
266+
* Fail if ''k<sub>1</sub> = 0'' or ''k<sub>2</sub> = 0''
217267
* Let ''R<sup>*</sup><sub>1</sub> = k<sub>1</sub>⋅G, R<sup>*</sup><sub>2</sub> = k<sub>2</sub>⋅G''
218268
* Let ''pubnonce = cbytes(R<sup>*</sup><sub>1</sub>) || cbytes(R<sup>*</sup><sub>2</sub>)''
219269
* Let ''secnonce = bytes(k<sub>1</sub>) || bytes(k<sub>2</sub>)''
@@ -305,12 +355,6 @@ Input:
305355
* Run ''PartialSigVerifyInternal(psig, pubnonce<sub>i</sub>, pk<sub>i</sub>, session_ctx)''
306356
* Return success iff no failure occurred before reaching this point.
307357
308-
Input:
309-
* The partial signature ''psig'': a 32-byte array
310-
* The public nonce of the signer ''pubnonce'': a 66-byte array
311-
* The public key of the signer ''pk<sup>*</sup>'' (in ''pk<sub>1..u</sub>'' of the session_ctx''): a 32-byte array
312-
* The ''session_ctx'': a [[#session-context|Session Context]] data structure
313-
314358
'''''PartialSigVerifyInternal(psig, pubnonce, pk<sup>*</sup>, session_ctx)''''':
315359
* Let ''(Q, gacc<sub>v</sub>, _, b, R, e) = GetSessionValues(session_ctx)''; fail if that fails
316360
* Let ''s = int(psig)''; fail if ''s &ge; n''
@@ -488,3 +532,5 @@ A scheme very similar to MuSig2 and with two-point nonces was independently prov
488532
<references />
489533

490534
== Acknowledgements ==
535+
536+
We thank Brandon Black, Riccardo Casatta, Russell O'Connor, and Pieter Wuille for their contributions to this document.

0 commit comments

Comments
 (0)