Docs · Verification
Verify your build.
Every QERYX binary should be provable, byte for byte, against the source it claims. This is the path, and it opens with v1.0.0.
Read the release manifest
Every release is described by one signed document: the hash of
every artifact on every channel, the source commit it was built
from, and its anchor in the transparency log. The manifest is
signed with ML-DSA-87 under FIPS 204 §5.2 framing —
0x00 || len(ctx) || ctx || M. The manifest carries the schema QERYX-RELEASE-MANIFEST-v1; its signing context is registered in the label catalog at release.
{
"schema": "QERYX-RELEASE-MANIFEST-v1",
"release_tag": "v1.0.0",
"repo_head": "<git sha1>",
"artifacts": [
{
"platform": "android",
"channel": "direct",
"filename": "qeryx-1.0.0.apk",
"sha256": "<hex>",
"sha384": "<hex>"
}
// …one entry per platform × channel
],
"build_attestation_sha256": "<hex>",
"sbom_sha384": "<hex>",
"kts_anchor": { "seq": 0, "root_hash": "<base64>" }
}
The per-channel hash law
Every distribution channel of the same release carries the same bytes: the manifest's Android entries must share one SHA-256, and the iOS entries share one. On iOS, platform notarization re-signs the bundle, so the manifest carries the hash of what actually arrives on the device — you verify against the bytes you hold, not against a pre-signing intermediate.
Run the three checks
Three commands: verify the signature, hash your artifact, confirm the log covers the release. From the first public manifest, if all three pass, the binary you hold is the binary the manifest describes.
# 1 — verify the manifest signature (ML-DSA-87)
qeryx-attest verify \
--public release-signing.pub \
--input qeryx-release-1.0.0.json \
--signature qeryx-release-1.0.0.json.sig
# 2 — hash the artifact you hold, compare to artifacts[]
shasum -a 256 qeryx-1.0.0.apk
# 3 — confirm the manifest's anchor resolves against the published log root
curl $RELAY/api/v1/kts/root
$RELAY stands for the relay's address.
Why the third check matters
The release leaf is anchored in KTS, the same append-only log that holds identity keys — one operator ML-DSA-87 key signs every root, verified against a SHA-384 anchor compiled into the app; the 2-of-3 witness quorum starts dormant. A release published to you but hidden from the log is a release the third check will refuse; the anchor ships populated with the first public manifest.
Witness the build
A single build machine signing releases is a single machine to compromise. Q-Build-Attest is built to route every release through a witness quorum: each witness pulls the same commit, rebuilds inside the pinned container, hashes the trees byte for byte, and refuses to contribute a signature share if its bytes diverge. The first public release runs it in single-witness bootstrap under one operator; independent witnesses enroll as they are onboarded, and this page says which posture produced each manifest.
What the attestation carries
Per-witness ML-DSA-87 signatures over the canonical attestation
bytes (ctx QERYX-Q-BUILD-ATTEST-v1) plus a Schnorr threshold aggregate that verifies under one group key, which no single witness controls once more than one witness holds a share. Attestations expire after 90 days, and a persisted
sequence floor refuses rollback to an older, still-valid build.
Know where this stands
The build-attestation manifest format is in the tree (ML-DSA-87, ctx QERYX-attest-v1) and signs build outputs; the endpoint that serves it answers when a release provisions one, and the update-authenticity trust-root registry is not yet claimed.
The signing helper and the witness protocol are written in crypto-core. Public manifest URLs appear on this page when the public release channel serves them — a link ships when its artifact does, and not before.
05The verifier questions — asked before the manifest is trusted
Interrogate the manifest.
Why can't iOS builds be fully reproducible?
Platform notarization rewrites the code-signature load command and re-stamps the bundle, so a third party cannot rebuild to the exact distributed bytes. We compensate by publishing both pre- and post-signing hashes and using one notarized artifact across every channel — the gap is named, not papered over.
What stops a malicious update signed with a stolen key?
The witness quorum: one stolen key yields one signature share, and the honest witnesses cannot reproduce malicious bytes, so the threshold signature never assembles. The remaining honest gap is the trust-root registry for update authenticity — not yet claimed, per the status above.
Can I verify without any QERYX tooling?
Steps two and three, yes — any SHA-256 tool and any HTTPS client.
Step one needs an ML-DSA-87 verifier; qeryx-attest is
the reference implementation, and the manifest format is documented
so an independent one can be written against FIPS 204 alone.