bip-0375: assign k in output index order - #2256
Open
fametrano wants to merge 1 commit into
Open
Conversation
The two sentences under "Computing the Output Scripts" ask for the codes sharing a scan key to be sorted lexicographically. The test vectors and bip-0375/validator/validate_psbt.py do not do that: the validator tracks k per scan key while walking the outputs in index order, and the vectors were generated the same way. Patching the validator to the prose fails the valid vector "two sp outputs - output 0 uses label=3 / output 1 uses label=1", whose two spend keys are in descending order; nothing else in the file changes verdict. Index order is also the cheaper rule to state. Lexicographic order needs a canonical encoding of a "code" -- the 66-byte PSBT_OUT_SP_V0_INFO, the bech32m address string, or the (scan, spend) pair are all readings of the present wording -- while output indices are already in the psbt. The invariance under output reordering that a code-based order would buy is unavailable here, because a Signer setting a missing PSBT_OUT_SCRIPT must clear the Inputs Modifiable and Outputs Modifiable flags, so the outputs cannot be reordered once the scripts exist. The second sentence, on codes sharing both keys, becomes redundant: one counter per scan key covers identical codes without a tie-break. What it did leave unsaid is added instead, since it is the part an implementer gets wrong: the counter counts the outputs of that scan key, not the output index, which the vector "three sp outputs (same scan key) / two regular outputs - k values assigned independently of output index" exercises.
This was referenced Aug 14, 2026
Member
|
@fametrano Thank you for your proposal. Can you summarize the PR description more concisely in your own words, please. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
BIP375 states one rule for assigning
kto the silent payment outputs of atransaction, and its test vectors and reference validator implement another.
This amends the prose to the rule the shipped artefacts follow.
The discrepancy
bip-0375.mediawikiL240-241 asks for the codes sharing a scan key to besorted lexicographically, with a tie-break by output index for codes sharing
both keys.
bip-0375/validator/validate_psbt.pydoes not sort: it trackskper scan key while walking
enumerate(psbt.o). The vectors were generated thesame way.
Measured with
bip-0375/test_runner.pyon Python 3.12, at60f5b33b:kby ascendingPSBT_OUT_SP_V0_INFO, ties by output indexvalid[8], "two sp outputs - output 0 uses label=3 / output 1 uses label=1"That vector's two spend keys are in descending order, so a lexicographic sort
gives
k = 0to output 1, and the scripts the file publishes are the onesindex order derives. No invalid vector changes verdict under either rule; the
two invalid vectors named after ordering do not discriminate, since in one the
spend keys are already ascending and in the other all three codes are
identical.
Why index order rather than the reverse fix
#2207 closes the same gap the
other way, by correcting the vectors and the validator to the prose. Both work.
This one is proposed because the rule is cheaper to state and to implement:
on it. "The codes" admits at least three readings — the 66-byte
PSBT_OUT_SP_V0_INFO, the bech32m address string, or the(scan, spend)pair — and the BIP names none of them. Output indices are already in the
psbt and already agreed by both parties;
reordering, is unavailable here: a Signer that sets any missing
PSBT_OUT_SCRIPTmust clear the Inputs Modifiable and Outputs Modifiableflags (L185), and a psbt carrying a script with
PSBT_GLOBAL_TX_MODIFIABLEnon-zero is invalid. The outputs cannot be reordered once the scripts exist;
BIP352 receiver scans by deriving
P_kfor k = 0, 1, 2 … and matchingagainst the transaction's outputs, so it never learns which output was
assigned which
k; and permutingkwithin a scan-key group still payseach recipient the same amount, since an output's script is derived from its
own spend key. If that is right, any deterministic rule is correct and the
choice is one of cost.
If the owners prefer #2207's direction, this should be closed in its favour —
the two are alternatives on the ordering question, and #2207's other half, the
labeled spend key in
PSBT_OUT_SP_V0_INFO, is independent of it and looksright either way.
The second sentence
Dropping it is not a loss: one counter per scan key covers codes sharing both
keys with no tie-break. What it left unsaid is added in its place, because it
is the part an implementer gets wrong — the counter counts the outputs of that
scan key, not the output index, which the vector "three sp outputs (same scan
key) / two regular outputs - k values assigned independently of output index"
exercises.
Checks
scripts/link-format-chk.sh,scripts/buildtable.pl,scripts/diffcheck.shand
typosall pass locally. The version header and the changelog entry arethe first thing to rebase if #2207 lands first.
Found while implementing BIP375 in btclib, which follows the vectors:
btclib-org/btclib#768