Skip to content

Commit 16a7592

Browse files
committed
Allow creating and verifying Schnorr sign-to-contract commitments
1 parent 8d2506e commit 16a7592

File tree

4 files changed

+205
-28
lines changed

4 files changed

+205
-28
lines changed

include/secp256k1_schnorrsig.h

+25-3
Original file line numberDiff line numberDiff line change
@@ -61,19 +61,24 @@ SECP256K1_API int secp256k1_schnorrsig_parse(
6161
* Returns 1 on success, 0 on failure.
6262
* Args: ctx: pointer to a context object, initialized for signing (cannot be NULL)
6363
* Out: sig: pointer to the returned signature (cannot be NULL)
64-
* nonce_is_negated: a pointer to an integer indicates if signing algorithm negated the
65-
* nonce (can be NULL)
64+
* s2c_data: pointer to an secp256k1_s2c_opening structure which can be
65+
* NULL but is required to be not NULL if this signature creates
66+
* a sign-to-contract commitment (i.e. the `s2c_data` argument
67+
* is not NULL).
6668
* In: msg32: the 32-byte message hash being signed (cannot be NULL)
6769
* seckey: pointer to a 32-byte secret key (cannot be NULL)
70+
* s2c_data32: pointer to a 32-byte data to create an optional
71+
* sign-to-contract commitment to if non-NULL (non-NULL).
6872
* noncefp: pointer to a nonce generation function. If NULL, secp256k1_nonce_function_bipschnorr is used
6973
* ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
7074
*/
7175
SECP256K1_API int secp256k1_schnorrsig_sign(
7276
const secp256k1_context* ctx,
7377
secp256k1_schnorrsig *sig,
74-
int *nonce_is_negated,
78+
secp256k1_s2c_opening *s2c_opening,
7579
const unsigned char *msg32,
7680
const unsigned char *seckey,
81+
const unsigned char *s2c_data32,
7782
secp256k1_nonce_function noncefp,
7883
void *ndata
7984
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
@@ -115,4 +120,21 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorrsig_verify_batch
115120
const secp256k1_pubkey *const *pk,
116121
size_t n_sigs
117122
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
123+
124+
/** Verify a sign-to-contract commitment.
125+
*
126+
* Returns: 1: the signature contains a commitment to data32
127+
* 0: incorrect opening
128+
* Args: ctx: a secp256k1 context object, initialized for verification.
129+
* In: sig: the signature containing the sign-to-contract commitment (cannot be NULL)
130+
* data32: the 32-byte data that was committed to (cannot be NULL)
131+
* opening: pointer to the opening created during signing (cannot be NULL)
132+
*/
133+
SECP256K1_API int secp256k1_schnorrsig_verify_s2c_commit(
134+
const secp256k1_context* ctx,
135+
const secp256k1_schnorrsig *sig,
136+
const unsigned char *data32,
137+
const secp256k1_s2c_opening *opening
138+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
139+
118140
#endif

src/bench_schnorrsig.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ void bench_schnorrsig_sign(void* arg) {
3535
msg[1] = i >> 8;
3636
sk[0] = i;
3737
sk[1] = i >> 8;
38-
CHECK(secp256k1_schnorrsig_sign(data->ctx, &sig, NULL, msg, sk, NULL, NULL));
38+
CHECK(secp256k1_schnorrsig_sign(data->ctx, &sig, NULL, msg, sk, NULL, NULL, NULL));
3939
}
4040
}
4141

@@ -100,7 +100,7 @@ int main(void) {
100100

101101
CHECK(secp256k1_ec_pubkey_create(data.ctx, &pk, sk));
102102
CHECK(secp256k1_ec_pubkey_serialize(data.ctx, pk_char, &pk_len, &pk, SECP256K1_EC_COMPRESSED) == 1);
103-
CHECK(secp256k1_schnorrsig_sign(data.ctx, sig, NULL, msg, sk, NULL, NULL));
103+
CHECK(secp256k1_schnorrsig_sign(data.ctx, sig, NULL, msg, sk, NULL, NULL, NULL));
104104
}
105105

106106
run_benchmark("schnorrsig_sign", bench_schnorrsig_sign, NULL, NULL, (void *) &data, 10, 1000);

src/modules/schnorrsig/main_impl.h

+60-6
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,31 @@ int secp256k1_schnorrsig_parse(const secp256k1_context* ctx, secp256k1_schnorrsi
2929
return 1;
3030
}
3131

32-
int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, secp256k1_schnorrsig *sig, int *nonce_is_negated, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, void *ndata) {
32+
int secp256k1_schnorrsig_verify_s2c_commit(const secp256k1_context* ctx, const secp256k1_schnorrsig *sig, const unsigned char *data32, const secp256k1_s2c_opening *opening) {
33+
secp256k1_fe rx;
34+
secp256k1_ge R;
35+
secp256k1_pubkey pubnonce;
36+
37+
VERIFY_CHECK(ctx != NULL);
38+
ARG_CHECK(sig != NULL);
39+
ARG_CHECK(data32 != NULL);
40+
ARG_CHECK(opening != NULL);
41+
ARG_CHECK(secp256k1_s2c_commit_is_init(opening));
42+
43+
if (!secp256k1_fe_set_b32(&rx, &sig->data[0])) {
44+
return 0;
45+
}
46+
if (!secp256k1_ge_set_xquad(&R, &rx)) {
47+
return 0;
48+
}
49+
if (opening->nonce_is_negated) {
50+
secp256k1_ge_neg(&R, &R);
51+
}
52+
secp256k1_pubkey_save(&pubnonce, &R);
53+
return secp256k1_ec_commit_verify(ctx, &pubnonce, &opening->original_pubnonce, data32, 32);
54+
}
55+
56+
int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, secp256k1_schnorrsig *sig, secp256k1_s2c_opening *s2c_opening, const unsigned char *msg32, const unsigned char *seckey, const unsigned char *s2c_data32, secp256k1_nonce_function noncefp, void *ndata) {
3357
secp256k1_scalar x;
3458
secp256k1_scalar e;
3559
secp256k1_scalar k;
@@ -41,12 +65,17 @@ int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, secp256k1_schnorrsig
4165
int overflow;
4266
unsigned char buf[33];
4367
size_t buflen = sizeof(buf);
68+
unsigned char noncedata[32];
4469

4570
VERIFY_CHECK(ctx != NULL);
4671
ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
4772
ARG_CHECK(sig != NULL);
4873
ARG_CHECK(msg32 != NULL);
4974
ARG_CHECK(seckey != NULL);
75+
/* sign-to-contract commitments only work with the default nonce function,
76+
* because we need to ensure that s2c_data is actually hashed into the nonce and
77+
* not just ignored. */
78+
ARG_CHECK(s2c_data32 == NULL || (noncefp == NULL || noncefp == secp256k1_nonce_function_bipschnorr));
5079

5180
if (noncefp == NULL) {
5281
noncefp = secp256k1_nonce_function_bipschnorr;
@@ -61,6 +90,24 @@ int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, secp256k1_schnorrsig
6190
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pkj, &x);
6291
secp256k1_ge_set_gej(&pk, &pkj);
6392

93+
if(s2c_data32 != NULL) {
94+
/* Provide s2c_data32 and ndata (if not NULL) to the the nonce function
95+
* as additional data to derive the nonce from. If both pointers are
96+
* not NULL, they need to be hashed to get the nonce data 32 bytes.
97+
* Even if only s2c_data32 is not NULL, it's hashed because it should
98+
* be possible to derive nonces even if only a SHA256 commitment to the
99+
* data is known. This is for example important in the
100+
* anti-nonce-sidechannel protocol.
101+
*/
102+
secp256k1_sha256_initialize(&sha);
103+
secp256k1_sha256_write(&sha, s2c_data32, 32);
104+
if (ndata != NULL) {
105+
secp256k1_sha256_write(&sha, ndata, 32);
106+
}
107+
secp256k1_sha256_finalize(&sha, noncedata);
108+
ndata = &noncedata;
109+
}
110+
64111
if (!noncefp(buf, msg32, seckey, NULL, (void*)ndata, 0)) {
65112
return 0;
66113
}
@@ -71,14 +118,21 @@ int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, secp256k1_schnorrsig
71118

72119
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &rj, &k);
73120
secp256k1_ge_set_gej(&r, &rj);
74-
75-
if (nonce_is_negated != NULL) {
76-
*nonce_is_negated = 0;
121+
if (s2c_opening != NULL) {
122+
secp256k1_s2c_opening_init(s2c_opening);
123+
if (s2c_data32 != NULL) {
124+
/* Create sign-to-contract commitment */
125+
secp256k1_pubkey_save(&s2c_opening->original_pubnonce, &r);
126+
secp256k1_ec_commit_seckey(ctx, buf, &s2c_opening->original_pubnonce, s2c_data32, 32);
127+
secp256k1_scalar_set_b32(&k, buf, NULL);
128+
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &rj, &k);
129+
secp256k1_ge_set_gej(&r, &rj);
130+
}
77131
}
78132
if (!secp256k1_fe_is_quad_var(&r.y)) {
79133
secp256k1_scalar_negate(&k, &k);
80-
if (nonce_is_negated != NULL) {
81-
*nonce_is_negated = 1;
134+
if (s2c_opening != NULL) {
135+
s2c_opening->nonce_is_negated = 1;
82136
}
83137
}
84138
secp256k1_fe_normalize(&r.x);

src/modules/schnorrsig/tests_impl.h

+118-17
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,24 @@ void test_schnorrsig_api(secp256k1_scratch_space *scratch) {
2525
unsigned char sk2[32];
2626
unsigned char sk3[32];
2727
unsigned char msg[32];
28+
unsigned char data32[32];
29+
unsigned char s2c_data32[32];
2830
unsigned char sig64[64];
2931
secp256k1_pubkey pk[3];
3032
secp256k1_schnorrsig sig;
3133
const secp256k1_schnorrsig *sigptr = &sig;
3234
const unsigned char *msgptr = msg;
3335
const secp256k1_pubkey *pkptr = &pk[0];
34-
int nonce_is_negated;
36+
secp256k1_s2c_opening s2c_opening;
37+
unsigned char ones[32];
3538

3639
/** setup **/
3740
secp256k1_context *none = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
3841
secp256k1_context *sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
3942
secp256k1_context *vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
4043
secp256k1_context *both = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
4144
int ecount;
45+
memset(ones, 0xff, 32);
4246

4347
secp256k1_context_set_error_callback(none, counting_illegal_callback_fn, &ecount);
4448
secp256k1_context_set_error_callback(sign, counting_illegal_callback_fn, &ecount);
@@ -59,20 +63,25 @@ void test_schnorrsig_api(secp256k1_scratch_space *scratch) {
5963

6064
/** main test body **/
6165
ecount = 0;
62-
CHECK(secp256k1_schnorrsig_sign(none, &sig, &nonce_is_negated, msg, sk1, NULL, NULL) == 0);
66+
CHECK(secp256k1_schnorrsig_sign(none, &sig, &s2c_opening, msg, sk1, s2c_data32, NULL, NULL) == 0);
6367
CHECK(ecount == 1);
64-
CHECK(secp256k1_schnorrsig_sign(vrfy, &sig, &nonce_is_negated, msg, sk1, NULL, NULL) == 0);
68+
CHECK(secp256k1_schnorrsig_sign(vrfy, &sig, &s2c_opening, msg, sk1, s2c_data32, NULL, NULL) == 0);
6569
CHECK(ecount == 2);
66-
CHECK(secp256k1_schnorrsig_sign(sign, &sig, &nonce_is_negated, msg, sk1, NULL, NULL) == 1);
70+
CHECK(secp256k1_schnorrsig_sign(sign, &sig, &s2c_opening, msg, sk1, s2c_data32, NULL, NULL) == 1);
6771
CHECK(ecount == 2);
68-
CHECK(secp256k1_schnorrsig_sign(sign, NULL, &nonce_is_negated, msg, sk1, NULL, NULL) == 0);
72+
CHECK(secp256k1_schnorrsig_sign(sign, NULL, &s2c_opening, msg, sk1, s2c_data32, NULL, NULL) == 0);
6973
CHECK(ecount == 3);
70-
CHECK(secp256k1_schnorrsig_sign(sign, &sig, NULL, msg, sk1, NULL, NULL) == 1);
74+
CHECK(secp256k1_schnorrsig_sign(sign, &sig, NULL, msg, sk1, s2c_data32, NULL, NULL) == 1);
7175
CHECK(ecount == 3);
72-
CHECK(secp256k1_schnorrsig_sign(sign, &sig, &nonce_is_negated, NULL, sk1, NULL, NULL) == 0);
76+
CHECK(secp256k1_schnorrsig_sign(sign, &sig, &s2c_opening, NULL, sk1, s2c_data32, NULL, NULL) == 0);
7377
CHECK(ecount == 4);
74-
CHECK(secp256k1_schnorrsig_sign(sign, &sig, &nonce_is_negated, msg, NULL, NULL, NULL) == 0);
78+
CHECK(secp256k1_schnorrsig_sign(sign, &sig, &s2c_opening, msg, NULL, s2c_data32, NULL, NULL) == 0);
7579
CHECK(ecount == 5);
80+
CHECK(secp256k1_schnorrsig_sign(sign, &sig, &s2c_opening, msg, sk1, NULL, NULL, NULL) == 1);
81+
CHECK(ecount == 5);
82+
/* s2c commitments with a different nonce function than bipschnorr are not allowed */
83+
CHECK(secp256k1_schnorrsig_sign(sign, &sig, &s2c_opening, msg, sk1, s2c_data32, secp256k1_nonce_function_rfc6979, NULL) == 0);
84+
CHECK(ecount == 6);
7685

7786
ecount = 0;
7887
CHECK(secp256k1_schnorrsig_serialize(none, sig64, &sig) == 1);
@@ -88,6 +97,33 @@ void test_schnorrsig_api(secp256k1_scratch_space *scratch) {
8897
CHECK(secp256k1_schnorrsig_parse(none, &sig, NULL) == 0);
8998
CHECK(ecount == 4);
9099

100+
/* Create sign-to-contract commitment to data32 for testing verify_s2c_commit */
101+
secp256k1_rand256(data32);
102+
CHECK(secp256k1_schnorrsig_sign(sign, &sig, &s2c_opening, msg, sk1, data32, NULL, NULL) == 1);
103+
ecount = 0;
104+
CHECK(secp256k1_schnorrsig_verify_s2c_commit(none, &sig, data32, &s2c_opening) == 0);
105+
CHECK(ecount == 1);
106+
CHECK(secp256k1_schnorrsig_verify_s2c_commit(vrfy, &sig, data32, &s2c_opening) == 1);
107+
CHECK(ecount == 1);
108+
{
109+
/* Overflowing x-coordinate in signature */
110+
secp256k1_schnorrsig sig_tmp = sig;
111+
memcpy(&sig_tmp.data[0], ones, 32);
112+
CHECK(secp256k1_schnorrsig_verify_s2c_commit(vrfy, &sig_tmp, data32, &s2c_opening) == 0);
113+
}
114+
CHECK(secp256k1_schnorrsig_verify_s2c_commit(vrfy, NULL, data32, &s2c_opening) == 0);
115+
CHECK(ecount == 2);
116+
CHECK(secp256k1_schnorrsig_verify_s2c_commit(vrfy, &sig, NULL, &s2c_opening) == 0);
117+
CHECK(ecount == 3);
118+
CHECK(secp256k1_schnorrsig_verify_s2c_commit(vrfy, &sig, data32, NULL) == 0);
119+
CHECK(ecount == 4);
120+
{
121+
/* Verification with uninitialized s2c_opening should fail */
122+
secp256k1_s2c_opening s2c_opening_tmp;
123+
CHECK(secp256k1_schnorrsig_verify_s2c_commit(vrfy, &sig, data32, &s2c_opening_tmp) == 0);
124+
CHECK(ecount == 5);
125+
}
126+
91127
ecount = 0;
92128
CHECK(secp256k1_schnorrsig_verify(none, &sig, msg, &pk[0]) == 0);
93129
CHECK(ecount == 1);
@@ -134,10 +170,10 @@ void test_schnorrsig_bip_vectors_check_signing(const unsigned char *sk, const un
134170
secp256k1_schnorrsig sig;
135171
unsigned char serialized_sig[64];
136172
secp256k1_pubkey pk;
137-
int nonce_is_negated;
173+
secp256k1_s2c_opening s2c_opening;
138174

139-
CHECK(secp256k1_schnorrsig_sign(ctx, &sig, &nonce_is_negated, msg, sk, NULL, NULL));
140-
CHECK(nonce_is_negated == expected_nonce_is_negated);
175+
CHECK(secp256k1_schnorrsig_sign(ctx, &sig, &s2c_opening, msg, sk, NULL, NULL, NULL));
176+
CHECK(s2c_opening.nonce_is_negated == expected_nonce_is_negated);
141177
CHECK(secp256k1_schnorrsig_serialize(ctx, serialized_sig, &sig));
142178
CHECK(memcmp(serialized_sig, expected_sig, 64) == 0);
143179

@@ -639,15 +675,15 @@ void test_schnorrsig_sign(void) {
639675
secp256k1_schnorrsig sig;
640676

641677
memset(sk, 23, sizeof(sk));
642-
CHECK(secp256k1_schnorrsig_sign(ctx, &sig, NULL, msg, sk, NULL, NULL) == 1);
678+
CHECK(secp256k1_schnorrsig_sign(ctx, &sig, NULL, msg, sk, NULL, NULL, NULL) == 1);
643679

644680
/* Overflowing secret key */
645681
memset(sk, 0xFF, sizeof(sk));
646-
CHECK(secp256k1_schnorrsig_sign(ctx, &sig, NULL, msg, sk, NULL, NULL) == 0);
682+
CHECK(secp256k1_schnorrsig_sign(ctx, &sig, NULL, msg, sk, NULL, NULL, NULL) == 0);
647683
memset(sk, 23, sizeof(sk));
648684

649-
CHECK(secp256k1_schnorrsig_sign(ctx, &sig, NULL, msg, sk, nonce_function_failing, NULL) == 0);
650-
CHECK(secp256k1_schnorrsig_sign(ctx, &sig, NULL, msg, sk, nonce_function_0, NULL) == 0);
685+
CHECK(secp256k1_schnorrsig_sign(ctx, &sig, NULL, msg, sk, NULL, nonce_function_failing, NULL) == 0);
686+
CHECK(secp256k1_schnorrsig_sign(ctx, &sig, NULL, msg, sk, NULL, nonce_function_0, NULL) == 0);
651687
}
652688

653689
#define N_SIGS 200
@@ -669,7 +705,7 @@ void test_schnorrsig_sign_verify(secp256k1_scratch_space *scratch) {
669705

670706
for (i = 0; i < N_SIGS; i++) {
671707
secp256k1_rand256(msg[i]);
672-
CHECK(secp256k1_schnorrsig_sign(ctx, &sig[i], NULL, msg[i], sk, NULL, NULL));
708+
CHECK(secp256k1_schnorrsig_sign(ctx, &sig[i], NULL, msg[i], sk, NULL, NULL, NULL));
673709
CHECK(secp256k1_schnorrsig_verify(ctx, &sig[i], msg[i], &pk));
674710
sig_arr[i] = &sig[i];
675711
msg_arr[i] = msg[i];
@@ -711,15 +747,80 @@ void test_schnorrsig_sign_verify(secp256k1_scratch_space *scratch) {
711747
}
712748
#undef N_SIGS
713749

750+
void test_schnorrsig_s2c_commit_verify(void) {
751+
unsigned char data32[32];
752+
secp256k1_schnorrsig sig;
753+
secp256k1_s2c_opening s2c_opening;
754+
unsigned char msg[32];
755+
unsigned char sk[32];
756+
secp256k1_pubkey pk;
757+
unsigned char noncedata[32];
758+
759+
secp256k1_rand256(data32);
760+
secp256k1_rand256(msg);
761+
secp256k1_rand256(sk);
762+
secp256k1_rand256(noncedata);
763+
CHECK(secp256k1_ec_pubkey_create(ctx, &pk, sk) == 1);
764+
765+
/* Create and verify correct commitment */
766+
CHECK(secp256k1_schnorrsig_sign(ctx, &sig, &s2c_opening, msg, sk, data32, NULL, noncedata) == 1);
767+
CHECK(secp256k1_schnorrsig_verify(ctx, &sig, msg, &pk));
768+
CHECK(secp256k1_schnorrsig_verify_s2c_commit(ctx, &sig, data32, &s2c_opening) == 1);
769+
{
770+
/* verify_s2c_commit fails if nonce_is_negated is wrong */
771+
secp256k1_s2c_opening s2c_opening_tmp;
772+
s2c_opening_tmp = s2c_opening;
773+
s2c_opening_tmp.nonce_is_negated = !s2c_opening.nonce_is_negated;
774+
CHECK(secp256k1_schnorrsig_verify_s2c_commit(ctx, &sig, data32, &s2c_opening_tmp) == 0);
775+
}
776+
{
777+
/* verify_s2c_commit fails if given data does not match committed data */
778+
unsigned char data32_tmp[32];
779+
memcpy(data32_tmp, data32, sizeof(data32_tmp));
780+
data32_tmp[31] ^= 1;
781+
CHECK(secp256k1_schnorrsig_verify_s2c_commit(ctx, &sig, data32_tmp, &s2c_opening) == 0);
782+
}
783+
{
784+
/* verify_s2c_commit fails if signature does not commit to data */
785+
secp256k1_schnorrsig sig_tmp;
786+
sig_tmp = sig;
787+
secp256k1_rand256(&sig_tmp.data[0]);
788+
CHECK(secp256k1_schnorrsig_verify_s2c_commit(ctx, &sig_tmp, data32, &s2c_opening) == 0);
789+
}
790+
{
791+
/* A commitment to different data creates a different original_pubnonce
792+
* (i.e. data is hashed into the nonce) */
793+
secp256k1_s2c_opening s2c_opening_tmp;
794+
secp256k1_schnorrsig sig_tmp;
795+
unsigned char data32_tmp[32];
796+
unsigned char serialized_nonce[33];
797+
unsigned char serialized_nonce_tmp[33];
798+
size_t outputlen = 33;
799+
secp256k1_rand256(data32_tmp);
800+
CHECK(secp256k1_schnorrsig_sign(ctx, &sig_tmp, &s2c_opening_tmp, msg, sk, data32_tmp, NULL, NULL) == 1);
801+
CHECK(secp256k1_schnorrsig_verify(ctx, &sig_tmp, msg, &pk));
802+
CHECK(secp256k1_schnorrsig_verify_s2c_commit(ctx, &sig_tmp, data32_tmp, &s2c_opening_tmp) == 1);
803+
secp256k1_ec_pubkey_serialize(ctx, serialized_nonce, &outputlen, &s2c_opening.original_pubnonce, SECP256K1_EC_COMPRESSED);
804+
secp256k1_ec_pubkey_serialize(ctx, serialized_nonce_tmp, &outputlen, &s2c_opening_tmp.original_pubnonce, SECP256K1_EC_COMPRESSED);
805+
CHECK(outputlen == 33);
806+
CHECK(memcmp(serialized_nonce, serialized_nonce_tmp, outputlen) != 0);
807+
}
808+
}
809+
714810
void run_schnorrsig_tests(void) {
811+
int i;
715812
secp256k1_scratch_space *scratch = secp256k1_scratch_space_create(ctx, 1024 * 1024);
716813

717814
test_schnorrsig_serialize();
718815
test_schnorrsig_api(scratch);
719816
test_schnorrsig_bip_vectors(scratch);
720817
test_schnorrsig_sign();
721818
test_schnorrsig_sign_verify(scratch);
722-
819+
for (i = 0; i < count; i++) {
820+
/* Run multiple times to increase probability that the nonce is negated in
821+
* a test. */
822+
test_schnorrsig_s2c_commit_verify();
823+
}
723824
secp256k1_scratch_space_destroy(scratch);
724825
}
725826

0 commit comments

Comments
 (0)