-
Notifications
You must be signed in to change notification settings - Fork 208
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
frost trusted dealer: add documentation file
This commit adds a documentation file with detailed instructions for how to use the module properly.
- Loading branch information
1 parent
081e5fc
commit abb2ee3
Showing
3 changed files
with
104 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
Notes on the frost module API | ||
=========================== | ||
|
||
The following sections contain additional notes on the API of the frost module | ||
(`include/secp256k1_frost.h`). A usage example can be found in | ||
`examples/frost.c`. | ||
|
||
# API misuse | ||
|
||
<!-- TODO: Add warning about not using DKG output directly on-chain (c.f. BIP341, unspendable script path) --> | ||
<!-- Also add warning in the headers file --> | ||
|
||
Users of the frost module must take great care to make sure of the following: | ||
|
||
1. Each participant exchanges public keys for identification and authentication | ||
purposes. Partipants must provide the same public key to each other | ||
participant. | ||
2. The dealer establishes a secure communications channel with each participant | ||
and uses that channel to transmit shares during key generation. | ||
3. A unique set of coefficients per key generation session is generated in | ||
`secp256k1_frost_shares_gen`. See the corresponding comment in | ||
`include/secp256k1_frost.h` for how to ensure that. | ||
4. The `pubnonces` provided to `secp256k1_frost_nonce_process` are sorted by | ||
the corresponding lexicographic ordering of the x-only pubkey of each | ||
participant, and the `ids33` provided to `secp256k1_frost_nonce_process` | ||
are sorted lexicographically. | ||
5. A unique nonce per signing session is generated in `secp256k1_frost_nonce_gen`. | ||
See the corresponding comment in `include/secp256k1_frost.h` for how to ensure that. | ||
6. The `secp256k1_frost_secnonce` structure is never copied or serialized. | ||
See also the comment on `secp256k1_frost_secnonce` in `include/secp256k1_frost.h`. | ||
7. Opaque data structures are never written to or read from directly. | ||
Instead, only the provided accessor functions are used. | ||
8. If adaptor signatures are used, all partial signatures are verified. | ||
|
||
# Key Generation | ||
|
||
1. Generate a keypair with `secp256k1_keypair_create` and obtain the public key | ||
with `secp256k1_keypair_pub`, and distribute it to each other participant to | ||
be used as an authentication key and identifier. | ||
2. The trusted dealer generate a VSS commitment and shares with | ||
`secp256k1_frost_shares_gen`. The VSS commitment must be broadcast to all | ||
participants. Assign each participant a share according to the order of | ||
`ids33` and distribute the shares to the participants using a secure | ||
channel. | ||
3. After receiving a share and VSS commitment from the dealer, call | ||
`secp256k1_frost_share_verify` to verify the share. | ||
4. Compute the public verification shares for each participant by calling | ||
`secp256k1_frost_compute_pubshare` with the public key of the participant. | ||
This share is required by `secp256k1_frost_partial_sig_verify` to verify | ||
partial signatures generated by `secp256k1_frost_partial_sign`, and public | ||
shares are required by `secp256k1_frost_pubkey_gen` to generate the group | ||
public key. | ||
5. Generate the group key by passing the public shares of all participants to | ||
`secp256k1_frost_pubkey_gen`, which will initialize a key generation | ||
context. The context can be passed to `secp256k1_frost_pubkey_get` to obtain | ||
the group public key. | ||
|
||
# Tweaking | ||
|
||
A (Taproot) tweak can be added to the resulting public key with | ||
`secp256k1_xonly_pubkey_tweak_add`, after converting it to an xonly pubkey if | ||
necessary with `secp256k1_xonly_pubkey_from_pubkey`. | ||
|
||
An ordinary tweak can be added to the resulting public key with | ||
`secp256k1_ec_pubkey_tweak_add`, after converting it to an ordinary pubkey if | ||
necessary with `secp256k1_frost_pubkey_get`. | ||
|
||
Tweaks can also be chained together by tweaking an already tweaked key. | ||
|
||
# Signing | ||
|
||
1. Initialize the key generation context with `secp256k1_frost_pubkey_gen`. | ||
2. Optionally add a tweak by calling `secp256k1_frost_pubkey_tweak` and then | ||
`secp256k1_frost_pubkey_xonly_tweak_add` for a Taproot tweak and | ||
`secp256k1_frost_pubkey_ec_tweak_add` for an ordinary tweak. | ||
3. Generate a pair of secret and public nonce with `secp256k1_frost_nonce_gen` | ||
and send the public nonce to the other signers. | ||
4. Process the aggregate nonce with `secp256k1_frost_nonce_process`. | ||
5. Create a partial signature with `secp256k1_frost_partial_sign`. | ||
6. Verify the partial signatures (optional in some scenarios) with | ||
`secp256k1_frost_partial_sig_verify`. | ||
7. Someone (not necessarily the signer) obtains all partial signatures and | ||
aggregates them into the final Schnorr signature using | ||
`secp256k1_frost_partial_sig_agg`. | ||
|
||
The aggregate signature can be verified with `secp256k1_schnorrsig_verify`. | ||
|
||
Note that steps 1 to 3 can happen before the message to be signed is known to | ||
the signers. Therefore, the communication round to exchange nonces can be | ||
viewed as a pre-processing step that is run whenever convenient to the signers. | ||
This disables some of the defense-in-depth measures that may protect against | ||
API misuse in some cases. Similarly, the API supports an alternative protocol | ||
flow where generating the key (see Key Generation above) is allowed to happen | ||
after exchanging nonces (step 3). | ||
|
||
# Verification | ||
|
||
A participant who wants to verify the partial signatures, but does not sign | ||
itself may do so using the above instructions except that the verifier skips | ||
steps 3 and 5. |