dusk-plonk: a PLONK proving system in Rust
Pure Rust implementation of the PLONK ZKProof System done by the Dusk team
At a glance
- What is it?
- dusk-plonk is a pure Rust implementation of the PLONK zero-knowledge proving system over the BLS12-381 curve, with KZG10 as the default polynomial commitment scheme, custom gates and a no_std build. The README attaches an explicit instability disclaimer and a side-channel note that proving is not constant-time, and both belong in your adoption decision.
- Who is it for?
- dusk-plonk suits a team building zero-knowledge circuits in Rust that needs no_std support, custom gates and a Dusk specific specification, and it suits a team that needs a production proof system less well, because the project itself calls the library unstable and tells you to use it at your own risk.
- Can I use it commercially?
- Yes, with conditions. MPL-2.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 12 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 October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
PLONK over BLS12-381, shipped with a warning
dusk-plonk is a pure Rust implementation of the PLONK zero-knowledge proving system over the BLS12-381 elliptic curve. It uses KZG10 as its default polynomial commitment scheme and includes custom gates for efficient circuit construction, and the details of the Dusk implementation live in a PLONK specification document inside the repository, at docs/dusk-plonk-specs.pdf.
The README leads with a disclaimer that any honest evaluation has to start from. The library is currently unstable, a security audit has been completed, further in-depth analysis and testing are encouraged, and it should be used at your own risk. The audits are published in a separate Dusk audits repository, so the audit trail is inspectable rather than a claim.
That combination, an audited but explicitly unstable cryptography library, is the defining fact about this project. It is the point where an adopter has to make a judgement rather than read a specification. The specification PDF tells you how Dusk's implementation differs and the audits tell you what was examined, but the disclaimer tells you the authors do not stand behind the result for production use.
The lineage is stated in the acknowledgements. The reference implementation is by Aztec Protocol through Barretenberg, the FFT module was adapted from ZEXE/Zcash, and the KZG10 module came from the SCIPR Lab. So the crate is a Rust reimplementation that follows a published reference rather than a first attempt at the protocol, and the two adapted modules are the parts where correctness depends on getting someone else's arithmetic exactly right.
The project is designed by the Dusk team, published on crates.io as dusk-plonk, documented on docs.rs, and licensed under the Mozilla Public License 2.0. The version is 0.24.0, released on 2026-10-08, with 0.22.1 from 2026-06-15 and 0.21.0 from 2025-02-06 before it.
Three cargo features decide what the crate can do
The feature flags are not decoration, they define the shape of the crate. The alloc feature enables the use of an allocator, and without it it is not possible to prove or verify anything. Its absence only makes dusk-plonk export certain fixed-size data structures such as Proof. The README makes the intended use explicit: this is for no_std environments that do not make use of an allocator.
The std feature enables std usage as well as rayon parallelization in some proving and verifying operations, and it uses the std versions of the elliptic curve dependencies with the parallel feature of dusk-bls12-381. It is enabled by default, so the default build is the parallel one.
The debug feature enables the runtime debugger backend, which writes CDF files to the path defined in the CDF_OUTPUT environment variable. When it is used, the binary must be compiled with debug = true, and the README links the cargo book for the profile details. It also recommends deriving stdout and stderr into a text file for efficient gate analysis, which is a hint about how the debugging output is meant to be consumed.
The no_std story is not aspirational. The Makefile has a target that adds the thumbv6m-none-eabi target and then builds the crate several ways, with no default features, with alloc, and with the rkyv implementation features, and runs a cargo check for the same combinations. A microcontroller target is the test, and the crate is expected to build there with and without an allocator.
The dependency list explains the rest. The curve comes from dusk-bls12-381 with the groups and pairings features, the transcript from dusk-merlin 4.0.0, hashing from blake2b_simd and sha2, and the field arithmetic from ff and subtle, which is the constant-time comparison library. There is also a dusk-jubjub dependency, a second curve, and rkyv and bytecheck for serialisation of witness data.
Proving is not constant-time, and the README says so plainly
The side channels section is the most valuable paragraph in this README, and it is worth reading in full before any other decision. Proving is not constant-time. The KZG commitments to witness polynomials use a variable-time multi-scalar multiplication, so an attacker who can observe the proving machine, through timing, cache or branch-predictor traces, may learn about the witness. The instruction is to prove on hardware such an attacker cannot observe.
The section also explains where the guarantee stops. Fixed-base scalar multiplication computes its NAF digits and selects each round's addend without branching on the scalar, and other witness code makes no such guarantee. Verification only handles public data, so the verifier side is not exposed in the same way.
This has a direct architectural consequence. If your proving runs on a shared machine, on a cloud instance where the hypervisor is not trusted, or anywhere an attacker can get at timing traces, the witness is at risk even though the protocol is correct. The mitigation is not a configuration flag. It is where you run the prover, and the README is explicit that this is a deployment decision rather than a library setting.
For a zero-knowledge library, that is an unusual and welcome admission. Plenty of cryptographic libraries leave side-channel analysis to the integrator, and plenty of integrators never do it. This one names the specific primitive that leaks, names the observation channels, and states which side of the protocol is affected.
Building, testing on 32-bit targets and running the circuit example
The Makefile is the interface for the development tasks, and it covers more ground than a typical crate. The test target runs the suite twice, once with the default features and once with all features:
test: ## Run tests
@cargo test --release
@cargo test --release --all-featuresThe 32-bit target is a separate target, and the comment above it explains why the flags are needed. Criterion's alloca compiles C, and clang is used to build it with its own headers, with a musl target triple and a freestanding, nostdinc C compiler invocation. Every feature except debug is exercised, because the README notes in the Makefile comment that the dusk-cdf format is not 32-bit safe.
The example is the fastest way to see the library work, and the repository ships a single example file, examples/circuit.rs:
run-examples: ## Run the examples
@cargo run --release --example circuitThe no_std verification target builds against a bare-metal target twice, once with alloc and once without, and then runs a check with the rkyv features enabled:
no-std: ## Verify no_std compatibility
@rustup target add thumbv6m-none-eabi
@cargo build --release --no-default-features --features alloc --target thumbv6m-none-eabiQuality gates are wired in as well. The clippy target runs with all features and with the rkyv size_32 feature, and with warnings denied, and it also runs against no-default-features and against alloc alone. Formatting uses nightly rustfmt, and the cq target combines both checks. The toolchain is pinned in rust-toolchain.toml, and the crate requires Rust 1.96.1 with edition 2024, so the toolchain requirement is strict.
Benchmarks on an M1, and how to reproduce them
The README publishes a small performance table and the numbers are specific. The benchmarks were taken on an Apple M1 with a circuit size of 2^16 constraints. Proving time is 7.871s, and verification time is 2.821ms, with the note that the verification time does not vary depending on the circuit size.
That verification figure is the interesting one, because it describes the shape of the cost model. A PLONK proof is fixed size regardless of the circuit, so verification work does not grow with the number of constraints, while proving grows roughly with the circuit. The ratio between 7.871 seconds and 2.821 milliseconds at 2^16 constraints is roughly three orders of magnitude, and it moves in the right direction as circuits get larger.
Reproducing the numbers is a documented step rather than a suggestion. The README says to run cargo bench for a full report of benchmarks in respect of constraint numbers, and the Makefile has a bench target that runs cargo bench, plus a build-benches target that compiles them without running them, which is what you want in continuous integration. The dev-dependencies include criterion 0.8, which is the benchmarking framework behind those numbers.
One caution when reading the figures. They are from one machine, an Apple M1, and the README does not claim they transfer to other hardware, and given the side-channel discussion, a machine with a different memory and cache behaviour can also behave differently on timing grounds. The table is a reference point for the shape of the cost, not a budget for your own deployment.
MPL-2.0 asks for file level disclosure, not a copyleft chain
The licence is the Mozilla Public License 2.0, recorded in the Cargo.toml metadata and in the LICENSE file at the root of the repository. For a cryptographic library this matters in a specific way. MPL 2.0 is a file-level copyleft licence: if you modify a file of the library, your modified version of that file has to be made available under the same licence. Changes you make in your own files, and the way you link the library into your application, are not affected.
That is a lighter obligation than the GPL, and it is a reasonable choice for a library that a company will modify and then embed in a product. The practical rule to remember is that the obligation attaches to modified files of the library itself, so if you patch dusk-plonk rather than wrapping it, that patch becomes something you publish.
The rest of the repository reflects a project with a serious process. There is a CHANGELOG.md, a CONTRIBUTING.md, an AGENTS.md and a CLAUDE.md, a deny.toml for dependency auditing, a rustfmt.toml, a benches directory, a tests directory, a docs directory and the spec PDF. The presence of a deny configuration and a dedicated audit repository suggests a team treating the supply chain and the cryptography as things to be checked by others.
The version scheme is worth watching. The crate sits at 0.24.0 and the release history shows 0.21.0 in February 2025, 0.22.1 in June 2026 and 0.24.0 in October 2026, so a lot of work has landed across a relatively young and still moving API. Under Cargo semantics a 0.x version carries no compatibility promise, and the README's own instability disclaimer says the same thing in stronger terms.
Editorial conclusion
dusk-plonk suits a team building zero-knowledge circuits in Rust that needs no_std support, custom gates and a Dusk specific specification, and it suits a team that needs a production proof system less well, because the project itself calls the library unstable and tells you to use it at your own risk. Before adopting it, read the side-channel section, since proving is not constant-time and the witness must be protected from timing, cache and branch predictor observation, and confirm the toolchain requirements, which are edition 2024 and Rust 1.96.1. The crate is version 0.24.0, released on 2026-10-08, and the last push was on 2026-10-11.
Frequently asked questions
What is dusk-plonk used for?
It is a pure Rust implementation of the PLONK zero-knowledge proving system over the BLS12-381 curve, using KZG10 as the default polynomial commitment scheme and providing custom gates for circuit construction.
Is dusk-plonk safe to use in production?
The README states that the library is currently unstable, that a security audit has been completed, that further in-depth analysis and testing are encouraged, and that it should be used at your own risk. The audits are published in the Dusk audits repository.
Is proving in dusk-plonk constant-time?
No. The KZG commitments to witness polynomials use a variable-time multi-scalar multiplication, so an observer of timing, cache or branch-predictor traces may learn about the witness. The README advises proving on hardware such an attacker cannot observe, and notes that verification only handles public data.
Can dusk-plonk be used without the standard library?
Yes. Without the alloc feature it is not possible to prove or verify anything, but the crate still exports fixed-size structures such as Proof, and the Makefile has a no-std target that builds it for the thumbv6m-none-eabi target.
How do I run the dusk-plonk benchmarks?
Run cargo bench for a full report against constraint numbers, or use the Makefile bench target, with build-benches to compile them without running. The README quotes proving time of 7.871s and verification time of 2.821ms for a 2^16 constraint circuit on an Apple M1.
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/dusk-network-plonk)Was this useful?