Skip to the content
Back to Nymbot

Knowledge base Privacy

Anonymous mode

Encryption was never the gap. Attribution was. Anonymous mode makes the server able to charge a message without being able to learn whose credits it is charging.

The gap it closes

The chat is end-to-end encrypted, but the service still knows which public key is talking to it. The seal inside each gift wrap is signed by your identity key; your credit row, your conversation thread and the turn de-duplication all hang off that key; and the archived copy of each reply is addressed to it.

So anyone holding the bot's private key could enumerate who used the paid chat, and anyone with the database could do it without the key. Nothing there is a decryption failure. It is simply that your name is on the bill.

The throwaway key

The Anon chip, or ?anon, generates a keypair on your device and moves the whole conversation onto it. From then on the rumor, the seal and the request signature are all that key — your identity key signs nothing in this conversation at all.

Replies stay hybrid post-quantum: the throwaway key carries its own KEM key, derived from a root generated independently of the signing key, so publishing one does not weaken the other.

While it is on, read receipts, typing indicators, reactions and edits to Nymbot are held back. Each of those would otherwise carry your real signature into the same conversation and undo the whole thing. If your app cannot honour that — a locked vault, state not yet restored — it refuses to send rather than quietly falling back to your identity key.

The throwaway key is stored under identity encryption and syncs to your other devices, so the conversation and its balance follow you. Rotating it keeps the previous keys around for a while so their history stays readable and their balance stays sweepable.

Blind credit vouchers

Simply transferring credits to the throwaway key would hand the server the link the mode exists to break. So credits move as blind vouchers, in the Chaumian style a Cashu mint uses.

  1. Your app picks a random secret and blinds it with a random factor.
  2. Authenticated as your nym, it asks the server to sign the blinded value. The server debits your balance and signs something it cannot read.
  3. Each signature comes with a proof that the published signing key was the one used. Your app verifies it, and refuses the whole move if it does not check out — an unprovable signature is a tagging vector, not a cosmetic problem.
  4. Your app unblinds. The result is a valid token that looks like nothing the server has seen.
  5. Later, authenticated as the throwaway key, it presents the token. The server verifies it, checks it has not been spent, and credits the key — with nothing to match it against.

The tables record that a voucher was issued and that a voucher was spent. Neither records who. That link is what the blinding destroys, and storing it would put it straight back.

The keyset is published, and your app pins it and warns you if it changes — a per-user keyset is exactly how a mint would tag its users. You can also skip the move entirely and buy credits straight onto the throwaway key with ?buy.

What it does not hide

Being honest about the edges is the only way the rest of it is worth anything.

  • The relays see one connection publishing both identities' events. If that is in your threat model, use Tor or a VPN.
  • Rotating the key and carrying the balance over shows the server one anonymous key paying another.
  • A conversation is a conversation. Every message under one throwaway key is linked to the others by construction — the assistant needs the thread as context.
  • What you write can identify you. No amount of key hygiene helps if the question names your employer.
  • ?gift and ?transfer stay on your real nym, because both are about a named account.
Careful

Credits on a throwaway key live and die with that key. A panic wipe takes it and anything left on it.