#36395 script: clarify implicit signature-cache input requirements

ReviewabilityReviewsAgreementSize
#36395 l0rinc script: clarify implicit signature-cache input requirementsWaiting on author0Mild35 + 117 tests
  • Enforce strict input preconditions for signature-cache hashing to avoid ambiguous cache commitments
  • Catch signature-cache validation bugs earlier with expanded test coverage
  • Ready for review
  • Concept support after mutation testing showed the new tests catch bugs missed on master (fametrano)
  • Objection that signature-cache refactoring carries excessive blast radius in critical code (instagibbs)
  • Author answered the objection by defending the cleanup, awaiting further reviewer response (instagibbs)
  • Suggestion to add a test verifying domain separation between ECDSA and Schnorr salts (fametrano)
  • 35 lines added or modified outside tests
  • 117 lines added or modified in tests
  • 39 lines removed in total
  • 7 files, 9 commits
Validation#39 of 53
P3 · cleanup
  • P3 because it hardens internal hashing against potential misuse without fixing an active consensus bug
  • Reduces future maintenance hazards in consensus validation code by asserting implicit input assumptions
Reviewability: ReadyStalePaused
Agreement: StrongPositivePositive w/ caveatsNeutralMildDisputedBlockedCrickets
Reviews: current code-review ACKs, then (+stale ACKs) and -NACKs; greener = more ACKs.
Size: lines added or modified outside tests, then in tests; greener = smaller.

Goal

Clarify and assert input preconditions for signature-cache hashing across ECDSA and Schnorr verification. The change extracts the common cache-entry hashing into a deduplicated, type-constrained helper, returns cache digests by value instead of writing through output parameters, adds assertions verifying public key validity and 64-byte Schnorr signatures, and expands test coverage for cached verification.

Problem: Signature-cache hashing serializes variable-length inputs without length prefixes, relying on implicit domain rules (a valid ECDSA public-key prefix defines its length, while Schnorr keys and signatures have fixed lengths) that were not documented or asserted at public entry points. A direct caller passing unexpected inputs could introduce ambiguous cache commitments.

Evidence of importance:

  • PR description: 'Inspired by the Elements rangeproof-cache vulnerability behind the recent Liquid incident and the subsequent cache-key fix, this change clarifies an easy-to-misread hashing pattern: Write(data, size) hashes the data bytes without encoding the size.'

Scope: The diff includes test coverage additions to script and key unit tests and script fuzzing, while the production code change is a localized refactor of `src/script/sigcache.{h,cpp}`.

Risk of a mistake: high (consensus, validation). Mistakes in signature cache hashing or unexpected assertion failures in the validation path could cause nodes to crash or accept invalid blocks.

Reviewability

Paused · Waiting on author

Open objection from fametrano with no author reply for 7 days; review would repeat what has been asked.

Waiting on (from the thread read):

  • reviewer: follow-up from instagibbs on refactor objection after author reply 2026-10-02
  • author: response to fametrano's suggestion to include cross-domain salt test 2026-10-25

Agreement

Mild

objection that needs a change was answered, no reply from the objector (instagibbs: Refactoring the signature cache carries an excessive blast radius and regression risk in critical code.)

Thread notes: fametrano gave a substantive Concept ACK after mutation testing sigcache.cpp, demonstrating that the PR's tests catch five bugs missed on master, and suggested adding an additional test for ECDSA/Schnorr salt domain separation.

Objections, suggestions, and questions:

ReviewerTypeHarm, request, or questionStatusMust beAuthor repliedQuote
instagibbs (member)objection, safetyRefactoring the signature cache carries an excessive blast radius and regression risk in critical code.answered · author argues refactoring is necessary to prevent errors and make code maintainablechangedyes2026-10-01: 'concept NACKy on the refactors due to blast radius'
Status from: 2026-10-02: l0rinc: 'The refactor is the meat of this change, the original error would still be possible even if we only add tests'
instagibbs (member)suggestion, scopeSplit the test additions out into a separate pull request from the refactor.answered · author declines splitting tests without the refactoransweredyes2026-10-01: 'Will review the tests closer if split out'
Status from: 2026-10-02: l0rinc: 'the original error would still be possible even if we only add tests, and I want to make sure we learn from those mistak'
fametrano (contributor)suggestion, correctnessAdd a test that checks ECDSA and Schnorr entries differ to ensure separate salts keep the two domains apart.openansweredno2026-10-25: 'A test that builds both entries with `ComputeEntryECDSA` and `ComputeEntrySchnorr` and checks that they differ passes on this PR and fails with that change. It could go in this PR'

Support:

  • fametrano (contributor) (2026-10-01) [tested: script_tests.json]: ran the two script_tests.json rows through btclib's script interpreter and both give the expected result
  • fametrano (contributor) (Concept ACK, 2026-10-25) [both: sigcache.cpp, script_tests, txvalidationcache_tests]: The new tests catch five signature-cache bugs that the current unit tests miss

Participants:

  • fametrano (contributor, support, 2 statements 2026-10-01 to 2026-10-25): Concept ACK; tested script_tests additions and mutation-tested signature cache
  • instagibbs (member, objection, 1 statements 2026-10-01 to 2026-10-01): concept NACK on refactor due to blast radius; suggested splitting out tests

Files

143 lines under test/bench/ci.

  • src/test/script_tests.cpp +88/-9
  • src/script/sigcache.cpp +25/-10
  • src/test/key_tests.cpp +15/-11
  • src/script/sigcache.h +8/-3
  • src/test/fuzz/script_sigcache.cpp +6/-5
  • src/test/data/script_tests.json +8/-1
  • src/script/interpreter.h +2/-0

Card

The short text the ranking pass compares across PRs.

Clarifies and asserts input preconditions when hashing signature-cache keys for ECDSA and Schnorr verification. The PR addresses an implicit assumption where cache keys hash variable-length components without prepending lengths, relying on invariants that were undocumented and unasserted at entry points. Motivated by a similar cache collision issue in Elements that led to the Liquid network incident, this refactors the hashing helper, returns entries by value, adds defensive assertions, and expands test coverage. No serialized cache key formats or validation rules are changed.

Data

dossier JSON · extract JSON · model ledger, generated 2026-10-26T01:21, confidence high, input hash c2c85b91911b93db
thread read through 2026-10-25 (4 statements), head c8d6a97afb
labels: Consensus

Categories

Validation

P3 · cleanup

Clarifies input requirements and hardens signature cache hashing against ambiguous commitments. The change removes an implicit assumption hazard inspired by an Elements vulnerability, asserting preconditions and improving test coverage, but fixes no live consensus bug in existing callers.

Membership: Carries the Consensus label and modifies signature cache hashing invariants in `src/script/sigcache.{h,cpp}` and `src/script/interpreter.h`.

Factors: security/stability 1, bug 0, performance 0, user value 0, leverage 0