Phone + PIN Encryption Architecture
Date: January 31, 2026
Status: 📋 Proposed
Related: ZERO_KNOWLEDGE_ENCRYPTION.md
Overview
This document describes a Phone + PIN authentication and encryption system that maintains zero-knowledge privacy while providing a better mobile user experience than the current passphrase-based approach.
Why Phone + PIN?
| Current (Passphrase) | Proposed (Phone + PIN) |
|---|---|
| Long passphrase to remember | 6-digit PIN |
| Easy to forget | Easy to remember |
| Harder to type on mobile | Quick entry |
| No identity verification | Phone verification via SMS |
| Single recovery path | Multiple recovery paths |
Privacy guarantee remains the same: Lantern still cannot decrypt user data.
Architecture
Key Derivation
Phone Number + PIN + Server Salt → PBKDF2(600,000 iterations) → AES-256 Key| Component | Purpose | Stored Where |
|---|---|---|
| Phone Number | Identity verification + key input | Firebase Auth + Firestore |
| PIN | Secret key input | NEVER stored (user memory only) |
| Server Salt | Prevents rainbow table attacks | Firestore (per-user, public) |
| Derived Key | Encrypts/decrypts user data | Session memory only (cached) |
Why This Is Still Zero-Knowledge
- Phone number alone cannot derive the key — PIN is required
- PIN is never transmitted or stored — only user knows it
- Server salt is public — safe to store, useless without PIN
- Key only exists in device memory — cleared on logout
┌─────────────────────────────────────────────────────────────────────┐
│ ZERO-KNOWLEDGE PROOF │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ User enters: Phone Number + PIN │
│ │ │ │
│ ▼ ▼ │
│ Key Derivation: [phone + pin + salt] → PBKDF2 → 256-bit Key │
│ │ │
│ ▼ │
│ Encryption: PlainText + Key → AES-GCM → CipherText │
│ │ │
│ ▼ │
│ Stored in DB: CipherText + Salt (key NEVER stored) │
│ │
│ ═══════════════════════════════════════════════════════════════ │
│ What Lantern has: CipherText, Salt, Phone Number │
│ What Lantern needs: PIN (to derive key) │
│ Can Lantern decrypt? ❌ NO — we don't have the PIN │
│ │
└─────────────────────────────────────────────────────────────────────┘User Flows
Signup Flow
┌─────────────────────────────────────────────────────────────────────┐
│ SIGNUP FLOW │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Step 1: Phone Verification │
│ ───────────────────────── │
│ ┌─────────────────────────────────────────────┐ │
│ │ 📱 Enter your phone number │ │
│ │ [+1] [555-123-4567] │ │
│ │ [Send Code] │ │
│ └─────────────────────────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────────────────────┐ │
│ │ Enter 6-digit code sent to your phone │ │
│ │ [● ● ● ● ● ●] │ │
│ │ [Verify] │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ Step 2: Create PIN │
│ ───────────────────── │
│ ┌─────────────────────────────────────────────┐ │
│ │ 🔐 Create a 6-digit PIN │ │
│ │ │ │
│ │ This PIN protects your private data. │ │
│ │ We cannot recover it for you. │ │
│ │ │ │
│ │ [● ● ● ● ● ●] │ │
│ │ │ │
│ │ ⚠️ Choose something memorable but not │ │
│ │ obvious (not 123456 or your birthday) │ │
│ └─────────────────────────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────────────────────┐ │
│ │ Confirm your PIN │ │
│ │ [● ● ● ● ● ●] │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ Step 3: Enable Biometrics (Optional) │
│ ──────────────────────────────────── │
│ ┌─────────────────────────────────────────────┐ │
│ │ 👆 Enable Face ID / Fingerprint? │ │
│ │ │ │
│ │ Skip entering your PIN each time. │ │
│ │ Your PIN still protects your data. │ │
│ │ │ │
│ │ [Enable Face ID] [Maybe Later] │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ Step 4: Save Recovery Phrase │
│ ──────────────────────────── │
│ ┌─────────────────────────────────────────────┐ │
│ │ 📝 Save Your Recovery Phrase │ │
│ │ │ │
│ │ Write down these 12 words and store them │ │
│ │ somewhere safe (not on this phone): │ │
│ │ │ │
│ │ ┌─────────────────────────────────────┐ │ │
│ │ │ 1. apple 5. eagle 9. island │ │ │
│ │ │ 2. brave 6. flame 10. jungle │ │ │
│ │ │ 3. candle 7. garden 11. kindle │ │ │
│ │ │ 4. dragon 8. harbor 12. lunar │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ │ │ │
│ │ ⚠️ IMPORTANT: If you forget your PIN, │ │
│ │ this is the ONLY way to recover your │ │
│ │ account. Lantern cannot help you. │ │
│ │ │ │
│ │ [I've Written It Down] │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ ✅ Setup Complete! │
│ │
└─────────────────────────────────────────────────────────────────────┘Daily Login Flow
┌─────────────────────────────────────────────────────────────────────┐
│ DAILY LOGIN │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Option A: Biometric (if enabled) │
│ ──────────────────────────────── │
│ ┌─────────────────────────────────────────────┐ │
│ │ 🔐 Unlock Lantern │ │
│ │ │ │
│ │ [Face ID icon] │ │
│ │ │ │
│ │ Look at your phone to unlock │ │
│ │ │ │
│ │ [Use PIN Instead] │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ Option B: PIN Entry │
│ ────────────────── │
│ ┌─────────────────────────────────────────────┐ │
│ │ 🔐 Enter Your PIN │ │
│ │ │ │
│ │ [● ● ● ● ● ●] │ │
│ │ │ │
│ │ [Forgot PIN?] │ │
│ └─────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘Lost Phone Recovery
┌─────────────────────────────────────────────────────────────────────┐
│ LOST PHONE RECOVERY │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Scenario A: User REMEMBERS their PIN │
│ ──────────────────────────────────── │
│ │
│ 1. Get new phone, install Lantern │
│ 2. Tap "I have an account" │
│ 3. Enter phone number │
│ 4. Verify via SMS (new SIM or ported number) │
│ 5. Enter PIN │
│ 6. ✅ Key re-derived → Data decrypted → Account restored │
│ 7. (Optional) Re-enable Face ID / fingerprint │
│ │
│ ═══════════════════════════════════════════════════════════════ │
│ │
│ Scenario B: User FORGOT their PIN │
│ ───────────────────────────────── │
│ │
│ 1. Get new phone, install Lantern │
│ 2. Tap "I have an account" │
│ 3. Enter phone number → Verify via SMS │
│ 4. Tap "Forgot PIN" │
│ 5. Enter 12-word recovery phrase │
│ 6. ✅ Key recovered from phrase │
│ 7. Create NEW PIN │
│ 8. (Optional) Enable biometrics │
│ │
│ ═══════════════════════════════════════════════════════════════ │
│ │
│ Scenario C: User forgot PIN AND lost recovery phrase │
│ ────────────────────────────────────────────────── │
│ │
│ 1. ❌ Data is PERMANENTLY UNRECOVERABLE │
│ 2. User can create a NEW account with same phone number │
│ 3. Old encrypted data remains in database (but useless forever) │
│ │
│ Note: This is not a bug — it's the privacy guarantee. │
│ Even Lantern cannot recover this data. │
│ │
└─────────────────────────────────────────────────────────────────────┘Phone Number Change
┌─────────────────────────────────────────────────────────────────────┐
│ PHONE NUMBER CHANGE │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ From WITHIN the app (user still has access): │
│ ─────────────────────────────────────────── │
│ 1. Go to Settings → Account → Change Phone Number │
│ 2. Enter current PIN (proves ownership) │
│ 3. Enter new phone number │
│ 4. Verify new number via SMS │
│ 5. ✅ Account linked to new number │
│ 6. Re-derive key with new phone + same PIN │
│ 7. Re-encrypt data with new key │
│ │
│ ═══════════════════════════════════════════════════════════════ │
│ │
│ From OUTSIDE the app (lost phone + changed number): │
│ ────────────────────────────────────────────── │
│ 1. Install Lantern on new phone │
│ 2. Tap "I have an account with a different number" │
│ 3. Enter 12-word recovery phrase (proves ownership) │
│ 4. ✅ Key recovered from phrase │
│ 5. Enter NEW phone number → Verify via SMS │
│ 6. Create NEW PIN │
│ 7. Account migrated to new phone number │
│ │
└─────────────────────────────────────────────────────────────────────┘Recovery Phrase System
What Is It?
A BIP39 mnemonic phrase — 12 random words that encode a 128-bit entropy seed.
Example: apple brave candle dragon eagle flame garden harbor island jungle kindle lunarHow It Works
┌─────────────────────────────────────────────────────────────────────┐
│ RECOVERY PHRASE SYSTEM │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ At Signup: │
│ ────────── │
│ 1. Generate 128 bits of entropy │
│ 2. Convert to 12-word BIP39 mnemonic │
│ 3. Derive recovery key from mnemonic │
│ 4. Recovery key can regenerate the same encryption key │
│ 5. Show words to user ONCE — they write them down │
│ 6. Store hash of phrase (for verification only, not recovery) │
│ │
│ During Recovery: │
│ ──────────────── │
│ 1. User enters 12 words │
│ 2. Derive recovery key from mnemonic │
│ 3. Recovery key regenerates encryption key │
│ 4. User creates new PIN │
│ 5. Re-encrypt key material with new phone + PIN │
│ │
│ ═══════════════════════════════════════════════════════════════ │
│ │
│ What's stored: Hash of phrase (verification only) │
│ What's NOT stored: The phrase itself, the recovery key │
│ Who has the phrase: User only (written on paper) │
│ │
└─────────────────────────────────────────────────────────────────────┘Security of Recovery Phrase
| Threat | Protected? | Notes |
|---|---|---|
| Brute force | ✅ Yes | 2^128 combinations = impossible |
| Server breach | ✅ Yes | Phrase never stored |
| Shoulder surfing | ⚠️ Partial | Only shown once at signup |
| Physical theft of paper | ❌ No | User must secure the paper |
Biometric Integration
How It Works
Biometrics do not replace the PIN — they unlock the cached key.
┌─────────────────────────────────────────────────────────────────────┐
│ BIOMETRIC FLOW │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ First Login (after signup or new device): │
│ ───────────────────────────────────────── │
│ 1. User enters PIN │
│ 2. Key derived from phone + PIN + salt │
│ 3. Key cached in device secure enclave (Keychain / Keystore) │
│ 4. Biometric enrolled to unlock the cached key │
│ │
│ Subsequent Logins: │
│ ────────────────── │
│ 1. User authenticates with Face ID / fingerprint │
│ 2. Biometric unlocks cached key from secure enclave │
│ 3. ✅ Data decrypted │
│ │
│ Important: │
│ ────────── │
│ - Biometric data NEVER leaves the device │
│ - Lantern never sees fingerprint or face data │
│ - If biometric fails 5x, fallback to PIN │
│ - New device = must enter PIN again (no biometric transfer) │
│ │
└─────────────────────────────────────────────────────────────────────┘Platform Implementation
| Platform | Secure Storage | Biometric API |
|---|---|---|
| iOS | Keychain (Secure Enclave) | Face ID / Touch ID |
| Android | Keystore (TEE/StrongBox) | BiometricPrompt |
| Web (PWA) | Not available | Not available (PIN only) |
Security Analysis
What Lantern Has vs. Needs
| Data | Lantern Has? | Needed to Decrypt? |
|---|---|---|
| Phone number | ✅ Yes | ✅ Yes (as key input) |
| Salt | ✅ Yes | ✅ Yes (as key input) |
| PIN | ❌ No | ✅ Yes (secret) |
| Encrypted data | ✅ Yes | N/A (this is the output) |
| Encryption key | ❌ No | N/A (derived, not stored) |
| Recovery phrase | ❌ No | Alternative to PIN |
Result: Lantern cannot decrypt user data without the PIN.
Threat Model
| Attack Vector | Risk | Mitigation |
|---|---|---|
| SIM swap attack | 🟡 Medium | Attacker gets SMS but still needs PIN |
| Database breach | 🟢 Low | Only ciphertext + salt exposed |
| PIN brute force (online) | 🟢 Low | Rate limiting, account lockout |
| PIN brute force (offline) | 🟡 Medium | 600k PBKDF2 iterations, 6-digit = 10^6 attempts max |
| Court order / subpoena | 🟢 Low | We can't decrypt — only user has PIN |
| Malware on device | 🔴 High | Key cached in memory during session |
| Physical coercion | 🔴 High | User can be forced to reveal PIN |
| Recovery phrase theft | 🔴 High | Full account access if phrase is stolen |
PIN Strength Considerations
A 6-digit PIN has 10^6 = 1,000,000 combinations.
With 600,000 PBKDF2 iterations:
- ~0.5 seconds per attempt on modern hardware
- Full brute force: ~500,000 seconds ≈ 5.8 days
Mitigations:
- Server-side rate limiting (max 5 attempts, then lockout)
- Exponential backoff on failures
- Account lockout notification via SMS
- Optional: Require 8-digit PIN for high-security users
Implementation Checklist
Phase 1: Core Infrastructure
- [ ] Update
encryption.jsto support phone + PIN derivation - [ ] Implement PIN validation (no weak PINs like 123456)
- [ ] Add phone number normalization (E.164 format)
- [ ] Create recovery phrase generation (BIP39)
- [ ] Implement recovery phrase verification
- [ ] Add rate limiting for PIN attempts
Phase 2: User Flows
- [ ] Signup flow with phone verification
- [ ] PIN creation and confirmation screens
- [ ] Recovery phrase display and confirmation
- [ ] Daily login with PIN
- [ ] "Forgot PIN" recovery flow
- [ ] Phone number change flow
Phase 3: Biometrics (Mobile)
- [ ] iOS Keychain integration
- [ ] Android Keystore integration
- [ ] Biometric enrollment flow
- [ ] Fallback to PIN on biometric failure
- [ ] Web PWA graceful degradation (PIN only)
Phase 4: Security Hardening
- [ ] PIN attempt rate limiting
- [ ] Account lockout notifications
- [ ] Suspicious activity detection
- [ ] Security audit
User-Facing Copy
Signup Messaging
Your PIN protects your privacy.
We use your phone number to find your account, but your 6-digit PIN is what actually locks your data. We never store your PIN — not even we can see your private information.
Recovery Phrase Messaging
Write down your recovery phrase.
These 12 words are the only way to recover your account if you forget your PIN. Store them somewhere safe — not on this phone. We cannot recover your account without them.
Lost PIN Messaging
Forgot your PIN?
Enter your 12-word recovery phrase to regain access. If you've lost both your PIN and recovery phrase, your data cannot be recovered — this is how we guarantee your privacy.
Comparison: Passphrase vs. Phone + PIN
| Aspect | Passphrase (Current) | Phone + PIN (Proposed) |
|---|---|---|
| User memory load | 12+ char passphrase | 6-digit PIN |
| Typing friction | High (long, complex) | Low (6 digits) |
| Recovery options | None (lost = gone) | Recovery phrase |
| Identity verification | Email only | Phone SMS |
| Biometric unlock | Not implemented | Supported |
| Multi-device | Enter passphrase each time | PIN + biometric per device |
| Security level | 🟢 High | 🟢 High (with rate limiting) |
| Mobile UX | 😐 Okay | 😊 Good |
Open Questions
- Should we support both systems? Allow users to choose passphrase OR phone + PIN?
- PIN length? 6 digits (standard) vs. 8 digits (more secure)?
- Recovery phrase length? 12 words (standard) vs. 24 words (more secure)?
- Web PWA support? PIN only, or require mobile app for biometrics?
- Migration path? How do existing passphrase users migrate to phone + PIN?
References
- BIP39 Mnemonic Code
- OWASP Password Storage Cheat Sheet
- Apple Keychain Services
- Android Keystore
- WebAuthn (future consideration for web biometrics)
- ZERO_KNOWLEDGE_ENCRYPTION.md — current passphrase implementation