diff --git a/doc/musig-spec.mediawiki b/doc/musig-spec.mediawiki index 7d5fca5d8..7a6eea78d 100644 --- a/doc/musig-spec.mediawiki +++ b/doc/musig-spec.mediawiki @@ -126,6 +126,19 @@ The algorithm ''NonceAgg(pubnonce1..u)'' is defined as: ** Let ''Ri = R'i'' if not ''is_infinite(R'i)'', otherwise let Ri = G'' * Return ''aggnonce = cbytes(R1) || cbytes(R2)'' +===== Note on ''is_infinite(R'i)'' ===== + +If ''is_infinite(R'i)'' there is at least one dishonest signer (except with negligible probability). +If we would fail here, we will never be able to determine who it is. +Therefore, we should continue such that the culprit is revealed when collecting and verifying partial signatures. +However, dealing with the point at infinity requires defining a serialization and may require extra code complexity in implementations. +Instead, we set the aggregate nonce to some arbitrary point, the generator. + +This modification does not affect the security of the scheme. +''NonceAgg'' (both the original and modified version) only depends on publicly available data (the set of public pre-nonces from every signer). +Thus in the multi-signature security game (EUF-CMA), we can consider ''NonceAgg'' to be performed by the adversary (rather than the challenger) without loss of generality. +The modification changes neither the behavior of the EUF-CMA challenger nor the condition required to win the security game (the adversary still has to output a valid forgery according to the unmodified MuSig2* scheme). Since we've already proved that MuSig2* is secure against an arbitrary adversary, we can conclude that the modified scheme is still secure. + ==== Signing ==== Input: diff --git a/src/modules/musig/session_impl.h b/src/modules/musig/session_impl.h index 7cdcebe3e..1231b2fc0 100644 --- a/src/modules/musig/session_impl.h +++ b/src/modules/musig/session_impl.h @@ -362,21 +362,7 @@ int secp256k1_musig_nonce_agg(const secp256k1_context* ctx, secp256k1_musig_aggn } for (i = 0; i < 2; i++) { if (secp256k1_gej_is_infinity(&aggnonce_ptj[i])) { - /* There must be at least one dishonest signer. If we would return 0 - here, we will never be able to determine who it is. Therefore, we - should continue such that the culprit is revealed when collecting - and verifying partial signatures. - - However, dealing with the point at infinity (loading, - de-/serializing) would require a lot of extra code complexity. - Instead, we set the aggregate nonce to some arbitrary point (the - generator). This is secure, because it only restricts the - abilities of the attacker: an attacker that forces the sum of - nonces to be infinity by sending some maliciously generated nonce - pairs can be turned into an attacker that forces the sum to be - the generator (by simply adding the generator to one of the - malicious nonces), and this does not change the winning condition - of the EUF-CMA game. */ + /* Set to G according to the specification */ aggnonce_pt[i] = secp256k1_ge_const_g; } else { secp256k1_ge_set_gej(&aggnonce_pt[i], &aggnonce_ptj[i]);