From bb1e8ca4bb962085bafd415b6e8b5b6a2e79c2cf Mon Sep 17 00:00:00 2001 From: Jonas Nick Date: Sun, 3 Apr 2022 23:43:05 +0000 Subject: [PATCH] musig-spec: explain NonceGen and tweaking in signing flow context --- doc/musig-spec.mediawiki | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/doc/musig-spec.mediawiki b/doc/musig-spec.mediawiki index 1482cf80b..07a2e37af 100644 --- a/doc/musig-spec.mediawiki +++ b/doc/musig-spec.mediawiki @@ -71,8 +71,6 @@ If all signers behaved honestly, the result passes [https://github.com/bitcoin/b Otherwise, extracting the secret signing key from the partial signatures is possible. To avoid accidental reuse, an implementation may securely erase the ''secnonce'' argument by overwriting it with zeros after ''Sign'' has been run. A ''secnonce'' consisting of only zeros is invalid for ''Sign'' and will cause it to fail. -The ''NonceGen'' algorithm '''must''' draw unbiased, uniformly random values ''k1'' and ''k2''. -In particular, ''k1'' and ''k2'' must _not_ be derived deterministically from the session parameters (see [[#nonce-generation|Nonce Generation]]). The output of ''KeyAgg'' is dependent on the order of the input public keys. 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. @@ -108,11 +106,39 @@ As a result, the [[#session-context|Session Context]] may look very different in ==== Nonce Generation ==== -TODO +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' '' would be identical in two ''NonceGen'' invocations, but any optional argument is unequal, the values ''k1'' and ''k2'' are unequal as well (with overwhelming probability). +In this case, 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 ''in'' can contain additional contextual data that has a chance of changing between ''NonceGen'' runs. +However, the protection from 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 attacker. + +On systems where obtaining uniformly random values is much harder than maintaining a global atomic counter, it can be beneficial to modify ''NonceGen''. +Instead of drawing ''rand' '' uniformly at random, ''rand' '' can be the output of an atomic counter. +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 counter must never return the same output in two ''NonceGen'' invocations with the same ''sk''. + +It is possible to modify ''NonceGen'' such that the ''secnonce'' of a single signer can be derived deterministically. +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. +In addition, ''NonceGen' '' requires the ''pubnonce'' value of _all_ other signers, which can be provided via the ''in'' argument. +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. +Lastly, to make ''NonceGen' '' deterministic, ''rand' '' is removed and ''rand'' is set to ''sk''. +Note that failure to provide the correct arguments to ''NonceGen' '' will allow attackers to extract secret keys. ==== Tweaking ==== -TODO +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. +For example, if ''KeyAgg'' is run with ''v = 2'', ''is_xonly_t1 = false'', ''is_xonly_t2 = true'', then the aggregate key is first ordinarily tweaked with ''tweak1'' and then X-only tweaked with ''tweak2''. + +The purpose of specifying tweaking is only to ensure compatibility with existing uses of tweaking, i.e., that the result of the signing is a valid signature with the tweaks applied. +The algorithms take arbitrary tweaks as input but allowing for arbitrary tweaks will render signatures insecure. +So, the tweaks themselves still need to be obtained according to other specifications, which preserve the security of tweaked signatures even if MuSig2 is used to generate the signatures. +This typically involves deriving the tweaks from a hash of the public key given as input to the tweaking algorithm and some other information. + +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]. +On the other hand, X-only tweaking is required for Taproot tweaking per [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341]. +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. === Notation ===