Five sealed bids, one anchor, one row revealed.
Five bidders sealed an amount each. The whole
table was committed on chain in a single transaction
(merkle-row-sealed-v1). Later, only one row was
disclosed — the other four stay HMAC-sealed under salts
the auditor never sees. Selective disclosure is the property a
plain log can’t give you.
Cheaper infrastructure can’t do all three.
Signed logs, append-only DBs, transparency logs — any of those can give you tamper-evidence. None of them can give you tamper-evidence plus a public timestamp plus selective disclosure to a counterparty who doesn’t trust you. Anchoring one Merkle root binds all five bids to a moment in BSV chain order; per-leaf salts let you reveal one bidder without unsealing any other.
- Late edits to any bid. No bidder can change a bid after the anchor — every row is folded into the Merkle root, and the root’s SHA-256 is already in a Bitcoin SV block.
- Pre-reveal copying. No bidder could have read another’s amount before the anchor — each leaf is a salted HMAC the holder keeps private.
One anchor · many items · one revealed
Selective disclosure manifest
One manifest anchor binds many items. Later, disclose only the row or artifact under review — the rest stay sealed.
-
Row 0
Sealed
- commit
- 9f3a…c1b2
- salt
- sealed
-
Row 1
Sealed
- commit
- 7b1e…d3f4
- salt
- sealed
-
Row 2
Disclosed
- commit
- 5c7d…e9a0
- salt
- f3b7…2cd1
- payload
- re-hashable by reviewer
-
Row 3
Sealed
- commit
- 2d8a…b6c7
- salt
- sealed
-
Row 4
Sealed
- commit
- 1a9f…8d2e
- salt
- sealed
Merkle root — one on-chain anchor
7d9f2e4b6a3c1d0e9b8a7c6d5e4f3a2b1c0d
Committed once on the public chain (BSV). The bundle carries the proof path; a verifier recomputes the root locally — no Satsignal account.
What gets revealed
- Only Row 2’s payload and its salt
- Only the sibling commitments on its Merkle path
- Rows 0, 1, 3, 4 stay opaque — commitments only
Why this matters
- Sealed bids & eval rows audited one line at a time
- Claims packets, contracts, change orders, photos
- Prove one record without exposing the batch
What a reviewer does
- Re-hash Row 2’s payload with its salt
- Walk the proof path to the committed root
- Confirm the root’s on-chain anchor
Privacy by design·Cryptographically anchored·Publicly verifiable
Five bids became one Merkle root.
Each bid was sealed into one leaf, the five leaves were folded into a single Merkle root, and a tiny commit doc binding that root and the leaf count was anchored on chain — one transaction, one OP_RETURN, the whole table sealed.
On-chain anchor
One transaction. One Merkle root. Five sealed leaves.
- Scheme
merkle-row-sealed-v1- Bundle ID
007dff5816814594- Commit-doc SHA-256
f3dd7420…608ef3584- Merkle root
a67956a2…ae477bf7- Leaf count
- 5
- Transaction
d623cb94…53a6c4dcc8- Anchored
- 2026-05-08 (BSV mainnet)
Public lookup, no auth
Resolve commit-doc SHA → bundle + txid.
Anyone can hit
/lookup_hash on the public lookup endpoint with
the commit-doc SHA-256 and get back the bundle id, txid, and
anchor time — no API key, no Satsignal account
required.
curl 'https://proof.satsignal.cloud/lookup_hash?sha=f3dd742039a4c287d23f735cb59833f669d1ff96dc50fab0c173a24608ef3584'Open the live lookup →
One bidder disclosed. The other four stay sealed.
To answer one auditor question (“what was bidder gamma’s amount?”) the holder publishes a single reveal payload: the row, its canonical bytes, the per-leaf salt for index 2 only, the leaf’s commitment, and the Merkle inclusion path back to the root. Nothing about rows 0, 1, 3, or 4 is exposed — not their bidders, not their amounts, not their salts.
Single-row reveal payload (JSON)
{
"version": "satsignal-merkle-row-sealed-v1",
"leaf_index": 2,
"leaf_count": 5,
"label": "row-2",
"row": { "bidder": "gamma", "bid_minor": 48 },
"row_canonical_b64": "eyJiaWRfbWlub3IiOjQ4LCJiaWRkZXIiOiJnYW1tYSJ9",
"salt_b64": "2BempkijPVIw5QHTSqw4hSh34j15Xgx4fEONhjc1tRE=",
"commitment_hex": "fe1a6ecc7e0ecfecab0335e3f18aa189d8c9cce35b7fb642148d9ae551208586",
"proof": [
{"sib": "42b18e56...0587eb", "side": "R"},
{"sib": "80119518...bce7f3", "side": "L"},
{"sib": "97912b95...182d99", "side": "R"}
],
"root_hex": "a67956a2d0ca871b665da9d99fb1ac2dc3690d9484bcac23dd09c2c5ae477bf7"
}
- Bidder gamma is checkable: re-canonicalize the row, HMAC under the supplied salt, walk the Merkle path — the result is the on-chain root.
- Bidders 0, 1, 3, 4 stay opaque: only their sibling commitments appear — salted HMACs with a 2256 salt space and no candidate set to brute-force.
Anyone can re-run the four binding checks.
Verification is fully client-side; nothing leaves the
auditor’s machine except the one
/lookup_hash call that resolves the commit-doc
SHA-256 to the on-chain transaction. Three independent
paths:
Open
/verify
and find the Sealed-row reveal card. Click
Try the live sample to auto-load this demo’s
commit doc + reveal, or drop your own pair of files. All four
binding checks (root match, row binding, leaf commitment,
Merkle path) run client-side; the on-chain commitment then
resolves via the public /lookup_hash.
Build this in your own integration.
Everything on this page was produced by a stdlib-only helper and the public anchor API — nothing to install.