Mutual HOTP/TOTP
Both devices share one secret and display the same code. Neither side has a privileged role.
Ask them to read their code aloud. Make sure it matches below. Don’t tell them your code.
Compare a mutual rotating code, or use a one-way proof that only one person can generate.
New relationship
Mutual codes compare a shared secret. One-way proofs keep generation power on one device.
Join a channel
New setup codes are encrypted and authenticated by a separate one-time passphrase.
Create or import a channel, or unlock your encrypted vault.
Compare together
One-way verification
Ask for their current proof phrase. A successful proof advances this verifier’s local state.
Two trust models
Both devices share one secret and display the same code. Neither side has a privileged role.
The prover holds a seed. The verifier stores only a hash anchor and cannot calculate the next configurable 5–10 word phrase.
The creator can bind setup material to a context and then discard it. Both people re-enter it when generating or checking a code or proof; it is never stored or exported.
Saved entries are encrypted with a random AES-256-GCM vault key. Your recovery password or generated code derives a key that wraps it; compatible browsers can also wrap it with a WebAuthn PRF secret after Face ID, fingerprint, or device-passcode verification. This protects closed or locked data at rest. While unlocked, the page’s JavaScript can use the vault key and decrypted secrets; a compromised page, extension, browser profile, or device could expose them. Browser data may also be cleared, so retain setup backups.
The verifier hashes the supplied phrase once and compares it with the stored anchor. After success, that phrase becomes the next anchor. Calculating the following phrase would require reversing SHA-256.
At creation, PBKDF2-HMAC-SHA256 uses the context and an independent random salt for each device to wrap its secret, seed, or anchor. The creator’s input is then cleared. Setup codes and the encrypted vault retain only the salt and wrapped material. Both people re-enter the context when generating or checking a code or proof. Even if both omit it or enter the same wrong value, their independently salted material does not match. Leaving context empty at creation preserves normal context-free behavior.