Notes on the frost module API
=============================

This module implements BIP 445 "FROST Signing Protocol for BIP340 Signatures"
(FROST3), a threshold Schnorr signature scheme: any t-of-n subset of
participants can jointly produce a BIP340 signature on the shared threshold
public key. The specification lives at
https://github.com/siv2r/bip-frost-signing. The implementation and its test
vectors are validated against the pinned spec commit
`bb5396f90d45ba5a954cbfd1af80f1b45e02b229` (BIP v0.10.0).

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`.

**This module is experimental.** Do not use it in production. The API should
not be considered stable.

Key generation
--------------

Distributed key generation (DKG) is out of scope for BIP 445; the intended DKG
is ChillDKG (https://github.com/BlockstreamResearch/bip-frost-dkg). This module
therefore only provides key generation with a trusted dealer:
`secp256k1_frost_trusted_dealer_keygen` derives, from a threshold secret key,
one secret share and one public share per participant.

The dealer MUST transmit each secret share to its participant over a secure
(authenticated and encrypted) channel and MUST erase the threshold secret key
and all secret shares afterwards. If key generation is compromised, the entire
setup is compromised; `secp256k1_frost_threshold_info_validate` cannot detect
this. It only proves that the key material is functionally compatible (the
public shares lie on a single polynomial consistent with the threshold public
key) — it says nothing about the security of the key generation that produced
it.

Signing flow
------------

A signing session involves u signers (threshold <= u <= n) and, optionally, a
coordinator:

1. Every signer runs `secp256k1_frost_nonce_gen` and sends the pubnonce to the
   coordinator.
2. The coordinator aggregates the pubnonces with `secp256k1_frost_nonce_agg`
   and sends the aggnonce to the signers.
3. Everyone runs `secp256k1_frost_session_init` on identical session
   parameters (aggnonce, signer ids, tweak cache, message).
4. Every signer runs `secp256k1_frost_sign` and sends the partial signature
   to the coordinator.
5. The coordinator verifies every partial signature with
   `secp256k1_frost_partial_sig_verify` and aggregates them with
   `secp256k1_frost_partial_sig_agg` into the final BIP340 signature.

The session object is signer-agnostic: a coordinator initializes a single
session and uses it to verify the partial signatures of all signers.

`secp256k1_frost_deterministic_sign` is an alternative for a signer that is
online throughout the whole session: it combines nonce generation and signing
into one deterministic step and involves no secnonce object.

`secp256k1_frost_nonce_agg` and `secp256k1_frost_partial_sig_agg` support
identifiable abort via their `error_index` out-params: on failure, they report
the index of the offending contribution. Note that invalid partial signatures
are only detected by `secp256k1_frost_partial_sig_verify`; a successful
`secp256k1_frost_partial_sig_agg` does NOT imply that the resulting signature
verifies.

The same `ids` array that is passed to `secp256k1_frost_session_init` must be
passed identically to `secp256k1_frost_sign` and
`secp256k1_frost_partial_sig_verify`.

Tweaking
--------

Public key tweaking (e.g. BIP 341 Taproot tweaking) is handled via a tweak
cache: initialize it from the untweaked threshold public key with
`secp256k1_frost_tweak_cache_init`, apply tweaks with
`secp256k1_frost_pubkey_xonly_tweak_add` (x-only/BIP 341 tweaking) and/or
`secp256k1_frost_pubkey_ec_tweak_add` (plain/BIP 32-style tweaking), and
retrieve the resulting x-only threshold public key with
`secp256k1_frost_tweaked_pubkey_get`. A tweak cache is required for
`secp256k1_frost_session_init` even if no tweaks are applied; all session
participants must apply the same tweaks in the same order.

Security notes
--------------

- A secnonce must never be reused. Reusing a secret nonce in two signatures
  leaks the signer's secret share. To prevent reuse, `secp256k1_frost_sign`
  wipes the secnonce (a second call with the same secnonce fails), and
  `secp256k1_frost_nonce_gen` wipes `session_secrand32`. Never copy, serialize
  or otherwise duplicate a `secp256k1_frost_secnonce` structure.
- `session_secrand32` must be 32 bytes of fresh, uniformly random data that is
  unique for every call to `secp256k1_frost_nonce_gen`. Passing the secret
  share to `nonce_gen` is recommended as defense-in-depth against bad
  randomness.
- Final signatures produced by `secp256k1_frost_partial_sig_agg` are ordinary
  BIP340 signatures; they are verified with `secp256k1_schnorrsig_verify`
  against the (tweaked) x-only threshold public key.

Deviations from the BIP 445 reference code
------------------------------------------

- Error model: the BIP 445 reference code raises exceptions; this API maps
  them to 0 return values, to the illegal-argument callback (for violations of
  the documented API contract, e.g. NULL arguments or corrupt opaque structs),
  and to `error_index` out-params (for identifying the offending contribution
  in `nonce_agg` and `partial_sig_agg`).
- `secp256k1_frost_threshold_info_validate` requires all n public shares to be
  present; the BIP 445 algorithm tolerates missing pubshares ("holes"), which
  is not expressible in this API.
- 8 error test cases of the BIP 445 tweak vectors (mismatched `tweaks` and
  `is_xonly` array lengths, non-32-byte tweaks) are not expressible in this
  API — tweaks are applied individually and have a fixed length of 32 bytes —
  and are therefore skipped (documented in `src/modules/frost/vectors.h`).
- Signer identifiers must be passed to `secp256k1_frost_sign` and
  `secp256k1_frost_partial_sig_verify` identical to
  `secp256k1_frost_session_init` (the BIP 445 reference code carries them in
  its session/context objects instead).
