Skip to content

Commit 6c9c85b

Browse files
committed
more fixes addressing PR comments (docs remain)
1 parent 5384982 commit 6c9c85b

File tree

5 files changed

+73
-42
lines changed

5 files changed

+73
-42
lines changed

.github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,7 @@ jobs:
704704
- { WIDEMUL: 'int128', RECOVERY: 'yes' }
705705
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', SCHNORRADAPTOR: 'yes' }
706706
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', SCHNORRADAPTOR: 'yes', CC: 'gcc' }
707-
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', SCHNORRADAPTOR: 'yes', WRAPPER_CMD: 'valgrind --error-exitcode=42', SECP256K1_TEST_ITERS: 2 }
707+
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', SCHNORRADAPTOR: 'yes', WRAPPER_CMD: 'valgrind --error-exitcode=42', SECP256K1_TEST_ITERS: 2 }
708708
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', SCHNORRADAPTOR: 'yes', CC: 'gcc', WRAPPER_CMD: 'valgrind --error-exitcode=42', SECP256K1_TEST_ITERS: 2 }
709709
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', SCHNORRADAPTOR: 'yes', CPPFLAGS: '-DVERIFY', CTIMETESTS: 'no' }
710710
- BUILD: 'distcheck'

ci/ci.sh

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ print_environment() {
1313
# does not rely on bash.
1414
for var in WERROR_CFLAGS MAKEFLAGS BUILD \
1515
ECMULTWINDOW ECMULTGENPRECISION ASM WIDEMUL WITH_VALGRIND EXTRAFLAGS \
16-
EXPERIMENTAL ECDH RECOVERY SCHNORRSIG SCHNORRSIG_HALFAGG ELLSWIFT \
17-
ECDSA_S2C GENERATOR RANGEPROOF WHITELIST MUSIG ECDSAADAPTOR BPPP \
16+
EXPERIMENTAL ECDH RECOVERY SCHNORRSIG SCHNORRSIG_HALFAGG SCHNORRADAPTOR \
17+
ELLSWIFT ECDSA_S2C GENERATOR RANGEPROOF WHITELIST MUSIG ECDSAADAPTOR BPPP \
1818
SECP256K1_TEST_ITERS BENCH SECP256K1_BENCH_ITERS CTIMETESTS\
1919
EXAMPLES \
2020
HOST WRAPPER_CMD \

include/secp256k1_schnorr_adaptor.h

+42-24
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ extern "C" {
6666

6767
/** A pointer to a function to deterministically generate a nonce.
6868
*
69-
* Same as secp256k1_schnorrsig_nonce function with the exception of using the
69+
* Same as `secp256k1_nonce_function_hardened` with the exception of using the
7070
* compressed 33-byte encoding for the adaptor argument.
7171
*
7272
* Returns: 1 if a nonce was successfully generated. 0 will cause signing to
@@ -96,12 +96,19 @@ typedef int (*secp256k1_nonce_function_hardened_schnorr_adaptor)(
9696
void *data
9797
);
9898

99-
/** A Schnorr Adaptor nonce generation function. */
99+
/** A modified BIP-340 nonce generation function. If a data pointer is passed, it is
100+
* assumed to be a pointer to 32 bytes of auxiliary random data as defined in BIP-340.
101+
* If the data pointer is NULL, the nonce derivation procedure uses a zeroed 32-byte
102+
* auxiliary random data. The hash will be tagged with algo after removing all
103+
* terminating null bytes.
104+
*/
100105
SECP256K1_API const secp256k1_nonce_function_hardened_schnorr_adaptor secp256k1_nonce_function_schnorr_adaptor;
101106

102-
/** Creates a Schnorr pre-signature.
103-
* TODO: this description could be improved & do we really need the
104-
* below paragraph?
107+
/** Creates a pre-signature for a given message and adaptor point.
108+
*
109+
* The pre-signature can be converted into a valid BIP-340 Schnorr signature
110+
* (using `schnorr_adaptor_adapt`) by combining it with the discrete logarithm
111+
* of the adaptor point.
105112
*
106113
* This function only signs 32-byte messages. If you have messages of a
107114
* different size (or the same size but without a context-specific tag
@@ -111,16 +118,16 @@ SECP256K1_API const secp256k1_nonce_function_hardened_schnorr_adaptor secp256k1_
111118
* signatures from being valid in multiple contexts by accident.
112119
*
113120
* Returns 1 on success, 0 on failure.
114-
* Args: ctx: pointer to a context object (not secp256k1_context_static).
115-
* Out: pre_sig65: pointer to a 65-byte array to store the serialized pre-signature.
116-
* In: msg32: the 32-byte message being signed.
117-
* keypair: pointer to an initialized keypair.
118-
* adaptor: pointer to an adaptor point encoded as a public key.
119-
* aux_rand32: pointer to arbitrary data used by the nonce generation
120-
* function (can be NULL). If it is non-NULL and
121-
* secp256k1_nonce_function_schnorr_adaptor is used, then
122-
* aux_rand32 must be a pointer to 32-byte auxiliary randomness
123-
* as per BIP-340.
121+
* Args: ctx: pointer to a context object (not secp256k1_context_static).
122+
* Out: pre_sig65: pointer to a 65-byte array to store the pre-signature.
123+
* In: msg32: the 32-byte message being signed.
124+
* keypair: pointer to an initialized keypair.
125+
* adaptor: pointer to an adaptor point encoded as a public key.
126+
* aux_rand32: pointer to arbitrary data used by the nonce generation
127+
* function (can be NULL). If it is non-NULL and
128+
* secp256k1_nonce_function_schnorr_adaptor is used, then
129+
* aux_rand32 must be a pointer to 32-byte auxiliary randomness
130+
* as per BIP-340.
124131
*/
125132
SECP256K1_API int secp256k1_schnorr_adaptor_presign(
126133
const secp256k1_context *ctx,
@@ -131,12 +138,17 @@ SECP256K1_API int secp256k1_schnorr_adaptor_presign(
131138
const unsigned char *aux_rand32
132139
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
133140

134-
/** Extract an adaptor point from the pre-signature.
141+
/** Extracts an adaptor point from the pre-signature.
142+
* TODO: Note: returning 1 doesn't neccessarily guarantee
143+
* that the extracted adaptor point is correct.
144+
* If this funtion passes, secp256k1_schnorr_adaptor_adapt called with
145+
* the secret key corresponding to public key T and presig65 outputs a
146+
* valid Schnorr signature.
135147
*
136148
* Returns 1 on success, 0 on failure.
137149
* Args: ctx: pointer to a context object.
138-
* Out: adaptor: pointer to an adaptor point.
139-
* In: pre_sig65: pointer to a 65-byte pre-signature.
150+
* Out: adaptor: pointer to store the adaptor point.
151+
* In: pre_sig65: pointer to a 65-byte pre-signature.
140152
* msg32: the 32-byte message being signed.
141153
* pubkey: pointer to the x-only public key used to
142154
* generate the `pre_sig65`
@@ -150,15 +162,19 @@ SECP256K1_API int secp256k1_schnorr_adaptor_extract(
150162
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
151163

152164
/** Creates a signature from a pre-signature and a secret adaptor.
165+
*
166+
* TODO: Note: returning 1 doesn't neccessarily guarantee
167+
* that the extracted adaptor point is correct.
153168
*
154169
* If the sec_adaptor32 argument is incorrect, the output signature will be
155170
* invalid. This function does not verify the signature.
156171
*
157172
* Returns 1 on success, 0 on failure.
158173
* Args: ctx: pointer to a context object.
159-
* Out: sig64: 64-byte signature. This pointer may point to the same
160-
* memory area as `pre_sig65`.
161-
* In: pre_sig65: 65-byte pre-signature
174+
* Out: sig64: pointer to a 64-byte array to store the adapted
175+
* pre-signature. This pointer may point to the same
176+
* memory area as `pre_sig65`.
177+
* In: pre_sig65: 65-byte pre-signature corresponding to `sec_adaptor32`.
162178
* sec_adaptor32: pointer to a 32-byte secret adaptor.
163179
*/
164180
SECP256K1_API int secp256k1_schnorr_adaptor_adapt(
@@ -171,12 +187,14 @@ SECP256K1_API int secp256k1_schnorr_adaptor_adapt(
171187
/** Extracts a secret adaptor from a pre-signature and the corresponding
172188
* signature.
173189
*
190+
* TODO: Note: returning 1 doesn't neccessarily guarantee
191+
* that the extracted adaptor point is correct.
192+
*
174193
* Returns 1 on success, 0 on failure.
175194
* Args: ctx: pointer to a context object.
176-
* Out: sec_adaptor32: 32-byte secret adaptor.
195+
* Out: sec_adaptor32: pointer to a 32-byte array to store the secret adaptor.
177196
* In: pre_sig65: the pre-signature corresponding to `sig64`
178-
* sig64: complete, valid 64-byte signature.
179-
* TODO: swap the presig and sig arg order
197+
* sig64: complete, valid 64-byte BIP-340 Schnorr signature.
180198
*/
181199
SECP256K1_API int secp256k1_schnorr_adaptor_extract_sec(
182200
const secp256k1_context *ctx,

src/modules/schnorr_adaptor/main_impl.h

+24-11
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ static int secp256k1_schnorr_adaptor_presign_internal(const secp256k1_context *c
112112
unsigned char seckey[32];
113113
unsigned char adaptor_buff[33];
114114
size_t cmprssd_len = 33; /* for serializing `adaptor_ge` and `pre_sig65` */
115+
int serialize_ret = 0;
115116
int ret = 1;
116117

117118
VERIFY_CHECK(ctx != NULL);
@@ -125,6 +126,11 @@ static int secp256k1_schnorr_adaptor_presign_internal(const secp256k1_context *c
125126
noncefp = secp256k1_nonce_function_schnorr_adaptor;
126127
}
127128

129+
/* T := adaptor_ge */
130+
if(!secp256k1_pubkey_load(ctx, &adaptor_ge, adaptor)){
131+
return 0;
132+
}
133+
128134
ret &= secp256k1_keypair_load(ctx, &sk, &pk, keypair);
129135
/* Because we are signing for a x-only pubkey, the secret key is negated
130136
* before signing if the point corresponding to the secret key does not
@@ -136,9 +142,8 @@ static int secp256k1_schnorr_adaptor_presign_internal(const secp256k1_context *c
136142
/* Generate the nonce k */
137143
secp256k1_scalar_get_b32(seckey, &sk);
138144
secp256k1_fe_get_b32(pk_buf, &pk.x);
139-
/* T := adaptor_ge */
140-
ret &= secp256k1_pubkey_load(ctx, &adaptor_ge, adaptor);
141-
ret &= secp256k1_eckey_pubkey_serialize(&adaptor_ge, adaptor_buff, &cmprssd_len, 1);
145+
serialize_ret = secp256k1_eckey_pubkey_serialize(&adaptor_ge, adaptor_buff, &cmprssd_len, 1);
146+
VERIFY_CHECK(serialize_ret);
142147
ret &= !!noncefp(nonce32, msg32, seckey, adaptor_buff, pk_buf, schnorr_adaptor_algo, sizeof(schnorr_adaptor_algo), ndata);
143148
secp256k1_scalar_set_b32(&k, nonce32, NULL);
144149
ret &= !secp256k1_scalar_is_zero(&k);
@@ -176,7 +181,10 @@ static int secp256k1_schnorr_adaptor_presign_internal(const secp256k1_context *c
176181
if (secp256k1_fe_is_odd(&rp.y)) {
177182
secp256k1_scalar_negate(&k, &k);
178183
}
179-
ret &= secp256k1_eckey_pubkey_serialize(&rp, pre_sig65, &cmprssd_len, 1);
184+
serialize_ret = secp256k1_eckey_pubkey_serialize(&rp, pre_sig65, &cmprssd_len, 1);
185+
/* R' is not the point at infinity with overwhelming probability */
186+
VERIFY_CHECK(serialize_ret);
187+
(void) serialize_ret;
180188

181189
secp256k1_schnorrsig_challenge(&e, &pre_sig65[1], msg32, 32, pk_buf);
182190
secp256k1_scalar_mul(&e, &e, &sk);
@@ -273,9 +281,11 @@ int secp256k1_schnorr_adaptor_adapt(const secp256k1_context *ctx, unsigned char
273281
VERIFY_CHECK(ctx != NULL);
274282
ARG_CHECK(sig64 != NULL);
275283
ARG_CHECK(pre_sig65 != NULL);
276-
ARG_CHECK(pre_sig65[0] == SECP256K1_TAG_PUBKEY_EVEN || pre_sig65[0] == SECP256K1_TAG_PUBKEY_ODD);
277284
ARG_CHECK(sec_adaptor32 != NULL);
278285

286+
if (pre_sig65[0] != SECP256K1_TAG_PUBKEY_EVEN && pre_sig65[0] != SECP256K1_TAG_PUBKEY_ODD) {
287+
return 0;
288+
}
279289
secp256k1_scalar_set_b32(&s, &pre_sig65[33], &overflow);
280290
if (overflow) {
281291
return 0;
@@ -300,10 +310,11 @@ int secp256k1_schnorr_adaptor_adapt(const secp256k1_context *ctx, unsigned char
300310
if (pre_sig65[0] == SECP256K1_TAG_PUBKEY_ODD) {
301311
secp256k1_scalar_negate(&t, &t);
302312
}
303-
304313
secp256k1_scalar_add(&s, &s, &t);
305314
secp256k1_scalar_get_b32(&sig64[32], &s);
306315
memmove(sig64, &pre_sig65[1], 32);
316+
317+
secp256k1_memczero(sig64, 64, !ret);
307318
secp256k1_scalar_clear(&t);
308319
return ret;
309320
}
@@ -317,16 +328,17 @@ int secp256k1_schnorr_adaptor_extract_sec(const secp256k1_context *ctx, unsigned
317328
VERIFY_CHECK(ctx != NULL);
318329
ARG_CHECK(sec_adaptor32 != NULL);
319330
ARG_CHECK(pre_sig65 != NULL);
320-
ARG_CHECK(pre_sig65[0] == SECP256K1_TAG_PUBKEY_EVEN || pre_sig65[0] == SECP256K1_TAG_PUBKEY_ODD);
321331
ARG_CHECK(sig64 != NULL);
322332

323-
secp256k1_scalar_set_b32(&t, &sig64[32], &overflow);
324-
ret &= !overflow;
325-
333+
if (pre_sig65[0] != SECP256K1_TAG_PUBKEY_EVEN && pre_sig65[0] != SECP256K1_TAG_PUBKEY_ODD) {
334+
return 0;
335+
}
326336
secp256k1_scalar_set_b32(&s, &pre_sig65[33], &overflow);
327337
if (overflow) {
328338
return 0;
329339
}
340+
secp256k1_scalar_set_b32(&t, &sig64[32], &overflow);
341+
ret &= !overflow;
330342

331343
/*TODO: should we parse presig[0:33] & sig[0:32], to make sure the presig &
332344
* has valid public nonce point?
@@ -348,8 +360,9 @@ int secp256k1_schnorr_adaptor_extract_sec(const secp256k1_context *ctx, unsigned
348360
if (pre_sig65[0] == SECP256K1_TAG_PUBKEY_ODD) {
349361
secp256k1_scalar_negate(&t, &t);
350362
}
351-
352363
secp256k1_scalar_get_b32(sec_adaptor32, &t);
364+
365+
secp256k1_memczero(sec_adaptor32, 32, !ret);
353366
secp256k1_scalar_clear(&t);
354367
return ret;
355368
}

src/modules/schnorr_adaptor/tests_impl.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -151,16 +151,16 @@ static void test_schnorr_adaptor_api(void) {
151151
CHECK(secp256k1_schnorr_adaptor_adapt(CTX, sig, pre_sig, sec_adaptor) == 1);
152152
CHECK_ILLEGAL(CTX, secp256k1_schnorr_adaptor_adapt(CTX, NULL, pre_sig, sec_adaptor));
153153
CHECK_ILLEGAL(CTX, secp256k1_schnorr_adaptor_adapt(CTX, sig, NULL, sec_adaptor));
154-
/* invokes the ARG_CHECK on pre_sig[0] */
155-
CHECK_ILLEGAL(CTX, secp256k1_schnorr_adaptor_adapt(CTX, sig, invalid_pre_sig, sec_adaptor));
154+
/* invalid pre_sig[0] byte */
155+
CHECK(secp256k1_schnorr_adaptor_adapt(CTX, sig, invalid_pre_sig, sec_adaptor) == 0);
156156
CHECK_ILLEGAL(CTX, secp256k1_schnorr_adaptor_adapt(CTX, sig, pre_sig, NULL));
157157

158158
CHECK(secp256k1_schnorr_adaptor_adapt(CTX, sig, pre_sig, sec_adaptor) == 1);
159159
CHECK(secp256k1_schnorr_adaptor_extract_sec(CTX, extracted_sec_adaptor, pre_sig, sig) == 1);
160160
CHECK_ILLEGAL(CTX, secp256k1_schnorr_adaptor_extract_sec(CTX, NULL, pre_sig, sig));
161161
CHECK_ILLEGAL(CTX, secp256k1_schnorr_adaptor_extract_sec(CTX, extracted_sec_adaptor, NULL, sig));
162-
/* invokes the ARG_CHECK on pre_sig[0] */
163-
CHECK_ILLEGAL(CTX, secp256k1_schnorr_adaptor_extract_sec(CTX, extracted_sec_adaptor, invalid_pre_sig, sig));
162+
/* invalid pre_sig[0] byte */
163+
CHECK(secp256k1_schnorr_adaptor_extract_sec(CTX, extracted_sec_adaptor, invalid_pre_sig, sig) == 0);
164164
CHECK_ILLEGAL(CTX, secp256k1_schnorr_adaptor_extract_sec(CTX, extracted_sec_adaptor, pre_sig, NULL));
165165
}
166166

0 commit comments

Comments
 (0)