enTrail

Verification

Verify a receipt Built

A receipt is the whole point. Anyone you hand one to can check it, with no account, and without taking our word for anything.

The check

curl
curl -sS https://<your-box>/v1/verify \
  -H "content-type: application/json" \
  -d '{ "receipt": <the receipt>, "payload_hash": "<sha256 of salt + payload>" }'

The salt is in the receipt, so the hash is sha256(payload_salt || your original bytes).

The endpoint will not accept your payload, only its hash. A hosted verifier that received payloads would be a hosted copy of everyone's evidence. You hash locally and send 32 bytes.

What comes back

The answer is valid, tampered or unknown, and it always lists what it has proven beside what it has not proven. Read the second list. It is the honest part, and it does not get shorter when someone important is watching.

Typically provenTypically not
The payload hash matches the sealed bytesThat the statement inside the record was true
The chain is continuous across this recordThat the named actor personally authorised it
The batch signature is valid under a published keyAnything outside the coverage window it reports
The head is published, and anchored once Bitcoin confirmsAn anchor that has not landed yet, which it says plainly

Without running our code at all

You can verify with openssl and nothing else. The signing key is published at a URL the box cannot rewrite, so no enTrail software has to be trusted, or even present. The cryptography is standard throughout: SHA-256, Ed25519, RFC 8785 canonical JSON, and the RFC 6962 Merkle tree, with golden test vectors published so an independent implementation can prove itself correct.

Proofs beyond one record

Anchoring takes time, on purpose

A head is offered to the OpenTimestamps calendars after an hour and anchored once Bitcoin confirms. So a receipt fetched minutes after sealing correctly says it is not anchored yet, and later says otherwise with no action from you. Every record is anchored eventually, and the receipt always says which state it is in.

The wait is what makes the time bound worth anything. An anchor gives a Bitcoin block rather than a wall-clock time, so the honest sentence is that this head existed no later than that block.

If verification fails

A tampered answer names what did not match. The usual cause is not an attack: it is bytes that changed on the way to the hash, such as a payload re-serialised by a client library before you hashed it. Hash exactly the bytes you sent. If they genuinely differ from what was sealed, that is what the product is for.

unknown means the receipt refers to something this endpoint cannot see, usually a different box or a record outside the coverage window it reports.

The limits of all of this are set out on the trust model, and we would rather you read it before you rely on anything here.