Grant Application - Constant-Time Hardening and Explicit Timing Semantics for Zcash Rust Cryptography

Hi everyone! we (Eryx) have just submitted a new Zcash Community Grant proposal and wanted to share it here for feedback: Grant Application - Constant-Time Hardening and Explicit Timing Semantics for Zcash Rust Cryptography · Issue #342 · ZcashCommunityGrants/zcashcommunitygrants · GitHub .

A bit about us. Eryx is a worker-owned labor cooperative with almost 15 years of experience solving complex problems involving mathematics and software development. We have a solid background in math and computer science, and our team has extensive experience in blockchain development, cryptography, and privacy-focused protocols, as well as many years building and maintaining large-scale software systems with a strong focus on scalability, reliability, and long-term maintainability. We’re interested in the Zcash ecosystem because we value its work on privacy-preserving technologies and rigorous cryptographic engineering. We think Zcash’s focus on sound cryptography, explicit security guarantees, and long-term sustainability strongly aligns with our own values and experience.

We first approached the ecosystem with an earlier grant proposal. That proposal was not accepted, and we were encouraged to begin by making concrete contributions to librustzcash to become familiar with the protocol and build trust through delivered work. We took that feedback and over the following months we contributed several well-scoped improvements to the codebase:

These contributions let us familiarize ourselves with the Zcash protocol, integrate into the maintainers’ review process, and consistently deliver quality work. We think this proposal is a good next step: a focused, well-scoped project that builds on that familiarity to strengthen the cryptographic foundations of librustzcash, while continuing to collaborate closely with the community.

About the proposal. librustzcash already implements careful constant-time behavior in its most privacy-critical paths, but those guarantees are implicit: they aren’t documented as invariants, labeled in the code, or protected by tests. The architecture docs themselves note that “nothing is labeled as constant/variable time.” Our goal is not to make everything constant-time (Zcash’s process separation and asynchronous data flow mean that’s neither required nor desirable everywhere), but to make the existing timing semantics explicit, testable, and resistant to regression. Concretely, that means a documented threat model and timing policy, inline labels distinguishing constant-time from intentionally variable-time paths (with rationale), compile-time guards on secret-handling types, and statistical (dudect-style) timing tests so future refactors can’t silently break these invariants.

The work is a focused, one-month effort ($10k) split into two milestones: (1) research + threat-model/timing-policy documentation and an agreed-upon list of target types and functions, and (2) in-code labeling, tests, contributor guidelines, and targeted fixes only where the audit surfaces a real gap — all delivered as reviewable PRs to zcash/librustzcash. This relates to existing open issues like #120 and #1114 in the Scan performance milestone.

We’d love feedback from maintainers and the community, especially on scope and on which code paths you consider most valuable to document first. We plan to validate the threat model iteratively through the R&D Discord #libraries channel as we go.

4 Likes

Which path are you hardening for constant time first, note decryption or signing, and how do you plan to keep the timing guarantees from regressing as the crates keep changing?

Hi, thanks for the question!

We’d go for decryption first, since it gives an attacker more to work with. A wallet has to trial-decrypt every output out there, and the attacker can craft those outputs himself. So he can throw a huge number of chosen inputs and watch the timing for information. Signing is more constrained since it only ever runs over the wallet’s own existing spend transactions.

On keeping the guarantees from regressing, the plan is a few layers working together:

  • Write the timing contract down. Each secret-handling function carries a doc-comment stating what its runtime is and isn’t allowed to depend on. This is the “explicit timing semantics” half of the proposal, and it is useful for reviewers to get a written invariant to check a diff against, and anyone refactoring the function will be able to see, right there in the code, that constant-time behavior is a contract they have to preserve.
  • Test in CI (dudect-style). Statistical timing tests so a regression gets caught whether it comes from someone changing the code in librustzcash or from a dependency update that quietly breaks the invariant. For example, a test around try_note_decryption in zcash_note_encryption would run it many times over two kinds of outputs (some where decryption succeeds and some where it fails) and confirm the timing looks the same either way.

Did that answer your question? Let me know if need anything else :slightly_smiling_face:

Hi @fdecroix,

Speaking for myself and not the ZCG Committee – Since this grant is tied to upstream approval and merge, I think it would be very helpful for the Committee to know if a named maintainer has confirmed both:

  • that the scope is useful; and
  • that review capacity will be available during the project.
1 Like

Hi, thanks for the question!

We asked for feedback in the R&D Discord a few months ago, and the responses we received were very helpful in refining the scope of the proposal and confirming that the work could be useful to the project.

However, at the time we did not explicitly ask about maintainer availability to answer questions during the work or to review the resulting PRs. Since some time has passed as well, I’ll follow up in the Discord channel to get a clearer and more up-to-date sense of that before the grant moves forward.

Thanks again for raising this.