Skip to content

Commit b81b158

Browse files
josibakejonasnicktheStack
committed
tests: add constant time tests
Co-authored-by: Jonas Nick <[email protected]> Co-authored-by: Sebastian Falbesoner <[email protected]>
1 parent 674fd8f commit b81b158

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

src/ctime_tests.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@
4040
#include "../include/secp256k1_ellswift.h"
4141
#endif
4242

43+
#ifdef ENABLE_MODULE_SILENTPAYMENTS
44+
#include "../include/secp256k1_silentpayments.h"
45+
#endif
46+
4347
static void run_tests(secp256k1_context *ctx, unsigned char *key);
4448

4549
int main(void) {
@@ -94,6 +98,27 @@ static void run_tests(secp256k1_context *ctx, unsigned char *key) {
9498
unsigned char ellswift[64];
9599
static const unsigned char prefix[64] = {'t', 'e', 's', 't'};
96100
#endif
101+
#ifdef ENABLE_MODULE_SILENTPAYMENTS
102+
secp256k1_xonly_pubkey generated_output;
103+
secp256k1_xonly_pubkey *generated_outputs[1];
104+
secp256k1_silentpayments_recipient recipient;
105+
const secp256k1_silentpayments_recipient *recipients[1];
106+
unsigned char outpoint_smallest[36] = { 0 };
107+
secp256k1_keypair taproot_seckey;
108+
const secp256k1_keypair *taproot_seckeys[1];
109+
const unsigned char *plain_seckeys[1];
110+
secp256k1_silentpayments_found_output *found_outputs[1];
111+
size_t n_found_outputs;
112+
const secp256k1_xonly_pubkey *tx_outputs[1];
113+
secp256k1_silentpayments_recipient_public_data public_data;
114+
unsigned char label_tweak[32] = { 0 };
115+
secp256k1_xonly_pubkey xonly_pubkey;
116+
const secp256k1_xonly_pubkey *xonly_pubkeys[1];
117+
secp256k1_pubkey plain_pubkey;
118+
const secp256k1_pubkey *plain_pubkeys[1];
119+
unsigned char public_data_ser[33] = { 0 };
120+
unsigned char shared_secret[33] = { 0 };
121+
#endif
97122

98123
for (i = 0; i < 32; i++) {
99124
msg[i] = i + 1;
@@ -263,5 +288,65 @@ static void run_tests(secp256k1_context *ctx, unsigned char *key) {
263288
CHECK(ret == 1);
264289
}
265290

291+
#endif
292+
293+
#ifdef ENABLE_MODULE_SILENTPAYMENTS
294+
SECP256K1_CHECKMEM_DEFINE(key, 32);
295+
296+
generated_outputs[0] = &generated_output;
297+
298+
/* Initialize recipient */
299+
CHECK(secp256k1_ec_pubkey_create(ctx, &recipient.scan_pubkey, key));
300+
key[31] ^= 1;
301+
CHECK(secp256k1_ec_pubkey_create(ctx, &recipient.spend_pubkey, key));
302+
key[31] ^= (1 << 1);
303+
recipient.index = 0;
304+
recipients[0] = &recipient;
305+
306+
/* Set up secret keys */
307+
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
308+
ret = secp256k1_keypair_create(ctx, &taproot_seckey, key);
309+
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
310+
CHECK(ret);
311+
key[31] ^= (1 << 2);
312+
taproot_seckeys[0] = &taproot_seckey;
313+
plain_seckeys[0] = key;
314+
315+
ret = secp256k1_silentpayments_sender_create_outputs(ctx, generated_outputs, recipients, 1, outpoint_smallest, taproot_seckeys, 1, plain_seckeys, 1);
316+
CHECK(ret == 1);
317+
318+
ret = secp256k1_silentpayments_recipient_create_label(ctx, &recipient.spend_pubkey, label_tweak, key, 0);
319+
key[31] ^= (1 << 3);
320+
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
321+
CHECK(ret == 1);
322+
323+
CHECK(secp256k1_keypair_xonly_pub(ctx, &xonly_pubkey, NULL, &taproot_seckey));
324+
SECP256K1_CHECKMEM_DEFINE(&xonly_pubkey, sizeof(xonly_pubkey));
325+
xonly_pubkeys[0] = &xonly_pubkey;
326+
ret = secp256k1_ec_pubkey_create(ctx, &plain_pubkey, plain_seckeys[0]);
327+
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
328+
CHECK(ret == 1);
329+
SECP256K1_CHECKMEM_DEFINE(&plain_pubkey, sizeof(plain_pubkey));
330+
plain_pubkeys[0] = &plain_pubkey;
331+
332+
ret = secp256k1_silentpayments_recipient_public_data_create(ctx, &public_data, outpoint_smallest, xonly_pubkeys, 1, plain_pubkeys, 1);
333+
CHECK(ret == 1);
334+
335+
tx_outputs[0] = generated_outputs[0];
336+
n_found_outputs = 1;
337+
SECP256K1_CHECKMEM_DEFINE(&recipient.spend_pubkey, sizeof(recipient.spend_pubkey));
338+
/* It is sufficient to check _recipient_scan_outputs without a label lookup function, since the shared secret is created once (which is where the constant timeness matters)
339+
* and then reused for the rest of the scanning logic.
340+
*/
341+
CHECK(secp256k1_silentpayments_recipient_scan_outputs(ctx, found_outputs, &n_found_outputs, tx_outputs, 1, key, &public_data, &recipient.spend_pubkey, NULL, NULL));
342+
/* Serialise and then deserialise the public data object before using in _recipient_create_shared_secret.
343+
* This is necessary since _recipent_created_shared_secret expects a public data object that was deserialised from
344+
* its serialised format, i.e., a compressed public key.
345+
*/
346+
CHECK(secp256k1_silentpayments_recipient_public_data_serialize(ctx, public_data_ser, &public_data));
347+
CHECK(secp256k1_silentpayments_recipient_public_data_parse(ctx, &public_data, public_data_ser));
348+
CHECK(secp256k1_silentpayments_recipient_create_shared_secret(ctx, shared_secret, key, &public_data));
349+
CHECK(secp256k1_silentpayments_recipient_create_output_pubkey(ctx, &xonly_pubkey, shared_secret, &recipient.spend_pubkey, 0));
350+
266351
#endif
267352
}

0 commit comments

Comments
 (0)