@@ -18,6 +18,9 @@ extern "C" {
18
18
*
19
19
* The module also supports BIP-341 ("Taproot") and BIP-32 ("ordinary") public
20
20
* key tweaking.
21
+ *
22
+ * Following the convention used in the MuSig module, the API uses the singular
23
+ * term "nonce" to refer to the two "nonces" used by the FROST scheme.
21
24
*/
22
25
23
26
/** Opaque data structures
@@ -46,6 +49,61 @@ typedef struct {
46
49
unsigned char data [36 ];
47
50
} secp256k1_frost_share ;
48
51
52
+ /** Opaque data structure that holds a signer's _secret_ nonce.
53
+ *
54
+ * Guaranteed to be 68 bytes in size.
55
+ *
56
+ * WARNING: This structure MUST NOT be copied or read or written to directly.
57
+ * A signer who is online throughout the whole process and can keep this
58
+ * structure in memory can use the provided API functions for a safe standard
59
+ * workflow. See
60
+ * https://blockstream.com/2019/02/18/musig-a-new-multisignature-standard/ for
61
+ * more details about the risks associated with serializing or deserializing
62
+ * this structure.
63
+ *
64
+ * We repeat, copying this data structure can result in nonce reuse which will
65
+ * leak the secret signing key.
66
+ */
67
+ typedef struct {
68
+ unsigned char data [68 ];
69
+ } secp256k1_frost_secnonce ;
70
+
71
+ /** Opaque data structure that holds a signer's public nonce.
72
+ *
73
+ * Guaranteed to be 132 bytes in size. It can be safely copied/moved.
74
+ * Serialized and parsed with `frost_pubnonce_serialize` and
75
+ * `frost_pubnonce_parse`.
76
+ */
77
+ typedef struct {
78
+ unsigned char data [132 ];
79
+ } secp256k1_frost_pubnonce ;
80
+
81
+ /** Parse a signer's public nonce.
82
+ *
83
+ * Returns: 1 when the nonce could be parsed, 0 otherwise.
84
+ * Args: ctx: pointer to a context object
85
+ * Out: nonce: pointer to a nonce object
86
+ * In: in66: pointer to the 66-byte nonce to be parsed
87
+ */
88
+ SECP256K1_API int secp256k1_frost_pubnonce_parse (
89
+ const secp256k1_context * ctx ,
90
+ secp256k1_frost_pubnonce * nonce ,
91
+ const unsigned char * in66
92
+ ) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 );
93
+
94
+ /** Serialize a signer's public nonce
95
+ *
96
+ * Returns: 1 when the nonce could be serialized, 0 otherwise
97
+ * Args: ctx: pointer to a context object
98
+ * Out: out66: pointer to a 66-byte array to store the serialized nonce
99
+ * In: nonce: pointer to the nonce
100
+ */
101
+ SECP256K1_API int secp256k1_frost_pubnonce_serialize (
102
+ const secp256k1_context * ctx ,
103
+ unsigned char * out66 ,
104
+ const secp256k1_frost_pubnonce * nonce
105
+ ) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 );
106
+
49
107
/** Serialize a FROST share
50
108
*
51
109
* Returns: 1 when the share could be serialized, 0 otherwise
@@ -271,6 +329,61 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_pubkey_xonly_twea
271
329
const unsigned char * tweak32
272
330
) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (3 ) SECP256K1_ARG_NONNULL (4 );
273
331
332
+ /** Starts a signing session by generating a nonce
333
+ *
334
+ * This function outputs a secret nonce that will be required for signing and a
335
+ * corresponding public nonce that is intended to be sent to other signers.
336
+ *
337
+ * FROST, like MuSig, differs from regular Schnorr signing in that
338
+ * implementers _must_ take special care to not reuse a nonce. This can be
339
+ * ensured by following these rules:
340
+ *
341
+ * 1. Each call to this function must have a UNIQUE session_id32 that must NOT BE
342
+ * REUSED in subsequent calls to this function.
343
+ * If you do not provide a seckey, session_id32 _must_ be UNIFORMLY RANDOM
344
+ * AND KEPT SECRET (even from other signers). If you do provide a seckey,
345
+ * session_id32 can instead be a counter (that must never repeat!). However,
346
+ * it is recommended to always choose session_id32 uniformly at random.
347
+ * 2. If you already know the seckey, message or group public key, they
348
+ * can be optionally provided to derive the nonce and increase
349
+ * misuse-resistance. The extra_input32 argument can be used to provide
350
+ * additional data that does not repeat in normal scenarios, such as the
351
+ * current time.
352
+ * 3. Avoid copying (or serializing) the secnonce. This reduces the possibility
353
+ * that it is used more than once for signing.
354
+ *
355
+ * Remember that nonce reuse will leak the secret share!
356
+ * Note that using the same agg_share for multiple FROST sessions is fine.
357
+ *
358
+ * Returns: 0 if the arguments are invalid and 1 otherwise
359
+ * Args: ctx: pointer to a context object (not secp256k1_context_static)
360
+ * Out: secnonce: pointer to a structure to store the secret nonce
361
+ * pubnonce: pointer to a structure to store the public nonce
362
+ * In: session_id32: a 32-byte session_id32 as explained above. Must be
363
+ * unique to this call to secp256k1_frost_nonce_gen and
364
+ * must be uniformly random unless you really know what you
365
+ * are doing.
366
+ * agg_share: the aggregated share that will later be used for
367
+ * signing, if already known (can be NULL)
368
+ * msg32: the 32-byte message that will later be signed, if
369
+ * already known (can be NULL)
370
+ * keygen_cache: pointer to the keygen_cache that was used to create the group
371
+ * (and potentially tweaked) public key if already known
372
+ * (can be NULL)
373
+ * extra_input32: an optional 32-byte array that is input to the nonce
374
+ * derivation function (can be NULL)
375
+ */
376
+ SECP256K1_API int secp256k1_frost_nonce_gen (
377
+ const secp256k1_context * ctx ,
378
+ secp256k1_frost_secnonce * secnonce ,
379
+ secp256k1_frost_pubnonce * pubnonce ,
380
+ const unsigned char * session_id32 ,
381
+ const secp256k1_frost_share * agg_share ,
382
+ const unsigned char * msg32 ,
383
+ const secp256k1_frost_keygen_cache * keygen_cache ,
384
+ const unsigned char * extra_input32
385
+ ) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 ) SECP256K1_ARG_NONNULL (4 );
386
+
274
387
#ifdef __cplusplus
275
388
}
276
389
#endif
0 commit comments