> For the complete documentation index, see [llms.txt](https://docs.nullmask.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nullmask.io/protocol-specification/transaction-nullifiers.md).

# Transaction Nullifiers

Nullmask shielded actions must be authorized by signed virtual transactions. This authorization model differs fundamentally from other privacy protocols.

## Authorization Model

* **Railgun and Zcash**: The host selects notes that fund a shielded transaction; the wallet then signs the full shielded transaction data, which includes note nullifiers. The wallet has direct knowledge of which notes are being spent.
* **Nullmask**: The wallet signs a standard transaction expressing an intent (e.g., "send 1 ETH to Alice"); the proxy then selects notes to fund the shielded transaction. The wallet has no knowledge of notes or nullifiers.

This separation introduces a fundamental problem: since the proxy controls note selection, a malicious proxy could replay the same signed intent with different funding notes.

## Solution

Transaction nullifiers prevent replay. The Nullmask contract stores all transaction nullifiers and rejects transactions with previously used nullifiers. Each executed transaction on the EVM can be indexed by the unique `(chainId, address, nonce)` triple. Nullmask shielded actions mask this triple by hashing it together with the nullifying key.

{% hint style="success" %}
**Definition 6: Transaction Nullifier**

For a transaction $$\mathtt{tx}$$ and nullifying key $$\mathtt{nk}$$:

$$\mathtt{nf\_{tx}} := \operatorname{Poseidon2T4}(\mathtt{nk}, ; \mathtt{tx.nonce} \cdot 2^{32} + \mathtt{tx.chainId}, ; \mathtt{pk\_hash})$$
{% endhint %}

The chain ID and nonce are compacted into a single field element, requiring only one Poseidon2T4 invocation.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.nullmask.io/protocol-specification/transaction-nullifiers.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
