0327 - Active - Informational - March 22, 2022 (4 years, 4 months ago)
22
2022
BIP: 327
Title: MuSig2 for BIP 340-compatible Multi-Signatures
Author: Jonas Nick <[email protected]>
Tim Ruffing <[email protected]>
Elliott Jin <[email protected]>
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP 327
Status: Active
Type: Informational
Created: 2022-03-22
License: BSD-3-Clause
Post-History: 2022-04-05: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-April/020198.html [bitcoin-dev] MuSig2 BIP
2022-10-11: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-October/021000.html [bitcoin-dev] MuSig2 BIP
This document proposes a standard for the MuSig2 multi-signature scheme. The standard is compatible with BIP 340 public keys and signatures. It supports tweaking , which allows deriving BIP 32 child keys from aggregate public keys and creating BIP 341 Taproot outputs with key and script paths.
This document is licensed under the 3-clause BSD license.
MuSig2 is a multi-signature scheme that allows multiple signers to create a single aggregate public key and cooperatively create ordinary Schnorr signatures valid under the aggregate public key. Signing requires interaction between all signers involved in key aggregation. (MuSig2 is a n-of-n multi-signature scheme and not a t-of-n threshold-signature scheme.)
The primary motivation is to create a standard that allows users of different software projects to jointly control Taproot outputs ( BIP 341 ). Such an output contains a public key which, in this case, would be the aggregate of all users' individual public keys. It can be spent using MuSig2 to produce a signature for the key-based spending path.
The on-chain footprint of a MuSig2 Taproot output is essentially a
single BIP 340 public key, and a transaction spending the output only
requires a single signature cooperatively produced by all signers. This
is
more compact
and has
lower verification
cost
than each signer providing an individual public key and
signature, as would be required by an
n-of-n
policy implemented
using
OP_CHECKSIGADD
as introduced in (
BIP
342
). As a side effect, the number
n
of signers is not
limited by any consensus rules when using MuSig2.
Moreover, MuSig2 offers a
higher level of privacy
than
OP_CHECKSIGADD
: MuSig2 Taproot outputs are
indistinguishable for a blockchain observer from regular, single-signer
Taproot outputs even though they are actually controlled by multiple
signers. By tweaking an aggregate public key, the shared Taproot output
can have script spending paths that are hidden unless used.
There are multi-signature schemes other than MuSig2 that are fully compatible with Schnorr signatures. The MuSig2 variant proposed below stands out by combining all the following features:
Implementers must make sure to understand this section thoroughly to avoid subtle mistakes that may lead to catastrophic failure.
The goal of this proposal is to support a wide range of possible application scenarios. Given a specific application scenario, some features may be unnecessary or not desirable, and implementers can choose not to support them. Such optional features include:
If applicable, the corresponding algorithms should simply fail when encountering inputs unsupported by a particular implementation. (For example, the signing algorithm may fail when given a message which is not 32 bytes.) Similarly, the test vectors that exercise the unimplemented features should be re-interpreted to expect an error, or be skipped if appropriate.
The signers start by exchanging their individual public keys and computing an aggregate public key using the KeyAgg algorithm. Whenever they want to sign a message, the basic order of operations to create a multi-signature is as follows:
First broadcast round: The signers start the signing session by running NonceGen to compute secnonce and pubnonce . 2 Then, the signers broadcast their pubnonce to each other and run NonceAgg to compute an aggregate nonce.
Second broadcast round: At this point, every signer has the required data to sign, which, in the algorithms specified below, is stored in a data structure called Session Context . Every signer computes a partial signature by running Sign with the secret signing key, the secnonce and the session context. Then, the signers broadcast their partial signatures to each other and run PartialSigAgg to obtain the final signature. If all signers behaved honestly, the result passes BIP 340 verification.
Both broadcast rounds can be optimized by using an aggregator who collects all signers' nonces or partial signatures, aggregates them using NonceAgg or PartialSigAgg , respectively, and broadcasts the aggregate result back to the signers. A malicious aggregator can force the signing session to fail to produce a valid Schnorr signature but cannot negatively affect the unforgeability of the scheme, i.e., even a malicious aggregator colluding with all but one signer cannot forge a signature.
IMPORTANT : The Sign algorithm must not be executed twice with the same secnonce . Otherwise, it is possible to extract the secret signing key from the two partial signatures output by the two executions of Sign . To avoid accidental reuse of secnonce , an implementation may securely erase the secnonce argument by overwriting it with 64 zero bytes after it has been read by Sign . A secnonce consisting of only zero bytes is invalid for Sign and will cause it to fail.
To simplify the specification of the algorithms, some intermediary values are unnecessarily recomputed from scratch, e.g., when executing GetSessionValues multiple times. Actual implementations can cache these values. As a result, the Session Context may look very different in implementations or may not exist at all. However, computation of GetSessionValues and storage of the result must be protected against modification from an untrusted third party. This party would have complete control over the aggregate public key and message to be signed.
We distinguish between two public key types, namely plain public keys , the key type traditionally used in Bitcoin, and X-only public keys . Plain public keys are byte strings of length 33 (often called compressed format). In contrast, X-only public keys are 32-byte strings defined in BIP 340 .
The individual public keys of signers as input to the key aggregation algorithm KeyAgg (and to GetSessionValues and PartialSigVerify ) are plain public keys. The output of KeyAgg is a KeyAgg Context which stores information required for tweaking the aggregate public key (see below ), and it can be used to produce an X-only aggregate public key, or a plain aggregate public key. In order to obtain an X-only public key compatible with BIP 340 verification, implementations call the GetXonlyPubkey function with the KeyAgg Context. To get the plain aggregate public key, which is required for some applications of tweaking , implementations call GetPlainPubkey instead.
The aggregate public key produced by KeyAgg (regardless of the type) depends on the order of the individual public keys. If the application does not have a canonical order of the signers, the individual public keys can be sorted with the KeySort algorithm to ensure that the aggregate public key is independent of the order of signers.
The same individual public key is allowed to occur more than once in the input of KeyAgg and KeySort . This is by design: All algorithms in this proposal handle multiple signers who (claim to) have identical individual public keys properly, and applications are not required to check for duplicate individual public keys. In fact, applications are recommended to omit checks for duplicate individual public keys in order to simplify error handling. Moreover, it is often impossible to tell at key aggregation which signer is to blame for the duplicate, i.e., which signer came up with an individual public key honestly and which disruptive signer copied it. In contrast, MuSig2 is designed to identify disruptive signers at signing time (see Identifying Disruptive Signers ).
While the algorithms in this proposal are able to handle duplicate individual public keys, there are scenarios where applications may choose to abort when encountering duplicates. For example, we can imagine a scenario where a single entity creates a MuSig2 setup with multiple signing devices. In that case, duplicates may not result from a malicious signing device copying an individual public key of another signing device but from accidental initialization of two devices with the same seed. Since MuSig2 key aggregation would accept the duplicate keys and not error out, which would in turn reduce the security compared to the intended key setup, applications may reject duplicate individual public keys before passing them to MuSig2 key aggregation and ask the user to investigate.
IMPORTANT : NonceGen must have access to a high-quality random generator to draw an unbiased, uniformly random value rand' . In contrast to BIP 340 signing, the values k 1 and k 2 must not be derived deterministically from the session parameters because otherwise active adversaries can trick the victim into reusing a nonce .
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. If the value rand' was identical in two NonceGen invocations, but any other argument was different, the secnonce would still be guaranteed to be different as well (with overwhelming probability), and thus accidentally using the same secnonce for Sign in both sessions would be avoided. Therefore, it is recommended to provide the optional arguments sk , aggpk , and m if these session parameters are already determined during nonce generation. The auxiliary input extra_in can contain additional contextual data that has a chance of changing between NonceGen runs, e.g., a supposedly unique session id (taken from the application), a session counter wide enough not to repeat in practice, any nonces by other signers (if already known), or the serialization of a data structure containing multiple of the above. However, the protection provided by the optional arguments should only be viewed as a last resort. In most conceivable scenarios, the assumption that the arguments are different between two executions of NonceGen is relatively strong, particularly when facing an active adversary.
In some applications, it is beneficial to generate and send a pubnonce before the other signers, their individual public keys, or the message to sign is known. In this case, only the available arguments are provided to the NonceGen algorithm. After this preprocessing phase, the Sign algorithm can be run immediately when the message and set of signers is determined. This way, the final signature is created quicker and with fewer round trips. 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. Moreover, this method is not compatible with the defense-in-depth mechanism described in the previous paragraph.
Instead of every signer broadcasting their pubnonce to every other signer, the signers can send their pubnonce to a single aggregator node that runs NonceAgg and sends the aggnonce back to the signers. This technique reduces the overall communication. A malicious aggregator can force the signing session to fail to produce a valid Schnorr signature but cannot negatively affect the unforgeability of the scheme.
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 signers' pubnonces or the aggnonce . However, it is possible for one of the signers to be stateless. This signer waits until it receives the pubnonce of all the other signers and until session parameters such as a message to sign, individual public keys, and tweaks are determined. Then, the signer can run NonceGen , NonceAgg and Sign in sequence and send out its pubnonce along with its partial signature. Stateless signers may want to consider signing deterministically (see Modifications to Nonce Generation ) to remove the reliance on the random number generator in the NonceGen algorithm.
The signing protocol makes it possible to identify malicious signers who send invalid contributions to a signing session in order to make the signing session abort and prevent the honest signers from obtaining a valid signature. This property is called "identifiable aborts" and ensures that honest parties can assign blame to malicious signers who cause an abort in the signing protocol.
Aborts are identifiable for an honest party if the following conditions hold in a signing session:
If these conditions hold and an honest party (signer or aggregator) runs an algorithm that fails due to invalid protocol contributions from malicious signers, then the algorithm run by the honest party will output the index of exactly one malicious signer. Additionally, if the honest parties agree on the contributions sent by all signers in the signing session, all the honest parties who run the aborting algorithm will identify the same malicious signer.
Some of the algorithms specified below may also assign blame to a malicious aggregator. While this is possible for some particular misbehavior of the aggregator, it is not guaranteed that a malicious aggregator can be identified. More specifically, a malicious aggregator (whose existence violates the second condition above) can always make signing abort and wrongly hold honest signers accountable for the abort (e.g., by claiming to have received an invalid contribution from a particular honest signer).
The only purpose of the algorithm PartialSigVerify is to ensure identifiable aborts, and it is not necessary to use it when identifiable aborts are not desired. In particular, partial signatures are not signatures. An adversary can forge a partial signature, i.e., create a partial signature without knowing the secret key for the claimed individual public key. 3 However, if PartialSigVerify succeeds for all partial signatures then PartialSigAgg will return a valid Schnorr signature. 4
The aggregate public key can be tweaked , which modifies the key as defined in the Tweaking Definition subsection. In order to apply a tweak, the KeyAgg Context output by KeyAgg is provided to the ApplyTweak algorithm with the is_xonly_t argument set to false for plain tweaking and true for X-only tweaking. The resulting KeyAgg Context can be used to apply another tweak with ApplyTweak or obtain the aggregate public key with GetXonlyPubkey or GetPlainPubkey .
The purpose of supporting 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. The MuSig2 algorithms take arbitrary tweaks as input but accepting arbitrary tweaks may negatively affect the security of the scheme. 5 Instead, signers should obtain the tweaks according to other specifications. This typically involves deriving the tweaks from a hash of the aggregate public key and some other information. Depending on the specific scheme that is used for tweaking, either the plain or the X-only aggregate public key is required. For example, to do BIP 32 derivation, you call GetPlainPubkey to be able to compute the tweak, whereas BIP 341 TapTweaks require X-only public keys that are obtained with GetXonlyPubkey .
The tweak mode provided to ApplyTweak depends on the application: Plain tweaking can be used to derive child public keys from an aggregate public key using BIP 32 . On the other hand, X-only tweaking is required for Taproot tweaking per BIP 341 . 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. Script path spends require a control block that contains a parity bit for the tweaked X-only public key. The bit can be obtained with GetPlainPubkey(keyagg_ctx)[0] & 1 .
The following specification of the algorithms has been written with a focus on clarity. As a result, the specified algorithms are not always optimal in terms of computation and space. In particular, some values are recomputed but can be cached in actual implementations (see General Signing Flow ).
The following conventions are used, with constants as defined for secp256k1 . We note that adapting this proposal to other elliptic curves is not straightforward and can result in an insecure scheme.
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
3
+ 7 mod p
and they can be computed as
y = ±c
(p+1)/4
mod p
(see
Quadratic residue
) if they exist, which can be checked by squaring and comparing with
c
.
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:
Algorithm IndividualPubkey(sk) : 6
The KeyAgg Context is a data structure consisting of the following elements:
We write "Let (Q, gacc, tacc) = keyagg_ctx " to assign names to the elements of a KeyAgg Context.
Algorithm GetXonlyPubkey(keyagg_ctx) :
Algorithm GetPlainPubkey(keyagg_ctx) :
Algorithm KeySort(pk 1..u ) :
Algorithm KeyAgg(pk 1..u ) :
Internal Algorithm HashKeys(pk 1..u ) :
Internal Algorithm GetSecondKey(pk 1..u ) :
Internal Algorithm KeyAggCoeff(pk 1..u , pk') :
Internal Algorithm KeyAggCoeffInternal(pk 1..u , pk', pk2) :
Algorithm ApplyTweak(keyagg_ctx, tweak, is_xonly_t) :
Algorithm NonceGen(sk, pk, aggpk, m, extra_in) :
The secnonce is effectively a local data structure of the signer which comprises the value triple (k 1 , k 2 , pk) , and implementations may choose any suitable method to carry it from NonceGen (first communication round) to Sign (second communication round). In particular, implementations may choose to hide the secnonce in internal state without exposing it in an API explicitly, e.g., in an effort to prevent callers from reusing a secnonce accidentally.
Algorithm NonceAgg(pubnonce 1..u ) :
The Session Context is a data structure consisting of the following elements:
We write "Let (aggnonce, u, pk 1..u , v, tweak 1..v , is_xonly_t 1..v , m) = session_ctx " to assign names to the elements of a Session Context.
Algorithm GetSessionValues(session_ctx) :
Algorithm GetSessionKeyAggCoeff(session_ctx, P) :
Algorithm Sign(secnonce, sk, session_ctx) :
Let d = g⋅gacc⋅d' mod n (See Negation Of The Secret Key When Signing )
Algorithm PartialSigVerify(psig, pubnonce 1..u , pk 1..u , tweak 1..v , is_xonly_t 1..v , m, i) :
Internal Algorithm PartialSigVerifyInternal(psig, pubnonce, pk, session_ctx) :
Let g' = g⋅gacc mod n (See Negation Of The Individual Public Key When Partially Verifying )
Algorithm PartialSigAgg(psig 1..u , session_ctx) :
We provide a naive, highly inefficient, and non-constant time pure Python 3 reference implementation of the key aggregation, partial signing, and partial signature verification algorithms .
Standalone JSON test vectors are also available in the same directory , to facilitate porting the test vectors into other implementations.
The reference implementation is for demonstration purposes only and not to be used in production environments.
The scheme in this proposal has been designed to be secure even if signers tweak their individual secret keys with tweaks known to the adversary (e.g., as in BIP 32 unhardened derivation) before providing the corresponding individual public keys as input to key aggregation. In particular, the scheme as specified above requires each signer to provide a final individual public key pk already to NonceGen , which writes it into the secnonce array so that it can be checked against IndividualPubkey(sk) in the Sign algorithm. The purpose of this check in Sign is to ensure that pk , and thus the secret key sk that will be provided to Sign , is determined before the signer sends out the pubnonce .
If the check in Sign was omitted, and a signer supported signing with at least two different secret keys sk 1 and sk 2 which have been obtained via tweaking another secret key with tweaks known to the adversary, then the adversary could, after having seen the pubnonce , influence whether sk 1 or sk 2 is provided to Sign . This degree of freedom may allow the adversary to perform a generalized birthday attack and thereby forge a signature (see bitcoin-dev mailing list post and writeup for details).
Checking pk against IndividualPubkey(sk) is a simple way to ensure that the secret key provided to Sign is fully determined already when NonceGen is invoked. This removes the adversary's ability to influence the secret key after having seen the pubnonce and thus rules out the attack. 16 Note that the scheme as given in the MuSig2 paper does not perform the check in Sign . However, the security model in the paper does not cover tweaking at all and assumes a single fixed secret key.
Implementers must avoid modifying the NonceGen algorithm without being fully aware of the implications. We provide two modifications to NonceGen that are secure when applied correctly and may be useful in special circumstances, summarized in the following table.
| needs secure randomness | needs secure counter | needs to keep state securely | needs aggregate nonce of all other signers (only possible for one signer) | |
|---|---|---|---|---|
|
NonceGen |
✓ |
|
✓ |
|
|
CounterNonceGen |
|
✓ |
✓ |
|
|
DeterministicSign |
|
|
|
✓ |
First, on systems where obtaining uniformly random values is much harder than maintaining a global atomic counter, it can be beneficial to modify NonceGen . The resulting algorithm CounterNonceGen does not draw rand' uniformly at random but instead sets rand' to the value of an atomic counter that is incremented whenever it is read. 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 . The security of the resulting scheme then depends on the requirement that reading the counter must never yield the same counter value in two NonceGen invocations with the same sk .
Second, if there is a unique signer who is supposed to send the pubnonce last, it is possible to modify nonce generation for this single signer to not require high-quality randomness. Such a nonce generation algorithm DeterministicSign is specified below. Note that the only optional argument is rand , which can be omitted if randomness is entirely unavailable. DeterministicSign requires the argument aggothernonce which should be set to the output of NonceAgg run on the pubnonce value of all other signers (but can be provided by an untrusted party). Hence, using DeterministicSign is only possible for the last signer to generate a nonce and makes the signer stateless, similar to the stateless signer described in the Nonce Generation section.
Algorithm DeterministicSign(sk, aggothernonce, pk 1..u , tweak 1..v , is_xonly_t 1..v , m, rand) :
Two modes of tweaking the aggregate public key are supported. They correspond to the following algorithms:
Algorithm ApplyPlainTweak(P, t) :
Algorithm ApplyXonlyTweak(P, t) :
In order to produce a partial signature for an X-only aggregate public key that is an aggregate of u individual public keys and tweaked v times (X-only or plain), the Sign algorithm may need to negate the secret key during the signing process.
P
i
= d
i
'⋅G
.
• Q 0 is the aggregate of the individual public keys. It is identical to value Q computed in KeyAgg and therefore defined as
Q
0
= a
1
⋅P
1
+ a
2
⋅P
2
+ ... + a
u
⋅P
u
.
• Q i is the tweaked aggregate public key after the i -th execution of ApplyTweak for 1 ≤ i ≤ v . It holds that
Q
i
= f(i-1) + t
i
⋅G
for
i = 1, ..., v
where
f(i-1) := with_even_y(Q
i-1
)
if
is_xonly_t
i
and
f(i-1) := Q
i-1
otherwise.
• with_even_y(Q v ) is the final result of the key aggregation and tweaking operations. It corresponds to the output of GetXonlyPubkey applied on the final KeyAgg Context.
The signer's goal is to produce a partial signature corresponding to the final result of key aggregation and tweaking, i.e., the X-only public key with_even_y(Q v ) .
f(i-1) = g
i-1
⋅Q
i-1
for
1 ≤ i ≤ v
.
Furthermore, the Sign and PartialSigVerify algorithms set value g depending on whether Q v needed to be negated to produce the (X-only) final output. For consistency, this value g is referred to as g v in this section.
with_even_y(Q
v
) = g
v
⋅Q
v
.
''with_even_y(Q
v
)
= g
v
⋅Q
v
= g
v
⋅(f(v-1) + t
v
⋅G)
= g
v
⋅(g
v-1
⋅(f(v-2) + t
v-1
⋅G) + t
v
⋅G)
= g
v
⋅g
v-1
⋅f(v-2) + g
v
⋅(t
v
+ g
v-1
⋅t
v-1
)⋅G
= g
v
⋅g
v-1
⋅f(v-2) + (sum
i=v-1..v
t
i
⋅prod
j=i..v
g
j
)⋅G
= g
v
⋅g
v-1
⋅...⋅g
1
⋅f(0) + (sum
i=1..v
t
i
⋅prod
j=i..v
g
j
)⋅G
= g
v
⋅...⋅g
0
⋅Q
0
+ g
v
⋅tacc
v
⋅G''
where
tacc
i
is computed by
KeyAgg
and
ApplyTweak
as follows:
''tacc
0
= 0
tacc
i
= t
i
+ g
i-1
⋅tacc
i-1
for i=1..v mod n''
for which it holds that
g
v
⋅tacc
v
= sum
i=1..v
t
i
⋅prod
j=i..v
g
j
.
''gacc
0
= 1
gacc
i
= g
i-1
⋅gacc
i-1
for i=1..v mod n''
So we can rewrite above equation for the final public key as
with_even_y(Q
v
) = g
v
⋅gacc
v
⋅Q
0
+ g
v
⋅tacc
v
⋅G
.
''with_even_y(Q
v
) - g
v
⋅tacc
v
⋅G
= g
v
⋅gacc
v
⋅Q
0
= g
v
⋅gacc
v
⋅(a
1
⋅P
1
+ ... + a
u
⋅P
u
)
= g
v
⋅gacc
v
⋅(a
1
⋅d
1
'⋅G + ... + a
u
⋅d
u
'⋅G)
= sum
i=1..u
(g
v
⋅gacc
v
⋅a
i
⋅d
i
')*G''.
Intuitively, gacc i tracks accumulated sign flipping and tacc i tracks the accumulated tweak value after applying the first i individual tweaks. Additionally, g v indicates whether Q v needed to be negated to produce the final X-only result. Thus, signer i multiplies its secret key d i ' with g v ⋅gacc v in the Sign algorithm.
d = g
v
⋅gacc
v
⋅d' mod n
when producing a partial signature to ensure that the aggregate signature will correspond to an aggregate public key with even Y coordinate.
s⋅G = Re
⁎
+ e⋅a⋅d⋅G
.
= g
v
⋅gacc
v
⋅d'⋅G
= g
v
⋅gacc
v
⋅cpoint(pk)
Note that the aggregate public key and list of tweaks are inputs to partial signature verification, so the verifier can also construct
g
v
and
gacc
v
''.
If the nonce aggregator provides aggnonce = bytes(33,0) || bytes(33,0) , either the nonce aggregator is dishonest or there is at least one dishonest signer (except with negligible probability). If signing aborted in this case, it would be impossible to determine who is dishonest. Therefore, signing continues so that the culprit is revealed when collecting and verifying partial signatures.
However, the final nonce R of a BIP 340 Schnorr signature cannot be the point at infinity. If we would nonetheless allow the final nonce to be the point at infinity, then the scheme would lose the following property: if PartialSigVerify succeeds for all partial signatures, then PartialSigAgg will return a valid Schnorr signature. Since this is a valuable feature, we modify MuSig2* (which is defined in the appendix of the MuSig2 paper ) to avoid producing an invalid Schnorr signature while still allowing detection of the dishonest signer: In GetSessionValues , if the final nonce R would be the point at infinity, set it to the generator instead (an arbitrary choice).
This modification to GetSessionValues does not affect the unforgeability of the scheme. Given a successful adversary against the unforgeability game (EUF-CMA) for the modified scheme, a reduction can win the unforgeability game for the original scheme by simulating the modification towards the adversary: When the adversary provides aggnonce' = bytes(33, 0) || bytes(33, 0) , the reduction sets aggnonce = cbytes_ext(G) || bytes(33, 0) . For any other aggnonce' , the reduction sets aggnonce = aggnonce' . (The case that the adversary provides an aggnonce' ≠ bytes(33, 0) || bytes(33, 0) but nevertheless R' in GetSessionValues is the point at infinity happens only with negligible probability.)
The MuSig2 paper contains two security proofs that apply to different variants of the scheme. The first proof relies on the random oracle model (ROM) and applies to a scheme variant where each signer's nonce consists of four elliptic curve points. The second proof requires a stronger model, namely the combination of the ROM and the algebraic group model (AGM), and applies to an optimized scheme variant where the signers' nonces consist of only two points. This proposal uses the latter, optimized scheme variant. Relying on the stronger model is a legitimate choice for the following reasons:
First, an approach widely taken is interpreting a Forking Lemma proof in the ROM merely as design justification and ignoring the loss of security due to the Forking Lemma. If one believes in this approach, then the ROM may not be the optimal model in the first place because some parts of the concrete security bound are arbitrarily ignored. One may just as well move to the ROM+AGM model, which produces bounds close to the best-known attacks, e.g., for Schnorr signatures.
Second, as of this writing, there is no instance of a serious cryptographic scheme with a security proof in the AGM that is not secure in practice. There are, however, insecure toy schemes with AGM security proofs, but those explicitly violate the requirements of the AGM. Broken AGM proofs of toy schemes provide group elements to the adversary without declaring them as group element inputs. In contrast, in MuSig2, all group elements that arise in the scheme are known to the adversary and declared as group element inputs. A scheme very similar to MuSig2 and with two-point nonces was independently proven secure in the ROM and AGM by Alper and Burdges .
This document proposes a standard for the MuSig2 multi-signature scheme that is compatible with BIP 340 . MuSig2 is not compatible with ECDSA signatures traditionally used in Bitcoin.
To help implementers understand updates to this document, we attach a
version number that resembles
semantic versioning
(
MAJOR.MINOR.PATCH
). The
MAJOR
version is
incremented if changes to the BIP are introduced that are incompatible
with prior versions. An exception to this rule is
MAJOR
version zero (0.y.z) which is for development and does not need to be
incremented if backwards incompatible changes are introduced. The
MINOR
version is incremented whenever the inputs or the
output of an algorithm changes in a backward-compatible way or new
backward-compatible functionality is added. The
PATCH
version is incremented for other changes that are noteworthy (bug fixes,
test vectors, important clarifications, etc.).
We thank Brandon Black, Riccardo Casatta, Sivaram Dhakshinamoorthy, Lloyd Fournier, Russell O'Connor, and Pieter Wuille for their contributions to this document.