diff --git a/CHANGELOG.md b/CHANGELOG.md index bcaf30802..ec28b4764 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4213,6 +4213,25 @@ documented at release-notes length in the first place, and are still in ### Documentation and the website +- **`psbt.silent_payments` said its `k` follows an order it does not + follow.** The module docstring described the BIP375 prose -- codes + sorted lexicographically by spend key -- and named `_ordered_sp_outputs` + as that sort, while the function is output index order and its own + docstring says so and says why: the BIP's vectors and its reference + validator are index order, and only its prose dissents. A reader had + the two halves of the file contradicting each other, and the API docs + carried the wrong one. The module docstring now describes the code and + points at the function for the discrepancy. + + `_ordered_sp_outputs` gains the correction the discrepancy itself + needed: the two invalid vectors named after ordering are refused under + either rule not because their scripts match no `k` assignment, but + because each carries one no ascending rule produces -- two values + swapped in one, three permuted in the other. It also names bips PR + 2207, which proposes settling the question the other way by correcting + the vectors and the validator to the prose; if that merges, the test + that pins index order is what fails here. + - **`dsa.Sig.parse`'s `strict` says which direction each accident goes** (issue #873). The flag stays read for its truth, which is what `bool_parameter_test.py` classifies it as and what the line diff --git a/btclib/psbt/silent_payments.py b/btclib/psbt/silent_payments.py index ccb27221a..14178b9d8 100644 --- a/btclib/psbt/silent_payments.py +++ b/btclib/psbt/silent_payments.py @@ -53,11 +53,12 @@ keys* of the eligible inputs -- which is why reading those keys is the first thing here and not an aside. -**The k of an output** is BIP375's own rule and not BIP352's ordering: the -codes sharing one scan key are sorted lexicographically by spend key, and -a subgroup sharing both keys by output index. `_ordered_sp_outputs` is -that sort, and `tests/psbt/silent_payments_test.py` says which of the -vectors pins it. +**The k of an output** is BIP375's own rule and not BIP352's ordering: it +counts per scan key, over the outputs in index order. That is what the +BIP's vectors and its reference validator do and *not* what its prose +says, which asks for the codes to be sorted lexicographically; +`_ordered_sp_outputs` is where the discrepancy is documented, and +`tests/psbt/silent_payments_test.py` says which of the vectors pins it. """ from __future__ import annotations @@ -272,10 +273,12 @@ def _ordered_sp_outputs(psbt: Psbt) -> list[tuple[int, PsbtOut]]: scan key while walking the outputs in index order -- and only the prose dissents. Index order is therefore what interoperates, and the two "output scripts" invalid vectors named after ordering are refused - under it anyway: their scripts match no assignment at all. - `tests/psbt/silent_payments_test.py` pins each of those facts, so a - later revision of the BIP that settles it the other way fails here - rather than passing quietly. + under it anyway: each carries a k assignment no ascending rule + produces, the two values swapped in one and three permuted in the + other. `tests/psbt/silent_payments_test.py` pins each of those facts, + so a revision of the BIP that settles it the other way fails here + rather than passing quietly -- which is what bips PR 2207 proposes, + correcting the vectors and the validator to match the prose. """ return [(i, o) for i, o in enumerate(psbt.outputs) if o.sp_v0_info]