Features

A closer look at the handshake, the verification checks, and the tools built around them.


The Handshake — Step by Step

The IRLid handshake is a three-step protocol that produces a cryptographic receipt in about ten seconds. Each step diagram below shows what happens on each phone and what data is exchanged.

1

Show Your HELLO QR

Step 1: Person A displays a signed HELLO QR code on their phone

Person A (the Initiator) opens IRLid on their phone. The app automatically generates a signed HELLO QR code and displays it full-screen. This QR encodes a compact JSON payload containing the device's ECDSA P-256 public key, the current GPS coordinates (rounded to ~1.1m precision), a Unix timestamp, and a random nonce.

The entire payload is signed with the device's private key, which means the QR itself is a self-contained cryptographic assertion: "I am the holder of this key, and I was at this location at this time."

What's in the HELLO: Public key (compact JWK) · GPS latitude & longitude (5 decimal places) · accuracy estimate · Unix timestamp · random nonce · ECDSA signature over the above

2

Scan & Accept

Step 2: Person B scans the HELLO QR and their phone shows an Accept QR

Person B (the Collaborator) scans A's QR code using their phone's standard camera — no app switch needed. The QR links to the IRLid Accept page, which decodes A's HELLO, verifies the signature and timestamp, then creates a signed response.

The response is cryptographically bound to A's specific HELLO via a SHA-256 hash. This binding is critical: it means B's response cannot be replayed against a different HELLO from a different person or time. B's phone displays the Accept QR and waits.

What's in the Accept response: SHA-256 hash of A's HELLO · offer hash (binding to A's signed offer) · B's GPS coordinates · B's timestamp · B's nonce · B's public key · B's ECDSA signature over the above

3

Verify & Receipt

Step 3: Person A scans the Accept QR, the combined receipt is created and verified

Person A opens the Scan page and points their camera at B's Accept QR. The app decodes B's response and runs a full verification suite: it checks B's signature, confirms the HELLO binding hash matches, validates that both timestamps are within 90 seconds of each other, and measures the GPS distance between both devices (must be within 12 metres).

If all checks pass, the two signed payloads are combined into a single receipt object. This receipt is uploaded to the IRLid server and becomes available to both parties. Anyone with the receipt hash can independently re-run every cryptographic check on the Check page.

What's in the receipt: The full HELLO object (A's signed offer) · A's signed response · B's signed response · tolerance config (12m distance, 90s time) · version marker

Verification Checks

Each receipt is scored against a series of independent checks. The receipt page and Check page display a percentage bar that reflects how many checks passed. Here is the full breakdown:


Platform Features

📱

No App Required

IRLid runs entirely in the browser. No download, no install, no app store. Works on any phone with a camera and a modern browser.

🔑

Device Key Pairs

Each browser generates a unique ECDSA P-256 key pair using the Web Crypto API. The private key never leaves the device — it's stored in localStorage and used only for signing.

🔗

Google Account Linking

Optionally link a Google account to attach your name and profile picture to receipts. Multiple devices can be linked to one account via a 6-digit code.

📋

Receipt History

All your receipts are stored server-side and accessible from your account page. Receipts are visible to both parties — if your key was involved, the receipt appears in your list.

🔍

Third-Party Verification

Anyone can verify a receipt on the Check page by pasting a receipt hash or URL. All cryptographic checks run in the browser — no login required, no trust in the server needed.

📦

Compressed QR Codes

Payloads are deflate-compressed before encoding into QR codes. This keeps QR codes scannable even with the full cryptographic data (public keys, signatures, GPS, timestamps).

🔒

Passkey Support

WebAuthn passkey authentication is available for device-local login, providing biometric-gated access without sending credentials to a server.

🌐

Open Source

The full codebase — frontend, Cloudflare Worker backend, D1 database schema — is on GitHub. Audit the crypto, run your own instance, or contribute.


Security Model

IRLid's security comes from layering independent constraints. A valid receipt requires correct ECDSA signatures from two distinct key pairs, hash bindings that chain the responses to a specific HELLO, timestamps within a tight window, and GPS proximity. An attacker would need to simultaneously control two devices at the same time and location while also possessing the private keys — which is equivalent to actually being there.

The server never sees private keys. It stores only the combined receipt JSON (which contains only public keys and signed data) and optional profile information. The server performs its own verification at upload time, but this is a convenience check — the receipt is self-verifying and can be validated by anyone with the raw JSON.

See it in action — the handshake takes about ten seconds.

Try IRLid