Skip to content

Commit 3891388

Browse files
committed
frost: add documentation file
This commit adds a documentation file with detailed instructions for how to use the module properly.
1 parent 36ff5b0 commit 3891388

File tree

3 files changed

+99
-1
lines changed

3 files changed

+99
-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

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

0 commit comments

Comments
 (0)