Notation
The formulas on this page use four objects.
Lower-case symbols (, , , ) are field elements; , ,
, and are Grumpkin points. A field element written against a
point, as in , means scalar multiplication.
The hierarchy
The seed is 32 bytes.
seed_lo is bytes 0–15 and seed_hi is bytes 16–31,
each interpreted as a big-endian unsigned integer. Their order is significant.
Recovering from requires solving a discrete logarithm on Grumpkin.
Recovering or from requires inverting Poseidon2 over ,
, and . A derived key therefore does not reveal its ancestors.
Addresses
A diversified address is the pair . The wallet chooses a fresh diversifier and derives the address point : The wallet solves in the Grumpkin base field and chooses the smaller of the two roots in canonical integer order. If there is no root, it chooses another diversifier. This exact derivation matters: a generic hash-to-curve function will produce different addresses. Three properties follow:- Unlinkable. Without the
ivkbehind them, two addresses with different diversifiers do not disclose a shared owner cryptographically. Reuse or offchain disclosure can still link them. - One scanner. A single
ivkrecognizes notes sent to every address it generates. Generating more addresses does not require more viewing keys. - Change ownership. The proof enforces that change belongs to the sender. Wallets should choose a fresh diversifier; the circuit does not check whether that diversifier has been used before.
Derived identifiers
The hierarchy also yields one stable identifier for the identity: . Every address generated from the sameivk shares this affilID.
An ivk holder can compute affilID and the address alone does not reveal it.
Linking to requires the ivk that produced both. Sanctions
screening binds to affilID, so generating a fresh address does not change
the sanctions result. Customer-to-VASP affiliation is maintained offchain;
affilID is not a customer registration in the pool’s VASP tree.
The capability lattice
Each key bundle grants a specific set of capabilities.
sees arrivals because derives from it. The reverse does not
hold: cannot reconstruct . A proving service still
needs the key holder’s signature for each shield or spend. Recipient proofs
are different:
ivk is sufficient for their ownership check, but resolution
also requires the recipient VASP’s policy-wrapper proof.
Seeing arrivals requires access to the encrypted note memos or note openings.
Detecting spends also requires each known note’s leaf index. The MIP410
authority has this visibility only if the relevant keys and data are shared
with it; contract administration does not grant them. The institutional
payload uses the recipient VASP’s separate messaging key.
Key custody
With custodial keys, the VASP’s custodial system holds the customer’szsk and
can generate addresses, scan notes, build proofs, and authorize spends. With
self-custodied keys, the customer’s wallet holds zsk and may share
with its VASP for proving. Both arrangements produce the same
onchain proofs. A customer using custodial keys may also receive for
watch-only access.
Spend authorization
Spending a note requires two checks inside the proof:- Ownership. The prover witnesses and re-derives the note’s diversified address.
- Authorization. The circuit verifies a Schnorr signature under over a Poseidon2 digest of the action’s public values.
Outsourced proving
Proof generation can be delegated without sharing the spending key. The following flow applies to self-custodied keys. With custodial keys, the VASP can sign and prove directly. Delegation hands the proving service and runs one round trip:- The wallet builds the payment intent and output note commitments.
- The service prepares the witness, including tree paths and policy inputs, computes the nullifiers and input lock IDs, and returns the digest.
- The wallet checks the digest against its intent and signs with .
- The service completes the proof and a submitter submits the finished transaction.
zsk over the
wallet-approved digest. A wallet may isolate proving services by deriving a
separate and sharing only its bundle.
The institution’s messaging key
One key on this page belongs to no wallet. Each VASP in the pool’s institution registry holds a messaging key: an independent Grumpkin Schnorr key pair, generated by the institution and not derived from any customer seed. Its verification key sits in the institution’s leaf of the pool’s VASP tree beside the hash of its policy verification key, so the leaf is the one place the chain learns which key speaks for the institution: The key signs payment requests, institutional payload commitments, payment contexts inside policy wrappers, and the institution’s own leaf updates. Wallets verify requests offchain. The receiving VASP verifies the institutional payload signature offchain. The wrapper verifies its context signature inside the proof under the key opened from the VASP tree.updateFi replaces the policy verification-key hash and messaging key under
a signature by the old messaging key, verified through the Grumpkin
precompiles. The VASP can rotate its own key without an authority transaction.
The pool accepts the previous registration root after an admission. A key
rotation or revocation clears that previous root, so proofs using the old leaf
must be rebuilt against the updated registry. Request validation must use an accepted registry snapshot
and check the request’s expiry.