Skip to content

Commit b607a8c

Browse files
committed
wip
1 parent 68b2867 commit b607a8c

File tree

6 files changed

+302
-312
lines changed

6 files changed

+302
-312
lines changed

examples/frost.c

+16-8
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,15 @@
2424
/* Threshold required in creating the aggregate signature */
2525
#define THRESHOLD 3
2626

27+
/* TODO: remove unused keypair */
2728
struct signer_secrets {
2829
secp256k1_keypair keypair;
2930
secp256k1_frost_share agg_share;
3031
secp256k1_frost_secnonce secnonce;
3132
unsigned char seed[32];
3233
};
3334

35+
/* TODO: remove unused vss_hash */
3436
struct signer {
3537
secp256k1_pubkey pubshare;
3638
secp256k1_frost_pubnonce pubnonce;
@@ -70,7 +72,7 @@ int create_keypair_and_seed(const secp256k1_context* ctx, struct signer_secrets
7072
}
7173

7274
/* Create shares and coefficient commitments */
73-
int create_shares(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, struct signer *signer, secp256k1_xonly_pubkey *pk) {
75+
int create_shares(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, struct signer *signer) {
7476
int i, j;
7577
secp256k1_frost_share shares[N_SIGNERS][N_SIGNERS];
7678
const secp256k1_pubkey *vss_commitments[N_SIGNERS];
@@ -101,7 +103,7 @@ int create_shares(const secp256k1_context* ctx, struct signer_secrets *signer_se
101103
assigned_shares[j] = &shares[j][i];
102104
}
103105
/* Each participant aggregates the shares they received. */
104-
if (!secp256k1_frost_share_agg(ctx, &signer_secrets[i].agg_share, pk, assigned_shares, vss_commitments, poks, N_SIGNERS, THRESHOLD, signer[i].id)) {
106+
if (!secp256k1_frost_share_agg(ctx, &signer_secrets[i].agg_share, assigned_shares, vss_commitments, poks, N_SIGNERS, THRESHOLD, signer[i].id)) {
105107
return 0;
106108
}
107109
for (j = 0; j < N_SIGNERS; j++) {
@@ -130,10 +132,6 @@ int tweak(const secp256k1_context* ctx, secp256k1_xonly_pubkey *pk, secp256k1_fr
130132
unsigned char ordinary_tweak[32] = "this could be a BIP32 tweak....";
131133
unsigned char xonly_tweak[32] = "this could be a taproot tweak..";
132134

133-
if (!secp256k1_frost_pubkey_tweak(ctx, cache, pk)) {
134-
return 0;
135-
}
136-
137135
/* Ordinary tweaking which, for example, allows deriving multiple child
138136
* public keys from a single aggregate key using BIP32 */
139137
if (!secp256k1_frost_pubkey_ec_tweak_add(ctx, NULL, cache, ordinary_tweak)) {
@@ -212,7 +210,7 @@ int sign(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, st
212210
/* Signing communication round 1: Exchange nonces */
213211
for (i = 0; i < THRESHOLD; i++) {
214212
signer_id = signers[i];
215-
if (!secp256k1_frost_nonce_process(ctx, &signer[signer_id].session, pubnonces, THRESHOLD, msg32, pk, signer[signer_id].id, ids, cache, NULL)) {
213+
if (!secp256k1_frost_nonce_process(ctx, &signer[signer_id].session, pubnonces, THRESHOLD, msg32, signer[signer_id].id, ids, cache, NULL)) {
216214
return 0;
217215
}
218216
/* partial_sign will clear the secnonce by setting it to 0. That's because
@@ -251,10 +249,12 @@ int main(void) {
251249
int i;
252250
struct signer_secrets signer_secrets[N_SIGNERS];
253251
struct signer signers[N_SIGNERS];
252+
const secp256k1_pubkey *pubshares_ptr[N_SIGNERS];
254253
secp256k1_xonly_pubkey pk;
255254
secp256k1_frost_tweak_cache cache;
256255
unsigned char msg[32] = "this_could_be_the_hash_of_a_msg!";
257256
unsigned char sig[64];
257+
const unsigned char *id_ptr[5];
258258

259259
/* Create a context for signing and verification */
260260
ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
@@ -264,10 +264,18 @@ int main(void) {
264264
printf("FAILED\n");
265265
return 1;
266266
}
267+
pubshares_ptr[i] = &signers[i].pubshare;
268+
id_ptr[i] = signers[i].id;
267269
}
268270
printf("ok\n");
269271
printf("Creating shares.........");
270-
if (!create_shares(ctx, signer_secrets, signers, &pk)) {
272+
if (!create_shares(ctx, signer_secrets, signers)) {
273+
printf("FAILED\n");
274+
return 1;
275+
}
276+
printf("ok\n");
277+
printf("Generating public key...");
278+
if (!secp256k1_frost_pubkey_gen(ctx, &cache, pubshares_ptr, N_SIGNERS, id_ptr)) {
271279
printf("FAILED\n");
272280
return 1;
273281
}

include/secp256k1_frost.h

+17-37
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ SECP256K1_API int secp256k1_frost_share_parse(
211211
* n_participants: the total number of participants
212212
* ids33: array of 33-byte participant IDs
213213
*/
214+
/* TODO: rename this */
214215
SECP256K1_API int secp256k1_frost_shares_gen(
215216
const secp256k1_context *ctx,
216217
secp256k1_frost_share *shares,
@@ -252,14 +253,13 @@ SECP256K1_API int secp256k1_frost_shares_gen(
252253
SECP256K1_API int secp256k1_frost_share_agg(
253254
const secp256k1_context *ctx,
254255
secp256k1_frost_share *agg_share,
255-
secp256k1_xonly_pubkey *agg_pk,
256256
const secp256k1_frost_share * const *shares,
257257
const secp256k1_pubkey * const *vss_commitments,
258258
const unsigned char * const *pok64s,
259259
size_t n_shares,
260260
size_t threshold,
261261
const unsigned char *id33
262-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(9);
262+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(8);
263263

264264
/** Verifies a share received during a key generation session
265265
*
@@ -306,37 +306,18 @@ SECP256K1_API int secp256k1_frost_compute_pubshare(
306306
size_t n_participants
307307
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
308308

309-
/** Obtain the aggregate public key from a FROST x-only aggregate public key.
310-
*
311-
* This is only useful if you need the non-xonly public key, in particular for
312-
* ordinary (non-xonly) tweaking or batch-verifying multiple key aggregations
313-
* (not implemented).
314-
*
315-
* Returns: 0 if the arguments are invalid, 1 otherwise
316-
* Args: ctx: pointer to a context object
317-
* Out: ec_agg_pk: the FROST-aggregated public key.
318-
* In: xonly_agg_pk: the aggregated x-only public key that is the output of
319-
* `secp256k1_frost_share_agg`
320-
*/
321-
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_pubkey_get(
309+
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_pubkey_gen(
322310
const secp256k1_context *ctx,
323-
secp256k1_pubkey *ec_agg_pk,
324-
const secp256k1_xonly_pubkey *xonly_agg_pk
325-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
311+
secp256k1_frost_tweak_cache *cache,
312+
const secp256k1_pubkey * const *pubshares,
313+
size_t n_pubshares,
314+
const unsigned char * const *ids33
315+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
326316

327-
/** Initializes a tweak cache used for applying tweaks to a FROST key
328-
*
329-
* Returns: 0 if the arguments are invalid, 1 otherwise
330-
* Args: ctx: pointer to a context object
331-
* Out: tweak_cache: pointer to a frost_tweak_cache struct that is required
332-
* for key tweaking
333-
* In: agg_pk: the aggregated x-only public key that is the output of
334-
* `secp256k1_frost_share_agg`
335-
*/
336-
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_pubkey_tweak(
317+
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_pubkey_get(
337318
const secp256k1_context *ctx,
338-
secp256k1_frost_tweak_cache *tweak_cache,
339-
const secp256k1_xonly_pubkey *agg_pk
319+
secp256k1_pubkey *pk,
320+
const secp256k1_frost_tweak_cache *cache
340321
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
341322

342323
/** Apply ordinary "EC" tweaking to a public key in a given tweak_cache by
@@ -490,22 +471,21 @@ SECP256K1_API int secp256k1_frost_nonce_gen(
490471
* n_pubnonces: number of elements in the pubnonces array. Must be
491472
* greater than 0.
492473
* msg32: the 32-byte message to sign
493-
* agg_pk: the FROST-aggregated public key
494474
* myd_id33: the 33-byte ID of the participant who will use the
495475
* session for signing
496476
* ids33: array of the 33-byte participant IDs of the signers
497-
* tweak_cache: pointer to frost_tweak_cache struct (can be NULL)
477+
* tweak_cache: pointer to frost_tweak_cache struct
498478
* adaptor: optional pointer to an adaptor point encoded as a
499479
* public key if this signing session is part of an
500480
* adaptor signature protocol (can be NULL)
501481
*/
482+
/* TODO(@jesseposner): const unsigned char * const *ids33 */
502483
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_nonce_process(
503484
const secp256k1_context *ctx,
504485
secp256k1_frost_session *session,
505486
const secp256k1_frost_pubnonce * const *pubnonces,
506487
size_t n_pubnonces,
507488
const unsigned char *msg32,
508-
const secp256k1_xonly_pubkey *agg_pk,
509489
const unsigned char *my_id33,
510490
const unsigned char * const* ids33,
511491
const secp256k1_frost_tweak_cache *tweak_cache,
@@ -529,7 +509,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_nonce_process(
529509
* In: agg_share: the aggregated share
530510
* session: pointer to the session that was created with
531511
* frost_nonce_process
532-
* tweak_cache: pointer to frost_tweak_cache struct (can be NULL)
512+
* tweak_cache: pointer to frost_tweak_cache struct
533513
*/
534514
SECP256K1_API int secp256k1_frost_partial_sign(
535515
const secp256k1_context *ctx,
@@ -538,7 +518,7 @@ SECP256K1_API int secp256k1_frost_partial_sign(
538518
const secp256k1_frost_share *agg_share,
539519
const secp256k1_frost_session *session,
540520
const secp256k1_frost_tweak_cache *tweak_cache
541-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
521+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);
542522

543523
/** Verifies an individual signer's partial signature
544524
*
@@ -565,7 +545,7 @@ SECP256K1_API int secp256k1_frost_partial_sign(
565545
* `secp256k1_frost_compute_pubshare`
566546
* session: pointer to the session that was created with
567547
* `frost_nonce_process`
568-
* tweak_cache: pointer to frost_tweak_cache struct (can be NULL)
548+
* tweak_cache: pointer to frost_tweak_cache struct
569549
*/
570550
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_partial_sig_verify(
571551
const secp256k1_context *ctx,
@@ -574,7 +554,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_partial_sig_verif
574554
const secp256k1_pubkey *pubshare,
575555
const secp256k1_frost_session *session,
576556
const secp256k1_frost_tweak_cache *tweak_cache
577-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
557+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);
578558

579559
/** Aggregates partial signatures
580560
*

src/modules/frost/keygen.h

+5
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515

1616
typedef struct {
1717
secp256k1_ge pk;
18+
/* tweak is identical to value tacc[v] in the specification. */
1819
secp256k1_scalar tweak;
20+
/* parity_acc corresponds to gacc[v] in the spec. If gacc[v] is -1,
21+
* parity_acc is 1. Otherwise, parity_acc is 0. */
1922
int parity_acc;
2023
} secp256k1_tweak_cache_internal;
2124

@@ -25,4 +28,6 @@ static int secp256k1_frost_share_load(const secp256k1_context* ctx, secp256k1_sc
2528

2629
static int secp256k1_frost_compute_indexhash(secp256k1_scalar *indexhash, const unsigned char *id33);
2730

31+
static int secp256k1_frost_lagrange_coefficient(secp256k1_scalar *r, const unsigned char * const *ids33, size_t n_participants, const unsigned char *my_id33);
32+
2833
#endif

0 commit comments

Comments
 (0)