Duress code
A second passcode that empties the account
Set two codes instead of one. The first opens the app. The second erases every message, contact and key on the device and signs you out - no warning, no confirmation, nothing on screen to show which one you typed.
Encryption answers the question “can they read this?” It does not answer “what happens when someone is standing over you asking for the passcode?” A duress code is an answer to the second question, and a narrow one. Read what it does not do before you rely on it.
What happens when you type it
The lock screen accepts both codes. Typing the real one unlocks the app. Typing the duress one runs the wipe and then shows the welcome screen, exactly as a freshly installed app would - the same screen, the same wording, no message, no delay, no trace of the account that was there a second earlier.
The wipe is deliberately ordered so that what is visible goes first. Messages and contacts are deleted before keys, so a process killed halfway through leaves a broken install rather than a readable conversation. The seed phrase goes out of the Keychain, both passcodes are deleted, and biometric unlock is turned off with them.
The failed-attempt counter is cleared on the way out too. An app that has just been wiped but still refuses passcodes for four minutes is visibly not a fresh install, and that detail is the whole point.
Why the two codes cannot be told apart
A duress code is worthless if the app behaves differently for it. Two things protect that.
First, both hashes are stored under the same salt, so entering a code derives one hash and compares it against both, in constant time. An earlier version gave the duress code its own salt, which meant a second key derivation on every unlock: it doubled the wait for everyone, and skipping it on a mismatch would have made the duress path measurably faster to someone holding the phone and watching the screen.
Second, the duress code must be the same length as your passcode. The keypad submits as soon as the last digit is entered, so a code of any other length could never be typed at all - it would be a setting that silently did nothing, discovered at the worst possible moment. Setting a mismatched length is refused.
The passcode itself cannot be changed into the duress code either. The check tests the real passcode first, so a collision would resolve as “unlock” and the duress code would quietly stop working. That change is refused.
What it does not do
It does not erase anything off the chain. Ciphertext already published is permanent and public. Without the keys nobody can read it, but the fact that an address sent messages, and when, stays visible forever. The duress code destroys the copy on your device. It does not unsend.
It does not wipe your phone or computer. Only PrivaMesh’s own data goes. Photos, other messengers and everything else are untouched.
It does not warn anyone. There is no silent alarm, no message to a contact and no server to notify - there is no server at all. The wipe is the entire action.
It does not show a decoy account. Some tools open a second, innocuous profile instead. PrivaMesh empties the real one and shows a first-run app. Which of those is safer depends on who is asking and what they already know; ours is the simpler promise, and the one we can actually keep.
It cannot help if the device was already imaged. Someone who copied the storage before you typed anything holds that copy. The duress code protects the moment you are asked to unlock, not the time before it.
It is not reversible. Your recovery phrase restores your identity and contacts on a new device, never the conversations - forward secrecy destroys those keys after use. Typing the duress code by accident costs you your history permanently. Choose two codes that cannot be confused under pressure.
Guessing is throttled, both codes alike
Five wrong entries start an escalating cooldown - 30 seconds, a minute, two, four, on up to an hour - shown on screen so the wait is visible rather than mysterious. Biometric unlock is refused while a cooldown is running, so it cannot be used to step around the wait. The codes are stretched with a slow key derivation before being compared, which is what makes guessing a short numeric code expensive for someone holding a copy of the storage.
Confirming your passcode inside Settings - to reveal the phrase, or to change a code - does not count against that throttle. Protecting an already-unlocked app against guessing buys nothing, and letting a mistype lock you out of your own account costs something real. That check also refuses the duress code: it is not a passcode, and accepting it there would let it authorise changes to the setting it exists to protect.
Where it works today
Windows
Shipped in 1.0.0
Both codes are set in Settings. The wipe deletes the local database, reopens it empty, and clears the keys held by Windows DPAPI. The app returns to its first-run state.
Android
Shipped in 0.1
The wipe closes the database first, then deletes its files together with the write-ahead log, the preference files and the caches, and cancels the background workers that would otherwise reopen them.
iPhone
In the source, not yet in the App Store
The code is written, tested and public, but the current App Store build is 1.0 from 7 August 2026 and predates it. It arrives in the next release. Until then, the duress code exists on the desktop and Android clients only.
The behaviour is the same on every client that has it: same two codes, same equal-length rule, same constant-time comparison, same cooldown. The differences are only in what a wipe has to delete on each system, because a Windows database, an Android database and an iOS keychain fail in different ways when you delete them carelessly.
All three implementations are open source and can be read before you trust them: iOS, Windows and Android.
Frequently asked questions
What is a duress code?
A second passcode that erases the account instead of opening it. You set both; the first unlocks the app, the second deletes every message, contact and key on the device and returns the app to its first-run screen, with nothing to show which one was typed.
Can someone tell the two codes apart?
Not from the app. Both are stored under the same salt, so one derivation is compared against both in constant time, and the duress code must be the same length as the passcode. After the wipe the app shows the welcome screen a fresh install shows, and the failed-attempt counter is cleared so nothing lingers to contradict that.
Does the duress code delete my messages from the blockchain?
No. Ciphertext already published to Solana is permanent and public. Nobody can read it without keys that were just destroyed, but the fact that an address sent messages, and when, stays visible. The duress code erases the copy on your device; it cannot unsend.
Does it wipe my whole phone?
No. Only PrivaMesh data is deleted: its messages, contacts, keys, both passcodes and biometric unlock. Nothing else on the device is touched.
Can I undo it or get my chats back?
No. Your recovery phrase restores your identity and contacts on a new device, never your conversations - forward secrecy destroyed those message keys after use. Pick two codes you cannot confuse under pressure.
Which versions of PrivaMesh have a duress code?
The Windows client from 1.0.0 and the Android client from 0.1, both released 27 August 2026. On iPhone the code is written and public but the current App Store build is 1.0 from 7 August and predates it, so it arrives in the next release.