Client-side cryptographic library for Zcash shielded voting. Implements proof generation, vote construction, and tree synchronization for the Zally governance protocol.
| Crate | Description |
|---|---|
| zcash_voting | Core library: ZKP delegation and vote proofs (Halo2), El Gamal encryption, governance PCZT construction, Merkle witness generation, chain confirmation parsing, SQLite round-state persistence |
| vote-commitment-tree | Append-only Poseidon Merkle tree for Vote Authority Notes and Vote Commitments |
| vote-commitment-tree-client | HTTP client and CLI for syncing the vote commitment tree from a chain node |
zcash_voting
├── config ───────────────────── config resolution + switch decisions
├── vote-commitment-tree-client ─ vote-commitment-tree
├── pir-client / vote-nullifier-pir types
├── voting-circuits ───────────── ZK delegation + vote proofs
└── librustzcash crates ───────── pczt, zcash_keys, zcash_client_sqlite, ...
The config resolver itself is transport-agnostic. Wallets choose the static
config source and network transport, fetch bytes, and pass those bytes into
zcash_voting::config. The wallet-example::example_config module shows a
direct HTTPS implementation for Rust consumers that do not need a custom
transport.
cargo check # check all crates
cargo build -p zcash_voting # build just the core libraryRun the Ironwood / NU6.3 tests with:
cargo test -p zcash_voting --lockedNew wallet integrations should import zcash_voting::prelude::* and use the
stage-oriented API:
round::*creates rounds and binds eligible notes into bundles.precompute::*prepares shielded note witnesses, delegation PIR inputs, and VAN witnesses for vote proofs.delegate::*builds delegation PCZTs, proves delegation, prepares signing requests, and assembles signed delegation submissions. Wallets keep root seed material outside this crate, sign requests at the wallet boundary, and pass only signature bytes back throughPreparedSigner::signature.confirmation::*parses delegation and cast-vote tx events, then records tx hashes and tree positions atomically.vote::*builds ZKP #2, signs cast-vote payloads, persists the canonicalVoteRecoveryBundle, and reconstructs vote-chain submissions after a crash.share::*recovers helper-share payloads, computes share nullifiers, applies share scheduling policy, and records helper-share confirmation state.session::*records durable ballot intent and returns a round-levelRoundPlanwith orderedNextSteps for restart recovery. Wallets should writeDecision::Choicewith the proposal's declared option count before starting a cast-vote flow, writeDecision::Skippedwith the same option count for proposals the user intentionally leaves blank, and useresume_planafter restart to decide whether to delegate, poll delegation/vote transactions, cast remaining votes, or confirm helper shares.CastVotesteps include the recorded choice.SubmitVotesteps mean a vote was already committed locally and should be reconstructed withvote::submissionrather than rebuilt from a draft. Submit those recovered cast-vote fields, persist the cast-vote tx hash withvote::record_submissionwhile polling, then record confirmed tx events withconfirmation::confirm_vote_submission. After confirmation, callvote::recover_commitagain and use its helper-share payloads so they carry the confirmed VC position. Persist each accepted helper share withshare::record, and re-run the planner because later work may depend on on-chain confirmations.open_proposalscontains only proposals with no terminal decision yet.
- Replace
VotingDb::build_vote_commitment+vote_commitment::sign_cast_voteVotingDb::build_share_payloadsorchestration withvote::commit.
- Replace custom cast-vote recovery JSON with
vote::serialize_recoveryandvote::parse_recovery. - Replace direct
VoteTreeSyncownership withprecompute::{sync_vote_tree, van_witness, reset_vote_tree}. - Replace direct
share_trackingcalls withshare::*, andshare_policyimports withshare::policy::*. - Replace raw vote/share workflow SQL with
VotingDb::{vote_phase, vote_phases, share_phase, share_phases}. - Replace wallet-local "what comes next" recovery planning with
session::resume_plan; fetch execution material through crate APIs such asvote::submission,vote::recover_commit,share::*, and the tx hash accessors, then keep wallet-specific networking, proof execution, and UI routing at the wallet boundary. - Replace wallet-local delegation proof and signing orchestration with
delegate::PreparedDelegationBundle. Callers can use the prepared lifecycle for setup, witness completion, proving, signing request construction, signed payload assembly, and Keystone request construction. - Use
confirmation::{confirm_delegation_submission, confirm_vote_submission}after chain clients report confirmed delegation or cast-vote tx events. The confirmation API parses the chainleaf_indexevents and records tx hashes, VAN positions, and VC positions atomically. - Use
vote::commit,vote::submission,vote::recover_commit,vote::record_submission, andvote::record_vc_positionfor the cast-vote lifecycle. Wallets should not write recovery JSON, submission flags, or vote commitment positions directly.
Pre-launch wallet databases with older schema versions are reset when opened by this branch; callers that need to preserve test data should export it before upgrading the crate.
The workspace uses the published voting-circuits 0.9.0-rc.2 release.
The root manifest selects one upstream Ironwood dependency stack for every workspace member:
orchard 0.15.0from zcash/orchard, withunstable-voting-circuitsenabled for the governance proof paths.pczt,zcash_client_backend,zcash_client_sqlite,zcash_keys,zcash_primitives, andzcash_protocolfrom a pinned upstream librustzcash revision containing Ironwood historical note selection.voting-circuits 0.9.0-rc.2from valargroup/voting-circuits for the delegation and vote proof circuits.
Cargo.toml is the source of truth for version and feature requirements, and
Cargo.lock records the exact package sources and versions used by this branch.
The Zcash wallet crates require Rust 1.88 or newer.
Mobile FFI bindings live in zcash-swift-wallet-sdk (hand-rolled C FFI + Swift wrappers). This repo is a pure Rust workspace.
TODO