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 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.
|
||||||
|
|
||||||
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
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