Zero-trust guide

Verify it yourself
no trust in AIO required

Everything AIO asserts about a signature is reproducible math over public data. Download the evidence bundle from the verification page (it holds the signed payload, the signature, the certificate, the platform keys and the transparency proofs), then re-check each layer with standard tools.

Back to the checker

00

What gets signed

A signature covers the UTF-8 bytes of the prefix AIO-SIG-v1\n followed by the payload JSON exactly as stored. Never reformat it. The payload embeds content_sha256, the SHA-256 of the document or of the canonical action record.

01

The document was not altered

shasum -a 256 document.pdf
# must equal payload.content_sha256

02

The signer really signed it

A hybrid key is base64( ed25519 32B ‖ ml-dsa-65 1952B ) and a hybrid signature is base64( ed25519 64B ‖ ml-dsa-65 3309B ). Both halves sign the same bytes, and both must verify.

# Python 3: pip install pynacl dilithium-py
import base64, json, nacl.signing
from dilithium_py.ml_dsa import ML_DSA_65

b = json.load(open("aio-evidence-….json"))
rec = b["signature_record"]
msg = b"AIO-SIG-v1\n" + rec["payload"].encode()
pub = base64.b64decode(rec["public_key"])
sig = base64.b64decode(rec["signature"])

# classical half (raises on failure)
nacl.signing.VerifyKey(pub[:32]).verify(msg, sig[:64])
# post-quantum half (FIPS 204, empty context)
assert ML_DSA_65.verify(pub[32:], msg, sig[64:])

03

They had the authority (certificate)

The certificate is a payload signed by AIO's platform key over AIO-CERT-v1\n. Fetch the platform keys independently from POST /attestation-keys/list. Never trust the copy inside the response you are checking. Each entry names its own algorithm: platform keys are hybrid, so verify both halves exactly as in step 02. Then read authority.permissions, for example sign.shipping_documents.

Then confirm issued_at ≤ signed_at ≤ expires_at and that certificate.public_key equals the key from step 02.

04

The history cannot be rewritten (transparency log)

Every certificate issuance and revocation is an entry in an append-only RFC 6962 Merkle log. Leaf hash is SHA256(0x00 ‖ entry), node hash is SHA256(0x01 ‖ left ‖ right).

  • POST /transparency/tree-head

    The signed root of the tree. Save it: it is your baseline.

  • POST /transparency/proof/inclusion

    Recompute the path from the entry's leaf hash up to that root yourself.

  • POST /transparency/proof/consistency

    Proves today's log is an append-only extension of the head you saved earlier. If it ever fails, you hold cryptographic proof of a rewrite.

05

Even AIO cannot rewrite it (independent timestamps)

A signed tree head only stops us rewriting history if you already hold an older one. So the same root is timestamped outside the platform, in two ways that fail differently. POST /transparency/anchors returns them all, each with its kind, status and raw proof.

Timestamping authorities (kind: rfc3161) sign "this digest existed at this time". Complete the moment they are issued, and under eIDAS a qualified one carries a legal presumption of accuracy. Save the proof bytes as a .tsr file:

openssl ts -reply -in token.tsr -text | head        # what the authority asserted
openssl ts -verify -digest <root_hash-hex> \
  -in token.tsr -CAfile authority-chain.pem

Several authorities in different jurisdictions are timestamped in parallel, because any single one could in principle be compromised or coerced. A forged time needs all of them to collude.

Bitcoin (kind: opentimestamps) needs no trusted party at all: the root is committed into the chain itself. Save the bytes as anchor.ots:

pip install opentimestamps-client
ots verify anchor.ots -d <root_hash-hex>

status: confirmed means the proof already carries its Bitcoin block attestation. status: pending means the block has not confirmed yet. Run ots upgrade anchor.ots to collect it yourself.

The honest limit

One thing math cannot prove

No offline equation can prove a certificate was not revoked seconds ago: freshness always needs either an online check or a recent signed status assertion, bundled and signed over AIO-STATUS-v1\n. Archive those assertions: two contradictory ones are cryptographic proof of dishonesty.