Skip to content

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 remember6-digit PIN
Easy to forgetEasy to remember
Harder to type on mobileQuick entry
No identity verificationPhone verification via SMS
Single recovery pathMultiple 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
ComponentPurposeStored Where
Phone NumberIdentity verification + key inputFirebase Auth + Firestore
PINSecret key inputNEVER stored (user memory only)
Server SaltPrevents rainbow table attacksFirestore (per-user, public)
Derived KeyEncrypts/decrypts user dataSession memory only (cached)

Why This Is Still Zero-Knowledge

  1. Phone number alone cannot derive the key — PIN is required
  2. PIN is never transmitted or stored — only user knows it
  3. Server salt is public — safe to store, useless without PIN
  4. 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 lunar

How 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

ThreatProtected?Notes
Brute force✅ Yes2^128 combinations = impossible
Server breach✅ YesPhrase never stored
Shoulder surfing⚠️ PartialOnly shown once at signup
Physical theft of paper❌ NoUser 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

PlatformSecure StorageBiometric API
iOSKeychain (Secure Enclave)Face ID / Touch ID
AndroidKeystore (TEE/StrongBox)BiometricPrompt
Web (PWA)Not availableNot available (PIN only)

Security Analysis

What Lantern Has vs. Needs

DataLantern Has?Needed to Decrypt?
Phone number✅ Yes✅ Yes (as key input)
Salt✅ Yes✅ Yes (as key input)
PIN❌ No✅ Yes (secret)
Encrypted data✅ YesN/A (this is the output)
Encryption key❌ NoN/A (derived, not stored)
Recovery phrase❌ NoAlternative to PIN

Result: Lantern cannot decrypt user data without the PIN.

Threat Model

Attack VectorRiskMitigation
SIM swap attack🟡 MediumAttacker gets SMS but still needs PIN
Database breach🟢 LowOnly ciphertext + salt exposed
PIN brute force (online)🟢 LowRate limiting, account lockout
PIN brute force (offline)🟡 Medium600k PBKDF2 iterations, 6-digit = 10^6 attempts max
Court order / subpoena🟢 LowWe can't decrypt — only user has PIN
Malware on device🔴 HighKey cached in memory during session
Physical coercion🔴 HighUser can be forced to reveal PIN
Recovery phrase theft🔴 HighFull 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:

  1. Server-side rate limiting (max 5 attempts, then lockout)
  2. Exponential backoff on failures
  3. Account lockout notification via SMS
  4. Optional: Require 8-digit PIN for high-security users

Implementation Checklist

Phase 1: Core Infrastructure

  • [ ] Update encryption.js to 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

AspectPassphrase (Current)Phone + PIN (Proposed)
User memory load12+ char passphrase6-digit PIN
Typing frictionHigh (long, complex)Low (6 digits)
Recovery optionsNone (lost = gone)Recovery phrase
Identity verificationEmail onlyPhone SMS
Biometric unlockNot implementedSupported
Multi-deviceEnter passphrase each timePIN + biometric per device
Security level🟢 High🟢 High (with rate limiting)
Mobile UX😐 Okay😊 Good

Open Questions

  1. Should we support both systems? Allow users to choose passphrase OR phone + PIN?
  2. PIN length? 6 digits (standard) vs. 8 digits (more secure)?
  3. Recovery phrase length? 12 words (standard) vs. 24 words (more secure)?
  4. Web PWA support? PIN only, or require mobile app for biometrics?
  5. Migration path? How do existing passphrase users migrate to phone + PIN?

References

Built with VitePress