# Key Derivation & Stealth Addresses

**Key Derivation**

There are two main components of each Hinkal account:

* The Spending Keys are used to spend notes of the associated account.
* The Viewing Keys are used to decrypt user commitments.

The Spending Keys (also referred to as Shielded Keys) are generated using Ethereum accounts by having users sign a message and deriving the Hinkal keys from the signed message. This process leverages Ethereum's ECDSA (Elliptic Curve Digital Signature Algorithm) signature scheme, which uses the secp256k1 elliptic curve. When a user signs a message with their Ethereum private key, it produces a deterministic signature that can be used as entropy for key derivation. The signature format follows Ethereum's standard (r, s, v) components, where 'r' and 's' are the signature values and 'v' is the recovery identifier. This ensures that as long as someone has access to their Ethereum account, they will be able to access their Hinkal account by signing the same message and reproducing the identical signature.

The Viewing Keys in Hinkal Protocol are deterministically derived from the user's private spending key using the [libsodium](https://www.npmjs.com/package/libsodium) cryptographic library and its *crypto\_box\_seed\_keypair* function. The private spending key, which is a 32-byte hexadecimal string generated from the user's Ethereum signature, serves as the seed for creating a Curve25519-based encryption key pair. The derivation process involves converting the spending private key into a byte array and using it as entropy to generate both a private viewing key and its corresponding public viewing key through libsodium's deterministic key generation algorithm.

#### Stealth Addresses

Stealth addresses are a fundamental privacy primitive in Hinkal Protocol that enable recipient anonymity by generating unique, unlinkable addresses for each transaction. They ensure that external observers cannot determine the recipient of a transaction or link multiple transactions to the same user.

A user’s canonical public key, which we will denote as C, is defined on BabyJubjub as:

$$
C = vk \* G
$$

where vk is the user’s private shielded key and G is the BabyJubjub generator point.

A user’s stealth address is represented as a pair of BabyJubjub points $$(H\_0,H\_1) \in F^2$$ such that

$$
vk \* H\_0 = H\_1
$$

This ensures that many possible stealth addresses can correspond to a single private key. To derive random stealth address, one should pick random number z (referred to as randomization) and make z elliptic curve shifts from (C, G):

$$
(C, G) \to (z \* C, z\* G) \to (H\_0, H\_1)
$$

We also define stealth address commitment (abusing notation, we also call this simply "stealth address") according to $$Poseidon\_4(H\_{0x}, H\_{0y}, H\_{1x}, H\_{1y}))$$

According to [Fauzi et al.](https://dl.acm.org/doi/10.1007/978-3-030-34578-5_23) it is impossible for an outsider to:

1. Link two stealth addresses with each other. In other words, find that they originate from the same private shielded key.
2. Extract the private shielded key from the stealth address.

#### **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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hinkal-team.gitbook.io/hinkal/technical-description/setup/key-derivation-and-stealth-addresses.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
