Key Derivation
Key Derivation
Each Hinkal account is defined by two capabilities: the ability to spend notes and the ability to view them. Spending is governed by two secrets - the Nullifying Key and the Spending Key - while viewing is governed by the Viewing Key. None of this key material is ever stored. Every key is derived deterministically from a single Ethereum signature, which means that as long as a user controls their Ethereum account, they can reconstruct their entire Hinkal identity simply by signing the same message again and reproducing the identical signature.
The root of the derivation is an Ethereum signature produced under the ECDSA (Elliptic Curve Digital Signature Algorithm) scheme over the secp256k1 elliptic curve. When the user signs Hinkal's fixed login message with their Ethereum private key, the wallet returns a deterministic signature whose (r, s, v) components - where r and s are the curve‑derived signature values and v is the recovery identifier - form a high‑entropy secret that no one without the Ethereum key can reproduce. Hinkal treats this signature as the master seed and applies one‑way hash functions to it to obtain each account key, so the keys are reproducible by the legitimate owner yet reveal nothing about one another.
The Spending Key is a dedicated EdDSA‑Poseidon keypair on the BabyJubJub curve that authorizes transactions. Its private scalar is derived from the same Ethereum signature under a fixed domain‑separation prefix, hashed with Poseidon so that it is cryptographically independent of the nullifying key, and the corresponding public key is computed with circomlib's standard derivation: the secret is expanded and clamped, then multiplied by the curve's base point. At spend time the wallet signs the transaction message with this key, and the resulting signature is verified against the public spending key inside the proof, cryptographically binding each spend to the account owner without ever revealing the secret on‑chain.
The Nullifying Key is the core secret of the shielded account and is obtained by hashing the Ethereum signature with keccak256, producing a 32‑byte value. Its name reflects its role: it is the secret used to compute the nullifiers that mark notes as spent, and it doubles as the scalar that derives each note's stealth point on the BabyJubJub curve. Because redeeming a note requires regenerating its nullifier, control of this key is precisely what lets a user move their shielded balance, while its public counterpart - a Poseidon hash of the key - can be published to identify the account without exposing the secret.
The Viewing Keys are deterministically derived from the user's nullifying key using the libsodium cryptographic library and its crypto_box_seed_keypair function. The 32‑byte hexadecimal nullifying key is converted into a byte array and supplied as the seed to libsodium's deterministic key‑generation algorithm, which produces a Curve25519‑based encryption keypair: a private viewing key and its corresponding public viewing key. The public viewing key is shared so that senders can encrypt note data addressed to the recipient, while the private viewing key allows the owner to scan the chain and decrypt their incoming commitments. Crucially, because this keypair is only an encryption key, it grants the ability to see balances and incoming transfers without granting the ability to spend them - spending always requires the nullifying and spending keys.
Org-scoped viewing keys
Hinkal allows an org/individual hierarchy for viewing keys, structured as a two-level deterministic derivation tree. Each organization holds a single org master viewing key vk_org. Individual viewing keys are derived as vk_user = Poseidon(vk_org, user_id), where Poseidon is a hash function and user_id is a stable per-member identifier within the org. At note creation, the sender encrypts the note payload to the recipient's stealth address using vk_user.pub; because vk_org deterministically generates the full set of {vk_user} private keys, the org master key can re-derive any vk_user and decrypt any note addressed to any member - without ever recovering spending keys, which remain rooted in the user's wallet signature and are derived along a separate, sibling branch of the tree. The individual key decrypts only that user's shielded notes and stealth-address activity, while the org master key - sitting one level up - decrypts everything across all members. This gives organizations a single credential for compliance, reconciliation, and treasury oversight, with viewing-key authority strictly read-only.
Last updated