TruthLens

How verification works — and why you can trust it

What we put on Midnight, what stays private, and how to confirm a verdict yourself.

Current system status
Where your verdicts are being recorded right now.
Checking sidecar…
What we put on Midnight
Only fingerprints and verdicts — never the image, never the model.

Recorded on-chain

  • media_hash — SHA-256 of your image (32 bytes)
  • score — confidence × 10000 (uint64)
  • model_id — SHA-256 of the model identifier
  • round — monotonic commit counter

Stays private

  • Your raw image bytes
  • The model weights
  • The model's intermediate outputs (logits)
  • Any metadata embedded in the image
Why the verdict can be trusted
Four cryptographic guarantees built into the Compact contract.

Image immutability

The 64-character hex hash is a SHA-256 of every byte of your image. Re-hash the same file later — even one pixel change produces a completely different hash. The verdict is bound to that exact file.

Verdict immutability

Once recordVerdict runs, the (hash, score, model_id, round) tuple is in the contract's verdicts Map. Compact's Map insert is single-write — the entry can't be edited or removed by a later call.

Model traceability

The model identifier is hashed and stored. Two verdicts for the same image under different models are distinguishable, and you can audit which model produced any given verdict.

Privacy by default

Compact treats everything as private unless explicitly disclosed. Our circuit only calls disclose() on the hash, score, and model_id — nothing else can leak.

How to verify a verdict
Two ways to confirm a TruthLens record independently.

1. In TruthLens

Hash the image (e.g. shasum -a 256 image.jpg) and paste the result on the Verify page. The contract returns whatever it has on record — or a clean "not found" if the image was never committed.

2. Directly against Midnight

Right now the sidecar is in simulator mode, so tx IDs are prefixed sim_and live only in this process — they aren't broadcast to a Midnight node. The Compact circuit, ledger Map, and round counter are real; the broadcast is the only thing missing.

When the sidecar is switched to chain mode (set MIDNIGHT_MODE=chain after running the deploy script), tx IDs become real Midnight transactions and you can look them up at:

https://explorer.testnet.midnight.network/transactions/<tx_id>

What "simulator" means here
Being upfront about what is and isn't a real Midnight transaction.

The TruthLens sidecar can run in two modes. Both execute the same Compact circuit and produce the same ledger updates — the difference is where the state lives.

Simulator (current default)

  • ✓ Real Compact circuit code runs
  • ✓ Real verdicts Map and round counter
  • ✓ Real witness → disclose privacy flow
  • ✗ tx ID is synthesized (prefixed sim_)
  • ✗ State is in-memory only (lost on restart)

Chain

  • ✓ All of the above
  • ✓ Real ZK proof generated by the proof server
  • ✓ Real transaction on the Midnight node
  • ✓ Persistent ledger via the indexer
  • ✓ Verifiable on the public Midnight explorer