frost: add documentation file

This commit adds a documentation file with detailed instructions for how
to use the module properly.
This commit is contained in:
Jesse Posner 2024-07-16 23:33:54 -07:00
parent 36ff5b02da
commit 3891388905
No known key found for this signature in database
GPG Key ID: 49A08EAB3A812D69
3 changed files with 99 additions and 1 deletions

View File

@ -12,7 +12,7 @@ Added features:
* Experimental module for Confidential Assets (Pedersen commitments, range proofs, and [surjection proofs](src/modules/surjection/surjection.md)). * Experimental module for Confidential Assets (Pedersen commitments, range proofs, and [surjection proofs](src/modules/surjection/surjection.md)).
* Experimental module for Bulletproofs++ range proofs. * Experimental module for Bulletproofs++ range proofs.
* Experimental module for [address whitelisting](src/modules/whitelist/whitelist.md). * Experimental module for [address whitelisting](src/modules/whitelist/whitelist.md).
* Experimental module for FROST. * Experimental module for [FROST](src/modules/frost/frost.md).
Experimental features are made available for testing and review by the community. The APIs of these features should not be considered stable. Experimental features are made available for testing and review by the community. The APIs of these features should not be considered stable.

View File

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

View File

@ -0,0 +1,95 @@
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
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. Each participant establishes a secure communications channel with each other
participant and uses that channel to transmit shares and commitments 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 x-only
public key with `secp256k1_keypair_xonly_pub`, and distribute it to each
other participant to be used as an authentication key and identifier.
2. Generate a VSS commitment, proof-of-knowledge, and shares with
`secp256k1_frost_shares_gen`. The VSS commitment and proof-of-knowledge 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 commitment set from each participant, call
`secp256k1_frost_share_agg` to compute the aggregate share, group public
key, and VSS hash. If this function returns an error,
`secp256k1_frost_share_verify` is called on each share to determine which
participants submitted faulty shares.
4. Optionally compute the public verification share by calling
`secp256k1_frost_compute_pubshare` with the x-only public key of each
participant. This share is required by `secp256k1_frost_partial_sig_verify`
to verify partial signatures generated by `secp256k1_frost_partial_sign`.
# 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. 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.
2. Generate a pair of secret and public nonce with `secp256k1_frost_nonce_gen`
and send the public nonce to the other signers.
3. Process the aggregate nonce with `secp256k1_frost_nonce_process`.
4. Create a partial signature with `secp256k1_frost_partial_sign`.
5. Verify the partial signatures (optional in some scenarios) with
`secp256k1_frost_partial_sig_verify`.
6. 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 2).
# 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 2 and 4.