Key Management
Users derive all keys from a single BIP-39 mnemonic. The mnemonic produces a seed, from which a spending key is derived via domain-separated SHA-256. The spending key is the master secret — it controls the user's funds and identity.
From the spending key, two child keys are derived via HMAC-SHA256: a signing key (for transaction authorization) and a viewing key (for decrypting incoming transfers without spending authority).
The Balance Public Key (BPK) is spending_key · G on the Grumpkin curve. This is the user's on-chain identity — balances are stored under the hash of the BPK, not under an EVM address. To send someone funds, you need their BPK.
An alternative linked mode derives the spending key from an EIP-712 signature produced by an existing EVM wallet (e.g. MetaMask), allowing users to tie their privacy identity to an Ethereum account without managing a separate mnemonic.
Derivation
Starting from a BIP-39 mnemonic:
- Mnemonic → seed via PBKDF2-SHA512 (standard BIP-39)
spending_key = SHA256("zkprivacy-eb-spending-key-v1" ∥ seed) mod curve_ordersigning_key = HMAC-SHA256(spending_key, "signing") mod curve_orderviewing_key = HMAC-SHA256(spending_key, "viewing") mod curve_order
Multiple accounts are supported via domain separation: account N uses "zkprivacy-eb-spending-key-v1/{N}".