Verifying a receipt

You should not have to take our word for it.

The short version. Every argument is signed with a private key the moment it's posted. The matching public key is published here. Anyone can check a receipt against it, on their own machine, forever — including after this website is gone.

What a receipt is

Three things: the exact text that was posted, the time it was signed, and a signature proving those two haven't been altered since. The signature is ordinary Ed25519 — a standard that every major programming language can check without anything special installed.

Change one character of the text and the signature stops matching. That's the whole idea.

What it proves, and what it doesn't

The public key

Served as a plain file at /receipt-key.pub. It includes the key's ID, which every receipt also names — so if the key is ever rotated, older receipts stay checkable against the key that actually signed them.

How to check one

Take any argument's receipt from /api/disputes/<id>/receipt. It gives you the exact signed bytes (payload) and the signature. Then, with Node installed:

curl -s https://amiright.app/receipt-key.pub -o key.pub
curl -s https://amiright.app/api/disputes/<id>/receipt -o receipt.json

node -e '
const c = require("crypto"), fs = require("fs");
const r = JSON.parse(fs.readFileSync("receipt.json", "utf8"));
const key = fs.readFileSync("key.pub", "utf8")
  .split("-----BEGIN")[1];
const pem = "-----BEGIN" + key;
const ok = c.verify(
  null,
  Buffer.from(r.payload, "utf8"),
  c.createPublicKey(pem),
  Buffer.from(r.signature, "base64")
);
console.log(ok ? "VALID" : "NOT VALID");
'

It prints VALID or NOT VALID. Nothing in that command talks to us except to fetch the two files, and you can keep both forever and re-run it offline whenever you like.

Checking the text matches

The payload is readable JSON containing the question and both sides exactly as signed. Compare it to what you see on the page. If someone edited the argument after posting, the receipt was re-signed and its timestamp says when the surviving version was signed — an argument can only be edited in the first 30 seconds, and never after anyone has voted on it in a way that changes the record.

If a receipt doesn't verify

Then something is wrong and we want to know. Email justin@cronkcompanies.com with the argument's link. A receipt that fails to verify is a bug or a tampering, and either way it matters more to us than it does to you.

See also: what receipts are, in plain words, Terms, Privacy.