From 6b0b22bc89cbacfdd16ae80f7d5c759a4bade2c3 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Fri, 8 Feb 2019 19:31:28 +0000 Subject: [PATCH] musig: add user documentation --- src/modules/musig/musig.md | 189 +++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 src/modules/musig/musig.md diff --git a/src/modules/musig/musig.md b/src/modules/musig/musig.md new file mode 100644 index 00000000..89b79076 --- /dev/null +++ b/src/modules/musig/musig.md @@ -0,0 +1,189 @@ +MuSig - Rogue-Key-Resistant Multisignatures Module +=========================== + +This module implements the MuSig [1] multisignature scheme. The majority of +the module is an API designed to be used by signing or auditing participants +in a multisignature scheme. This involves a somewhat complex state machine +and significant effort has been taken to prevent accidental misuse of the +API in ways that could lead to accidental signatures or loss of key material. + +# Theory + +In MuSig all participants contribute key material to a single signing key, +using the equation + + P = sum_i µ_i * P_i + +where `P_i` is the public key of the `i`th participant and `µ_i` is a so-called +_MuSig coefficient_ computed according to the following equation + + C = H(P_1 || P_2 || ... || P_n) + µ_i = H(C || i) + +where H is a hash function modelled as a random oracle. + +To produce a multisignature `(s, R)` on a message `m` using verification key +`P`, signers act as follows: + + 1. Each computes a nonce, or ephemeral keypair, `(k_i, R_i)`. Every participant + communinicates `H(R_i)` to every other participant. + 2. Upon receipt of every `H(R_i)`, each participant communicates `R_i` to every + other participant. The recipients check that each `R_i` is consistent with + the previously-communicated hash. + 3. Each participant computes a combined nonce + R = sum_i R_i + and shared challenge + e = H(R || P || m) + and partial signature + s_i = k_i + µ_i*x_i*e + where `x_i` is the secret key corresponding to `P_i`. + +The complete signature is then the `(s, R)` where `s = sum_i s_i` and `R = sum_i R_i`. + +# API Usage + +It is essential to security that signers use a unique uniformly random none for all +signing sessions, and that they do not reuse these nonces even in the case that a +signing session fails to complete. To that end, all signing state is encapsulated +in the data structure `secp256k1_musig_session`. The API does not expose any +functionality to serialize or deserialize this structure; it is designed to exist +only in memory. + +Users who need to persist this structure must take additional security measures +which cannot be enforced by a C API. Some guidance is provided in the documentation +for this data structure in `include/secp256k1_musig.h`. + +## Key Generation + +To use MuSig, users must first compute their combined public key `P`, which is +suitable for use on a blockchain or other public key repository. They do this +by calling `secp256k1_musig_pubkey_combine`. + +This function takes as input a list of public keys `P_i` in the argument +`pubkeys`. It outputs the combined public key `P` in the out-pointer `combined_pk` +and hash `C` in the out-pointer `pk_hash32`, if this pointer is non-NULL. + +## Signing + +A participant who wishes to sign a message (as opposed to observing/auditing the +signature process, which is also a supported mode) acts as follows. + +### Signing Participant + + 1. Starts the session by calling `secp256k1_musig_session_initialize`. This + function outputs + * an initialized session state in the out-pointer `session` + * an array of initialized signer data in the out-pointer `signers` + * a commitment `H(R_i)` to a nonce in the out-pointer `nonce_commitment32` + It takes as input + * a unique session ID `session_id32` + * (optionally) a message to be signed `msg32` + * the combined public key output from `secp256k1_musig_pubkey_combine` + * the public key hash output from `secp256k1_musig_pubkey_combine` + * the signer's index `i` `my_index` + * the signer's secret key `seckey` + 2. The signer then communicates `H(R_i)` to all other signers, and receives + commitments `H(R_j)` from all other signers `j`. These hashes are simply + length-32 byte arrays which can be communicated however is communicated. + 3. Once all signers nonce commitments have been received, the signer records + these commitments with the function `secp256k1_musig_session_get_public_nonce`. + This function updates in place + * the session state `session` + * the array of signer data `signers` + taking in as input the list of commitments `commitments` and outputting the + signer's public nonce `R_i` in the out-pointer `nonce`. + 4. The signer then communicates `R_i` to all other signers, and receives `R_j` + from each signer `j`. On receipt of a nonce `R_j` he calls the function + `secp256k1_musig_set_nonce` to record this fact. This function checks that + the received nonce is consistent with the previously-received nonce and will + return 0 in this case. + These nonces `R_i` are secp256k1 public keys; they should be serialized using + `secp256k1_ec_pubkey_serialize` and parsed with `secp256k1_ec_pubkey_parse`. + 5. Once all nonces have been exchanged in this way, signers are able to compute + their partial signatures. They do so by calling `secp256k1_musig_session_combine_nonces` + which updates in place + * the session state `session` + * the array of signer data `signers` + It outputs an auxillary integer `nonce_is_negated` and has an auxillary input + `adaptor`. Both of these may be set to NULL for ordinary signing purposes. + If the signer did not provide a message to `secp256k1_musig_session_initialize`, + a message must be provided now by calling `secp256k1_musig_session_set_msg` which + updates the session state in place. + 6. The signer computes a partial signature `s_i` using the function + `secp256k1_musig_partial_sign` which takes the session state as input and + partial signature as output. + 7. The signer then communicates the partial signature `s_i` to all other signers, or + to a central coordinator. These partial signatures should be serialized using + `musig_partial_signature_serialize` and parsed using `musig_partial_signature_parse`. + 8. Each signer calls `secp256k1_musig_partial_sig_verify` on the other signers' partial + signatures to verify their correctness. If only the validity of the final signature + is important, not assigning blame, this step can be skipped. + 9. Any signer, or central coordinator, may combine the partial signatures to obtain + a complete signature using `secp256k1_musig_partial_sig_combine`. This function takes + a signing session and array of MuSig partial signatures, and outputs a single + Schnorr signature. + +### Non-signing Participant + +A participant who wants to verify the signing process but not actually contribute a +partial signature, may do so using the above instructions except for the following +changes: + + 1. A signing session should be produced using `musig_session_initialize_verifier` + rather than `musig_session_initialize`; this function takes no secret data or + signer index. + 2. The participant receives nonce commitments, public nonces and partial signatures, + but does not produce these values. Therefore `secp256k1_musig_session_get_public_nonce` + and `secp256k1_musig_partial_sign` are not called. + +### Verifier + +The final signature is simply a valid Schnorr signature using the combined public key. It +can be verified using the `secp256k1_schnorrsig_verify` with the correct message and +public key output from `secp256k1_musig_pubkey_combine`. + +## Atomic Swaps + +The signing API supports the production of "adaptor signatures", modified partial signatures +which have an auxiliary secret encrypted to them. A partial signature is revealed to a party +who learns the secret; conversely, a party with the corresponding secret will learn the +secret. + +Using these adaptor signatures, two 2-of-2 MuSig signing protocols can be executed in +parallel such that one party's partial signatures are made atomic. That is, when the other +party learns one partial signature, she automatically learns the other. This has applications +in cross-chain atomic swaps. + +Such a protocol can be executed as follows. Consider two participants, Alice and Bob, who +are simultaneously producing 2-of-2 multisignatures for two blockchains A and B. They act +as follows. + + 1. Before the protocol begins, Bob chooses a 32-byte auxiliary secret `t` at random and + computes a corresponding public point `T` by calling `secp256k1_ec_pubkey_create`. + He communicates `T` to Alice. + 2. Together, the parties execute steps 1-4 of the signing protocol above. + 3. At step 5, when combining the two parties' public nonces, both parties call + `secp256k1_musig_session_combine_nonces` with `adaptor` set to `T` and `nonce_is_negated` + set to a non-NULL pointer to int. + 4. Steps 6 and 7 proceed as before. Step 8, verifying the partial signatures, is now + essential to the security of the protocol and must not be omitted! + +The above steps are executed identically for both signing sessions. However, step 9 will +not work as before, since the partial signatures will not add up to a valid total signature. +Additonal steps must be taken, and it is at this point that the two signing sessions +diverge. From here on we consider "Session A" which benefits Alice (e.g. which sends her +coins) and "Session B" which benefits Bob (e.g. which sends him coins). + + 5. In Session B, Bob calls `secp256k1_musig_partial_sig_adapt` with his partial signature + and `t`, to produce an adaptor signature. He can then call `secp256k1_musig_partial_sig_combine` + with this adaptor signature and Alice's partial signature, to produce a complete + signature for blockchain B. + 6. Alice reads this signature from blockchain B. She calls `secp256k1_musig_extract_secret_adaptor`, + passing the complete signature along with her and Bob's partial signatures. This function + outputs `t`, which until this point was only known to Bob. + 7. In Session A, Alice is now able to replicate Bob's action, calling + `secp256k1_musig_partial_sig_adapt` with her own partial signature and `t`, ultimately + producing a complete signature on blockchain A. + +[1] https://eprint.iacr.org/2018/068 +