Skip to content

Commit f41560c

Browse files
committed
frost trusted dealer: add documentation file
This commit adds a documentation file with detailed instructions for how to use the module properly.
1 parent fafc1f1 commit f41560c

File tree

3 files changed

+104
-1
lines changed

3 files changed

+104
-1
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Added features:
1212
* Experimental module for Confidential Assets (Pedersen commitments, range proofs, and [surjection proofs](src/modules/surjection/surjection.md)).
1313
* Experimental module for Bulletproofs++ range proofs.
1414
* Experimental module for [address whitelisting](src/modules/whitelist/whitelist.md).
15-
* Experimental module for FROST.
15+
* Experimental module for [FROST](src/modules/frost/frost.md).
1616

1717
Experimental features are made available for testing and review by the community. The APIs of these features should not be considered stable.
1818

include/secp256k1_frost.h

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ extern "C" {
2121
* The module also supports BIP-341 ("Taproot") and BIP-32 ("ordinary") public
2222
* key tweaking, and adaptor signatures.
2323
*
24+
* It is recommended to read the documentation in this include file carefully.
25+
* Further notes on API usage can be found in src/modules/frost/frost.md
26+
*
2427
* Following the convention used in the MuSig module, the API uses the singular
2528
* term "nonce" to refer to the two "nonces" used by the FROST scheme.
2629
*/

src/modules/frost/frost.md

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
Notes on the frost module API
2+
===========================
3+
4+
The following sections contain additional notes on the API of the frost module
5+
(`include/secp256k1_frost.h`). A usage example can be found in
6+
`examples/frost.c`.
7+
8+
# API misuse
9+
10+
<!-- TODO: Add warning about not using DKG output directly on-chain (c.f. BIP341, unspendable script path) -->
11+
<!-- Also add warning in the headers file -->
12+
13+
Users of the frost module must take great care to make sure of the following:
14+
15+
1. Each participant exchanges public keys for identification and authentication
16+
purposes. Partipants must provide the same public key to each other
17+
participant.
18+
2. The dealer establishes a secure communications channel with each participant
19+
and uses that channel to transmit shares during key generation.
20+
3. A unique set of coefficients per key generation session is generated in
21+
`secp256k1_frost_shares_gen`. See the corresponding comment in
22+
`include/secp256k1_frost.h` for how to ensure that.
23+
4. The `pubnonces` provided to `secp256k1_frost_nonce_process` are sorted by
24+
the corresponding lexicographic ordering of the x-only pubkey of each
25+
participant, and the `ids33` provided to `secp256k1_frost_nonce_process`
26+
are sorted lexicographically.
27+
5. A unique nonce per signing session is generated in `secp256k1_frost_nonce_gen`.
28+
See the corresponding comment in `include/secp256k1_frost.h` for how to ensure that.
29+
6. The `secp256k1_frost_secnonce` structure is never copied or serialized.
30+
See also the comment on `secp256k1_frost_secnonce` in `include/secp256k1_frost.h`.
31+
7. Opaque data structures are never written to or read from directly.
32+
Instead, only the provided accessor functions are used.
33+
8. If adaptor signatures are used, all partial signatures are verified.
34+
35+
# Key Generation
36+
37+
1. Generate a keypair with `secp256k1_keypair_create` and obtain the public key
38+
with `secp256k1_keypair_pub`, and distribute it to each other participant to
39+
be used as an authentication key and identifier.
40+
2. The trusted dealer generate a VSS commitment and shares with
41+
`secp256k1_frost_shares_gen`. The VSS commitment must be broadcast to all
42+
participants. Assign each participant a share according to the order of
43+
`ids33` and distribute the shares to the participants using a secure
44+
channel.
45+
3. After receiving a share and VSS commitment from the dealer, call
46+
`secp256k1_frost_share_verify` to verify the share.
47+
4. Compute the public verification shares for each participant by calling
48+
`secp256k1_frost_compute_pubshare` with the public key of the participant.
49+
This share is required by `secp256k1_frost_partial_sig_verify` to verify
50+
partial signatures generated by `secp256k1_frost_partial_sign`, and public
51+
shares are required by `secp256k1_frost_pubkey_gen` to generate the group
52+
public key.
53+
5. Generate the group key by passing the public shares of all participants to
54+
`secp256k1_frost_pubkey_gen`, which will initialize a key generation
55+
context. The context can be passed to `secp256k1_frost_pubkey_get` to obtain
56+
the group public key.
57+
58+
# Tweaking
59+
60+
A (Taproot) tweak can be added to the resulting public key with
61+
`secp256k1_xonly_pubkey_tweak_add`, after converting it to an xonly pubkey if
62+
necessary with `secp256k1_xonly_pubkey_from_pubkey`.
63+
64+
An ordinary tweak can be added to the resulting public key with
65+
`secp256k1_ec_pubkey_tweak_add`, after converting it to an ordinary pubkey if
66+
necessary with `secp256k1_frost_pubkey_get`.
67+
68+
Tweaks can also be chained together by tweaking an already tweaked key.
69+
70+
# Signing
71+
72+
1. Initialize the key generation context with `secp256k1_frost_pubkey_gen`.
73+
2. Optionally add a tweak by calling `secp256k1_frost_pubkey_tweak` and then
74+
`secp256k1_frost_pubkey_xonly_tweak_add` for a Taproot tweak and
75+
`secp256k1_frost_pubkey_ec_tweak_add` for an ordinary tweak.
76+
3. Generate a pair of secret and public nonce with `secp256k1_frost_nonce_gen`
77+
and send the public nonce to the other signers.
78+
4. Process the aggregate nonce with `secp256k1_frost_nonce_process`.
79+
5. Create a partial signature with `secp256k1_frost_partial_sign`.
80+
6. Verify the partial signatures (optional in some scenarios) with
81+
`secp256k1_frost_partial_sig_verify`.
82+
7. Someone (not necessarily the signer) obtains all partial signatures and
83+
aggregates them into the final Schnorr signature using
84+
`secp256k1_frost_partial_sig_agg`.
85+
86+
The aggregate signature can be verified with `secp256k1_schnorrsig_verify`.
87+
88+
Note that steps 1 to 3 can happen before the message to be signed is known to
89+
the signers. Therefore, the communication round to exchange nonces can be
90+
viewed as a pre-processing step that is run whenever convenient to the signers.
91+
This disables some of the defense-in-depth measures that may protect against
92+
API misuse in some cases. Similarly, the API supports an alternative protocol
93+
flow where generating the key (see Key Generation above) is allowed to happen
94+
after exchanging nonces (step 3).
95+
96+
# Verification
97+
98+
A participant who wants to verify the partial signatures, but does not sign
99+
itself may do so using the above instructions except that the verifier skips
100+
steps 3 and 5.

0 commit comments

Comments
 (0)