A malicious server can trivially lie about which chain is canonical. Without header verification, it can present a fabricated chain with invalid PoW, convince the client to accept transactions on a minority fork, or hide reorgs entirely.
Lightwalletd clients have no defense against this - they trust the server completely.
The proof asserts that for blocks 1..N: each header's PoW satisfies its target, the difficulty adjustment algorithm was correctly applied at each epoch, timestamps are monotonically increasing, and hash(header[i]) = prev_hash(header[i+1]).
The client verifies this in O(log²N/log log N) time without downloading headers.
Gigaproof: Proves genesis → last epoch boundary. Generated once per ~1024 blocks. ~200KB, proves ~2.7M headers.
Tip proof: Proves epoch boundary → current tip. Generated on-demand. Continuity check: tip_proof.start_hash == gigaproof.end_hash.
Verification uses recursive FRI (Fast Reed-Solomon IOP) folding. The polynomial is committed at dimension 2^k, then folded down in rounds:
2^26 → 2^23 → 2^20 → 2^17 → 2^14 → 2^11 → final
Each round: verifier sends random challenge α, prover commits to f'(x) = f_even(x) + α·f_odd(x). Verifier spot-checks consistency at random points. After ℓ rounds, the polynomial is small enough to send directly.
Soundness error: (ρ)^|S| per round, where ρ = rate and |S| = query count (~148 queries for 100-bit security).
Soundness relies on the hardness of Reed-Solomon proximity testing. Ligerito is a polynomial commitment scheme with WI (not ZK) - the witness is not hidden, only correctness is proven.
Proofs can be verified independently using the ligerito CLI verifier.
Zcash uses Nakamoto consensus - finality is probabilistic. A 51% attacker can reorg arbitrarily deep. Even without 51%, a malicious server can claim any block is "canonical" and the client has no way to dispute it without an independent reference.
Lightwalletd provides no finality guarantees whatsoever.
Zanchor checkpoints (block_hash, tree_root) are written to a Polkadot parachain. Once finalized by GRANDPA (BFT finality with 1000+ validators), the checkpoint becomes irreversible - even a Zcash 51% attack cannot reorg past it.
The client can verify checkpoint authenticity via Polkadot light client or trusted RPC.
epoch: Sequential checkpoint number
block_hash: Zcash block hash at checkpoint height
tree_root: Commitment to nullifier set state
Checkpoints are signed via FROST threshold signature (t-of-n scheme).
Trust assumption shifts from "the server is honest" to "Polkadot validators are honest (BFT: >2/3 honest)". This is a strictly weaker assumption - compromising 1000+ validators is harder than compromising one server.
ParaId 5082 on Paseo testnet. Query on-chain state to verify checkpoint authenticity.
RPC: paseo.rpc.amforc.com | Explorer: subscan
JSON: epoch, height, block_hash, tree_root
The nullifier set (all spent note commitments) is critical for double-spend prevention. A malicious server can: (1) omit nullifiers to make spent notes appear unspent, (2) inject fake nullifiers to make unspent notes appear spent, or (3) serve inconsistent state to different clients.
Lightwalletd clients accept nullifier queries on faith.
NOMT maintains a merkle tree over the nullifier set. For any query "is nullifier X in the set?", the server provides a membership/non-membership proof verifiable against the root.
The root is committed in the header chain proof, binding it to the proven chain state.
Membership proof: Path from leaf to root, O(log N) hashes
Non-membership proof: Adjacent leaves proving gap at query position
Client computes root from proof, compares to committed root. Forgery requires collision in Blake3.
Soundness: collision resistance of Blake3. Completeness: server must have the full nullifier set to generate valid proofs. The "Nearly-Optimal" in NOMT refers to page-aligned storage for efficient disk I/O during proof generation.
JSON: nullifier_root, proven_height, nullifiers_observed