Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4798484

Browse files
committedJul 4, 2019
Allow creating and verifying Schnorr sign-to-contract commitments
1 parent 64475a7 commit 4798484

File tree

4 files changed

+220
-18
lines changed

4 files changed

+220
-18
lines changed
 

‎include/secp256k1_schnorrsig.h

+28-3
Original file line numberDiff line numberDiff line change
@@ -67,19 +67,28 @@ SECP256K1_API int secp256k1_schnorrsig_parse(
6767
* Returns 1 on success, 0 on failure.
6868
* Args: ctx: pointer to a context object, initialized for signing (cannot be NULL)
6969
* Out: sig: pointer to the returned signature (cannot be NULL)
70-
* In: msg32: the 32-byte message being signed (cannot be NULL)
70+
* s2c_opening: pointer to an secp256k1_s2c_opening structure which can be
71+
* NULL but is required to be not NULL if this signature creates
72+
* a sign-to-contract commitment (i.e. the `s2c_data` argument
73+
* is not NULL).
74+
* In: msg32: the 32-byte message hash being signed (cannot be NULL)
7175
* seckey: pointer to a 32-byte secret key (cannot be NULL)
76+
* s2c_data32: pointer to a 32-byte data to create an optional
77+
* sign-to-contract commitment to if not NULL (can be NULL).
7278
* noncefp: pointer to a nonce generation function. If NULL, secp256k1_nonce_function_bipschnorr is used
73-
* ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
79+
* ndata: pointer to arbitrary data used by the nonce generation function. If s2c_data is not NULL,
80+
* nust be NULL or `secp256k1_nonce_function_bipschnorr` (can be NULL)
7481
*/
7582
SECP256K1_API int secp256k1_schnorrsig_sign(
7683
const secp256k1_context* ctx,
7784
secp256k1_schnorrsig *sig,
85+
secp256k1_s2c_opening *s2c_opening,
7886
const unsigned char *msg32,
7987
const unsigned char *seckey,
88+
const unsigned char *s2c_data32,
8089
secp256k1_nonce_function noncefp,
8190
void *ndata
82-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
91+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
8392

8493
/** Verify a Schnorr signature.
8594
*
@@ -119,6 +128,22 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorrsig_verify_batch
119128
size_t n_sigs
120129
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
121130

131+
/** Verify a sign-to-contract commitment.
132+
*
133+
* Returns: 1: the signature contains a commitment to data32
134+
* 0: incorrect opening
135+
* Args: ctx: a secp256k1 context object, initialized for verification.
136+
* In: sig: the signature containing the sign-to-contract commitment (cannot be NULL)
137+
* data32: the 32-byte data that was committed to (cannot be NULL)
138+
* opening: pointer to the opening created during signing (cannot be NULL)
139+
*/
140+
SECP256K1_API int secp256k1_schnorrsig_verify_s2c_commit(
141+
const secp256k1_context* ctx,
142+
const secp256k1_schnorrsig *sig,
143+
const unsigned char *data32,
144+
const secp256k1_s2c_opening *opening
145+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
146+
122147
#ifdef __cplusplus
123148
}
124149
#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, 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, 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

+64-1
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, 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,19 @@ 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 because otherwise this could result in nonce reuse. */
78+
ARG_CHECK(s2c_data32 == NULL || (noncefp == NULL || noncefp == secp256k1_nonce_function_bipschnorr));
79+
/* s2c_opening and s2c_data32 should be either both non-NULL or both NULL. */
80+
ARG_CHECK((s2c_opening != NULL) == (s2c_data32 != NULL));
5081

5182
if (noncefp == NULL) {
5283
noncefp = secp256k1_nonce_function_bipschnorr;
@@ -61,6 +92,24 @@ int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, secp256k1_schnorrsig
6192
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pkj, &x);
6293
secp256k1_ge_set_gej(&pk, &pkj);
6394

95+
if (s2c_data32 != NULL) {
96+
/* Provide s2c_data32 and ndata (if not NULL) to the the nonce function
97+
* as additional data to derive the nonce from. If both pointers are
98+
* not NULL, they need to be hashed to get the nonce data 32 bytes.
99+
* Even if only s2c_data32 is not NULL, it's hashed because it should
100+
* be possible to derive nonces even if only a SHA256 commitment to the
101+
* data is known. This is for example important in the anti nonce
102+
* sidechannel protocol.
103+
*/
104+
secp256k1_sha256_initialize(&sha);
105+
secp256k1_sha256_write(&sha, s2c_data32, 32);
106+
if (ndata != NULL) {
107+
secp256k1_sha256_write(&sha, ndata, 32);
108+
}
109+
secp256k1_sha256_finalize(&sha, noncedata);
110+
ndata = &noncedata;
111+
}
112+
64113
if (!noncefp(buf, msg32, seckey, NULL, (void*)ndata, 0)) {
65114
return 0;
66115
}
@@ -72,8 +121,22 @@ int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, secp256k1_schnorrsig
72121
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &rj, &k);
73122
secp256k1_ge_set_gej(&r, &rj);
74123

124+
if (s2c_opening != NULL) {
125+
secp256k1_s2c_opening_init(s2c_opening);
126+
if (s2c_data32 != NULL) {
127+
/* Create sign-to-contract commitment */
128+
secp256k1_pubkey_save(&s2c_opening->original_pubnonce, &r);
129+
secp256k1_ec_commit_seckey(ctx, buf, &s2c_opening->original_pubnonce, s2c_data32, 32);
130+
secp256k1_scalar_set_b32(&k, buf, NULL);
131+
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &rj, &k);
132+
secp256k1_ge_set_gej(&r, &rj);
133+
}
134+
}
75135
if (!secp256k1_fe_is_quad_var(&r.y)) {
76136
secp256k1_scalar_negate(&k, &k);
137+
if (s2c_opening != NULL) {
138+
s2c_opening->nonce_is_negated = 1;
139+
}
77140
}
78141
secp256k1_fe_normalize(&r.x);
79142
secp256k1_fe_get_b32(&sig->data[0], &r.x);

‎src/modules/schnorrsig/tests_impl.h

+126-12
Original file line numberDiff line numberDiff line change
@@ -25,19 +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];
36+
secp256k1_s2c_opening s2c_opening;
37+
unsigned char ones[32];
3438

3539
/** setup **/
3640
secp256k1_context *none = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
3741
secp256k1_context *sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
3842
secp256k1_context *vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
3943
secp256k1_context *both = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
4044
int ecount;
45+
memset(ones, 0xff, 32);
4146

4247
secp256k1_context_set_error_callback(none, counting_illegal_callback_fn, &ecount);
4348
secp256k1_context_set_error_callback(sign, counting_illegal_callback_fn, &ecount);
@@ -52,24 +57,36 @@ void test_schnorrsig_api(secp256k1_scratch_space *scratch) {
5257
secp256k1_rand256(sk2);
5358
secp256k1_rand256(sk3);
5459
secp256k1_rand256(msg);
60+
secp256k1_rand256(s2c_data32);
5561
CHECK(secp256k1_ec_pubkey_create(ctx, &pk[0], sk1) == 1);
5662
CHECK(secp256k1_ec_pubkey_create(ctx, &pk[1], sk2) == 1);
5763
CHECK(secp256k1_ec_pubkey_create(ctx, &pk[2], sk3) == 1);
5864

5965
/** main test body **/
6066
ecount = 0;
61-
CHECK(secp256k1_schnorrsig_sign(none, &sig, msg, sk1, NULL, NULL) == 0);
67+
CHECK(secp256k1_schnorrsig_sign(none, &sig, &s2c_opening, msg, sk1, s2c_data32, NULL, NULL) == 0);
6268
CHECK(ecount == 1);
63-
CHECK(secp256k1_schnorrsig_sign(vrfy, &sig, msg, sk1, NULL, NULL) == 0);
69+
CHECK(secp256k1_schnorrsig_sign(vrfy, &sig, &s2c_opening, msg, sk1, s2c_data32, NULL, NULL) == 0);
6470
CHECK(ecount == 2);
65-
CHECK(secp256k1_schnorrsig_sign(sign, &sig, msg, sk1, NULL, NULL) == 1);
71+
CHECK(secp256k1_schnorrsig_sign(sign, &sig, &s2c_opening, msg, sk1, s2c_data32, NULL, NULL) == 1);
6672
CHECK(ecount == 2);
67-
CHECK(secp256k1_schnorrsig_sign(sign, NULL, msg, sk1, NULL, NULL) == 0);
73+
CHECK(secp256k1_schnorrsig_sign(sign, NULL, &s2c_opening, msg, sk1, s2c_data32, NULL, NULL) == 0);
6874
CHECK(ecount == 3);
69-
CHECK(secp256k1_schnorrsig_sign(sign, &sig, NULL, sk1, NULL, NULL) == 0);
75+
CHECK(secp256k1_schnorrsig_sign(sign, &sig, NULL, msg, sk1, s2c_data32, NULL, NULL) == 0);
7076
CHECK(ecount == 4);
71-
CHECK(secp256k1_schnorrsig_sign(sign, &sig, msg, NULL, NULL, NULL) == 0);
77+
CHECK(secp256k1_schnorrsig_sign(sign, &sig, &s2c_opening, NULL, sk1, s2c_data32, NULL, NULL) == 0);
7278
CHECK(ecount == 5);
79+
CHECK(secp256k1_schnorrsig_sign(sign, &sig, &s2c_opening, msg, NULL, s2c_data32, NULL, NULL) == 0);
80+
CHECK(ecount == 6);
81+
CHECK(secp256k1_schnorrsig_sign(sign, &sig, &s2c_opening, msg, sk1, NULL, NULL, NULL) == 0);
82+
CHECK(ecount == 7);
83+
/* It's okay if both s2c_opening and s2c_data32 are NULL. It's just not okay if
84+
* only a single one of them is NULL. */
85+
CHECK(secp256k1_schnorrsig_sign(sign, &sig, NULL, msg, sk1, NULL, NULL, NULL) == 1);
86+
CHECK(ecount == 7);
87+
/* s2c commitments with a different nonce function than bipschnorr are not allowed */
88+
CHECK(secp256k1_schnorrsig_sign(sign, &sig, &s2c_opening, msg, sk1, s2c_data32, secp256k1_nonce_function_rfc6979, NULL) == 0);
89+
CHECK(ecount == 8);
7390

7491
ecount = 0;
7592
CHECK(secp256k1_schnorrsig_serialize(none, sig64, &sig) == 1);
@@ -85,6 +102,36 @@ void test_schnorrsig_api(secp256k1_scratch_space *scratch) {
85102
CHECK(secp256k1_schnorrsig_parse(none, &sig, NULL) == 0);
86103
CHECK(ecount == 4);
87104

105+
/* Create sign-to-contract commitment to data32 for testing verify_s2c_commit */
106+
secp256k1_rand256(data32);
107+
CHECK(secp256k1_schnorrsig_sign(sign, &sig, &s2c_opening, msg, sk1, data32, NULL, NULL) == 1);
108+
ecount = 0;
109+
CHECK(secp256k1_schnorrsig_verify_s2c_commit(none, &sig, data32, &s2c_opening) == 0);
110+
CHECK(ecount == 1);
111+
CHECK(secp256k1_schnorrsig_verify_s2c_commit(vrfy, &sig, data32, &s2c_opening) == 1);
112+
CHECK(ecount == 1);
113+
{
114+
/* Overflowing x-coordinate in signature */
115+
secp256k1_schnorrsig sig_tmp = sig;
116+
memcpy(&sig_tmp.data[0], ones, 32);
117+
CHECK(secp256k1_schnorrsig_verify_s2c_commit(vrfy, &sig_tmp, data32, &s2c_opening) == 0);
118+
}
119+
CHECK(secp256k1_schnorrsig_verify_s2c_commit(vrfy, NULL, data32, &s2c_opening) == 0);
120+
CHECK(ecount == 2);
121+
CHECK(secp256k1_schnorrsig_verify_s2c_commit(vrfy, &sig, NULL, &s2c_opening) == 0);
122+
CHECK(ecount == 3);
123+
CHECK(secp256k1_schnorrsig_verify_s2c_commit(vrfy, &sig, data32, NULL) == 0);
124+
CHECK(ecount == 4);
125+
{
126+
/* Verification with uninitialized s2c_opening should fail. Actually testing
127+
* that would be undefined behavior. Therefore we simulate it by setting the
128+
* opening to 0. */
129+
secp256k1_s2c_opening s2c_opening_tmp;
130+
memset(&s2c_opening_tmp, 0, sizeof(s2c_opening_tmp));
131+
CHECK(secp256k1_schnorrsig_verify_s2c_commit(vrfy, &sig, data32, &s2c_opening_tmp) == 0);
132+
CHECK(ecount == 5);
133+
}
134+
88135
ecount = 0;
89136
CHECK(secp256k1_schnorrsig_verify(none, &sig, msg, &pk[0]) == 0);
90137
CHECK(ecount == 1);
@@ -132,7 +179,7 @@ void test_schnorrsig_bip_vectors_check_signing(const unsigned char *sk, const un
132179
unsigned char serialized_sig[64];
133180
secp256k1_pubkey pk;
134181

135-
CHECK(secp256k1_schnorrsig_sign(ctx, &sig, msg, sk, NULL, NULL));
182+
CHECK(secp256k1_schnorrsig_sign(ctx, &sig, NULL, msg, sk, NULL, NULL, NULL));
136183
CHECK(secp256k1_schnorrsig_serialize(ctx, serialized_sig, &sig));
137184
CHECK(memcmp(serialized_sig, expected_sig, 64) == 0);
138185

@@ -634,15 +681,16 @@ void test_schnorrsig_sign(void) {
634681
secp256k1_schnorrsig sig;
635682

636683
memset(sk, 23, sizeof(sk));
637-
CHECK(secp256k1_schnorrsig_sign(ctx, &sig, msg, sk, NULL, NULL) == 1);
684+
685+
CHECK(secp256k1_schnorrsig_sign(ctx, &sig, NULL, msg, sk, NULL, NULL, NULL) == 1);
638686

639687
/* Overflowing secret key */
640688
memset(sk, 0xFF, sizeof(sk));
641-
CHECK(secp256k1_schnorrsig_sign(ctx, &sig, msg, sk, NULL, NULL) == 0);
689+
CHECK(secp256k1_schnorrsig_sign(ctx, &sig, NULL, msg, sk, NULL, NULL, NULL) == 0);
642690
memset(sk, 23, sizeof(sk));
643691

644-
CHECK(secp256k1_schnorrsig_sign(ctx, &sig, msg, sk, nonce_function_failing, NULL) == 0);
645-
CHECK(secp256k1_schnorrsig_sign(ctx, &sig, msg, sk, nonce_function_0, NULL) == 0);
692+
CHECK(secp256k1_schnorrsig_sign(ctx, &sig, NULL, msg, sk, NULL, nonce_function_failing, NULL) == 0);
693+
CHECK(secp256k1_schnorrsig_sign(ctx, &sig, NULL, msg, sk, NULL, nonce_function_0, NULL) == 0);
646694
}
647695

648696
#define N_SIGS 200
@@ -664,7 +712,7 @@ void test_schnorrsig_sign_verify(secp256k1_scratch_space *scratch) {
664712

665713
for (i = 0; i < N_SIGS; i++) {
666714
secp256k1_rand256(msg[i]);
667-
CHECK(secp256k1_schnorrsig_sign(ctx, &sig[i], msg[i], sk, NULL, NULL));
715+
CHECK(secp256k1_schnorrsig_sign(ctx, &sig[i], NULL, msg[i], sk, NULL, NULL, NULL));
668716
CHECK(secp256k1_schnorrsig_verify(ctx, &sig[i], msg[i], &pk));
669717
sig_arr[i] = &sig[i];
670718
msg_arr[i] = msg[i];
@@ -706,7 +754,68 @@ void test_schnorrsig_sign_verify(secp256k1_scratch_space *scratch) {
706754
}
707755
#undef N_SIGS
708756

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

712821
test_schnorrsig_serialize();
@@ -715,6 +824,11 @@ void run_schnorrsig_tests(void) {
715824
test_schnorrsig_sign();
716825
test_schnorrsig_sign_verify(scratch);
717826

827+
for (i = 0; i < count; i++) {
828+
/* Run multiple times to increase probability that the nonce is negated in
829+
* a test. */
830+
test_schnorrsig_s2c_commit_verify();
831+
}
718832
secp256k1_scratch_space_destroy(ctx, scratch);
719833
}
720834

0 commit comments

Comments
 (0)
Please sign in to comment.