How It's Me Works
Deepfakes Can Fool Anyone
AI-generated voice and video are now indistinguishable from real humans. A scammer can clone your family member's voice from a few seconds of audio, call you, and ask for money. How do you know it's really them?
Traditional solutions like voice recognition or video analysis are losing the arms race against AI. We need a completely different approach—one that doesn't try to detect fakes, but instead proves authenticity.
Cryptographic Identity Verification
It's Me uses the same mathematics that secures your bank account and encrypted messages. When you set up the app, it generates a unique cryptographic identity that only you possess. When you add a contact, you establish a shared secret that only the two of you know.
During a call, both parties generate a time-based code from this shared secret. If the codes match, you know you're talking to the real person—not an AI impersonator.
Adding Contacts
Before you can verify someone, you need to establish a shared secret with them. It's Me offers multiple methods, each with different trust levels.
QR Code
🟢 In PersonScan each other's QR codes when you're physically together. The QR contains an ephemeral public key and identity fingerprint.
Bluetooth
🟢 In PersonExchange keys over encrypted Bluetooth Low Energy. Works when cameras aren't convenient—in low light, crowds, or for accessibility.
Online (Async)
🌐 OnlineShare invite and encryption codes over any channel. The invitee accepts later, and you verify with SAS codes on a voice call.
Real-time
🌐 OnlineWhen both parties are on a call, exchange happens instantly via WebSocket. Both see codes at the same time for immediate verification.
Key Exchange Protocol
When you add a contact, the following cryptographic exchange occurs:
Generate Ephemeral Keys
Both parties generate a temporary X25519 key pair for the exchange. These are used only once and discarded.
Exchange Public Keys
Public keys are exchanged via QR, Bluetooth, or online (encrypted with a shared code). Identity fingerprints are also exchanged.
Derive Shared Secret
ECDH (Elliptic Curve Diffie-Hellman) derives a shared secret from the two public keys. Both parties compute the same value independently.
Derive Verification Seed
HKDF-SHA256 derives a verification seed from the shared secret plus both fingerprints. This ensures each relationship has a unique seed.
Store Locally
The verification seed is stored in the iOS Keychain, protected by hardware encryption and optional biometric authentication.
// Simplified key derivation
let sharedSecret = ECDH(myPrivateKey, theirPublicKey)
let info = myFingerprint + theirFingerprint
let seed = HKDF-SHA256(sharedSecret, salt: "itsme-v2", info)
Time-Based Codes
Verification codes are generated using a TOTP-like algorithm with modifications for voice readability:
Time Window
The current Unix timestamp is divided into 30-second windows. Both devices use the same time (synced via NTP).
HMAC Computation
HMAC-SHA256 is computed using the verification seed and time window as inputs.
Code Extraction
The hash is converted to a NATO phonetic word (26 options) and 3 digits (000-999), giving 26,000 possible codes.
Why NATO Words?
NATO phonetic words (Alpha, Bravo, Charlie...) are designed to be unambiguous over poor audio connections. Combined with numbers, they're easy to speak aloud and verify during a phone call.
Remote Contact Addition
When you can't meet in person, online exchange allows secure contact addition with end-to-end encryption.
How It Works
Generate Codes
The inviter generates two 8-character codes: an INVITE code (room identifier) and an ENCRYPTION code (key material).
Share Codes
Codes are shared via a separate secure channel (phone call, Signal, etc.). The encryption code should never be sent through the same channel as your main conversation.
Encrypted Exchange
Both parties' identity information is encrypted with a key derived from the encryption code (HKDF → AES-256-GCM). The server only sees encrypted blobs.
SAS Verification
After exchange, both parties verify a Short Authentication String (SAS) code on a voice call to confirm no man-in-the-middle attack occurred.
Server-Blind Security
The encryption code never touches our server. Even if our server were compromised, attackers could only see encrypted data they cannot decrypt.
Device Binding
Each contact relationship includes a "device secret" that ties the identity to a specific device. If a contact gets a new phone, you'll be alerted.
| Scenario | What Happens |
|---|---|
| Normal verification | Code matches, device secret matches — all good ✓ |
| Contact changed phones | Code matches, device secret differs — warning shown ⚠️ |
| Impersonation attempt | Code doesn't match — verification fails ✗ |
If a contact legitimately changed phones, they should re-establish trust with you using in-person exchange.
Trust Levels
Different exchange methods provide different levels of trust assurance:
| Method | Badge | Trust Level | Why |
|---|---|---|---|
| QR Code (In Person) | 🟢 In Person | Highest | Physical presence confirms identity |
| Bluetooth | 🟢 In Person | Highest | ~10m range ensures proximity |
| QR Code (Screenshot) | Other | Medium | No proof of physical presence |
| Online Exchange | 🌐 Online | Medium | Relies on SAS verification |
Security Properties
- Forward secrecy: Ephemeral keys are discarded after exchange
- Replay protection: Codes change every 30 seconds
- Device binding: Detects if contact changes phones
- End-to-end encryption: Server cannot read online exchange data
- Offline capable: Verification works without internet
- No accounts: No email, no phone number, no tracking
- Local storage: Keys never leave your device
- Biometric protection: Face ID / Touch ID secures access