# ZKP #1 — Delegation Proof

> **Status: Needs review by Dev**

## ZKP #1 — Delegation Proof

This ZKP proves that a user owns valid, unspent Orchard notes at the snapshot height and is delegating their voting weight to a governance hotkey.

### Public inputs

* `signed_note_nullifier` — nullifier of the dummy signed note
* `rk` — randomized signature verification key
* `nc_root` — note commitment tree anchor at snapshot height
* `nullifier_imt_root` — IMT root of all on-chain nullifiers at snapshot height
* `vote_authority_note` — the initial VAN commitment (binds hotkey, weight, round)
* `gov_null_1, ..., gov_null_5` — governance nullifiers for each note
* `vote_round_id`
* `cmx_new` — the output note commitment (to the gov hotkey address)
* `dom` — nullifier domain (derived from protocol identifier and vote\_round\_id)

### Witness (private inputs)

* `ak` — spend auth validating key (Pallas point)
* `nk` — nullifier deriving key
* `rivk` — CommitIvk randomness
* `alpha` — spend auth randomizer
* `vpk` — voting hotkey public key as a tuple `(vpk_d, vpk_pk_d)`
* `gov_comm_rand` — randomness for the VAN commitment
* For the signed (dummy) note: `d_signed, pk_d_signed, rho_signed, psi_signed, rcm_signed, cm_signed` (value = 1)
* For the output note: `d_new, pk_d_new, v_new, rho_new, psi_new, rcm_new` (address = hotkey)
* For each note `i` (5 slots — real + padded):
  * full note data, `cm_i`, Merkle path, `real_nf_i`, IMT proof

### Conditions

#### Signed note (conditions 1-5)

1. [**Note Commitment Integrity**](https://valargroup.gitbook.io/shielded-vote-docs/circuit-components/note-commitment-integrity) — Signed note commitment correctly constructed
2. [**Nullifier Derivation**](https://valargroup.gitbook.io/shielded-vote-docs/circuit-components/nullifier-derivation) — Public nullifier correctly derived
3. [**Rho Binding**](https://valargroup.gitbook.io/shielded-vote-docs/circuit-components/rho-binding) — `rho_signed = Poseidon(cmx_1..5, van_cmx, vote_round_id)`
4. [**Spend Authority**](https://valargroup.gitbook.io/shielded-vote-docs/circuit-components/spend-authority) — `rk` is valid rerandomization of `ak`
5. [**Diversified Address Integrity**](https://valargroup.gitbook.io/shielded-vote-docs/circuit-components/diversified-address-integrity) — Signed note address belongs to `(ak, nk)`

#### Output note (condition 6)

6. [**Note Commitment Integrity**](https://valargroup.gitbook.io/shielded-vote-docs/circuit-components/note-commitment-integrity) — Output note commitment to hotkey address

#### Global (conditions 7-8)

7. **VAN Integrity** — `van_comm_core = Poseidon(DOMAIN_VAN, vpk_g_d, vpk_pk_d, num_ballots, vote_round_id, MAX_PROPOSAL_AUTHORITY)`, then `vote_authority_note = Poseidon(van_comm_core, gov_comm_rand)`
8. [**Ballot Scaling**](https://valargroup.gitbook.io/shielded-vote-docs/circuit-components/ballot-scaling) — `num_ballots = floor(sum(v_i) / 12,500,000); num_ballots > 0`

#### Per-note (conditions 9-14, all 5 slots)

9. [**Note Commitment Integrity**](https://valargroup.gitbook.io/shielded-vote-docs/circuit-components/note-commitment-integrity) — Each note's commitment matches its data
10. [**Merkle Tree Membership**](https://valargroup.gitbook.io/shielded-vote-docs/circuit-components/merkle-tree-membership) — Notes with v > 0 exist in `nc_root`; skipped for v=0 dummy notes
11. [**Diversified Address Integrity**](https://valargroup.gitbook.io/shielded-vote-docs/circuit-components/diversified-address-integrity) — Same `ivk` owns each note
12. [**Nullifier Derivation**](https://valargroup.gitbook.io/shielded-vote-docs/circuit-components/nullifier-derivation) — Real nullifier derived (kept private)
13. [**IMT Non-Membership**](https://valargroup.gitbook.io/shielded-vote-docs/circuit-components/imt-non-membership) — Real nullifier not in the nullifier set
14. [**Governance Nullifier**](https://valargroup.gitbook.io/shielded-vote-docs/circuit-components/governance-nullifier) — Gov nullifier correctly derived and published

### Out-of-circuit checks

* Verify signature under `rk` over `sighash`
* `nc_root` and `nullifier_imt_root` match published values
* No `gov_null_i` has been seen before
* `dom` is derived from `vote_round_id` and the protocol identifier (verified by construction)
* `vote_round_id` matches an active round
