Skip to content

Cross-cutting: keep-core RNG, Bitcoin/PSBT, and CI hardening #803

Description

@kwsantiago

Grab-bag of keep-core RNG, Bitcoin/PSBT and CI hardening. Most of the original list is now done; the body below is narrowed to what is actually left so the closed items are not re-verified.

Break out individual PRs as you tackle them.

Remaining

Wire the bitcoin-sighash structured payload into PSBT signing. Audited and NOT straightforward as originally worded, so read this before starting. The machinery is complete: BitcoinSighashPayload carries the PSBT, input index, sighash flag and every prevout, and verify_bitcoin_sighash reconstructs the BIP-341 taproot sighash and checks it equals the digest being signed. The generic signing path already uses it, verifying when present, with RequireStructuredPayloadHooks as the opt-in gate that makes presence mandatory.

The obvious reading, that PSBT co-signers sign a bare digest and need this binding, does not hold: contribute_psbt_signature takes a merged PSBT, so a co-signer already works from the full transaction and the binding is structural. The place a bare sighash can still leave the system is a responder reconstructing one to forward to an external NIP-46 signer, which is what psbt_session_proposal_psbt exists for, but its only callers today use it for a TOCTOU hash guard rather than forwarding.

So this item needs its intent settled first: which path is meant to carry the payload, and what a receiver is expected to verify that it cannot already derive. Adding a field to the PSBT coordination messages without that answer risks duplicating a binding that already exists on a fund-safety protocol.

EsploraChainView HTTP parse-path + regtest test. Unit tests exist for the chain view; whether they cover the HTTP parse path specifically was not confirmed.

Done

  • Re-run the RNG entropy health-check after fork/snapshot. The check re-runs on a process-identity change, which covers fork and clone, and the recheck interval bounds a snapshot resumed under the same pid.
  • Convert remaining panicking random_bytes() in infallible constructors. Closed by keep-web: fail closed instead of panicking when the RNG health check trips #918. Four production callers existed, all in keep-web: the WebSocket ticket, the approval id, the admin bearer token and a temp-file suffix. Every other occurrence in the workspace is inside a test module, where panicking is fine.
  • Right-size MAX_STRUCTURED_PAYLOAD_SIZE. Now derived from the maximum PSBT size plus headroom, and enforced on the decode path.
  • Emit PsbtAborted on descriptor_hash mismatch. The mismatch branch emits the abort event before returning the error.
  • Fix the duplicate clippy-allow that breaks CI -D warnings. keep-core is clippy-clean.

Metadata

Metadata

Assignees

No one assigned

    Labels

    p2PriorityrustPull requests that update rust codesecuritySecurity-related issues

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions