Skip to content

"Chunk health" reports retrievable, not authentic — no BMT or SOC verification #1

Description

@petfold

Labels: enhancement


The chunk check reports whether a chunk is retrievable, not whether the bytes returned are the bytes that address names. So a gateway serving wrong content for a valid reference reads as healthy.

Concretely, index.html fetches chunks/<hash> (~line 882) and the health pass reports reachability (~line 665). There's keccak256 in the file (~line 792), but its own comment scopes it:

Keccak-256 (Ethereum), Uint8Array -> Uint8Array(32). BigInt lanes; only used a handful of times to derive feed-update addresses.

Searching the file for BMT root computation, signature recovery, or an address comparison turns up nothing — the returned payload is never hashed and checked against the requested address, and SOC signatures are parsed (~line 950, with the nice dual-format fallback for older gateways) but not verified against the claimed owner.

Why it matters for this tool specifically

For most clients, trusting your own node is fine. A reference scanner is the exception: its job is to tell you which thing is wrong. Right now it can distinguish "chunk missing" from "chunk present," but not:

  • content served for an address that doesn't hash to it — a misbehaving or lying gateway
  • a feed update whose SOC signature doesn't recover to the owner you asked about — a forged update
  • partial corruption inside an otherwise-retrievable manifest

Those are exactly the diagnoses someone reaches for dscan to make, and "healthy" currently means something weaker than a reader would assume from the word.

What it needs

Both checks need only keccak256, which is already vendored in the file:

  1. BMT root over the payload, compared to the requested address — a chunk is 8-byte span ‖ payload; the address is the binary Merkle root over 32-byte segments of the payload zero-padded to 4096.
  2. SOC verification — derive the address from keccak256(identifier ‖ owner) and recover the signature over identifier ‖ payload-hash to confirm the owner.

Reference implementations, if useful: js/src/verify.js in swarmlite does both in ~270 lines of dependency-free JS (BMT addressing, a verifying chunk store over /chunks, SOC verification), and it's pinned to vectors generated by an independent Python implementation. It's a line-for-line port of swarmfs's bmt.py/feeds.py, so the two cross-check each other.

Given dscan is deliberately a single self-contained HTML file, I'd expect to inline the two functions rather than take a dependency — the point is the algorithms, not the packaging.

Suggested UI consequence

If this lands, the health verdict has three states rather than two: unreachable / reachable but does not verify / verified. The middle one is the interesting new signal, and it should probably be louder than a green check turning grey.

Related: solardev-xyz/swarm-kit#2 proposes consolidating the duplicated JS copies of these primitives; dscan is the most natural first consumer either way.

Caveat: I read the fetch paths, the keccak/SOC sections, and grepped for verification, rather than all 1203 lines. If an address check exists somewhere I missed, say so and I'll close this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions