Bitcoin Core 32.99.0
P2P Digital Currency
Loading...
Searching...
No Matches
tests_impl.h
Go to the documentation of this file.
1/***********************************************************************
2 * Distributed under the MIT software license, see the accompanying *
3 * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
4 ***********************************************************************/
5
6#ifndef SECP256K1_MODULE_SILENTPAYMENTS_TESTS_H
7#define SECP256K1_MODULE_SILENTPAYMENTS_TESTS_H
8
9#include "../../../include/secp256k1_silentpayments.h"
10#include "../../unit_test.h"
11#include "../../util.h"
12#include "../../../src/modules/silentpayments/vectors.h"
13
25static unsigned char MALFORMED_SECKEY[32] = { 0x00 };
26static unsigned char BOB_ADDRESS[2][33] = {
27 {
28 0x02, 0x15, 0x40, 0xae, 0xa8, 0x97, 0x54, 0x7a,
29 0xd4, 0x39, 0xb4, 0xe0, 0xf6, 0x09, 0xe5, 0xf0,
30 0xfa, 0x63, 0xde, 0x89, 0xab, 0x11, 0xed, 0xe3,
31 0x1e, 0x8c, 0xde, 0x4b, 0xe2, 0x19, 0x42, 0x5f,
32 0x23
33 },
34 {
35 0x02, 0x3e, 0xff, 0xf8, 0x18, 0x51, 0x65, 0xea,
36 0x63, 0xa9, 0x92, 0xb3, 0x9f, 0x31, 0xd8, 0xfd,
37 0x8e, 0x0e, 0x64, 0xae, 0xf9, 0xd3, 0x88, 0x07,
38 0x34, 0x97, 0x37, 0x14, 0xa5, 0x3d, 0x83, 0x11,
39 0x8d
40 }
41};
42static unsigned char CAROL_ADDRESS[2][33] = {
43 {
44 0x03, 0xbb, 0xc6, 0x3f, 0x12, 0x74, 0x5d, 0x3b,
45 0x9e, 0x9d, 0x24, 0xc6, 0xcd, 0x7a, 0x1e, 0xfe,
46 0xba, 0xd0, 0xa7, 0xf4, 0x69, 0x23, 0x2f, 0xbe,
47 0xcf, 0x31, 0xfb, 0xa7, 0xb4, 0xf7, 0xdd, 0xed,
48 0xa8
49 },
50 {
51 0x03, 0x81, 0xeb, 0x9a, 0x9a, 0x9e, 0xc7, 0x39,
52 0xd5, 0x27, 0xc1, 0x63, 0x1b, 0x31, 0xb4, 0x21,
53 0x56, 0x6f, 0x5c, 0x2a, 0x47, 0xb4, 0xab, 0x5b,
54 0x1f, 0x6a, 0x68, 0x6d, 0xfb, 0x68, 0xea, 0xb7,
55 0x16
56 }
57};
58static unsigned char BOB_OUTPUT[32] = {
59 0x46, 0x0d, 0x68, 0x08, 0x65, 0x64, 0x45, 0xee,
60 0x4d, 0x4e, 0xc0, 0x8e, 0xba, 0x8a, 0x66, 0xea,
61 0x66, 0x8e, 0x4e, 0x12, 0x98, 0x9a, 0x0e, 0x60,
62 0x4b, 0x5c, 0x36, 0x0e, 0x43, 0xf5, 0x5a, 0xfa
63};
64static unsigned char CAROL_OUTPUT_ONE[32] = {
65 0x4b, 0x81, 0x34, 0x5d, 0x53, 0x89, 0xba, 0xa3,
66 0xd8, 0x93, 0xe2, 0xfb, 0xe7, 0x08, 0xdd, 0x6d,
67 0x82, 0xdc, 0xd8, 0x49, 0xab, 0x03, 0xc1, 0xdb,
68 0x68, 0xbe, 0xc7, 0xe9, 0x2a, 0x45, 0xfa, 0xc5
69};
70static unsigned char CAROL_OUTPUT_TWO[32] = {
71 0xb7, 0xf3, 0xc6, 0x79, 0x30, 0x4a, 0xef, 0x8c,
72 0xc0, 0xc7, 0x61, 0xf1, 0x00, 0x99, 0xdd, 0x7b,
73 0x20, 0x65, 0x20, 0xd7, 0x11, 0x6f, 0xb7, 0x91,
74 0xee, 0x74, 0x54, 0xa2, 0xfc, 0x22, 0x79, 0xf4
75};
76static unsigned char SMALLEST_OUTPOINT[36] = {
77 0x16, 0x9e, 0x1e, 0x83, 0xe9, 0x30, 0x85, 0x33, 0x91,
78 0xbc, 0x6f, 0x35, 0xf6, 0x05, 0xc6, 0x75, 0x4c, 0xfe,
79 0xad, 0x57, 0xcf, 0x83, 0x87, 0x63, 0x9d, 0x3b, 0x40,
80 0x96, 0xc5, 0x4f, 0x18, 0xf4, 0x00, 0x00, 0x00, 0x00
81};
82static unsigned char ALICE_SECKEY[32] = {
83 0xea, 0xdc, 0x78, 0x16, 0x5f, 0xf1, 0xf8, 0xea,
84 0x94, 0xad, 0x7c, 0xfd, 0xc5, 0x49, 0x90, 0x73,
85 0x8a, 0x4c, 0x53, 0xf6, 0xe0, 0x50, 0x7b, 0x42,
86 0x15, 0x42, 0x01, 0xb8, 0xe5, 0xdf, 0xf3, 0xb1
87};
88
89struct label_cache_entry {
90 unsigned char label[33];
91 unsigned char label_tweak[32];
92};
93struct labels_cache {
94 size_t entries_used;
95 struct label_cache_entry entries[10];
96};
98const unsigned char* label_lookup(const unsigned char* key, const void* cache_ptr) {
99 const struct labels_cache* cache;
100 size_t i;
101
102 if (cache_ptr == NULL) {
103 return NULL;
104 }
105 cache = (const struct labels_cache*)cache_ptr;
106 for (i = 0; i < cache->entries_used; i++) {
107 if (secp256k1_memcmp_var(cache->entries[i].label, key, 33) == 0) {
108 return cache->entries[i].label_tweak;
109 }
110 }
111 return NULL;
112}
113
114static void test_recipient_sort_helper(unsigned char (*sp_addresses[3])[2][33], unsigned char (*sp_outputs[3])[32]) {
115 unsigned char const *seckey_ptrs[1];
120 unsigned char xonly_ser[32];
121 size_t i;
122 int ret;
123
125 for (i = 0; i < 3; i++) {
126 CHECK(secp256k1_ec_pubkey_parse(CTX, &recipients[i].scan_pubkey, (*sp_addresses[i])[0], 33));
127 CHECK(secp256k1_ec_pubkey_parse(CTX, &recipients[i].spend_pubkey,(*sp_addresses[i])[1], 33));
128 recipients[i].index = i;
129 recipient_ptrs[i] = &recipients[i];
131 }
136 NULL, 0,
137 seckey_ptrs, 1
138 );
139 CHECK(ret == 1);
140 for (i = 0; i < 3; i++) {
143 }
144}
145
146static void test_recipient_sort(void) {
147 unsigned char (*sp_addresses[3])[2][33];
148 unsigned char (*sp_outputs[3])[32];
149
150 /* With a fixed set of addresses and a fixed set of inputs,
151 * test that we always get the same outputs, regardless of the ordering
152 * of the recipients
153 */
157
162
166
171
175
180}
181
182static void test_send_api(void) {
183 unsigned char (*sp_addresses[2])[2][33];
184 unsigned char const *p[1];
185 secp256k1_keypair const *t[1];
191 size_t i;
192
193 /* Set up Bob and Carol as the recipients */
196 for (i = 0; i < 2; i++) {
197 CHECK(secp256k1_ec_pubkey_parse(CTX, &r[i].scan_pubkey, (*sp_addresses[i])[0], 33));
198 CHECK(secp256k1_ec_pubkey_parse(CTX, &r[i].spend_pubkey,(*sp_addresses[i])[1], 33));
199 /* Set the index value incorrectly */
200 r[i].index = 0;
201 rp[i] = &r[i];
202 op[i] = &o[i];
203 }
204 /* Set up a taproot key and a plain key for Alice */
206 t[0] = &taproot;
207 p[0] = ALICE_SECKEY;
208
209 /* Fails if the index is set incorrectly */
211
212 /* Set the index correctly for the next tests */
213 for (i = 0; i < 2; i++) {
214 r[i].index = i;
215 }
217
218 /* Check that NULL in "array of pointers" arguments is not allowed */
219 for (i = 0; i < 2; i++) {
222
223 op[i] = NULL;
225 op[i] = original_ptr_xpk;
226
227 rp[i] = NULL;
229 rp[i] = original_ptr_rec;
230 }
231 {
232 secp256k1_keypair const *original_ptr = t[0];
233 t[0] = NULL;
235 t[0] = original_ptr;
236 }
237 {
238 unsigned char const *original_ptr = p[0];
239 p[0] = NULL;
241 p[0] = original_ptr;
242 }
243
244 /* Check that null arguments are handled */
250
251 /* Check correct context is used */
253
254 /* Check that array arguments are verified */
257 /* Empty key arrays can have both NULL or non-NULL as pointer value */
264
265 /* Create malformed keys for Alice by using a key that will overflow */
269 /* Malleate the keypair object so that the secret key is all zeros. We need to keep
270 * public key as is since it is loaded first and would hit an ARG_CHECK if invalid.
271 */
272 memset(&taproot.data[0], 0, 32);
273 /* Check that an invalid plain secret key is caught */
275 /* Check that an invalid keypair is caught */
277 /* Create malformed keys for Alice by using a zero'd seckey */
278 p[0] = MALFORMED_SECKEY;
280 p[0] = ALICE_SECKEY;
281 /* Check that an invalid plain secret key is caught even when it is passed alongside a valid one.
282 * With a single invalid key, the failure would also be caught by the subsequent zero-sum check,
283 * so use two keys to ensure the seckey loop itself rejects the invalid key. The invalid key is
284 * tested in both positions so that neither the first nor the last key is skipped by the check. */
285 {
286 unsigned char const *p2[2];
287 p2[0] = ALICE_SECKEY;
288 p2[1] = MALFORMED_SECKEY;
292 p2[0] = MALFORMED_SECKEY;
293 p2[1] = ALICE_SECKEY;
297 }
298 /* Create malformed recipients by setting all of the public key bytes to zero.
299 * Realistically, this would never happen since a bad public key would get caught when
300 * trying to parse the public key with _ec_pubkey_parse
301 */
302 {
304 memset(&r[1].spend_pubkey, 0, sizeof(r[1].spend_pubkey));
306 r[1].spend_pubkey = tmp;
307 }
308 {
310 int32_t ecount = 0;
311
312 memset(&r[1].scan_pubkey, 0, sizeof(r[1].scan_pubkey));
315 CHECK(ecount == 2);
317 r[1].scan_pubkey = tmp;
318 }
319 {
320 unsigned char malformed_spend_key[32] = {
321 0x83, 0xe1, 0x79, 0xdf, 0x51, 0xbb, 0xc9, 0x6f,
322 0xfb, 0x59, 0xb6, 0x2e, 0x57, 0xcf, 0x4e, 0x54,
323 0x71, 0x79, 0x04, 0x9c, 0x01, 0x47, 0x00, 0xfe,
324 0x52, 0xef, 0x5f, 0x53, 0x76, 0x39, 0xec, 0xe0
325 };
330 for (i = 0; i < 2; i++) {
331 r[i].index = i;
332 rp[i] = &r[i];
333 }
335 }
336
337 /* check that sending API respects the per-group recipient limit (K_max) */
338 {
344 size_t test_num_recipients;
345
346 for (i = 0; i < total_recipients; i++) {
347 /* use the same scan/spend pubkey for every recipient initially; the scan pubkeys
348 * will change later on for each test case to modify the group sizes, while the
349 * spend pubkeys will remain unchanged, as they are not relevant for the scenarios */
350 recipients[i].scan_pubkey = r[1].scan_pubkey;
351 recipients[i].spend_pubkey = r[1].spend_pubkey;
352 recipients[i].index = i;
353 recipients_ptrs[i] = &recipients[i];
354 outputs_ptrs[i] = &outputs[i];
355 }
356
357 /* one group with the number of recipients being just on the limit => succeeds */
361
362 /* one group with the number of recipients exceeding the limit => fails */
366
367 /* multiple groups with each being just on the limit => succeeds */
368 for (i = 0; i < total_recipients; i++) {
369 /* create recipient blocks of K_max size, each with different tweak values */
371 unsigned char tweak[32] = {0};
373 CHECK(secp256k1_ec_pubkey_tweak_add(CTX, &recipients[i].scan_pubkey, tweak) == 1);
374 }
378
379 /* multiple groups, one of them exceeding the limit => fails */
380 for (i = 0; i < total_recipients; i++) { /* restore original order first */
381 recipients_ptrs[i] = &recipients[i];
382 }
388
389 free(outputs_ptrs);
390 free(outputs);
391 free(recipients_ptrs);
392 free(recipients);
393 }
394}
395
396static void test_label_api(void) {
398 secp256k1_pubkey s, ls, e; /* spend pk, labeled spend pk, expected labeled spend pk */
399 unsigned char lt[32]; /* label tweak */
400 unsigned char label_ser[33]; /* serialized label */
401 const unsigned char expected[33] = {
402 0x03, 0xdc, 0x7f, 0x09, 0x9a, 0xbe, 0x95, 0x7a,
403 0x58, 0x43, 0xd2, 0xb6, 0xbb, 0x35, 0x79, 0x61,
404 0x5c, 0x60, 0x36, 0xa4, 0x9b, 0x86, 0xf4, 0xbe,
405 0x46, 0x38, 0x60, 0x28, 0xa8, 0x1a, 0x77, 0xd4,
406 0x91
407 };
408
409 /* Create a label and labeled spend public key, verify we get the expected result */
413 CHECK(secp256k1_ec_pubkey_parse(CTX, &e, expected, 33));
415
416 /* Check label (de)serialization round-trip */
417 {
419 unsigned char parsed_label_ser[33];
420 static const unsigned char invalid_label_ser[33] = {0};
421
426
429 }
430
431 /* Check null values are handled */
442 /* Check that creating a label with an invalid scan key fails */
445 /* Check for malformed spend public key and label, i.e., any single pubkey is malformed or the public
446 * keys are valid but sum up to zero.
447 */
448 {
450 unsigned char neg_spend_label_ser[33];
451 size_t serlen = 33;
453
457
459 /* Also test with a malformed spend public key. */
460 memset(&s, 0, sizeof(s));
462 /* Reset s back to a valid public key for the next test. */
464 memset(&l, 0, sizeof(l));
466 /* Reset l back to a valid public key for the next test */
468 memset(&s, 0, sizeof(s));
470 }
471}
472
473static void test_recipient_api(void) {
474 secp256k1_silentpayments_prevouts_summary ps; /* prevouts_summary */
475 secp256k1_silentpayments_found_output f; /* a silent payment found output */
476 secp256k1_silentpayments_found_output *fp[1]; /* array of pointers to found outputs */
477 secp256k1_xonly_pubkey t; /* taproot x-only public key */
478 secp256k1_xonly_pubkey malformed_t; /* malformed x-only public key */
479 secp256k1_xonly_pubkey const *tp[1]; /* array of pointers to xonly pks */
480 secp256k1_pubkey p; /* plain public key */
481 secp256k1_pubkey malformed_p; /* malformed public key */
482 secp256k1_pubkey const *pp[1]; /* array of pointers to plain pks */
483 uint32_t n_f; /* number of found outputs */
484
486 memset(&malformed_p, 0, sizeof(malformed_p));
487 memset(&malformed_t, 0, sizeof(malformed_t));
489 tp[0] = &t;
490 pp[0] = &p;
491 fp[0] = &f;
493 /* Reusing a prevouts_summary after a failure must not leave the old object valid. */
494 {
497
499 pp_sum_zero[0] = &p;
500 pp_sum_zero[1] = &neg_p;
504 }
505 /* Check that malformed input public keys are caught. Input public keys summing to zero is tested later,
506 * in the BIP0352 test vectors.
507 */
508 pp[0] = &malformed_p;
510 pp[0] = &p;
511 /* Check that malformed x-only input public keys are caught. */
512 tp[0] = &malformed_t;
514 tp[0] = &t;
515
516 /* Check that NULL in "array of pointers" arguments is not allowed */
517 {
519 tp[0] = NULL;
521 tp[0] = original_ptr;
522 }
523 {
524 secp256k1_pubkey const *original_ptr = pp[0];
525 pp[0] = NULL;
527 pp[0] = original_ptr;
528 }
529
530 /* Check null values are handled */
535
536 /* Empty key arrays can have both NULL or non-NULL as pointer value */
544
545 /* check the _recipient_scan_outputs cornercase where internal tweaking would fail;
546 this is the case if the recipient spend public key is P = -(create_output_tweak(shared_secret, k))*G */
547 {
548 unsigned char output_tweak[32] = {
549 0x96, 0x32, 0xb4, 0x06, 0xeb, 0x56, 0xcc, 0xb2,
550 0x0f, 0xc6, 0xe5, 0x2c, 0x41, 0xd5, 0x73, 0xb2,
551 0xae, 0xa0, 0x45, 0x07, 0x63, 0xf1, 0xf6, 0x22,
552 0xfa, 0x87, 0xc2, 0x4c, 0x7d, 0x80, 0x58, 0x62,
553 };
558 }
559 /* check the _recipients_scan_outputs cornercase where the output_tweak is the negation of the label_tweak */
560 {
561 unsigned char output_tweak[32] = {
562 0x96, 0x32, 0xb4, 0x06, 0xeb, 0x56, 0xcc, 0xb2,
563 0x0f, 0xc6, 0xe5, 0x2c, 0x41, 0xd5, 0x73, 0xb2,
564 0xae, 0xa0, 0x45, 0x07, 0x63, 0xf1, 0xf6, 0x22,
565 0xfa, 0x87, 0xc2, 0x4c, 0x7d, 0x80, 0x58, 0x62,
566 };
567 static const unsigned char zero[32] = {0};
569 secp256k1_xonly_pubkey output_xonly;
571 size_t len = 33;
572 uint32_t found;
575 output_xonly_ptrs[0] = &output_xonly;
581 found = 0;
583 CHECK(found == 1);
584 CHECK(secp256k1_memcmp_var(fp[0]->tweak, zero, 32) == 0);
585 CHECK(fp[0]->found_with_label == 1);
586 {
587 unsigned char found_label_ser[33];
590 }
591 }
592
593 n_f = 0;
598
599 /* Check that NULL in "array of pointers" arguments is not allowed */
600 {
602 fp[0] = NULL;
604 fp[0] = original_ptr;
605 }
606 {
608 tp[0] = NULL;
610 tp[0] = original_ptr;
611 }
612
621
622 /* Check that malformed secret key, public keys, and prevouts_summary arguments are handled */
625 memset(&ps, 0, sizeof(ps));
627}
628
630 static const unsigned char sender_seckey[32] = { 1 };
631 static const unsigned char scan_seckey[32] = { 2 };
632 static const unsigned char spend_seckey[32] = { 3 };
635 const unsigned char *sender_seckeys[1];
639 const secp256k1_silentpayments_recipient *recipients[1];
642 const secp256k1_xonly_pubkey *tx_outputs[2];
645 struct labels_cache cache;
646 unsigned char found_label[33];
648
650 CHECK(secp256k1_ec_pubkey_create(CTX, &scan_pubkey, scan_seckey));
656
657 memset(&cache, 0, sizeof(cache));
659 CTX, &label, cache.entries[0].label_tweak, scan_seckey, 1));
661 cache.entries_used = 1;
664
665 recipient.scan_pubkey = scan_pubkey;
667 recipient.index = 0;
668 recipients[0] = &recipient;
669 /* Produce two k = 0 outputs, with the labeled output first. */
672 CTX, generated_outputs, recipients, 1, SMALLEST_OUTPOINT, NULL, 0, sender_seckeys, 1));
676 CTX, generated_outputs, recipients, 1, SMALLEST_OUTPOINT, NULL, 0, sender_seckeys, 1));
678
679 tx_outputs[0] = &labeled_output;
680 tx_outputs[1] = &direct_output;
681 found_outputs[0] = &found_output[0];
682 found_outputs[1] = &found_output[1];
684 CTX, found_outputs, &n_found_outputs, tx_outputs, 2, scan_seckey, &prevouts_summary,
688 CHECK(found_output[0].found_with_label);
691}
692
700 static unsigned char const *seckeys[MAX_INPUTS_PER_TEST_CASE];
701 unsigned char created_output[32];
702 size_t i, j, k;
703 int match, ret;
704
705 /* Check that sender creates expected outputs */
706 j = 0; /* index to expand given recipient entries (with possible repeated entries) to full list */
707 for (i = 0; i < test->num_recipient_entries; i++) {
708 size_t c;
709 secp256k1_pubkey scan_pubkey, spend_pubkey;
712 for (c = 0; c < test->recipient_pubkeys[i].count; c++) {
713 recipients[j].scan_pubkey = scan_pubkey;
714 recipients[j].spend_pubkey = spend_pubkey;
715 recipients[j].index = j;
716 recipient_ptrs[j] = &recipients[j];
718 j++;
719 }
720 }
721 CHECK(j == test->num_outputs);
722 for (i = 0; i < test->num_plain_inputs; i++) {
723 seckeys[i] = test->plain_seckeys[i];
724 }
725 for (i = 0; i < test->num_taproot_inputs; i++) {
726 CHECK(secp256k1_keypair_create(CTX, &keypairs[i], test->taproot_seckeys[i]));
727 keypair_ptrs[i] = &keypairs[i];
728 }
729 {
730 int32_t ecount = 0;
735 test->num_outputs,
736 test->outpoint_smallest,
738 test->num_plain_inputs > 0 ? seckeys : NULL, test->num_plain_inputs
739 );
741 /* We expect exactly one ARG_CHECK if the number of input keys was 0. */
742 CHECK(ecount == ((test->num_taproot_inputs + test->num_plain_inputs) == 0));
743 }
744 /* If the expected number of recipient outputs is zero, check that the creation of outputs
745 * failed (e.g. due to input keys summing to zero) */
746 if (test->num_recipient_outputs == 0) {
747 CHECK(!ret);
748 return;
749 }
750 CHECK(ret);
751
752 match = 0;
753 for (i = 0; i < test->num_output_sets; i++) {
754 size_t n_matches = 0;
755 for (j = 0; j < test->num_outputs; j++) {
757 /* Loop over both lists to ensure tests don't fail due to different orderings of outputs */
758 for (k = 0; k < test->num_recipient_outputs; k++) {
759 if (secp256k1_memcmp_var(created_output, test->recipient_outputs[i][k], 32) == 0) {
760 n_matches++;
761 break;
762 }
763 }
764 }
765 if (n_matches == test->num_recipient_outputs) {
766 match = 1;
767 break;
768 }
769 }
770 CHECK(match);
771}
772
778 static secp256k1_pubkey const *pubkeys[MAX_INPUTS_PER_TEST_CASE];
779 static secp256k1_xonly_pubkey const *xonly_pubkeys[MAX_INPUTS_PER_TEST_CASE];
780 static secp256k1_xonly_pubkey const *tx_outputs[MAX_OUTPUTS_PER_TEST_CASE];
785 size_t i,j;
786 int ret;
787 uint32_t n_found = 0;
788 unsigned char found_output[32];
790
791
792 /* prepare the inputs */
793 for (i = 0; i < test->num_plain_inputs; i++) {
795 pubkeys[i] = &pubkeys_objs[i];
796 }
797 for (i = 0; i < test->num_taproot_inputs; i++) {
799 xonly_pubkeys[i] = &xonly_pubkeys_objs[i];
800 }
801 {
802 int32_t ecount = 0;
805 test->outpoint_smallest,
806 test->num_taproot_inputs > 0 ? xonly_pubkeys : NULL, test->num_taproot_inputs,
807 test->num_plain_inputs > 0 ? pubkeys : NULL, test->num_plain_inputs
808 );
810 /* We expect exactly one ARG_CHECK if the number of input keys was 0. */
811 CHECK(ecount == ((test->num_taproot_inputs + test->num_plain_inputs) == 0));
812 }
813 /* If we are unable to create the prevouts_summary object, e.g., the input public keys sum to
814 * zero, check that the expected number of recipient outputs for this test case is zero
815 */
816 if (!ret) {
817 CHECK(subtest->num_found_output_pubkeys == 0);
818 return;
819 }
820 /* prepare the outputs */
821 for (i = 0; i < subtest->num_to_scan_outputs; i++) {
822 CHECK(secp256k1_xonly_pubkey_parse(CTX, &tx_output_objs[i], subtest->to_scan_outputs[i]));
823 tx_outputs[i] = &tx_output_objs[i];
824 found_outputs[i] = &found_output_objs[i];
825 }
826
827 /* scan / spend pubkeys are not in the given data of the recipient part, so let's compute them */
830
831 /* create labels cache */
833 for (i = 0; i < subtest->num_labels; i++) {
834 unsigned int m = subtest->label_integers[i];
839 }
841 found_outputs, &n_found,
842 tx_outputs, subtest->num_to_scan_outputs,
843 subtest->scan_seckey,
847 );
848 if (subtest->full_check) {
849 /* compare expected and scanned outputs (including calculated seckey tweaks and signatures) */
850#ifdef ENABLE_MODULE_SCHNORRSIG
851 static unsigned char found_signatures[MAX_OUTPUTS_PER_TEST_CASE][64];
852 /* sha256("message") */
853 static unsigned char MSG32[32] = {
854 0xab,0x53,0x0a,0x13,0xe4,0x59,0x14,0x98,
855 0x2b,0x79,0xf9,0xb7,0xe3,0xfb,0xa9,0x94,
856 0xcf,0xd1,0xf3,0xfb,0x22,0xf7,0x1c,0xea,
857 0x1a,0xfb,0xf0,0x2b,0x46,0x0c,0x6d,0x1d
858 };
859 /* sha256("random auxiliary data") */
860 static unsigned char AUX32[32] = {
861 0x0b,0x3f,0xdd,0xfd,0x67,0xbf,0x76,0xae,
862 0x76,0x39,0xee,0x73,0x5b,0x70,0xff,0x15,
863 0x83,0xfd,0x92,0x48,0xc0,0x57,0xd2,0x86,
864 0x07,0xa2,0x15,0xf4,0x0b,0x0a,0x3e,0xcc
865 };
866 for (i = 0; i < n_found; i++) {
867 unsigned char full_seckey[32];
868 secp256k1_keypair keypair;
869 unsigned char signature[64];
870 memcpy(&full_seckey, subtest->spend_seckey, 32);
874 memcpy(found_signatures[i], signature, 64);
875 }
876#endif
877
878 for (i = 0; i < n_found; i++) {
879 int match = 0;
880 CHECK(secp256k1_xonly_pubkey_serialize(CTX, found_output, &found_outputs[i]->output));
881 for (j = 0; j < subtest->num_found_output_pubkeys; j++) {
882 if (secp256k1_memcmp_var(&found_output, subtest->found_output_pubkeys[j], 32) == 0) {
883 CHECK(secp256k1_memcmp_var(found_outputs[i]->tweak, subtest->found_seckey_tweaks[j], 32) == 0);
884#ifdef ENABLE_MODULE_SCHNORRSIG
885 CHECK(secp256k1_memcmp_var(found_signatures[i], subtest->found_signatures[j], 64) == 0);
886#endif
887 match = 1;
888 break;
889 }
890 }
891 CHECK(match);
892
893 if (subtest->num_labels == 0) {
894 /* if the test case doesn't involve labels, we must not have any labeled matches */
895 CHECK(!found_outputs[i]->found_with_label);
896 } else if (found_outputs[i]->found_with_label) {
897 /* if the test case involves labels and we have a labeled match, verify that the returned
898 * label is in the list of expected ones by manually checking against the label cache
899 * (note that the test vectors only contain a list of used labels, but not exactly which one
900 * of these have been applied for each individual output, so that's the best we can do) */
901 unsigned char found_label_ser[33];
902 const unsigned char *found_label_tweak;
906 }
907 }
908 }
909 CHECK(n_found == subtest->num_found_output_pubkeys);
910}
911
914 {
915 /* "BIP0352/Inputs" */
916 static const unsigned char tag[] = {'B','I','P','0','3','5','2','/','I','n','p','u','t','s'};
918 test_sha256_tag_midstate(&CTX->hash_ctx, &sha, tag, sizeof(tag));
919 }
920 {
921 /* "BIP0352/SharedSecret" */
922 static const unsigned char tag[] = {'B','I','P','0','3','5','2','/','S','h','a','r','e','d', 'S','e','c','r','e','t'};
924 test_sha256_tag_midstate(&CTX->hash_ctx, &sha, tag, sizeof(tag));
925 }
926 {
927 /* "BIP0352/Label" */
928 static const unsigned char tag[] = {'B','I','P','0','3','5','2','/','L','a','b','e','l'};
930 test_sha256_tag_midstate(&CTX->hash_ctx, &sha, tag, sizeof(tag));
931 }
932}
933
934
936 size_t i, j;
937
938 for (i = 0; i < ARRAY_SIZE(bip352_test_vectors); i++) {
939 const struct bip352_test_vector *test = &bip352_test_vectors[i];
941 for (j = 0; j < test->num_receive_subtests; j++) {
943 }
944 }
945}
946
947/* --- Test registry --- */
957
958#endif
int ret
#define CHECK(cond)
Unconditional failure on condition failure.
Definition util.h:49
static int tweak(const secp256k1_context *ctx, secp256k1_xonly_pubkey *agg_pk, secp256k1_musig_keyagg_cache *cache)
Definition musig.c:64
static SECP256K1_INLINE int secp256k1_memcmp_var(const void *s1, const void *s2, size_t n)
Semantics like memcmp.
Definition util.h:281
#define ARRAY_SIZE(arr)
Definition util.h:194
static SECP256K1_INLINE void secp256k1_write_be32(unsigned char *p, uint32_t x)
Definition util.h:436
static SECP256K1_INLINE void * checked_malloc(const secp256k1_callback *cb, size_t size)
Definition util.h:172
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_negate(const secp256k1_context *ctx, unsigned char *seckey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2)
Negates a secret key in place.
Definition secp256k1.c:650
SECP256K1_API int secp256k1_ec_pubkey_serialize(const secp256k1_context *ctx, unsigned char *output, size_t *outputlen, const secp256k1_pubkey *pubkey, unsigned int flags) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Serialize a pubkey object into a serialized byte sequence.
Definition secp256k1.c:282
SECP256K1_API int secp256k1_ec_pubkey_negate(const secp256k1_context *ctx, secp256k1_pubkey *pubkey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2)
Negates a public key in place.
Definition secp256k1.c:665
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_cmp(const secp256k1_context *ctx, const secp256k1_pubkey *pubkey1, const secp256k1_pubkey *pubkey2) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Compare two public keys using lexicographic (of compressed serialization) order.
Definition secp256k1.c:308
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(const secp256k1_context *ctx, const unsigned char *seckey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2)
Verify an elliptic curve secret key.
Definition secp256k1.c:611
SECP256K1_API void secp256k1_context_set_illegal_callback(secp256k1_context *ctx, void(*fun)(const char *message, void *data), const void *data) SECP256K1_ARG_NONNULL(1)
Set a callback function to be called when an illegal argument is passed to an API call.
Definition secp256k1.c:201
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const unsigned char *input, size_t inputlen) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Parse a variable-length public key into the pubkey object.
Definition secp256k1.c:264
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const unsigned char *seckey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Compute the public key for a secret key.
Definition secp256k1.c:632
#define SECP256K1_EC_COMPRESSED
Flag to pass to secp256k1_ec_pubkey_serialize.
Definition secp256k1.h:216
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const unsigned char *tweak32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Tweak a public key by adding tweak times the generator to it.
Definition secp256k1.c:715
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_add(const secp256k1_context *ctx, unsigned char *seckey, const unsigned char *tweak32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Tweak a secret key by adding tweak to it.
Definition secp256k1.c:692
SECP256K1_API int secp256k1_xonly_pubkey_cmp(const secp256k1_context *ctx, const secp256k1_xonly_pubkey *pk1, const secp256k1_xonly_pubkey *pk2) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Compare two x-only public keys using lexicographic order.
Definition main_impl.h:66
SECP256K1_API int secp256k1_xonly_pubkey_from_pubkey(const secp256k1_context *ctx, secp256k1_xonly_pubkey *xonly_pubkey, int *pk_parity, const secp256k1_pubkey *pubkey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4)
Converts a secp256k1_pubkey into a secp256k1_xonly_pubkey.
Definition main_impl.h:106
SECP256K1_API int secp256k1_xonly_pubkey_serialize(const secp256k1_context *ctx, unsigned char *output32, const secp256k1_xonly_pubkey *pubkey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Serialize an xonly_pubkey object into a 32-byte sequence.
Definition main_impl.h:51
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_create(const secp256k1_context *ctx, secp256k1_keypair *keypair, const unsigned char *seckey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Compute the keypair for a valid secret key.
Definition main_impl.h:203
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_parse(const secp256k1_context *ctx, secp256k1_xonly_pubkey *pubkey, const unsigned char *input32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Parse a 32-byte sequence into a xonly_pubkey object.
Definition main_impl.h:29
SECP256K1_API int secp256k1_schnorrsig_sign32(const secp256k1_context *ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, const unsigned char *aux_rand32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Create a Schnorr signature.
Definition main_impl.h:188
SECP256K1_API int secp256k1_silentpayments_recipient_label_serialize(const secp256k1_context *ctx, unsigned char *out33, const secp256k1_silentpayments_label *label) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Serialize a Silent Payments label.
Definition main_impl.h:374
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_prevouts_summary_create(const secp256k1_context *ctx, secp256k1_silentpayments_prevouts_summary *prevouts_summary, const unsigned char *outpoint_smallest36, const secp256k1_xonly_pubkey *const *xonly_pubkeys, size_t n_xonly_pubkeys, const secp256k1_pubkey *const *pubkeys, size_t n_pubkeys) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Compute Silent Payments prevouts summary from prevout public keys and transaction inputs.
Definition main_impl.h:484
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_label_parse(const secp256k1_context *ctx, secp256k1_silentpayments_label *label, const unsigned char *in33) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Parse a Silent Payments label.
Definition main_impl.h:358
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_sender_create_outputs(const secp256k1_context *ctx, secp256k1_xonly_pubkey **generated_outputs, const secp256k1_silentpayments_recipient **recipients, size_t n_recipients, const unsigned char *outpoint_smallest36, const secp256k1_keypair *const *keypairs, size_t n_keypairs, const unsigned char *const *seckeys, size_t n_seckeys) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5)
Create Silent Payments outputs for recipient(s).
Definition main_impl.h:187
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_create_labeled_spend_pubkey(const secp256k1_context *ctx, secp256k1_pubkey *labeled_spend_pubkey, const secp256k1_pubkey *unlabeled_spend_pubkey, const secp256k1_silentpayments_label *label) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Create Silent Payments labeled spend public key.
Definition main_impl.h:426
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_scan_outputs(const secp256k1_context *ctx, secp256k1_silentpayments_found_output **found_outputs, uint32_t *n_found_outputs, const secp256k1_xonly_pubkey *const *tx_outputs, size_t n_tx_outputs, const unsigned char *scan_key32, const secp256k1_silentpayments_prevouts_summary *prevouts_summary, const secp256k1_pubkey *unlabeled_spend_pubkey, secp256k1_silentpayments_label_lookup label_lookup, const void *label_context) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(8)
Scan for Silent Payments transaction outputs.
Definition main_impl.h:598
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_label_create(const secp256k1_context *ctx, secp256k1_silentpayments_label *label, unsigned char *label_tweak32, const unsigned char *scan_key32, uint32_t m) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Create Silent Payments label tweak and label.
Definition main_impl.h:389
#define SECP256K1_SILENTPAYMENTS_RECIPIENT_GROUP_LIMIT
This module provides an implementation for Silent Payments, as specified in BIP352.
static void secp256k1_silentpayments_sha256_init_sharedsecret(secp256k1_sha256 *hash)
Set hash state to the BIP340 tagged hash midstate for "BIP0352/SharedSecret".
Definition main_impl.h:110
static void secp256k1_silentpayments_sha256_init_inputs(secp256k1_sha256 *hash)
Set hash state to the BIP340 tagged hash midstate for "BIP0352/Inputs".
Definition main_impl.h:57
static void secp256k1_silentpayments_sha256_init_label(secp256k1_sha256 *hash)
Set hash state to the BIP340 tagged hash midstate for "BIP0352/Label".
Definition main_impl.h:335
static void test_recipient_sort(void)
Definition tests_impl.h:146
static void test_recipient_scan_label_precedes_direct_match(void)
Definition tests_impl.h:629
void run_silentpayments_test_vector_receive(const struct bip352_test_vector *test, const struct bip352_receive_subtest *subtest)
Definition tests_impl.h:773
static unsigned char SMALLEST_OUTPOINT[36]
Definition tests_impl.h:76
static unsigned char CAROL_ADDRESS[2][33]
Definition tests_impl.h:42
static unsigned char BOB_OUTPUT[32]
Definition tests_impl.h:58
static const struct tf_test_entry tests_silentpayments[]
Definition tests_impl.h:948
const unsigned char * label_lookup(const unsigned char *key, const void *cache_ptr)
Definition tests_impl.h:98
static unsigned char BOB_ADDRESS[2][33]
Definition tests_impl.h:26
static unsigned char ALICE_SECKEY[32]
Definition tests_impl.h:82
static void test_label_api(void)
Definition tests_impl.h:396
void run_silentpayments_test_vectors(void)
Definition tests_impl.h:935
static void test_recipient_api(void)
Definition tests_impl.h:473
static unsigned char CAROL_OUTPUT_TWO[32]
Definition tests_impl.h:70
static unsigned char MALFORMED_SECKEY[32]
Constants.
Definition tests_impl.h:25
static unsigned char CAROL_OUTPUT_ONE[32]
Definition tests_impl.h:64
void run_silentpayments_test_vector_send(const struct bip352_test_vector *test)
Definition tests_impl.h:693
static void test_send_api(void)
Definition tests_impl.h:182
static void test_recipient_sort_helper(unsigned char(*sp_addresses[3])[2][33], unsigned char(*sp_outputs[3])[32])
Definition tests_impl.h:114
static void silentpayments_sha256_tag_test(void)
Definition tests_impl.h:912
static const struct bip352_test_vector bip352_test_vectors[SECP256K1_SILENTPAYMENTS_NUMBER_TESTVECTORS]
Definition vectors.h:61
#define MAX_OUTPUTS_PER_TEST_CASE
Definition vectors.h:6
#define MAX_INPUTS_PER_TEST_CASE
Definition vectors.h:5
unsigned char scan_pubkey[33]
Definition vectors.h:13
unsigned char spend_pubkey[33]
Definition vectors.h:14
size_t num_recipient_entries
Definition vectors.h:47
struct bip352_receive_subtest receive_subtests[MAX_RECEIVE_SUBTESTS]
Definition vectors.h:56
size_t num_receive_subtests
Definition vectors.h:55
unsigned char recipient_outputs[MAX_PERMUTATIONS_PER_SENDING_TEST_CASE][MAX_OUTPUTS_PER_TEST_CASE][32]
Definition vectors.h:53
unsigned char xonly_pubkeys[MAX_INPUTS_PER_TEST_CASE][32]
Definition vectors.h:42
size_t num_plain_inputs
Definition vectors.h:37
unsigned char outpoint_smallest[36]
Definition vectors.h:43
size_t num_recipient_outputs
Definition vectors.h:52
unsigned char plain_pubkeys[MAX_INPUTS_PER_TEST_CASE][33]
Definition vectors.h:39
unsigned char plain_seckeys[MAX_INPUTS_PER_TEST_CASE][32]
Definition vectors.h:38
unsigned char taproot_seckeys[MAX_INPUTS_PER_TEST_CASE][32]
Definition vectors.h:41
size_t num_outputs
Definition vectors.h:46
size_t num_taproot_inputs
Definition vectors.h:40
struct bip352_recipient_addressdata recipient_pubkeys[MAX_RECIPIENT_ENTRIES_PER_TEST_CASE]
Definition vectors.h:48
size_t num_output_sets
Definition vectors.h:51
Labels.
unsigned char label_tweak[32]
unsigned char label[33]
struct label_cache_entry entries[5]
size_t entries_used
secp256k1_callback error_callback
Definition secp256k1.c:65
secp256k1_hash_ctx hash_ctx
Definition secp256k1.c:63
Opaque data structure that holds a keypair consisting of a secret and a public key.
Opaque data structure that holds a parsed and valid public key.
Definition secp256k1.h:62
Opaque data structure that holds a Silent Payments label.
Opaque data structure that holds Silent Payments prevouts summary data.
The data from a single recipient address.
Opaque data structure that holds a parsed and valid "x-only" public key.
Definition unit_test.h:53
static void counting_callback_fn(const char *str, void *data)
Definition tests.c:88
static void test_sha256_tag_midstate(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *sha_tagged, const unsigned char *tag, size_t taglen)
Definition tests.c:855
#define CHECK_ILLEGAL(ctx, expr)
Definition tests.c:85
static secp256k1_context * CTX
Definition tests.c:48
static secp256k1_context * STATIC_CTX
Definition tests.c:49
static const unsigned char secp256k1_group_order_bytes[32]
Definition testutil.h:24
#define CASE1(name)
Definition unit_test.h:27
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.
Definition time.h:82