Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
jesseposner committed Aug 15, 2024
1 parent 68b2867 commit b607a8c
Show file tree
Hide file tree
Showing 6 changed files with 302 additions and 312 deletions.
24 changes: 16 additions & 8 deletions examples/frost.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@
/* Threshold required in creating the aggregate signature */
#define THRESHOLD 3

/* TODO: remove unused keypair */
struct signer_secrets {
secp256k1_keypair keypair;
secp256k1_frost_share agg_share;
secp256k1_frost_secnonce secnonce;
unsigned char seed[32];
};

/* TODO: remove unused vss_hash */
struct signer {
secp256k1_pubkey pubshare;
secp256k1_frost_pubnonce pubnonce;
Expand Down Expand Up @@ -70,7 +72,7 @@ int create_keypair_and_seed(const secp256k1_context* ctx, struct signer_secrets
}

/* Create shares and coefficient commitments */
int create_shares(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, struct signer *signer, secp256k1_xonly_pubkey *pk) {
int create_shares(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, struct signer *signer) {
int i, j;
secp256k1_frost_share shares[N_SIGNERS][N_SIGNERS];
const secp256k1_pubkey *vss_commitments[N_SIGNERS];
Expand Down Expand Up @@ -101,7 +103,7 @@ int create_shares(const secp256k1_context* ctx, struct signer_secrets *signer_se
assigned_shares[j] = &shares[j][i];
}
/* Each participant aggregates the shares they received. */
if (!secp256k1_frost_share_agg(ctx, &signer_secrets[i].agg_share, pk, assigned_shares, vss_commitments, poks, N_SIGNERS, THRESHOLD, signer[i].id)) {
if (!secp256k1_frost_share_agg(ctx, &signer_secrets[i].agg_share, assigned_shares, vss_commitments, poks, N_SIGNERS, THRESHOLD, signer[i].id)) {
return 0;
}
for (j = 0; j < N_SIGNERS; j++) {
Expand Down Expand Up @@ -130,10 +132,6 @@ int tweak(const secp256k1_context* ctx, secp256k1_xonly_pubkey *pk, secp256k1_fr
unsigned char ordinary_tweak[32] = "this could be a BIP32 tweak....";
unsigned char xonly_tweak[32] = "this could be a taproot tweak..";

if (!secp256k1_frost_pubkey_tweak(ctx, cache, pk)) {
return 0;
}

/* Ordinary tweaking which, for example, allows deriving multiple child
* public keys from a single aggregate key using BIP32 */
if (!secp256k1_frost_pubkey_ec_tweak_add(ctx, NULL, cache, ordinary_tweak)) {
Expand Down Expand Up @@ -212,7 +210,7 @@ int sign(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, st
/* Signing communication round 1: Exchange nonces */
for (i = 0; i < THRESHOLD; i++) {
signer_id = signers[i];
if (!secp256k1_frost_nonce_process(ctx, &signer[signer_id].session, pubnonces, THRESHOLD, msg32, pk, signer[signer_id].id, ids, cache, NULL)) {
if (!secp256k1_frost_nonce_process(ctx, &signer[signer_id].session, pubnonces, THRESHOLD, msg32, signer[signer_id].id, ids, cache, NULL)) {
return 0;
}
/* partial_sign will clear the secnonce by setting it to 0. That's because
Expand Down Expand Up @@ -251,10 +249,12 @@ int main(void) {
int i;
struct signer_secrets signer_secrets[N_SIGNERS];
struct signer signers[N_SIGNERS];
const secp256k1_pubkey *pubshares_ptr[N_SIGNERS];
secp256k1_xonly_pubkey pk;
secp256k1_frost_tweak_cache cache;
unsigned char msg[32] = "this_could_be_the_hash_of_a_msg!";
unsigned char sig[64];
const unsigned char *id_ptr[5];

/* Create a context for signing and verification */
ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
Expand All @@ -264,10 +264,18 @@ int main(void) {
printf("FAILED\n");
return 1;
}
pubshares_ptr[i] = &signers[i].pubshare;
id_ptr[i] = signers[i].id;
}
printf("ok\n");
printf("Creating shares.........");
if (!create_shares(ctx, signer_secrets, signers, &pk)) {
if (!create_shares(ctx, signer_secrets, signers)) {
printf("FAILED\n");
return 1;
}
printf("ok\n");
printf("Generating public key...");
if (!secp256k1_frost_pubkey_gen(ctx, &cache, pubshares_ptr, N_SIGNERS, id_ptr)) {
printf("FAILED\n");
return 1;
}
Expand Down
54 changes: 17 additions & 37 deletions include/secp256k1_frost.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ SECP256K1_API int secp256k1_frost_share_parse(
* n_participants: the total number of participants
* ids33: array of 33-byte participant IDs
*/
/* TODO: rename this */
SECP256K1_API int secp256k1_frost_shares_gen(
const secp256k1_context *ctx,
secp256k1_frost_share *shares,
Expand Down Expand Up @@ -252,14 +253,13 @@ SECP256K1_API int secp256k1_frost_shares_gen(
SECP256K1_API int secp256k1_frost_share_agg(
const secp256k1_context *ctx,
secp256k1_frost_share *agg_share,
secp256k1_xonly_pubkey *agg_pk,
const secp256k1_frost_share * const *shares,
const secp256k1_pubkey * const *vss_commitments,
const unsigned char * const *pok64s,
size_t n_shares,
size_t threshold,
const unsigned char *id33
) 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);
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(8);

/** Verifies a share received during a key generation session
*
Expand Down Expand Up @@ -306,37 +306,18 @@ 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);

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

/** Initializes a tweak cache used for applying tweaks to a FROST key
*
* Returns: 0 if the arguments are invalid, 1 otherwise
* Args: ctx: pointer to a context object
* Out: tweak_cache: pointer to a frost_tweak_cache struct that is required
* for key tweaking
* In: agg_pk: the aggregated x-only public key that is the output of
* `secp256k1_frost_share_agg`
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_pubkey_tweak(
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_pubkey_get(
const secp256k1_context *ctx,
secp256k1_frost_tweak_cache *tweak_cache,
const secp256k1_xonly_pubkey *agg_pk
secp256k1_pubkey *pk,
const secp256k1_frost_tweak_cache *cache
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);

/** Apply ordinary "EC" tweaking to a public key in a given tweak_cache by
Expand Down Expand Up @@ -490,22 +471,21 @@ SECP256K1_API int secp256k1_frost_nonce_gen(
* n_pubnonces: number of elements in the pubnonces array. Must be
* greater than 0.
* msg32: the 32-byte message to sign
* agg_pk: the FROST-aggregated public key
* myd_id33: the 33-byte ID of the participant who will use the
* session for signing
* ids33: array of the 33-byte participant IDs of the signers
* tweak_cache: pointer to frost_tweak_cache struct (can be NULL)
* tweak_cache: pointer to frost_tweak_cache struct
* adaptor: optional pointer to an adaptor point encoded as a
* public key if this signing session is part of an
* adaptor signature protocol (can be NULL)
*/
/* TODO(@jesseposner): const unsigned char * const *ids33 */
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_nonce_process(
const secp256k1_context *ctx,
secp256k1_frost_session *session,
const secp256k1_frost_pubnonce * const *pubnonces,
size_t n_pubnonces,
const unsigned char *msg32,
const secp256k1_xonly_pubkey *agg_pk,
const unsigned char *my_id33,
const unsigned char * const* ids33,
const secp256k1_frost_tweak_cache *tweak_cache,
Expand All @@ -529,7 +509,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_nonce_process(
* In: agg_share: the aggregated share
* session: pointer to the session that was created with
* frost_nonce_process
* tweak_cache: pointer to frost_tweak_cache struct (can be NULL)
* tweak_cache: pointer to frost_tweak_cache struct
*/
SECP256K1_API int secp256k1_frost_partial_sign(
const secp256k1_context *ctx,
Expand All @@ -538,7 +518,7 @@ SECP256K1_API int secp256k1_frost_partial_sign(
const secp256k1_frost_share *agg_share,
const secp256k1_frost_session *session,
const secp256k1_frost_tweak_cache *tweak_cache
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);

/** Verifies an individual signer's partial signature
*
Expand All @@ -565,7 +545,7 @@ SECP256K1_API int secp256k1_frost_partial_sign(
* `secp256k1_frost_compute_pubshare`
* session: pointer to the session that was created with
* `frost_nonce_process`
* tweak_cache: pointer to frost_tweak_cache struct (can be NULL)
* tweak_cache: pointer to frost_tweak_cache struct
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_partial_sig_verify(
const secp256k1_context *ctx,
Expand All @@ -574,7 +554,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_partial_sig_verif
const secp256k1_pubkey *pubshare,
const secp256k1_frost_session *session,
const secp256k1_frost_tweak_cache *tweak_cache
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);

/** Aggregates partial signatures
*
Expand Down
5 changes: 5 additions & 0 deletions src/modules/frost/keygen.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@

typedef struct {
secp256k1_ge pk;
/* tweak is identical to value tacc[v] in the specification. */
secp256k1_scalar tweak;
/* parity_acc corresponds to gacc[v] in the spec. If gacc[v] is -1,
* parity_acc is 1. Otherwise, parity_acc is 0. */
int parity_acc;
} secp256k1_tweak_cache_internal;

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

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

static int secp256k1_frost_lagrange_coefficient(secp256k1_scalar *r, const unsigned char * const *ids33, size_t n_participants, const unsigned char *my_id33);

#endif
Loading

0 comments on commit b607a8c

Please sign in to comment.