frost: nonce generation
This commits adds nonce generation, as well as serialization and parsing.
This commit is contained in:
@@ -15,6 +15,9 @@ extern "C" {
|
||||
* This module implements a variant of Flexible Round-Optimized Schnorr
|
||||
* Threshold Signatures (FROST) by Chelsea Komlo and Ian Goldberg
|
||||
* (https://crysp.uwaterloo.ca/software/frost/).
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/** Opaque data structures
|
||||
@@ -34,6 +37,61 @@ typedef struct {
|
||||
unsigned char data[36];
|
||||
} secp256k1_frost_share;
|
||||
|
||||
/** Opaque data structure that holds a signer's _secret_ nonce.
|
||||
*
|
||||
* Guaranteed to be 68 bytes in size.
|
||||
*
|
||||
* WARNING: This structure MUST NOT be copied or read or written to directly.
|
||||
* A signer who is online throughout the whole process and can keep this
|
||||
* structure in memory can use the provided API functions for a safe standard
|
||||
* workflow. See
|
||||
* https://blockstream.com/2019/02/18/musig-a-new-multisignature-standard/ for
|
||||
* more details about the risks associated with serializing or deserializing
|
||||
* this structure.
|
||||
*
|
||||
* We repeat, copying this data structure can result in nonce reuse which will
|
||||
* leak the secret signing key.
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned char data[68];
|
||||
} secp256k1_frost_secnonce;
|
||||
|
||||
/** Opaque data structure that holds a signer's public nonce.
|
||||
*
|
||||
* Guaranteed to be 132 bytes in size. It can be safely copied/moved.
|
||||
* Serialized and parsed with `frost_pubnonce_serialize` and
|
||||
* `frost_pubnonce_parse`.
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned char data[132];
|
||||
} secp256k1_frost_pubnonce;
|
||||
|
||||
/** Parse a signer's public nonce.
|
||||
*
|
||||
* Returns: 1 when the nonce could be parsed, 0 otherwise.
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: nonce: pointer to a nonce object
|
||||
* In: in66: pointer to the 66-byte nonce to be parsed
|
||||
*/
|
||||
SECP256K1_API int secp256k1_frost_pubnonce_parse(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_frost_pubnonce *nonce,
|
||||
const unsigned char *in66
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Serialize a signer's public nonce
|
||||
*
|
||||
* Returns: 1 when the nonce could be serialized, 0 otherwise
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: out66: pointer to a 66-byte array to store the serialized nonce
|
||||
* In: nonce: pointer to the nonce
|
||||
*/
|
||||
SECP256K1_API int secp256k1_frost_pubnonce_serialize(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *out66,
|
||||
const secp256k1_frost_pubnonce *nonce
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Serialize a FROST share
|
||||
*
|
||||
* Returns: 1 when the share could be serialized, 0 otherwise
|
||||
@@ -181,6 +239,59 @@ SECP256K1_API int secp256k1_frost_compute_pubshare(
|
||||
size_t n_participants
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
/** Starts a signing session by generating a nonce
|
||||
*
|
||||
* This function outputs a secret nonce that will be required for signing and a
|
||||
* corresponding public nonce that is intended to be sent to other signers.
|
||||
*
|
||||
* FROST, like MuSig, differs from regular Schnorr signing in that
|
||||
* implementers _must_ take special care to not reuse a nonce. This can be
|
||||
* ensured by following these rules:
|
||||
*
|
||||
* 1. Each call to this function must have a UNIQUE session_id32 that must NOT BE
|
||||
* REUSED in subsequent calls to this function.
|
||||
* If you do not provide a seckey, session_id32 _must_ be UNIFORMLY RANDOM
|
||||
* AND KEPT SECRET (even from other signers). If you do provide a seckey,
|
||||
* session_id32 can instead be a counter (that must never repeat!). However,
|
||||
* it is recommended to always choose session_id32 uniformly at random.
|
||||
* 2. If you already know the seckey, message or aggregate public key, they
|
||||
* can be optionally provided to derive the nonce and increase
|
||||
* misuse-resistance. The extra_input32 argument can be used to provide
|
||||
* additional data that does not repeat in normal scenarios, such as the
|
||||
* current time.
|
||||
* 3. Avoid copying (or serializing) the secnonce. This reduces the possibility
|
||||
* that it is used more than once for signing.
|
||||
*
|
||||
* Remember that nonce reuse will leak the secret key!
|
||||
* Note that using the same agg_share for multiple FROST sessions is fine.
|
||||
*
|
||||
* Returns: 0 if the arguments are invalid and 1 otherwise
|
||||
* Args: ctx: pointer to a context object (not secp256k1_context_static)
|
||||
* Out: secnonce: pointer to a structure to store the secret nonce
|
||||
* pubnonce: pointer to a structure to store the public nonce
|
||||
* In: session_id32: a 32-byte session_id32 as explained above. Must be
|
||||
* unique to this call to secp256k1_frost_nonce_gen and
|
||||
* must be uniformly random unless you really know what you
|
||||
* are doing.
|
||||
* agg_share: the aggregated share that will later be used for
|
||||
* signing, if already known (can be NULL)
|
||||
* msg32: the 32-byte message that will later be signed, if
|
||||
* already known (can be NULL)
|
||||
* agg_pk: the FROST-aggregated public key (can be NULL)
|
||||
* extra_input32: an optional 32-byte array that is input to the nonce
|
||||
* derivation function (can be NULL)
|
||||
*/
|
||||
SECP256K1_API int secp256k1_frost_nonce_gen(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_frost_secnonce *secnonce,
|
||||
secp256k1_frost_pubnonce *pubnonce,
|
||||
const unsigned char *session_id32,
|
||||
const secp256k1_frost_share *agg_share,
|
||||
const unsigned char *msg32,
|
||||
const secp256k1_xonly_pubkey *agg_pk,
|
||||
const unsigned char *extra_input32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user