Skip to content

Commit 630e1ac

Browse files
committed
f set musig limit to 2^32 and hash fixed 4 bytes in musig coefficient
1 parent 72cfe7d commit 630e1ac

File tree

3 files changed

+38
-17
lines changed

3 files changed

+38
-17
lines changed

include/secp256k1_musig.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#ifndef SECP256K1_MUSIG_H
22
#define SECP256K1_MUSIG_H
33

4+
#include <stdint.h>
5+
46
/** This module implements a Schnorr-based multi-signature scheme called MuSig
57
* (https://eprint.iacr.org/2018/068.pdf). There's an example C source file in the
68
* module's directory (src/modules/musig/example.c) that demonstrates how it can be
@@ -53,7 +55,7 @@
5355
*/
5456
typedef struct {
5557
secp256k1_pubkey combined_pk;
56-
size_t n_signers;
58+
uint32_t n_signers;
5759
unsigned char pk_hash[32];
5860
secp256k1_pubkey combined_nonce;
5961
int nonce_is_set;
@@ -97,7 +99,7 @@ typedef struct {
9799
*/
98100
typedef struct {
99101
int present;
100-
size_t index;
102+
uint32_t index;
101103
secp256k1_pubkey nonce;
102104
unsigned char nonce_commitment[32];
103105
} secp256k1_musig_session_signer_data;
@@ -161,7 +163,7 @@ SECP256K1_API int secp256k1_musig_pubkey_combine(
161163
* pk_hash32: the 32-byte hash of the signers' individual keys (cannot be
162164
* NULL)
163165
* n_signers: length of signers array. Number of signers participating in
164-
* the MuSig. Must be greater than 0.
166+
* the MuSig. Must be greater than 0 and smaller than 2^32 - 1.
165167
* my_index: index of this signer in the signers array
166168
* seckey: the signer's 32-byte secret key (cannot be NULL)
167169
*/
@@ -262,7 +264,8 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_set_nonce(
262264
* set with `musig_set_nonce`. Array length must equal to `n_signers`
263265
* (cannot be NULL)
264266
* n_signers: the length of the signers array. Must be the total number of
265-
* signers participating in the MuSig.
267+
* signers participating in the MuSig. Must be greater than 0 and
268+
* smaller than 2^32.
266269
* Out: nonce_is_negated: a pointer to an integer that indicates if the combined
267270
* public nonce had to be negated.
268271
* adaptor: point to add to the combined public nonce. If NULL, nothing is

src/modules/musig/main_impl.h

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,12 @@ static int secp256k1_musig_compute_ell(const secp256k1_context *ctx, unsigned ch
2929
return 1;
3030
}
3131

32-
/* Compute r = SHA256(ell, idx). The serialization of idx is least significant byte
33-
* first and variable-length such that the last byte is non-zero. */
34-
static void secp256k1_musig_coefficient(secp256k1_scalar *r, const unsigned char *ell, size_t idx) {
32+
/* Compute r = SHA256(ell, idx). The four bytes of idx are serialized least significant byte first. */
33+
static void secp256k1_musig_coefficient(secp256k1_scalar *r, const unsigned char *ell, uint32_t idx) {
3534
secp256k1_sha256 sha;
3635
unsigned char buf[32];
36+
size_t i;
37+
3738
secp256k1_sha256_initialize(&sha);
3839
secp256k1_sha256_write(&sha, ell, 32);
3940
/* We're hashing the index of the signer instead of its public key as specified
@@ -48,13 +49,12 @@ static void secp256k1_musig_coefficient(secp256k1_scalar *r, const unsigned char
4849
* equivalent to hashing the public key. Because the public key can be
4950
* identified by the index given the ordered list of public keys (included in
5051
* ell), the index is just a different encoding of the public key.*/
51-
while (idx > 0) {
52+
for (i = 0; i < sizeof(uint32_t); i++) {
5253
unsigned char c = idx;
5354
secp256k1_sha256_write(&sha, &c, 1);
54-
idx /= 0x100;
55+
idx >>= 8;
5556
}
5657
secp256k1_sha256_finalize(&sha, buf);
57-
5858
secp256k1_scalar_set_b32(r, buf, NULL);
5959
}
6060

@@ -72,8 +72,8 @@ static int secp256k1_musig_pubkey_combine_callback(secp256k1_scalar *sc, secp256
7272
}
7373

7474

75-
static void secp256k1_musig_signers_init(secp256k1_musig_session_signer_data *signers, size_t n_signers) {
76-
size_t i;
75+
static void secp256k1_musig_signers_init(secp256k1_musig_session_signer_data *signers, uint32_t n_signers) {
76+
uint32_t i;
7777
for (i = 0; i < n_signers; i++) {
7878
memset(&signers[i], 0, sizeof(signers[i]));
7979
signers[i].index = i;
@@ -144,8 +144,11 @@ int secp256k1_musig_session_initialize(const secp256k1_context* ctx, secp256k1_m
144144
if (n_signers == 0 || my_index >= n_signers) {
145145
return 0;
146146
}
147-
session->n_signers = n_signers;
148-
secp256k1_musig_signers_init(signers, n_signers);
147+
if (n_signers > UINT32_MAX) {
148+
return 0;
149+
}
150+
session->n_signers = (uint32_t) n_signers;
151+
secp256k1_musig_signers_init(signers, session->n_signers);
149152
session->nonce_commitments_hash_is_set = 0;
150153

151154
/* Compute secret key */
@@ -154,7 +157,7 @@ int secp256k1_musig_session_initialize(const secp256k1_context* ctx, secp256k1_m
154157
secp256k1_scalar_clear(&secret);
155158
return 0;
156159
}
157-
secp256k1_musig_coefficient(&mu, pk_hash32, my_index);
160+
secp256k1_musig_coefficient(&mu, pk_hash32, (uint32_t) my_index);
158161
secp256k1_scalar_mul(&secret, &secret, &mu);
159162
secp256k1_scalar_get_b32(session->seckey, &secret);
160163

@@ -238,6 +241,11 @@ int secp256k1_musig_session_initialize_verifier(const secp256k1_context* ctx, se
238241
ARG_CHECK(combined_pk != NULL);
239242
ARG_CHECK(pk_hash32 != NULL);
240243
ARG_CHECK(commitments != NULL);
244+
/* Check n_signers before checking commitments to allow testing the case where
245+
* n_signers is big without allocating the space. */
246+
if (n_signers > UINT32_MAX) {
247+
return 0;
248+
}
241249
for (i = 0; i < n_signers; i++) {
242250
ARG_CHECK(commitments[i] != NULL);
243251
}
@@ -249,8 +257,8 @@ int secp256k1_musig_session_initialize_verifier(const secp256k1_context* ctx, se
249257
if (n_signers == 0) {
250258
return 0;
251259
}
252-
session->n_signers = n_signers;
253-
secp256k1_musig_signers_init(signers, n_signers);
260+
session->n_signers = (uint32_t) n_signers;
261+
secp256k1_musig_signers_init(signers, session->n_signers);
254262

255263
memcpy(session->pk_hash, pk_hash32, 32);
256264
session->nonce_is_set = 0;

src/modules/musig/tests_impl.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,12 @@ void musig_api_tests(secp256k1_scratch_space *scratch) {
122122
CHECK(ecount == 8);
123123
CHECK(secp256k1_musig_session_initialize(sign, &session[0], signer0, nonce_commitment[0], session_id[0], msg, &combined_pk, pk_hash, 0, 0, sk[0]) == 0);
124124
CHECK(ecount == 8);
125+
/* If more than UINT32_MAX fits in a size_t, test that session_initialize
126+
* rejects n_signers that high. */
127+
if (SIZE_MAX > ((size_t) UINT32_MAX) + 1) {
128+
CHECK(secp256k1_musig_session_initialize(sign, &session[0], signer0, nonce_commitment[0], session_id[0], msg, &combined_pk, pk_hash, ((size_t) UINT32_MAX) + 2, 0, sk[0]) == 0);
129+
}
130+
CHECK(ecount == 8);
125131
CHECK(secp256k1_musig_session_initialize(sign, &session[0], signer0, nonce_commitment[0], session_id[0], msg, &combined_pk, pk_hash, 2, 0, NULL) == 0);
126132
CHECK(ecount == 9);
127133
/* secret key overflows */
@@ -155,6 +161,10 @@ void musig_api_tests(secp256k1_scratch_space *scratch) {
155161
CHECK(ecount == 4);
156162
CHECK(secp256k1_musig_session_initialize_verifier(none, &verifier_session, verifier_signer_data, msg, &combined_pk, pk_hash, ncs, 0) == 0);
157163
CHECK(ecount == 4);
164+
if (SIZE_MAX > ((size_t) UINT32_MAX) + 1) {
165+
CHECK(secp256k1_musig_session_initialize_verifier(none, &verifier_session, verifier_signer_data, msg, &combined_pk, pk_hash, ncs, ((size_t) UINT32_MAX) + 2) == 0);
166+
}
167+
CHECK(ecount == 4);
158168
CHECK(secp256k1_musig_session_initialize_verifier(none, &verifier_session, verifier_signer_data, msg, &combined_pk, pk_hash, ncs, 2) == 1);
159169

160170
CHECK(secp256k1_musig_compute_messagehash(none, msghash, &verifier_session) == 0);

0 commit comments

Comments
 (0)