Wonderful! Thank you for your trust in us. We’re excited to get started.
I’m enthusiastic about this grant not only because it unlocks a NAM airdrop, but because the underlying research could become for future Zcash mechanisms that we don’t fully know how to build yet.
There are two directions where I believe this work might become strategically important for the community.
1) Deprecation paths for legacy shielded pools
As discussed in the Sprout thread, Zcash will inevitably need to retire old protocols over time. Whether it’s Sprout today, or Sapling pool, the recurring challenge is the same: how do we give users a safe, private and realistic way to “claim” assets from a pool that is no longer maintained?
When I raised this idea earlier (link below), it was just a rough thought, but this grant now makes it feel less hypothetical. A carefully designed “claim by proving private ownership at snapshot height” abstraction could become a standardized exit mechanism for deprecated pools.
@str4d proposed very interesting pathway using ZSA, which I truly like, but it requires those assets to exist.
2) Making coinholder voting more accessible and less risky
I deeply respect the work done so far. We have real progress, but participation numbers show that the current process is still too heavy for most holders. Running nodes, carefully timing for votes and exposing seed to a standalone voting tool is intimidating, especially once ZEC is more valuable. Many holders understandably don’t want to move funds or manage technical risks just to vote.
One idea is to use a shielded snapshot mechanism to mint temporary voting tokens in another network (for example Namada today, or ZSA later). These tokens could represent voting power proportional to shielded ZEC holdings and allow users to vote without touching their actual ZEC, without timing windows, and without exposing secrets to additional software.
This is just a sketch, but the key is separation between ownership assets and governance.
I’m excited to follow the progress, and I appreciate everyone involved for pushing this frontier forward.
Dear Zcash Community,
We report on the completion of milestone 1 for the ZEC-NAM shielded airdrop protocol. In this first of four milestones, the focus has been on the Zcash side regarding specification and implementation, closely following the design and discussions from, see [1].
The core functionality in this milestone is the generation of a chain snapshot frozen at a given height to be used as the public parameters for the airdrop. In addition, we have the specification and implementation of airdrop nullifiers, used for protection against airdrop double-claims.
For verifying airdrop claims, the public parameters include for a given height:
-
Merkle-root of Sapling note commitments,
-
Merkle-root of Orchard note commitments,
-
Merkle-root committing to the gaps of sorted Sapling nullifiers, and
-
Merkle-root committing to the gaps of sorted Orchard nullifiers.
To claim an airdrop, one furthermore needs the explicit nullifier gaps for Sapling and Orchard, to prove a given note was not spent, via a Merkle non-membership proof as described below:
Merkle Non-Membership Proofs
Let S=\{x_1,...,x_n\} be the set of nullifiers sorted by integer value such that
Define the complement gaps G_0=(0,x_1), G_1=(x_1,x_2), G_2=(x_2,x_3), … , G_n=(x_n,\textsf{MAX}) as open intervals between values (a,b) such that a and b are excluded. From each gap, we compute a Merkle leaf L_i = H(pp || G_i) given public parameters pp and a hash function H to be fixed later - in the current implementation the pp are empty and H=\textsf{SHA-256}. This naturally defines a Merkle root and standard Merkle-paths used for proving inclusion of a leaf.
A non-membership proof for any nullifier y in the open interval G_i = (a,b) is
Here intervalProof is used to verify the statement a<y<b. The verification of the interval proof together with the Merkle path guarantees a given gap between spent nullifiers is valid for this snapshot, and that the claimed nullifier y was indeed in this gap.
We note the use of 0 and \textsf{U256::MAX} as fixed gap-bounds, which imply nullifiers with these special-case values cannot be used to prove non-membership, and therefore cannot be used to claim airdrops. Further, checking if y is also a valid field element (e.g. y<p) must be done separately. The intervalProof is to be specified in the next phase using appropriate zk-systems.
Airdrop Nullifiers
To guard against airdrop double-claims while ensuring user privacy, we derive deterministic airdrop nullifiers from notes while ensuring unlinkability to later spends on Zcash, see also [1].
For Sapling, we derive airdrop nullifiers like standard Sapling nullifiers, but change the pp prefix used by the outer-most hash function for proper domain separation. In more detail, section 5.4.2 (Pseudo Random Functions) in [2] specify Sapling nullifiers as:
Here we generalize to below, where {targetS} is a fixed public airdrop target chain parameter:
For Orchard, we derive airdrop nullifiers like standard Orchard nullifiers, but change the pp preimage used by the hash generating the curve point for proper domain separation. In more detail, section 4.16 (Computing ρ values and Nulliers) in [3] specify Orchard nullifiers as:
Here the curve generator \mathcal{K}^\textsf{Orchard} is derived as:
\mathcal{K}^\textsf{Orchard} := \textsf{GroupHash}^\mathbb{P}(\text{“z.cash:Orchard”},\text{“K”})
We use the below, where \text{\{targetO\}} is a fixed public airdrop target chain parameter:
\mathcal{K}^\textsf{Orchard} := \textsf{GroupHash}^\mathbb{P}(\text{"\{targetO\}"},\text{“K”})
An airdrop can be set up with any \text{target}S and \text{targetO}, that must be different from \text{“Zcash_nf"} and \text{“z.cash:Orchard”} respectively.
Implementation
The implementation contains the necessary tools and building blocks to integrate with Zcash, for example generating public airdrop parameters incl. nullifier gaps and resolving note indices.
https://github.com/eigerco/zcash-namada-airdrop/
The implementation primarily consists of two modules:
-
non-membership-proofs: The core library of the implementation. It contains utilities for:
- Snapshot creation
- Finding user notes. Takes a viewing key and returns the notes that can be viewed with that key.
- Create the non-membership proofs
-
airdrop: Orchestrates non-membership-proof functions to provide the necessary functionalities to the users of the airdrop
Summary and Next Steps
In summary, the delivery of milestone 1 marks the primary integration with Zcash as completed, that mainly include snapshot generation, nullifier gaps, locating notes and Merkle-trees.
The next milestone estimated for mid February focuses on using these building blocks to specify and implement the central zero-knowledge proof that a given airdrop claim is valid.
Best regards,
Eiger Co