# Status update & RFC: ZEC-NAM shielded airdrop protocol

**URL:** <https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144>\
**Category:** Ecosystem Updates\
**Created:** [October 25, 2024, 3:41pm UTC](https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144 "2024-10-25T15:41:03Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![camofu](https://avatars.discourse-cdn.com/v4/letter/c/f07891/32.png) [@camofu](https://forum.zcashcommunity.com/u/camofu)\
**Post date:** [October 25, 2024, 3:41pm UTC](https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144/1 "2024-10-25T15:41:03Z")

</div>

After a hiatus period, the Heliax team would like to update you on the status of the _Shielded Airdrop Protocol_ and share with you our latest reflections and plans. The goal of this post is twofold:

1. To update you, the Zcash community, on our latest work, and
2. To open up an opportunity for you to provide technical feedback so we can focus our efforts accordingly.

Your help can maximize the utility of our work, so we look forward to reviewing your feedback; it has a proven positive impact on this project. Throughout this post we are going to mark in with 🔴 what we look forward to discussing with you the most.

## Post Structure

This post is going to describe a _Shielded Airdrop Transaction Structure_ as it would happen between _Sapling_ and the [_Multi Asset Shielded Pool_](https://github.com/anoma/masp/blob/main/docs/multi-asset-shielded-pool.pdf) (MASP) and also _Orchard_ and the _MASP_. Here we will:

1. Point out what statements are present in the _Shielded Airdrop Transaction Structure_, and propose an abstract specification of such statements.
2. Refer to an abstract specification of a _Balance and Binding Signature_, purposefully created for the _Shielded Airdrop Protocol_.
3. Describe the an airdrop transaction structure, showing how statements and signatures are put together to create a verifiable transaction structure.
4. Give an outlook on possible future developments.

**On notation:** _When variables or symbols are introduced without definition, their definition follows Zcash and MASP specifications_.

## Historical context

A thorough review from Zcash cryptographers pointed out a flaw in the previous iteration of our protocol design, [here](https://github.com/anoma/namada-shielded-airdrop/tree/cc92de1f752c51e8abd7509f4f47a0d48f2d37d7) shown as it was on Apr 3, 2024, right before it was reviewed. For context, we would like to redirect the interested reader to:

- A [non-technical](https://forum.zcashcommunity.com/t/on-namada-zcash-alliance-shielded-airdrop-to-zcash-holders/46189) and a [technical](https://forum.zcashcommunity.com/t/technical-rfc-zec-nam-shielded-airdrop-mechanism/47301) discussion between us and the zcash community.\[1\]
- A [review](https://hackmd.io/vcJ20aZSTwWZLzUGjo8UpQ?view) by Daira-Emma Hopwood.

To say it briefly, our scheme revealed nullifiers of unspent zcash notes, in turn breaking non-linkability between note commitments and nullifier set. This constituted a privacy leak for Zcash users involved in the shielded airdrop protocol.

## Updeted protocol requirements

For the current iteration of the _Shielded Airdrop Protocol_, version 2.0, we set the following requirements:

**Protocol requirement 1**

> Fix the privacy leakage of the previous protocol design iteration.

**Protocol requirement 2**

> Design a shielded airdrop transaction structure involving both: Zcash _Orchard_ pool and _MASP_; Zcash _Sapling_ pool and _MASP_.

# Non membership proofs

To comply with **protocol requirement 1** we introduce non-membership proofs over the _Nullifier Set_ in our statements. After describing their functioning here, we are going to specify how they fit in the Statements later in this document. A non-membership proof is used to produce statements that guarantee that the prover knows a nullifier that does not belong to the public set of revealed nullifiers. In both Sapling and Orchard, the _Nullifier Set_ is a set of **N** Field Elements:

\mathcal{N} = \mathsf{\{{nf}\_1\ , {nf}\_2 , ... {nf}\_N\}}

Let us call \mathsf{nf\_{unspent}} the nullifier of a unspent note.

Both constructions can be described as a statement in which a prover assures that given as primary input:

1. A function over \mathcal{N}.

The prover knows the auxiliary input:

1. \mathsf{nf\_{unspent}}.

Such that:

**Non-membership check** : \mathsf{nf\_{unspent}} \not\subset \mathcal{N}.

We discuss two approaches to a non-membership proof of this kind:

1. One can prove that the nullifier belongs to the complement set of revealed nullfiers: since nullifiers are arbitrary finite field elements, the set of all possible non-spent nullifiers in well-defined. We refer to this as the _Complement set approach_.
2. One can prove that the nullifier is different to every single nullifier of the nullfier set, treating the published nullifier effectively set as a blacklist which users prove they do not belong to. We refer to this as the _Not-blacklisted approach_.

🔴 We see both as plausible solutions, and we still have to evaluate the tradeoffs between the two.

### Complement set approach

A “nullifier non-membership tree” is a Merkle tree of sorted disjoint (start, end) pairs representing the gaps between the elements of \mathcal{N}. That is, the union of the regions start..=end is exactly the complement of the set of \mathcal{N}. We call the root of such tree \mathsf{rt^{excl}}, and \mathsf{path^{excl}} a path.

The statement than assures that given a primary input:

| Orchard | Sapling |
| --- | --- |
| \mathsf{rt^{excl}} ⦂ \{ 0 .. q\_{\mathbb{P}}-1 \} | \mathsf{rt^{excl}} ⦂ \mathbb{B}^{[\ell\_{Merkle}^{Sapling}]} |

The prover knows an auxiliary input:

| Orchard | Sapling |
| --- | --- |
| \mathsf{path^{excl}} ⦂ \{ 0 .. q\_{\mathbb{P}}-1 \}^{[\mathsf{MerkleDepth^{excl}}]} | \mathsf{path^{excl} ⦂ \mathbb{B}^{[\ell\_{Merkle}^{Sapling}][MerkleDepth^{excl}]}} |
| \mathsf{pos^{excl}} ⦂ \{ 0 .. 2^{\mathsf{MerkleDepth^{excl}}}\!-1 \} | \mathsf{pos^{excl}} ⦂ \{ 0 .. 2^{\mathsf{MerkleDepth^{excl}}}\!-1 \} |
| \mathsf{start} ⦂ \{ 0 .. 2^{\mathsf{MerkleDepth^{Orchard}}}\!-1 \} | \mathsf{start} ⦂ \{ 0 .. 2^{\mathsf{MerkleDepth^{Sapling}}}\!-1 \} |
| \mathsf{end} ⦂ \{ 0 .. 2^{\mathsf{MerkleDepth^{Orchard}}}\!-1 \} | \mathsf{end} ⦂ \{ 0 .. 2^{\mathsf{MerkleDepth^{Sapling}}}\!-1 \} |
| \mathsf{nf\_{unspent}} ⦂\{ 0 .. 2^{\ell^{\mathsf{Orchard}}\_{\mathsf{scalar}}}-1 \} | \mathsf{nf\_{unspent}} ⦂\mathbb{B^{Y^{[\ell\_{\mathsf{PRFnfSapling}}/8]}}} |

Such that the following conditions hold:

- **Merkle path validity for** (\mathsf{start}, \mathsf{end}) \hspace{0.5em} (\mathsf{path^{excl}}, \mathsf{pos^{excl}}) is a valid Merkle path of depth \mathsf{MerkleDepth^{excl}}, as defined in § 4.9 ‘Merkle Path Validity’ in Zcash specs, from \mathsf{excl} to the anchor \mathsf{rt^{excl}}, where \mathsf{excl} = \mathsf{MerkleCRH^{Pool}}(\mathsf{MerkleDepth^{excl}}, \mathsf{start}, \mathsf{end}).
- **Nullifier in excluded range** \hspace{0.5em} \mathsf{start} \leq \mathsf{nf\_{unspent}} \leq \mathsf{end}.

### 🔴 Not-blacklisted approach

The belonging of nullifier set elements to a prime order group allow us to frame a polynomial evaluation argument efficiently as a circuit satisfiability one. Such statement can be proved using _Groth16_ when we are concerned with _Sapling_ and _Halo 2_ when we are with _Orchard_.

Our goal is again to prove knowledge of a nullifier such that \mathsf{nf\_{unspent}} \not\subset \mathcal{N} .

Let us consider the following polynomial over the finite field that contains the revealed nullifiers:

P(X) = \prod\_{i=1}^{N}(X-\mathsf{nf\_{i}})

Given:

v = P(\mathsf{nf\_{unspent}})  
w = v^{-1}

We can construct a circuit that proves that:

1. **Polynomial evaluation** v = P(\mathsf{nf\_{unspent}})
2. **inverse correctness** w \* v = 1

Indeed, if \mathsf{nf\_{unspent}} \subset \mathcal{N} then P(\mathsf{nf\_{unspent}}) = 0 and it is not possible to find any w such that w \* v = 1.

# Airdrop nullifier

To comply with **protocol requirement 1** we introduce the notion of an “airdrop nullifier”. An “airdrop nullifier” is a value derived from a note, with similar cryptographic properties to its standard nullifier. It is distinct from and unlinkable from the standard nullifier. In an _Shielded Airdrop Transaction_ the alternate nullifier will be revealed in place of the actual note nullifier, to prevent double-claims. We also introduce an Airdrop nullifier set, which accumulates all the Airdrop nullifiers that are revealed in airdrop transactions. Airdrop nullifier are specified as:

In **Sapling** :  
\mathsf{PRF^{nfSAir}\_{nk\star}}(\rho\star) = BLAKE2s\text{-}256(\texttt{"MASP\_alt"},   
\phantom{\mathsf{PRF^{nfSAir}\_{nk\star}}(\rho\star) = BLAKE2s\text{-}256(}\boxed{\mathsf{LESBS2OP\_{256}(nk\star)}}\boxed{\mathsf{LESBS2OP\_{256}(\rho\star)}})  
\mathsf{nf\_{Air}^{Sapling}} = PRF^{nfSAir}\_{nk\star}(\rho\star)  
\phantom{\mathsf{nf\_{Air}^{Sapling}}} = \mathsf{DeriveAirdropNullifier\_{nk}^{Sapling}(\rho)}

🔴 In **Orchard** :  
\mathcal{K}^{Airdrop} := GroupHash^{\mathbb{P}}(\texttt{"MASP:Airdrop", "K"})  
\mathsf{PRF^{nfSAir}\_{nk}}(\rho) = PoseidonHash(nk, \rho)  
\mathsf{nf\_{Air}^{Orchard}} = Extract\_{\mathbb{P}}( ((PRF^{nfSAir}\_{nk}(\rho) + \psi) \bmod q \cdot \mathbb{P}||\mathcal{K}^{Airdrop}+cm))  
\phantom{\mathsf{nf\_{Air}^{Orchard}}} = \mathsf{DeriveAirdropNullifier^{Orchard}\_{nk}}(\texttt{p}, \texttt{\psi}, \mathsf{cm})

# Statements

_In the following statements_ \mathsf{old} _is used to refer to the notes (eith in Sapling or Orchard) that are being you to claim an airdrop reward_.

## Claim Statement (Orchard or Sapling)

A valid instance of a Claim statement, \pi, assures that given a _primary input_:

| Orchard | Sapling |
| --- | --- |
| \mathsf{rt^{Orchard}} ⦂ \{ 0 .. q\_{\mathbb{P}}-1 \} | \mathsf{rt^{Sapling} ⦂ \mathbb{B}^{[\ell\_{Merkle}^{Sapling}]}} |
| \mathsf{cv^{Orchard}} ⦂ \mathsf{ValueCommit^{Orchard}.Output} | \mathsf{cv^{old} ⦂ ValueCommitment^{Sapling}.Output} |
| \mathsf{nf\_{Air}^{Orchard} } ⦂ \{0..q\_{\mathbb{P}}-1\} | \mathsf{nf\_{Air}^{Sapling} ⦂ \mathbb{B}^{[\ell\_{PRFnfSapling}]}} |
| \mathsf{rk} ⦂ \mathsf{SpendAuthSig^{Orchard}.Public} | \mathsf{rk ⦂ SpendAuthSig^{Sapling}.Public} |
| \mathcal{N} | \mathcal{N} |

The prover knows an _auxiliary private input_:

| Orchard | Sapling |
| --- | --- |
| \mathsf{path} ⦂ \{ 0 .. q\_{\mathbb{P}}-1 \}^{[\mathsf{MerkleDepth^{Orchard}}]} | \mathsf{path ⦂ \mathbb{B}^{[\ell\_{Merkle}^{Sapling}][MerkleDepth^{Sapling}]}} |
| \mathsf{pos} ⦂ \{ 0 .. 2^{\mathsf{MerkleDepth^{Orchard}}}\!-1 \} | \mathsf{g\_d ⦂ \mathbb{J}} |
| \mathsf{g\_d^{old}} ⦂ \mathbb{P}^\* | \mathsf{pk\_d ⦂ \mathbb{J}} |
| \mathsf{pk\_d^{old}} ⦂ \mathbb{P}^\* | \mathsf{v^{old} ⦂ \{ 0..2^{\ell\_{value}} -1\}} |
| \mathsf{v^{old}} ⦂ { 0 .. 2^{\ell\_{\mathsf{value}}}-1 } | \mathsf{rcv^{old} ⦂ \{ 0..2^{\ell^{Sapling}\_{scalar}} -1\}} |
| \text{ρ}^{\mathsf{old}} ⦂ \mathbb{F}\_{q\_{\mathbb{P}}} | \mathsf{cm^{old} ⦂ \mathbb{J}} |
| \text{φ}^{\mathsf{old}} ⦂ \mathbb{F}\_{q\_{\mathbb{P}}} | \mathsf{rcm^{old} ⦂ \{ 0..2^{\ell^{Sapling}\_{scalar}} -1\}} |
| \mathsf{rcm^{old}} ⦂ { 0 .. 2^{\ell^{\mathsf{Orchard}}{\mathsf{scalar}}}-1 } | \mathsf{\alpha ⦂ \{ 0..2^{\ell^{Sapling}\_{scalar}} -1\}} |
| \mathsf{cm^{old}} ⦂ \mathbb{P} | \mathsf{ak ⦂ SpendAuthSig.Public} |
| \mathsf{nf^{old}} ⦂ \{ 0 .. q\_{\mathbb{P}}-1 \} | \mathsf{nsk ⦂ \{ 0..2^{\ell^{Sapling}\_{scalar}} -1\}} |
| \alpha ⦂ \{ 0 .. 2^{\ell^{\mathsf{Orchard}}{\mathsf{scalar}}}-1 \} | - |
| \mathsf{ak}^{\mathbb{P}} ⦂ \mathbb{P}^\* | - |
| \mathsf{nk} ⦂ \mathbb{F}\_{q\_{\mathbb{P}}} | - |
| \mathsf{rivk} ⦂ \mathsf{Commit^{ivk}.Trapdoor} | - |
| \mathsf{rcv} ⦂ \{ 0 .. 2^{\ell^{\mathsf{Orchard}}{\mathsf{scalar}}}-1 \} | - |
| \mathsf{nf\_{unspent}^{old}} ⦂ \{0..q\_{\mathbb{P}}-1\} | \mathsf{nf\_{unspent}^{old}}⦂ \mathbb{B}^{[\ell\_{PRFnfSapling}]} |

Such that the following conditions hold:

| | Orchard | Sapling |
| --- | --- | --- |
| **Note commitment integrity** | \hspace{0.5em} \mathsf{NoteCommit^{Orchard}\_{rcm^{old}}}(\mathsf{repr}\_{\mathbb{P}}(\mathsf{g\_d^{old}}), \mathsf{repr}\_{\mathbb{P}}(\mathsf{pk\_d^{old}}), \mathsf{v^{old}}, \text{ρ}^{\mathsf{old}}, \text{φ}^{\mathsf{old}}) \in \{ \mathsf{cm^{old}}, \bot \} | \hspace{0.5em} \mathsf{NoteCommit^{Sapling}\_{rcm^{old}}}(\mathsf{repr}\_{\mathbb{J}}(\mathsf{g\_d}), \mathsf{repr}\_{\mathbb{J}}(\mathsf{pk\_d}), \mathsf{v^{old}} ) |
| **Merkle path validity** | Either \mathsf{v^{old} = 0} or (\mathsf{path}, \mathsf{pos}) is a valid Merkle path of depth \mathsf{MerkleDepth^{Orchard}}, as defined in § 4.9 ‘Merkle Path Validity’, from \mathsf{cm^{old}} to the anchor \mathsf{rt^{Orchard}}. | Either \mathsf{v^{old} = 0}, or \mathsf{(path, pos)} is a valid _Merkle Path_ of depth \mathsf{MerkleDepth^{Sapling}}, as defined in the original Sapling specification, from \mathsf{cm\_{u}=Extract\_{\mathbb{J}^{(r)}}(cm^{old})} to the _anchor_ \mathsf{rt} |
| **Value commitment integrity** | \hspace{0.5em} \mathsf{cv} = \mathsf{ValueCommit^{Orchard}\_{rcv}}(\mathsf{v^{old}}). | \hspace{0.5em} \mathsf{cv^{old}} = \mathsf{ValueCommit^{old}\_{rcv}}(\mathsf{v^{old}}). |
| **Small order checks** | - | \hspace{0.5em} \mathsf{g\_d} and \mathsf{ak} are not of small order, i.e. [h\_{\mathbb{J}}]\mathsf{g\_d}\neq \mathcal{O}\_{\mathbb{J}} and [h\_{\mathbb{J}}]\mathsf{ak}\neq \mathcal{O}\_{\mathbb{J}}. |
| **Nullifier integrity** | \hspace{0.5em} \mathsf{nf^{old}} = \mathsf{DeriveNullifier\_{nk}}(\text{ρ}^{\mathsf{old}}, \text{φ}^{\mathsf{old}}, \mathsf{cm^{old}}). | \hspace{0.5em} \mathsf{nf^{old} = PRF\_{nk\star}^{nfSapling}(\rho\star)} where \hspace{2.5em} \mathsf{nk\star = repr\_{\mathbb{J}}([nsk]\mathcal{H})} \hspace{2.5em} \mathsf{\rho\star = repr\_{\mathbb{J}}(MixingPedersenHash(cm^{Sapling}, pos))} |
| **Spend authority** | \hspace{0.5em} \mathsf{rk} = \mathsf{SpendAuthSig^{Orchard}.RandomizePublic}(\alpha, \mathsf{ak}^{\mathbb{P}}). | \hspace{0.5em} \mathsf{rk = SpendAuthoritySig.RandomizePublic(\alpha, ak )}. |
| **Diversifier address integrity** | \hspace{0.5em} \mathsf{ivk} = \bot or \mathsf{pk\_d^{old}} = [\mathsf{ivk}]\, \mathsf{g\_d^{old}} where \mathsf{ivk} = \mathsf{Commit^{ivk}\_{rivk}}(\mathsf{Extract}\_{\mathbb{P}}(\mathsf{ak}^{\mathbb{P}}), \mathsf{nk}). | \hspace{0.5em} \mathsf{pk\_d = [ivk]g\_d} where \hspace{2.5em} \mathsf{ivk = CRH^{ivk}(ak\star,nk\star)} \hspace{2.5em} \mathsf{ak\star = repr\_\mathbb{J}(ak)}. |
| **Non-membership check** | _As defined above_ | _As defined above_ |
| **Airdrop nullifier integrity** | \hspace{0.5em} \mathsf{nf\_{Air}^{Orchard}} = \mathsf{DeriveAirdropNullifier\_{nk}^{Orchard}}(\text{ρ}^{\mathsf{old}}, \text{φ}^{\mathsf{old}}, \mathsf{cm^{old}}). | \hspace{0.5em} \mathsf{nf\_{Air}^{Sapling} = DeriveAirdropNullifier\_{nk}^{Sapling}}(\text{ρ}^{\mathsf{old}}) |

## Output Statement

The _Output Circuit_ is defined in § 0.12.3 ‘Output Statement (MASP)’ of the Multi-Asset Shielded Pool Specification.

## Convert Statement

The _Convert Statement_ is defined in § 0.12.5 ‘Convert Statement’ of the Multi-Asset Shielded Pool Specification.  
Within the MASP protocol, the Convert Statement allows for a shileded burn-and-mint conversion between assets of different types, according to a predetermined, public, fixed ratio. Broadly speaking, in this context is used to burn a proof of ownership of zcash asset to mint an airdrop reward.

## Equivalence Statement

To comply with **Protocol requirement 2** we introduce the _Equivalence Statement_. The _Equivalence Statement_ allows the conversion between a \mathsf{ValueCommitment} in _Sapling_ and one in _Orchard_ by proving they are equivalent, i.e. they are commitments to the same value.

A valid instance of the _Equivalence Stament_ assures that given as _primary input_:

1. \mathsf{cv^{Sapling} : ValueCommit^{Sapling}.Output}
2. \mathsf{cv^{Orchard} : ValueCommit^{Orchard}.Output}

the prover knows as auxiliary input:

1. \mathsf{v: \{0..MAX\_MONEY\}}
2. \mathsf{rcv^{Sapling} : ValueCommit^{Sapling}.Trapdoor}
3. \mathsf{rcv^{Orchard} : ValueCommit^{Orchard}.Trapdoor}

such that:

1. \mathsf{cv^{Sapling} = ValueCommit^{Sapling}(rcv^{Sapling}, v)}
2. \mathsf{cv^{Orchard} = ValueCommit^{Orchard}(rcv^{Orchard}, v)}

**Notes on circuit implentation of the _Equivalence Statement_**

1. Such statement can be proven using either in Halo2 or Groth16.
2. A circuit implementing the _Equivalence Statement_ would use non-native field arithmetics.

# Binding and Balance Signature

The signature specification can be found [here](https://github.com/anoma/namada-shielded-airdrop/blob/main/BINDING_SIGNATURE.pdf). This part of the protocol is left unchanged from the previous protocol design iteration.

# Create an Shielded Airdrop Transaction

_Here we are going to mark with 🟢 steps that are specific to Sapling and with 🔵 steps that are specific to Orchard. 🟢 and 🔵 steps are alternative._  
To create a valid _Shielded Airdrop Transaction Structure_ an actor must:

1. Generate a _Output Description_ tuple \mathsf{(cv^{MASP}, cm^{MASP}, epk, C^{enc}, C^{out}, \pi\_{ZKOuput})} as described in § 0.11.1 ‘Sending Notes (Sapling)’ of the _MASP Specification_.
2. 
  - 🟢 Generate a _Sapling Claim Description_ tuple \mathsf{(cv^{Sapling}, rt^{Sapling}, nf\_{Air}^{Sapling}, rk^{Sapling}, \mathcal{N}, \pi\_{ClaimSapling}, spendAuthSig^{Sapling})}
  - 🔵 Generate a _Orchard Claim Description_ tuple \mathsf{(cv^{Orchard}, rt^{Orchard}, nf\_{Air}^{Orchard}, rk^{Orchard}, \mathcal{N}, \pi\_{ClaimOrchard}, spendAuthSig^{Orchard})}
  - 🔵 Generate a _Equivalence Description_ tuple \mathsf{(cv^{Sapling}, cv^{Orchard}, \pi\_{Equivalence})}

3. Generate a _Convert Description Tuple_ \mathsf{(rt^{Convert}, cv^{mint}, \pi\_{Convert})}
4. Generate an _Airdrop Binding Signature_ \mathsf{bindingSigAirdrop}.

A _Shielded Airdrop Transaction Structure_ would be composed by the set of descriptions above together with the _Airdrop Binding Signature_.

A _Shielded Airdrop Transaction Structure_ constitutes a valid _Shielded Airdrop Transaction_ is valid if:

1. All the statemetns proofs present in the transaction are valid.
2. All the signatures are valid.
3. The Airdrop nullifier reveald is not in the Airdrop nullifier set.
4. 🔵 \mathsf{cv^{Orchard}} given as a public input to the _Equivalence statement_ and \mathsf{cv^{Orchard}} given as a public input to the _Claim statement_ are equal.

# Conclusions and outlook

To the best of our knowledge, there are no further **Protocol requirements** that this design iteration is not meeting and would require a further “_Shielded Airdrop protocol 3.0_” protocol update. What we have interest in further researching is:

1. A more efficient and implementation friendly shielded airdrop protocol.
2. 🔴 Applications of the shielded airdrop protocol mechanisms outside the scope of a shielded airdrop. We are interested in exploring how we can leverage these techniques so that Zcash users can leverage our work here for governance purposes.
3. Anything that comes up from discussions on this post.

* * *

1. _N.b. the github link referenced in the discussion above was pointing to the version previously linked, Apr 3, 2024_.

---

<div class="post-metadata">

**Author:** ![speedfox](https://sea2.discourse-cdn.com/zcash/user_avatar/forum.zcashcommunity.com/speedfox/32/30612_2.png) [@speedfox](https://forum.zcashcommunity.com/u/speedfox)\
**Post date:** [November 17, 2024, 8:21am UTC](https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144/2 "2024-11-17T08:21:56Z")

</div>

> [@camofu](#):
>
> - **Polynomial evaluation** v = P(\mathsf{nf\_{unspent}})v=P(nfunspent)v = P(\mathsf{nf\_{unspent}})
> - **inverse correctness**

Thanks for the update. I was thinking if we could get kind of a less condense d mathematical related explanation as it would be of great benefit to the understanding of ` **WE`\*\* who do not know what the meaning of \*** Polynomial evaluation** nor it related siblings are.

---

<div class="post-metadata">

**Author:** ![noamchom](https://sea2.discourse-cdn.com/zcash/user_avatar/forum.zcashcommunity.com/noamchom/32/20269_2.png) [@noamchom](https://forum.zcashcommunity.com/u/noamchom)\
**Post date:** [November 21, 2024, 2:14pm UTC](https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144/3 "2024-11-21T14:14:25Z")

</div>

Is someone in the Zcash community able to boil these contents down into something comprehendible for a typical ZEC holder?

---

<div class="post-metadata">

**Author:** ![silentZcollector](https://sea2.discourse-cdn.com/zcash/user_avatar/forum.zcashcommunity.com/silentzcollector/32/30093_2.png) [@silentZcollector](https://forum.zcashcommunity.com/u/silentZcollector)\
**Post date:** [November 22, 2024, 7:46am UTC](https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144/4 "2024-11-22T07:46:48Z")

</div>

> **[Proposing Mainnet Genesis Time](https://forum.namada.net/t/proposing-mainnet-genesis-time/1104)**
>
> Hello! The dry-run of mainnet has been generally a success so far. Thank you so much to the community for orchestrating such an effective decentralized launch and for smoothly testing the transitions between the different phases of mainnet. To...

… but still nothing concrete, no snapshot time, no amount, atm i am not even sure if we will see an airdrop by the time that mainnet is going live.

---

<div class="post-metadata">

**Author:** ![tokidoki](https://avatars.discourse-cdn.com/v4/letter/t/dc4da7/32.png) [@tokidoki](https://forum.zcashcommunity.com/u/tokidoki)\
**Post date:** [November 22, 2024, 10:52am UTC](https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144/5 "2024-11-22T10:52:31Z")

</div>

The shielded ZEC airdrop will happen after mainnet. There’s already an allocation for that in the Namada (Restrospective) Public Goods Fund pool. Also, there’s a proposal to launch mainnet in the first week of December on the Namada forum.

---

<div class="post-metadata">

**Author:** ![artkor](https://sea2.discourse-cdn.com/zcash/user_avatar/forum.zcashcommunity.com/artkor/32/28573_2.png) [@artkor](https://forum.zcashcommunity.com/u/artkor)\
**Post date:** [November 26, 2024, 3:33pm UTC](https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144/6 "2024-11-26T15:33:23Z")

</div>

> <https://x.com/Airdrops_one/status/1860169033586278591>

---

<div class="post-metadata">

**Author:** ![earthrise](https://sea2.discourse-cdn.com/zcash/user_avatar/forum.zcashcommunity.com/earthrise/32/11887_2.png) [@earthrise](https://forum.zcashcommunity.com/u/earthrise)\
**Post date:** [November 27, 2024, 12:23am UTC](https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144/7 "2024-11-27T00:23:31Z")

</div>

> [@noamchom](#):
>
> Is someone in the Zcash community able to boil these contents down into something comprehendible for a typical ZEC holder?

Here’s the ELI5 version (well, as best I can):

To be eligible for the airdrop, you need to prove how much unspent shielded ZEC you had at the time of the snapshot. The protocol also needs to guarantee that you can only do this once, i.e. so that you can’t just have 1.0 shielded ZEC and prove you have it 100 times in order to get 100 ZEC worth of airdrop rewards.

In every Zcash shielded transaction, you prove that you own a ZEC note (without revealing which one), and you reveal its nullifier. The consensus rules enforce all the nullifiers to be unique, which is what prevents double-spending the same note. A note is spent once its nullifier has been added to the nullifier set.

In the original airdrop design, you would basically do what you normally do when you’re producing a shielded transaction: you prove you own a note, you reveal its nullifier and its value, but you don’t produce the signatures needed to actually spend it. The airdrop protocol verifies that proof and, after checking that the nullifier is unique, gives you your airdrop funds.

But there’s a privacy leak in that design: claiming the airdrop reward reveals the real nullifier of your note. When you eventually spend the note in a shielded transaction, it will reveal the same nullifier as you already revealed in the airdrop reward claim, so the two actions can be linked together.

The proposed fix to that is: instead of revealing your note’s actual nullifier to claim the airdrop reward, you reveal a different kind of nullifier for the note, which is unlikable to the note’s actual nullifier and which is used to prevent double-claiming airdrop rewards. But, since you’re not revealing the actual nullifier, in order to check that your note is unspent at the time of the snapshot, you also need to use a zero-knowledge proof to prove that your nullifier is not in the nullifier set at the time of the snapshot.

In other words, you’re producing a proof that “I had x amount of unspent ZEC at the time of the snapshot”, but (in the new design) without revealing any of your notes’ actual nullifiers.

---

<div class="post-metadata">

**Author:** ![earthrise](https://sea2.discourse-cdn.com/zcash/user_avatar/forum.zcashcommunity.com/earthrise/32/11887_2.png) [@earthrise](https://forum.zcashcommunity.com/u/earthrise)\
**Post date:** [December 5, 2024, 11:35pm UTC](https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144/8 "2024-12-05T23:35:58Z")

</div>

Btw when is the snapshot? Has it already happened or has the date not yet been announced yet?

---

<div class="post-metadata">

**Author:** ![tokidoki](https://avatars.discourse-cdn.com/v4/letter/t/dc4da7/32.png) [@tokidoki](https://forum.zcashcommunity.com/u/tokidoki)\
**Post date:** [December 6, 2024, 12:51am UTC](https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144/9 "2024-12-06T00:51:52Z")

</div>

> <https://x.com/cwgoes/status/1863233838677164364>

I don’t think the snapshot has been decided yet.

---

<div class="post-metadata">

**Author:** ![cwgoes](https://sea2.discourse-cdn.com/zcash/user_avatar/forum.zcashcommunity.com/cwgoes/32/14213_2.png) [@cwgoes](https://forum.zcashcommunity.com/u/cwgoes)\
**Post date:** [December 30, 2024, 5:53pm UTC](https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144/10 "2024-12-30T17:53:34Z")

</div>

No concrete details of the airdrop have been decided yet – and they won’t be until we’re confident that we have a mechanism which the Zcash community considers to be secure, privacy-preserving, and fair – and which could also be reused by other parties (to conduct other shielded airdrops) in the future. That’s our first priority.

Right now, we’re looking for technical feedback on this proposal (from technical folks in the Zcash ecosystem). I’ve reached out to a few folks at ECC but haven’t heard back yet – any help appreciated!

---

<div class="post-metadata">

**Author:** ![joshs](https://sea2.discourse-cdn.com/zcash/user_avatar/forum.zcashcommunity.com/joshs/32/13631_2.png) [@joshs](https://forum.zcashcommunity.com/u/joshs)\
**Post date:** [December 30, 2024, 5:58pm UTC](https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144/11 "2024-12-30T17:58:53Z")

</div>

Hi Chris. Who did you reach out to? Most have been heads down recently and then taking a little time off for the holidays. I’m happy to ensure we take a look.

---

<div class="post-metadata">

**Author:** ![cwgoes](https://sea2.discourse-cdn.com/zcash/user_avatar/forum.zcashcommunity.com/cwgoes/32/14213_2.png) [@cwgoes](https://forum.zcashcommunity.com/u/cwgoes)\
**Post date:** [December 31, 2024, 10:44pm UTC](https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144/12 "2024-12-31T22:44:00Z")

</div>

Thanks @joshs! @camofu and I reached out to @str4d and @daira awhile back. To be clear, I’m sure that ECC folks are busy and don’t mean to complain at all – just wanted to let the Zcash community know that we’re waiting for feedback before starting next steps on our side.

(btw - happy New Year to all! 🎉 )

---

<div class="post-metadata">

**Author:** ![Gavin](https://sea2.discourse-cdn.com/zcash/user_avatar/forum.zcashcommunity.com/gavin/32/27644_2.png) [@Gavin](https://forum.zcashcommunity.com/u/Gavin)\
**Post date:** [April 23, 2025, 12:44am UTC](https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144/13 "2025-04-23T00:44:16Z")

</div>

it would be 🔥 to fulfill Namada’s commitment to the ZEC holder airdrop, but the tool needs ~~code~~ protocol review, ideally from ECC

---

<div class="post-metadata">

**Author:** ![Gavin](https://sea2.discourse-cdn.com/zcash/user_avatar/forum.zcashcommunity.com/gavin/32/27644_2.png) [@Gavin](https://forum.zcashcommunity.com/u/Gavin)\
**Post date:** [April 29, 2025, 3:30pm UTC](https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144/14 "2025-04-29T15:30:32Z")

</div>

update can be found in this forum topic:

> [@Zcash Airdrop Tool](https://forum.zcashcommunity.com/t/zcash-airdrop-tool/50378/13):
>
> @cwgoes @Gavin: @daira is looking at it with the plan to have it reviewed by Monday.

---

<div class="post-metadata">

**Author:** ![daira](https://sea2.discourse-cdn.com/zcash/user_avatar/forum.zcashcommunity.com/daira/32/43253_2.png) [@daira](https://forum.zcashcommunity.com/u/daira)\
**Post date:** [April 30, 2025, 11:22pm UTC](https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144/15 "2025-04-30T23:22:32Z")

</div>

Here is the review by @str4d and me: [Review of Namada airdrop protocol - HackMD](https://hackmd.io/kbc_ylgBQmG3P2Gc2CfH1w)

---

<div class="post-metadata">

**Author:** ![Shawn](https://sea2.discourse-cdn.com/zcash/user_avatar/forum.zcashcommunity.com/shawn/32/187_2.png) [@Shawn](https://forum.zcashcommunity.com/u/Shawn)\
**Post date:** [April 30, 2025, 11:38pm UTC](https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144/16 "2025-04-30T23:38:59Z")

</div>

Tagging @cwgoes and @Gavin for visibility

👆🏻

---

<div class="post-metadata">

**Author:** ![decentralistdan](https://sea2.discourse-cdn.com/zcash/user_avatar/forum.zcashcommunity.com/decentralistdan/32/28747_2.png) [@decentralistdan](https://forum.zcashcommunity.com/u/decentralistdan)\
**Post date:** [May 1, 2025, 12:01am UTC](https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144/17 "2025-05-01T00:01:36Z")

</div>

![IMG_2960](https://global.discourse-cdn.com/zcash/original/3X/4/3/43f52e3a90441abfb6e1922297b7feea65bfef6f.jpeg)

👍 to re-use of [hahn’s implementation of nullifier non-membership for coin-holder voting](https://hhanh00.github.io/coin-voting-book/implementation/circuit.html)

more review. more eyeballs. move both forward faster.

---

<div class="post-metadata">

**Author:** ![cwgoes](https://sea2.discourse-cdn.com/zcash/user_avatar/forum.zcashcommunity.com/cwgoes/32/14213_2.png) [@cwgoes](https://forum.zcashcommunity.com/u/cwgoes)\
**Post date:** [May 1, 2025, 10:02am UTC](https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144/18 "2025-05-01T10:02:21Z")

</div>

Lovely, thank you @daira and @str4d! 🎉

More feedback and ideas are always welcome, but this should be enough to proceed on our end. I’ll follow up here with a more detailed status update soon (to set expectations: this may take a few weeks as we have a lot in flight at the moment).

[as an aside: happy May Day all! 🌻]

---

<div class="post-metadata">

**Author:** ![camofu](https://avatars.discourse-cdn.com/v4/letter/c/f07891/32.png) [@camofu](https://forum.zcashcommunity.com/u/camofu)\
**Post date:** [June 4, 2025, 10:35am UTC](https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144/19 "2025-06-04T10:35:16Z")

</div>

Thank you for the review @daira and @str4d! 🙏

---

<div class="post-metadata">

**Author:** ![cwgoes](https://sea2.discourse-cdn.com/zcash/user_avatar/forum.zcashcommunity.com/cwgoes/32/14213_2.png) [@cwgoes](https://forum.zcashcommunity.com/u/cwgoes)\
**Post date:** [June 15, 2025, 3:38pm UTC](https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144/20 "2025-06-15T15:38:36Z")

</div>

Thanks all for your patience here. Heliax (along with other folks working on Anoma & Namada) has just held our quarterly offsite and planned work for Q3. Unfortunately we do not currently have the resources to commit to a full implementation here in the next quarter – we need to prioritize some urgent work first. It’s possible that we will have more time than I expect in Q3, but I want to share the most realistic assessment that we currently have.

One great advantage of distributed open-source collaboration, however, is that it needn’t be blocked on any particular entity – our protocol proposal and the lovely response from ECC are already public here, and anyone can get started on implementing them. In that spirit, since Heliax is not able to commit to this work in Q3, **I’m offering a $20k grant** (payable in ZEC on Zcash, NAM on Namada, or USDC on Namada – your choice) to anyone who is willing and able to complete a full prototype implementation of this shielded airdrop protocol integrated with a Zcash wallet (a CLI wallet is fine to start), such that the implementation could be reviewed against our protocol spec and tested by interested Zcash users, and such that the Namada chain could integrate verification code. If you are seriously interested in this work, please contact me (here on the forums) or respond to this thread, and we can work out further exact requirements, payment schedule, etc.

[Next page](https://forum.zcashcommunity.com/t/status-update-rfc-zec-nam-shielded-airdrop-protocol/49144.md?page=2)
