Skip to content

Commit 311b4eb

Browse files
committed
track already found outputs in scanning
1 parent d26753d commit 311b4eb

File tree

1 file changed

+14
-0
lines changed

1 file changed

+14
-0
lines changed

src/modules/silentpayments/main_impl.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,7 @@ int secp256k1_silentpayments_recipient_scan_outputs(
585585
secp256k1_xonly_pubkey output_xonly;
586586
unsigned char shared_secret[33];
587587
const unsigned char *label_tweak = NULL;
588+
unsigned char *is_found = NULL;
588589
size_t i, j, k, n_found, found_idx;
589590
int found, combined, valid_scan_key, ret;
590591

@@ -624,6 +625,13 @@ int secp256k1_silentpayments_recipient_scan_outputs(
624625
/* Clear the scan_key_scalar since we no longer need it and leaking this value would break indistinguishability of the transaction. */
625626
secp256k1_scalar_clear(&scan_key_scalar);
626627

628+
/* Allocate tracking array to skip already-matched outputs */
629+
is_found = (unsigned char*)calloc(n_tx_outputs, sizeof(unsigned char));
630+
if (!is_found) {
631+
secp256k1_memclear_explicit(shared_secret, sizeof(shared_secret));
632+
return 0;
633+
}
634+
627635
found_idx = 0;
628636
n_found = 0;
629637
k = 0;
@@ -637,6 +645,7 @@ int secp256k1_silentpayments_recipient_scan_outputs(
637645
if (!secp256k1_silentpayments_create_output_tweak(&output_tweak_scalar, shared_secret, k)) {
638646
secp256k1_scalar_clear(&output_tweak_scalar);
639647
secp256k1_memclear_explicit(&shared_secret, sizeof(shared_secret));
648+
free(is_found);
640649
return 0;
641650
}
642651

@@ -647,11 +656,13 @@ int secp256k1_silentpayments_recipient_scan_outputs(
647656
/* Leaking these values would break indistinguishability of the transaction, so clear them. */
648657
secp256k1_scalar_clear(&output_tweak_scalar);
649658
secp256k1_memclear_explicit(&shared_secret, sizeof(shared_secret));
659+
free(is_found);
650660
return 0;
651661
}
652662
found = 0;
653663
secp256k1_xonly_pubkey_save(&output_xonly, &output_ge);
654664
for (j = 0; j < n_tx_outputs; j++) {
665+
if (is_found[j]) continue; /* Skip already-matched outputs */
655666
if (secp256k1_xonly_pubkey_cmp(ctx, &output_xonly, tx_outputs[j]) == 0) {
656667
label_tweak = NULL;
657668
found = 1;
@@ -711,6 +722,7 @@ int secp256k1_silentpayments_recipient_scan_outputs(
711722
}
712723
}
713724
if (found) {
725+
is_found[found_idx] = 1; /* Mark this output as matched */
714726
found_outputs[n_found]->output = *tx_outputs[found_idx];
715727
secp256k1_scalar_get_b32(found_outputs[n_found]->tweak, &output_tweak_scalar);
716728
/* Clear the output_tweak_scalar since we no longer need it and leaking this value would
@@ -747,6 +759,7 @@ int secp256k1_silentpayments_recipient_scan_outputs(
747759
if (k < UINT32_MAX) {
748760
k++;
749761
} else {
762+
free(is_found);
750763
return 0;
751764
}
752765
} else {
@@ -758,6 +771,7 @@ int secp256k1_silentpayments_recipient_scan_outputs(
758771

759772
/* Leaking the shared_secret would break indistinguishability of the transaction, so clear it. */
760773
secp256k1_memclear_explicit(shared_secret, sizeof(shared_secret));
774+
free(is_found);
761775
return 1;
762776
}
763777

0 commit comments

Comments
 (0)