secp256k1_silentpayments_check_label_batch maps a candidate index within a batch back to a tx output index via j_start + i / 2. None of the existing tests put a labeled output past the first batch, and in the first batch j_start == 0, so an incorrect mapping is indistinguishable from the correct one. For example, this mutant survives the current tests:
diff --git a/src/modules/silentpayments/main_impl.h b/src/modules/silentpayments/main_impl.h
index 0ea3ee1..533be40 100644
--- a/src/modules/silentpayments/main_impl.h
+++ b/src/modules/silentpayments/main_impl.h
@@ -589,7 +589,7 @@ static int secp256k1_silentpayments_check_label_batch(
*label_tweak = label_lookup(label33, label_context);
if (*label_tweak != NULL) {
*label_ge = label_candidates_ge[i];
- return (int)(j_start + i / 2);
+ return (int)((j_start + i) / 2);
}
}
return -1;
This PR adds test_recipient_scan_label_batch_index. It puts LABEL_BATCH_SIZE non-matching outputs before a labeled output, so the match lands in the second batch.