ACCOUNT & SECURITY

Key Management

How Dust derives, stores, and protects your stealth keys — and what you should back up.

Key Derivation

Dust derives two secp256k1 private keys — a spend key and a view key — purely in the browser. They are never sent to any server.

KEY MANAGEMENT / PBKDF2 DERIVATION
1You provide two secrets
Wallet Signature
from your connected wallet
••••
PIN Code
your secret 4-digit PIN
combined into
2Key derivation runs
PBKDF2-SHA512
100,000 iterations · produces 64 bytes
splits into
3Two keys are derived
Spend Key
Controls funds
First 32 bytes
NEVER STORED
View Key
Detects payments
Last 32 bytes
NEVER STORED
BOTH INPUTS REQUIRED — NEITHER ALONE IS SUFFICIENT
walletSignature = sign("Dust Protocol stealth keys", wallet) salt = "dust-stealth-v1" ikm = PBKDF2-SHA512( password = walletSignature + PIN, salt = salt, iters = 100_000, dkLen = 64 bytes ) spendKey = ikm[0:32] (mod secp256k1 order) viewKey = ikm[32:64] (mod secp256k1 order)

Because the derivation uses both the wallet signature and the PIN, neither alone is sufficient to reproduce the keys. An attacker who compromises your wallet cannot derive stealth keys without knowing your PIN, and vice versa.

The Two Keys

Spend Key

HIGH SENSITIVITY

Controls the ability to claim funds from stealth addresses. Used to derive the per-payment stealth private key when a payment is detected. Never leaves the browser. The public part (spendKey × G) is registered on-chain as half of your meta-address.

View Key

MEDIUM SENSITIVITY

Used to detect incoming payments by scanning announcements. Cannot spend funds. The public part is registered on-chain. The private part is used only in the scanner and never leaves the browser.

V2 Key Derivation (Privacy Pool)

DustPool V2 uses a separate key derivation for its ZK-UTXO model. V2 keys operate on the BN254 curve (required for FFLONK proofs) rather than secp256k1.

walletSignature = sign("Dust Protocol stealth keys", wallet) salt = "dust-stealth-v2" ikm = PBKDF2-SHA512( password = walletSignature + PIN, salt = salt, iters = 100_000, dkLen = 64 bytes ) spendingSeed = ikm[0:32] viewingSeed = ikm[32:64] spendingKey = SHA-256(spendingSeed) mod BN254_ORDER nullifierKey = SHA-256(viewingSeed) mod BN254_ORDER ownerPubKey = Poseidon(spendingKey)

Spending Key

HIGH SENSITIVITY

Derives the ownerPubKey (via Poseidon hash) that appears in UTXO commitments. Required to spend notes. The ownerPubKey is public; the spending key is secret.

Nullifier Key

MEDIUM SENSITIVITY

Used to compute nullifiers: N = Poseidon(nullifierKey, leafIndex). Knowing this key allows an auditor to track which notes have been spent — used in view keys for voluntary disclosure.

View Keys & Selective Disclosure

A view key allows a third party (auditor, tax authority, compliance officer) to verify your transaction history without gaining spending authority. It contains the ownerPubKeyand nullifierKey — enough to verify commitments and track spent notes, but not enough to move funds.

ViewKey = { ownerPubKey: Poseidon(spendingKey) // public — in commitments nullifierKey: SHA-256(viewingSeed) mod BN254_ORDER } Serialized as: dvk1:<hex(ownerPubKey)><hex(nullifierKey)> Verification: For each note (amount, asset, chainId, blinding): recompute C = Poseidon(ownerPubKey, amount, asset, chainId, blinding) check C == on-chain commitment ✓

View key security

A view key holder can see all your deposits, transfers, and spending patterns. They can compute nullifiers (track which notes are spent). They cannot spend your funds — the spending key is not included. Share view keys only with parties you trust to see your full transaction history.

What Is Stored Locally

ItemWhereSensitivity
PIN hash (bcrypt)localStorageMedium — reveals PIN if brute-forced
Scan cursor (last scanned block)localStorageLow — public information
Detected stealth addresses + balances cachelocalStorageLow — public information
DustPool deposit notes (nullifier + secret)localStorageHIGH — losing this = losing funds
DustSwap deposit notes (nullifier + secret)localStorageHIGH — losing this = losing funds
Payment link definitionslocalStorageLow
Claim addresses (HD-derived)localStorageLow — derivable from keys
V2 deposit notes (encrypted)IndexedDBHIGH — AES-256-GCM encrypted, key from spendingKey
V2 note encryption keyDerived on-demandNever stored — SHA-256(spendingKey bytes)

Back up your deposit notes

Pool and swap deposit notes (nullifier + secret) are the only way to generate a withdrawal proof. They exist only in your browser's localStorage. Export them from the Wallet page and store them securely. If you lose them, your deposited funds cannot be recovered.

What If I Lose Something?

I forget my PIN

You cannot re-derive your stealth keys. However, your wallet address still holds any funds you've claimed to it. You can re-register by creating a new PIN and a new .dust name — you'll lose the old name and any unclaimed stealth payments.

I lose access to my wallet (seed phrase)

You cannot re-derive your stealth keys (wallet signature required). Same outcome as forgetting your PIN. Claimed funds are whatever your seed phrase controls — they are not in the stealth system.

I clear my browser localStorage

Stealth keys can be re-derived (log in again with wallet + PIN). Your .dust name is on-chain — it persists. Deposit notes are lost — DustPool / DustSwap deposits become unrecoverable if not backed up.

Someone sees my localStorage

They see deposit notes and cached scan data. They cannot derive stealth keys from localStorage alone (keys are never stored — only re-derived on demand). Deposit notes are bearer instruments — treat localStorage like a physical notepad.

I want to share my transaction history with an auditor

Generate a view key from Settings → Disclosure. The view key contains your ownerPubKey and nullifierKey — enough for the auditor to verify all your notes and spending, but not enough to move funds. The auditor can independently verify commitments using Poseidon hash checks.

Security Best Practices

  • Use a strong, unique PIN — it is the second factor protecting your stealth keys.
  • Export deposit notes from the Wallet page and store them offline or in a password manager.
  • Do not share the private view key — it allows others to see all your incoming payments.
  • The spend key is never stored — it is re-derived each session. This is a feature, not a bug.
  • Settings → Danger Zone lets you clear all keys and start fresh if your PIN is compromised.
  • V2 deposit notes are encrypted with AES-256-GCM in IndexedDB — even browser access doesn't expose note data without your keys.
  • View keys allow selective disclosure. Share them only with trusted parties — they reveal your full transaction graph.