Shielded Transfers

A shielded transfer sends tokens privately from one address to another within the Nullmask privacy pool. The recipient must have a registered receiving key.

Transaction Nullifiers

circle-check

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

Why Transaction Nullifiers?

Nullmask's design separates the signing authority (wallet) from the note selection (proxy). The wallet signs an intent ("send 1 ETH to Alice"), and the proxy chooses which notes fund the transaction.

This creates a replay risk: a malicious proxy could resubmit the same signed transaction with different funding notes. Transaction nullifiers prevent this — the contract stores all transaction nullifiers and rejects duplicates.

Comparison with Other Protocols

Nullmask's authorization model differs fundamentally from Zcash and Railgun:

  • 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. Transaction nullifiers solve this — each unique (chainId, address, nonce) triple can only be used once, and the contract rejects duplicates.

Circuit Verification Checklist

The shielded transfer circuit verifies all of the following:

#
Verification
Purpose

1

Transaction Nullifier

Prevents replay attacks

2

Commitments of all funding notes

Proves note existence

3

Merkle tree paths of all funding notes

Proves notes are in the tree

4

Nullifiers of all funding notes

Enables double-spend prevention

5

Balance equation (input ≥ output + fee)

Prevents value creation

6

RLP deserialization of the virtual transaction

Parses the signed transaction

7

ECDSA signature of the virtual transaction

Proves user authorization

8

Sender matches shielded action sender

Links signature to action

9

Recipient matches shielded action recipient

Prevents recipient substitution

10

Gas fee matches the transaction

Prevents fee manipulation

11

Change note correctness

Ensures correct change

12

Recipient key in Key Registry (Merkle proof)

Verifies recipient registration

13

Output note encryption

Prevents unspendable notes

Public Inputs (45 fields)

The shielded transfer circuit produces 45 public output fields:

Output Notes

A shielded transfer produces 3 new notes:

  1. Output note — For the recipient, containing the transferred value

  2. Change note — For the sender, containing leftover action-asset value

  3. Fee change note — For the sender, containing leftover fee-asset value

If the action asset and fee asset are the same token, one of the change notes may have zero value.

Last updated