Skip to content
Anon Wallet

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 CryptoKey stored in a non-extractable form in chrome.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)