Skip to content

Commit f065a84

Browse files
committed
Use keygen session object to track state between rounds
1 parent 475554e commit f065a84

File tree

2 files changed

+45
-22
lines changed

2 files changed

+45
-22
lines changed

include/secp256k1_frost.h

+22-7
Original file line numberDiff line numberDiff line change
@@ -34,28 +34,43 @@ typedef struct {
3434
unsigned char data[64];
3535
} secp256k1_frost_secnonce;
3636

37+
typedef struct {
38+
size_t threshold;
39+
size_t my_index;
40+
size_t n_signers;
41+
int pk_parity;
42+
secp256k1_xonly_pubkey combined_pk;
43+
secp256k1_pubkey coeff_pk;
44+
} secp256k1_frost_keygen_session;
45+
3746
SECP256K1_API int secp256k1_frost_keygen_init(
3847
const secp256k1_context *ctx,
48+
secp256k1_frost_keygen_session *session,
3949
secp256k1_scalar *privcoeff,
4050
secp256k1_pubkey *pubcoeff,
4151
const size_t threshold,
4252
const size_t n_signers,
53+
const size_t my_index,
4354
const unsigned char *seckey
44-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(6);
55+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(8);
4556

4657
SECP256K1_API void secp256k1_frost_generate_shares(
4758
secp256k1_frost_share *shares,
48-
const secp256k1_scalar *coefficients,
49-
const size_t threshold,
50-
const size_t n_signers
59+
secp256k1_scalar *coeff,
60+
const secp256k1_frost_keygen_session *session
61+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
62+
63+
SECP256K1_API void secp256k1_frost_aggregate_shares(
64+
secp256k1_frost_share *aggregate_share,
65+
const secp256k1_frost_share *shares,
66+
const secp256k1_frost_keygen_session *session
5167
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
5268

5369
SECP256K1_API int secp256k1_frost_pubkey_combine(
5470
const secp256k1_context *ctx,
5571
secp256k1_scratch_space *scratch,
56-
secp256k1_xonly_pubkey *combined_pk,
57-
const secp256k1_pubkey *pubkeys,
58-
size_t n_pubkeys
72+
secp256k1_frost_keygen_session *session,
73+
const secp256k1_pubkey *pubkeys
5974
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
6075

6176
#ifdef __cplusplus

src/modules/frost/main_impl.h

+23-15
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#include "include/secp256k1_frost.h"
1313
#include "hash.h"
1414

15-
int secp256k1_frost_keygen_init(const secp256k1_context *ctx, secp256k1_scalar *privcoeff, secp256k1_pubkey *pubcoeff, const size_t threshold, const size_t n_signers, const unsigned char *seckey32) {
15+
int secp256k1_frost_keygen_init(const secp256k1_context *ctx, secp256k1_frost_keygen_session *session, secp256k1_scalar *privcoeff, secp256k1_pubkey *pubcoeff, const size_t threshold, const size_t n_signers, const size_t my_index, const unsigned char *seckey32) {
1616
secp256k1_sha256 sha;
1717
size_t i;
1818
unsigned char rngseed[32];
@@ -25,15 +25,20 @@ int secp256k1_frost_keygen_init(const secp256k1_context *ctx, secp256k1_scalar *
2525
return 0;
2626
}
2727

28+
session->threshold = threshold;
29+
session->my_index = my_index;
30+
session->n_signers = n_signers;
31+
2832
/* Compute a random seed which commits to all inputs */
2933
/* TODO: allow user suplied function that takes seckey, threshold, and n_signers as inputs and supplies the rngseed */
3034
secp256k1_sha256_initialize(&sha);
3135
secp256k1_sha256_write(&sha, seckey32, 32);
3236
for (i = 0; i < 8; i++) {
3337
rngseed[i + 0] = threshold / (1ull << (i * 8));
3438
rngseed[i + 8] = n_signers / (1ull << (i * 8));
39+
rngseed[i + 16] = my_index / (1ull << (i * 8));
3540
}
36-
secp256k1_sha256_write(&sha, rngseed, 16);
41+
secp256k1_sha256_write(&sha, rngseed, 24);
3742
secp256k1_sha256_finalize(&sha, rngseed);
3843

3944
/* Derive coefficients from the seed. */
@@ -50,36 +55,40 @@ int secp256k1_frost_keygen_init(const secp256k1_context *ctx, secp256k1_scalar *
5055
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &rj, &rand[i % 2]);
5156
secp256k1_ge_set_gej(&rp, &rj);
5257
secp256k1_pubkey_save(&pubcoeff[i], &rp);
58+
59+
if (i == 0) {
60+
secp256k1_pubkey_save(&session->coeff_pk, &rp);
61+
}
5362
}
5463

5564
return 1;
5665
}
5766

58-
void secp256k1_frost_generate_shares(secp256k1_frost_share *shares, const secp256k1_scalar *coefficients, const size_t threshold, const size_t n_signers) {
67+
void secp256k1_frost_generate_shares(secp256k1_frost_share *shares, secp256k1_scalar *coeff, const secp256k1_frost_keygen_session *session) {
5968
size_t i;
6069

61-
for (i = 0; i < n_signers; i++) {
70+
for (i = 0; i < session->n_signers; i++) {
6271
size_t j;
6372
secp256k1_scalar share_i;
6473
secp256k1_scalar scalar_i;
6574

6675
/* Horner's method */
6776
secp256k1_scalar_clear(&share_i);
6877
secp256k1_scalar_set_int(&scalar_i, i + 1);
69-
for (j = threshold; j > 0; j--) {
78+
for (j = session->threshold; j > 0; j--) {
7079
secp256k1_scalar_mul(&share_i, &share_i, &scalar_i);
71-
secp256k1_scalar_add(&share_i, &share_i, &coefficients[j - 1]);
80+
secp256k1_scalar_add(&share_i, &share_i, &coeff[j - 1]);
7281
}
7382
secp256k1_scalar_get_b32(shares[i].data, &share_i);
7483
}
7584
}
7685

77-
void secp256k1_frost_aggregate_shares(secp256k1_frost_share *aggregate_share, secp256k1_frost_share *shares, const size_t n_signers) {
86+
void secp256k1_frost_aggregate_shares(secp256k1_frost_share *aggregate_share, const secp256k1_frost_share *shares, const secp256k1_frost_keygen_session *session) {
7887
size_t i;
7988
secp256k1_scalar acc;
8089

8190
secp256k1_scalar_clear(&acc);
82-
for (i = 0; i < n_signers; i++) {
91+
for (i = 0; i < session->n_signers; i++) {
8392
secp256k1_scalar share_i;
8493
secp256k1_scalar_set_b32(&share_i, shares[i].data, NULL);
8594
secp256k1_scalar_add(&acc, &acc, &share_i);
@@ -98,28 +107,27 @@ static int secp256k1_frost_pubkey_combine_callback(secp256k1_scalar *sc, secp256
98107
return secp256k1_pubkey_load(ctx->ctx, pt, &ctx->pks[idx]);
99108
}
100109

101-
int secp256k1_frost_pubkey_combine(const secp256k1_context *ctx, secp256k1_scratch_space *scratch, secp256k1_xonly_pubkey *combined_pk, const secp256k1_pubkey *pubkeys, size_t n_pubkeys) {
110+
int secp256k1_frost_pubkey_combine(const secp256k1_context *ctx, secp256k1_scratch_space *scratch, secp256k1_frost_keygen_session *session, const secp256k1_pubkey *pubkeys) {
102111
secp256k1_frost_pubkey_combine_ecmult_data ecmult_data;
103112
secp256k1_gej pkj;
104113
secp256k1_ge pkp;
105114

106115
VERIFY_CHECK(ctx != NULL);
107-
ARG_CHECK(combined_pk != NULL);
108116
ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
109117
ARG_CHECK(pubkeys != NULL);
110-
ARG_CHECK(n_pubkeys > 0);
118+
ARG_CHECK(session->n_signers > 0);
111119

112120
ecmult_data.ctx = ctx;
113121
ecmult_data.pks = pubkeys;
114122

115-
if (!secp256k1_ecmult_multi_var(&ctx->error_callback, &ctx->ecmult_ctx, scratch, &pkj, NULL, secp256k1_frost_pubkey_combine_callback, (void *) &ecmult_data, n_pubkeys)) {
123+
if (!secp256k1_ecmult_multi_var(&ctx->error_callback, &ctx->ecmult_ctx, scratch, &pkj, NULL, secp256k1_frost_pubkey_combine_callback, (void *) &ecmult_data, session->n_signers)) {
116124
return 0;
117125
}
118126

119127
secp256k1_ge_set_gej(&pkp, &pkj);
120-
secp256k1_fe_normalize(&pkp.y);
121-
secp256k1_extrakeys_ge_even_y(&pkp);
122-
secp256k1_xonly_pubkey_save(combined_pk, &pkp);
128+
secp256k1_fe_normalize_var(&pkp.y);
129+
session->pk_parity = secp256k1_extrakeys_ge_even_y(&pkp);
130+
secp256k1_xonly_pubkey_save(&session->combined_pk, &pkp);
123131

124132
return 1;
125133
}

0 commit comments

Comments
 (0)