> For the complete documentation index, see [llms.txt](https://valargroup.gitbook.io/shielded-vote-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://valargroup.gitbook.io/shielded-vote-docs/circuit-components/governance-nullifier.md).

# Governance Nullifier

**Used in:** ZKP #1 (condition 14)

## What it does

Derives a governance-domain nullifier for each delegated note. These nullifiers are published to prevent double-delegation, without revealing the note's real on-chain nullifier.

## Circuit

```
gov_null_i = Poseidon(nk, dom, real_nf_i)
```

A single `ConstantLength<3>` Poseidon call with 3 inputs:

* `nk` — the nullifier deriving key (private witness, same as used in standard nullifier derivation)
* `dom` — the nullifier domain (public input), derived out-of-circuit as `Poseidon("governance authorization", vote_round_id)`. Scopes the nullifier to this voting round.
* `real_nf_i` — the note's real on-chain nullifier (derived in condition 12, kept private)

## Privacy properties

* The governance nullifier is **deterministic** — the same note in the same round always produces the same `gov_null`
* It is **unlinkable** to the real on-chain nullifier, even if `real_nf_i` is later revealed when the note is spent. This is because the derivation depends on `nk`, which is secret.
* It is **unique** per note per round — different rounds produce different governance nullifiers for the same note

## Domain separation

The governance nullifier keys off `nk`. `nk` and `vsk.nk` (used by the ZKP #2 VAN nullifier) are the **same field element** — both are the nullifier deriving key from the FVK; the "vsk" prefix denotes voting-context role only.

Cross-circuit collision uniqueness relies on the nullifier domains being distinct. In ZKP #1, `dom` is a public input derived from the protocol identifier `"governance authorization"` and `vote_round_id`. In ZKP #2, the VAN nullifier uses a VK-baked constant `"vote authority spend"`. Because `dom` incorporates the protocol identifier, governance nullifiers and VAN nullifiers cannot collide even though they share the same `nk`. See [VAN Nullifier — Domain separation](https://github.com/z-cale/shielded-vote-book/blob/main/circuits/shielded_vote_book/circuits/van-nullifier.md#domain-separation) for the full analysis.

## Out-of-circuit check

The vote chain verifies that no `gov_null_i` has been seen before. This prevents the same note from being delegated twice in the same round. The verifier derives `dom` from `vote_round_id` and the protocol identifier, ensuring it is valid for the current voting round.
