Docs/Mobile SDK/Concepts

On-device Verification

In short

Octet.verify checks a proof on the device, offline, with no network call. It runs the same checks as the octet-verify command-line tool and reports the same tri-state verdict.

A proof of location is verified by re-checking its signatures against the keys inside it. octet-verify does that as a standalone tool. Octet.verify (new in 2.0) does the same work in-process, so an app can check a proof it just produced, or one it received, without a round trip.

What it runs

Octet.verify runs ECDSA P-256 stage-signature verification, plus the structural, binding, freshness, region, and wire-format self-consistency checks. These checks catch a tampered field, an edited region, a stale proof, or a forged signature, all offline. When the proof's attestation can be anchored, it also checks the device attestation against the bundled Apple and Google roots, so the proof is hardware-attested. Android proofs carry their own key-attestation chain. For an iOS proof that carries only an assertion, pass attestationBundle.

Two properties need state that a single proof does not carry, so on the device they always report NOT-CHECKED:

  • Cross-proof replay-uniqueness. The Octet proofs backend enforces nullifier uniqueness when a proof is uploaded. octet-verify --nullifier-store <file> adds a local seen-before check across your own runs.
  • Revocation. The Octet backend checks Google's keybox-revocation list. Neither Octet.verify nor octet-verify consults a revocation list.

Octet.verify is the fast local gate.

The verdict

Octet.verify returns a ProofVerification with a tri-state verdict and two booleans:

Field Meaning
verdict valid, invalid, or inconclusive.
isValid No check is FAIL. NOT-CHECKED and WARN never reject.
isAuthentic isValid and stage-signatures is PASS. A NOT-CHECKED signature check does not count.

The rules match octet-verify. A check that could not run is reported as NOT-CHECKED, and NOT-CHECKED never makes a proof authentic.

  • verdict is invalid if any check is FAIL.
  • Otherwise valid if the proof is authentic.
  • Otherwise inconclusive: the structure passed but the signatures were not verified (for example, an iOS proof with no embedded certificate and no attestation bundle supplied).

Read isAuthentic (or verdict == valid) when you need the cryptographic guarantee. Reading isValid alone accepts an inconclusive proof.

Relationship to octet-verify

Octet.verify and octet-verify share one check recipe and one verdict model, so a proof gets the same verdict in both. Use the on-device call for an immediate local gate on the phone. Use octet-verify off-device for an audit trail independent of the app, for hardware-attestation validation (appattest build), or for a local replay check with --nullifier-store.

Where to go next

TermsPrivacy© 2026 Understone, Inc. d/b/a Octet