Encryption
Anon uses modern, audited cryptographic primitives throughout. This page documents what is encrypted, how, and where.
At-Rest Encryption (IndexedDB)
Your mnemonic phrase and other sensitive account data are stored in the browser's IndexedDB, encrypted with AES-256-GCM:
- AES-256-GCM provides both confidentiality and integrity (it's an authenticated encryption scheme — tampering is detected)
- The encryption key is a
CryptoKeystored in a non-extractable form inchrome.storage.local, itself encrypted with a key derived from your passkey/password - The IV (initialization vector) is randomly generated per encryption operation
Encryption Flow (at rest)
Passkey PRF output
│
HKDF (SHA-256)
│
Storage wrap key
│
Encrypts CryptoKey ──→ chrome.storage.local
│
CryptoKey (AES-256-GCM)
│
Encrypts mnemonic ──→ IndexedDB
In-Memory Keys
Several keys exist only in memory and are never persisted:
| Key | Purpose | Lifetime |
|---|---|---|
| PRF key | Root derivation input | Auth flow only (~seconds) |
| Railgun key | Balance decryption, zk-SNARK proofs, tx signing | Session (until lock) |
| IDB CryptoKey (decrypted) | IndexedDB encryption/decryption | Session |
These keys are cleared from memory when Anon locks.
HKDF Key Derivation
HKDF (HMAC-based Key Derivation Function, RFC 5869) is used to derive multiple independent keys from a single root secret:
PRF output (32 bytes)
│
├── HKDF("anon:railgun:full:v1") ──→ Railgun key (viewing + spending)
└── HKDF("anon:secrets:indexeddb:v1") ──→ IDB CryptoKey (AES-GCM wrap key)
Each derivation uses a persistent master salt and a unique info label for domain separation. Using HKDF ensures that compromise of one derived key does not compromise others.
Railgun Note Encryption
Inside the Railgun protocol, each encrypted note (a spendable balance commitment) is encrypted with the recipient's public key using a hybrid scheme:
- ECDH key agreement to derive a shared secret
- AES-256-GCM to encrypt the note contents
Note decryption happens locally in Anon using your Railgun key.
What's Not Encrypted
The following data is stored in plaintext because it is public by nature:
- Your public Ethereum address
- Network RPC URLs
- Connected DApp list (hostnames only)
- Extension settings (theme, timeout preferences)