PIN & Duress Mode

Your PIN is not a password. It is the encryption key.

How the PIN System Works

In most applications, a PIN or password is used to authenticate you to the application. The application then unlocks the data using a key stored somewhere (keychain, server, etc.). This means someone with access to the key storage can bypass the PIN entirely.

RVNT's PIN system is different. The PIN is the encryption key. More precisely, the PIN is the sole input to a key derivation function that produces the encryption key for the local database. There is no separate stored key. There is no server that knows the key. There is no "forgot PIN" recovery path. If you do not know the PIN, the data is cryptographically inaccessible.

PIN → Argon2id → database_key → SQLCipher(AES-256-CBC + HMAC-SHA256)

There is no other path to the data.
The database_key exists only in memory while the app is unlocked.
When the app locks, database_key is securely zeroed.

Argon2id Key Derivation

RVNT uses Argon2id (the hybrid variant of Argon2, combining resistance to side-channel attacks and GPU/ASIC attacks) to derive the database encryption key from the user's PIN.

Parameters

ParameterValuePurpose
Memory (m)65536 KB (64 MB)Memory-hard: prevents GPU/ASIC brute force
Iterations (t)3Time cost: ~300ms on modern hardware
Parallelism (p)4Number of parallel lanes
Output length32 bytes (256 bits)AES-256 key
Salt32 bytes (random, per device)Prevents rainbow tables
VersionArgon2id v1.3RFC 9106

Key Derivation Flow

Input:
  pin:  User's PIN (6+ digits, UTF-8 encoded)
  salt: 32 random bytes (generated at identity creation, stored in Keychain)

Process:
  raw_key = Argon2id(
      password: pin,
      salt:     salt,
      m_cost:   65536,    // 64 MB
      t_cost:   3,        // 3 iterations
      p_cost:   4,        // 4 parallel lanes
      output:   32        // 32 bytes
  )

  // Derive separate keys for different purposes
  db_key     = HKDF-SHA256(ikm=raw_key, info="rvnt-db-key",      len=32)
  backup_key = HKDF-SHA256(ikm=raw_key, info="rvnt-backup-key",  len=32)
  export_key = HKDF-SHA256(ikm=raw_key, info="rvnt-export-key",  len=32)

  // Zero the raw key
  secure_zero(raw_key)

Output:
  db_key:     Used to open the SQLCipher database
  backup_key: Used to encrypt local backups
  export_key: Used to encrypt data exports

All three keys are zeroed from memory when the app locks.

Why These Parameters

64 MB memory cost means an attacker needs 64 MB of RAM per concurrent brute-force attempt. A GPU with 24 GB VRAM can run ~375 parallel attempts. At ~300ms per attempt, the attack rate is approximately:

GPU attack rate: 375 / 0.3s ≈ 1,250 attempts/second

For a 6-digit PIN (10^6 = 1,000,000 possibilities):
  Time to exhaust:  1,000,000 / 1,250 ≈ 800 seconds ≈ 13 minutes

For an 8-digit PIN (10^8 = 100,000,000 possibilities):
  Time to exhaust:  100,000,000 / 1,250 ≈ 80,000 seconds ≈ 22 hours

For a 10-digit PIN (10^10):
  Time to exhaust:  ~93 days

For an alphanumeric PIN (62^8 ≈ 2 × 10^14):
  Time to exhaust:  ~5,000 years
PIN strength matters. A 6-digit numeric PIN provides protection against casual attackers but not against a determined adversary with GPU resources. Use a longer PIN (8+ digits) or an alphanumeric passphrase for higher security. The lockout escalation system provides additional protection.

Lockout Escalation

To further slow brute-force attacks against the PIN, RVNT implements an escalating lockout system:

Failed AttemptsLockout DurationCumulative Wait
1-3None0
4-530 seconds1 minute
6-75 minutes11 minutes
8-930 minutes71 minutes
101 hour131 minutes
154 hours~21 hours
2024 hours~5 days
25+Optional: auto-wipeN/A

The lockout counter is stored in the Secure Enclave (Apple) or StrongBox (Android) and cannot be reset by reinstalling the app or manipulating local storage. On desktop platforms without hardware-backed storage, the counter is stored in a tamper-evident file protected by a hardware-bound key (where available) or a platform-specific credential store.

Duress Mode

Duress mode is designed for the scenario where you are compelled to unlock your device -- at a border crossing, during a police stop, under physical threat, or during a legal proceeding where you must comply.

How It Works

Setup (done in advance):
  1. Go to Settings > Security > Duress PIN
  2. Set a secondary PIN (must differ from primary PIN)
  3. Choose duress behavior:
     a. Full wipe (panic mode) + show empty state
     b. Full wipe (panic mode) + show decoy conversations
     c. Show restricted view (hide sensitive conversations only)

Activation:
  1. At the lock screen, enter the duress PIN instead of the real PIN
  2. The app appears to unlock normally
  3. Behind the scenes:
     a. Panic mode executes (key destruction, database wipe)
     b. A pre-staged decoy database is loaded
     c. OR: an empty state is presented
  4. The person compelling you sees a normal-looking app
  5. Your actual cryptographic material is already destroyed

Decoy Conversations

If you configure decoy conversations, the duress mode will present a pre-staged set of innocuous conversations after destroying the real data. These conversations are generated from templates and appear to contain mundane messages (grocery lists, meeting confirmations, family check-ins). They use realistic timestamps spread over the previous 2 weeks.

Decoy database:
  - 3-5 contacts with generic names
  - 10-20 messages per conversation
  - Timestamps distributed over 14 days
  - No media attachments (avoids suspicion of staging)
  - Message content is mundane and culturally appropriate
  - All decoy data is encrypted with a derived key
    (derived from the duress PIN, not the real PIN)
Duress mode is irreversible. Entering the duress PIN destroys all real cryptographic material. There is no "undo." The actual data cannot be recovered. Your contacts will see that your identity key has changed (if you re-register), which may alert them that a duress event occurred.

Lock Modes

RVNT supports multiple lock modes for different security contexts:

ModeBehaviorUse Case
Standard Lock PIN required to unlock. Auto-lock after 5 minutes (configurable). Normal daily use
Instant Lock Lock immediately on app background. No grace period. High-risk environments
Travel Mode Only whitelisted conversations visible. All others hidden behind a secondary PIN. Border crossings, device inspections
Per-Conversation Lock Individual conversations can require a separate PIN to access. Compartmentalized security

Per-Conversation Lock

Individual conversations can be locked with a separate PIN. This provides compartmentalized security: even if someone unlocks the main app, specific conversations remain hidden and encrypted.

Per-conversation encryption:
  conv_key = HKDF-SHA256(
      ikm:  Argon2id(conversation_pin, conversation_salt),
      info: "rvnt-conv-lock-" || conversation_id,
      len:  32
  )

The conversation's messages are re-encrypted with conv_key.
The conversation does not appear in the conversation list
unless the per-conversation PIN is entered.

Biometric Unlock

RVNT supports biometric unlock (Face ID, Touch ID, fingerprint) as a convenience feature. Biometric unlock works by storing the database key in the platform's Secure Enclave / StrongBox, protected by a biometric access policy.

Biometric unlock flow:
  1. User sets PIN (Argon2id derives db_key)
  2. User enables biometric unlock
  3. db_key is stored in Secure Enclave with biometric policy:
     - Access requires valid biometric (face/fingerprint)
     - Key is hardware-bound (cannot be extracted)
     - Key is invalidated if biometrics are modified
  4. On subsequent unlock:
     a. Biometric prompt appears
     b. If valid: Secure Enclave releases db_key to app memory
     c. If invalid: Fall back to PIN entry

Security considerations:
  - Biometric unlock does NOT bypass the PIN. The PIN-derived key is
    what's stored in the Secure Enclave.
  - The Secure Enclave provides hardware-backed protection.
  - Biometrics can be compelled (fingerprint on sleeping person, etc.).
  - For maximum security, disable biometric unlock and use PIN only.
Biometric ≠ PIN security. In many jurisdictions, courts have ruled that biometric data (fingerprints, face) can be compelled, while PIN/passcode knowledge is protected by the Fifth Amendment (US) or equivalent protections. Consider your jurisdiction before enabling biometric unlock.

Further Reading

  • Panic Mode -- The complete data destruction system
  • Threat Model -- Physical device seizure threat analysis
  • Forward Secrecy -- Why past messages are safe even if current keys are compromised

Last updated: 2026-04-12

RVNT Documentation — Post-quantum encrypted communications