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:
parent
36ff5b02da
commit
3891388905
@ -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 Bulletproofs++ range proofs.
|
||||
* 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.
|
||||
|
||||
|
@ -21,6 +21,9 @@ extern "C" {
|
||||
* The module also supports BIP-341 ("Taproot") and BIP-32 ("ordinary") public
|
||||
* 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
|
||||
* term "nonce" to refer to the two "nonces" used by the FROST scheme.
|
||||
*/
|
||||
|
95
src/modules/frost/frost.md
Normal file
95
src/modules/frost/frost.md
Normal 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.
|
Loading…
x
Reference in New Issue
Block a user