halo2 is the Rust proving system published by the Zcash project
The Halo2 zero-knowledge proving system
At a glance
- What is it?
- halo2 is the zero-knowledge proving system developed by Zcash, published as a Rust workspace of four crates that you are meant to depend on directly. It is dual licensed under Apache-2.0 or MIT, it requires Rust 1.88, and it parallelises with rayon unless you disable the multicore feature.
- Who is it for?
- halo2 suits engineers building circuits rather than running a node, who want a proving system with a permissive licence and a published API to code against. It does not suit a team that needs a released version number to pin, because the repository has no GitHub releases and version tracking happens through the crates, and it does not suit a machine on an older Rust toolchain, since the workspace requires Rust 1.88 or higher.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 9 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 7, 2026, and from our analysis. They are not legal advice.
Star history
- zcash/halo2933 ★ · +6
| Repository | 2026-10-21 | 2026-11-07 |
|---|---|---|
| zcash/halo2 | 927 | 933 |
6 Stars in the last 17 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
A proving system, published by the Zcash project
halo2 is described in the repository description as the Halo2 zero-knowledge proving system, and its homepage is zcash.github.io/halo2/.
The important framing for an evaluator is that this is the proving system, not the chain. The topics attached to the repository list cryptocurrency, cryptography, zcash and zero-knowledge, and the project lives under the zcash organisation rather than as a general purpose cryptography library. The audience is therefore people building circuits and provers: teams implementing a zero-knowledge protocol, or a blockchain layer that needs one, rather than application developers who want a proof to be checked.
The implementation language is Rust, and the whole workspace sits on a single modern toolchain. The home page hosts documentation, and there is a book/ directory in the repository..
Four crates, and the README tells you which two to depend on
The repository is a Cargo workspace with four members, declared in Cargo.toml.
[workspace]
resolver = "2"
members = [
"halo2",
"halo2_gadgets",
"halo2_poseidon",
"halo2_proofs",
]The workspace package section pins the shared settings, including the edition, the toolchain floor and the licence expression.
edition = "2021"
rust-version = "1.88"
license = "MIT OR Apache-2.0"
repository = "https://github.com/zcash/halo2"The Usage section of the README is short and specific: the repository contains the halo2_proofs and halo2_gadgets crates, which should be used directly.
The intra-workspace dependencies are declared with both a version and a path, so a downstream user picks them up from crates.io by version.
halo2_proofs = { version = "0.4", path = "halo2_proofs", default-features = false }
halo2_poseidon = { version = "0.2", path = "halo2_poseidon", default-features = false }
halo2_gadgets = { version = "0.6", path = "halo2_gadgets", default-features = false }Note that every one of them sets default-features = false. The consequences of that choice are discussed further down.
Rust 1.88 is the floor, and it can move with a minor version bump
The README has a dedicated section for the minimum supported Rust version. It requires Rust 1.88 or higher, and it says the minimum supported Rust version can be changed in the future, but that it will be done with a minor version bump.
That is a small policy statement with a large practical consequence. Under semver, a minor version bump is not supposed to break your build, so a Rust version bump can arrive in a release that looks routine. If your build pins a toolchain, you need to watch for those bumps rather than assume a new release of halo2 is compatible with the Rust you have today.
The repository also contains a rust-toolchain.toml at the root.
Two more details from the manifest are worth noting. The workspace resolver is set to 2, which is the version that matches the 2021 edition and avoids the older feature-resolution behaviour. And the edition itself is 2021, so the code is not written for the newest edition.
rayon gives the parallelism, and the multicore feature is the switch
Parallelism is handled by rayon, and the README gives you two controls over it.
The first is the RAYON_NUM_THREADS environment variable, which sets the number of threads. The second is a Cargo feature. The multicore feature can be disabled, and the README warns that halo2 will lose access to parallelism if you disable it, and that this will significantly degrade performance.
That warning is the reason to read this section rather than skim it. A Cargo feature is exactly the kind of thing that gets turned off by someone trying to trim a dependency tree or work around a build problem, and the consequence here is not a compile error but a silent and large slowdown of the prover. If you inherit a build with default-features = false, check whether multicore is among the disabled features before benchmarking anything.
The workspace dependencies also list maybe-rayon under a Performance heading, which is the crate that makes the optional parallelism compile-time selectable. The manifest groups its dependencies into labelled sections, Cryptography, Correctness, Performance, Developer tooling dependencies, Legacy circuit compatibility and Testing, and those labels are a useful map of what the project considers load-bearing.
The Legacy circuit compatibility entry, halo2_legacy_pdqsort, deserves a note of its own: it exists to keep older circuits working, which tells you the library has a compatibility surface with circuits built against earlier versions.
Apache-2.0 or MIT, and contributions are dual licensed by default
The licence situation is the friendliest part of this repository, and it is worth reading carefully because the summary in the metadata is misleading.
The metadata says the licence is a custom one that GitHub cannot classify, but the README states that the work is licensed under either of the Apache License, Version 2.0, referenced as LICENSE-APACHE, or the MIT license, referenced as LICENSE-MIT, at your option. The repository root contains both files, plus COPYING.md.
The choice of a dual licence is meaningful for a cryptography project. Apache-2.0 carries an explicit patent grant and requires notices when you redistribute, while MIT is permissive and short. Offering both means a downstream user can pick the terms that suit their legal context without the project having to guess.
The Contribution section adds a clause worth noting: unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work, as defined in the Apache-2.0 licence, shall be dual licensed as above without any additional terms or conditions. So by default contributions are dual licensed on the same terms, and no one has to negotiate terms before sending a pull request.
If you are building a product on top of this, the obligations are the standard ones: keep the notices, and check the two licence files rather than relying on the GitHub metadata label.
The dependency list names the curve system and the hash constructions
The workspace dependencies are the fastest way to understand what this proving system is built on.
For cryptography the manifest lists bitvec, blake2b_simd, ff, group, pasta_curves, rand, rand_core, sinsemilla, subtle and uint. Two of those names carry most of the information. ff is the field abstraction that a circuit programmer works against, and pasta_curves is the curve family, at version 0.6. The pair tells you that the field and group abstractions come from the ff and group crates rather than being defined inside halo2 itself, which is what lets a circuit be written against a generic field.
group and rand and rand_core cover group operations and randomness, and subtle is the constant-time comparison crate, which is a dependency you want to see in any cryptographic library.
blake2b_simd and sinsemilla are hash-related crates in the dependency list, and the workspace also contains a separate halo2_poseidon crate.
For correctness the manifest pins arrayvec and indexmap, for performance maybe-rayon, and the Testing section lists criterion, gumdrop and proptest, which tells you the benchmarking and property testing setup. The developer tooling section lists backtrace, plotters, tabbycat and tracing.
No GitHub releases, so versions live in Cargo and the lockfile
The repository has no GitHub releases, which is worth understanding before you pin a dependency.
For a Rust library that is not unusual. The published artefact versions are the ones in the workspace dependencies, halo2_proofs 0.4, halo2_poseidon 0.2 and halo2_gadgets 0.6, and Cargo resolves them for you when you add the dependency. The Cargo.lock at the root is for the workspace itself, so contributors and CI get the same dependency graph.
The cost of no tagged releases is that there is no single place to look for a changelog or a migration note between versions, and the repository root listing does not include a CHANGELOG file. If you need to know what changed between two published versions of halo2_proofs, the answer is in the diff of the crate's own repository history rather than in a release note.
On maintenance, the repository is not archived and the last push was on 2026-10-16, so the code is being worked on. The absence of releases says more about how a Rust library is published than about whether the work has stopped.
For an evaluation, the concrete checks are narrow: read the two crate READMEs the root README points to, check the version you would depend on, and confirm that the Rust version in your CI matches the 1.88 floor.
Editorial conclusion
halo2 suits engineers building circuits rather than running a node, who want a proving system with a permissive licence and a published API to code against. It does not suit a team that needs a released version number to pin, because the repository has no GitHub releases and version tracking happens through the crates, and it does not suit a machine on an older Rust toolchain, since the workspace requires Rust 1.88 or higher. Before you build on it, confirm your prover runs on hardware with the cores you expect, because the multicore feature is what gives the parallelism and turning it off is documented as a significant performance loss.
Frequently asked questions
Which Rust version does halo2 require?
The README states that halo2 requires Rust 1.88 or higher, and that the minimum supported Rust version can change in the future but only with a minor version bump. The workspace uses edition 2021.
How do I control the number of threads halo2 uses?
halo2 uses rayon for parallel computation and the RAYON_NUM_THREADS environment variable sets the number of threads. The multicore Cargo feature can be disabled, but the README warns that this removes parallelism and will significantly degrade performance.
Which halo2 crate should I depend on?
The README states that the repository contains the halo2_proofs and halo2_gadgets crates, which should be used directly. The workspace also contains halo2 and halo2_poseidon, and its dependency table declares halo2_proofs 0.4, halo2_poseidon 0.2 and halo2_gadgets 0.6.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/zcash-halo2)Star history chart for your README
[](https://hysenlabs.com/projects/zcash-halo2)Was this useful?