Plonky3 is a parts bin for STARK provers rather than a proving system
A toolkit for polynomial IOPs (PIOPs)
At a glance
- What is it?
- Plonky3 is a Rust toolkit of polynomial IOP primitives, and its README is an honest status checklist: which fields exist, which commitment schemes are done, which are not, and which interactive proof pieces are missing. The practical entry points are the example binaries, one that proves a recurrence over a binary field and one that proves hash permutations and compressions.
- Who is it for?
- Plonky3 fits a team building a STARK based zero knowledge virtual machine or another polynomial IOP system and wanting proven components for fields, commitment schemes, sumcheck and lookup arguments rather than writing them from scratch. Skip it if you need a finished proving system, since the README's checklist still shows PLONK, the tensor commitment scheme and the univariate to multivariate adapters as unfinished.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- 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
A toolkit of primitives, not a product
The README's opening paragraph sets the scope precisely. Plonky3 is a toolkit which provides a set of primitives, such as polynomial commitment schemes, for implementing polynomial IOPs, and it is mainly used to power STARK-based zkVMs, though in principle it may be used for PLONK-based circuits or other PIOPs.
That is a different proposition from a proving system. A system would give you a virtual machine and a proving pipeline. A toolkit gives you the parts, and the README is organised as a parts inventory, with a status checklist that says what exists, what is planned and what is explicitly not done.
The licence situation is generous and unusual for a cryptography project. There are two licence files at the top of the tree, `LICENSE-APACHE` and `LICENSE-MIT`, and the README carries a badge for each. So the code can be used under either Apache-2.0 or MIT, which for a library that other projects build their provers on removes a common source of friction.
The primary language is Rust, the default branch is `main`, and the repository is not archived, with the last push on 2026-10-18. Discussion happens on a Telegram group rather than on the issue tracker, and the README points at it as the place for questions.
The repository layout is a list of the parts themselves. There are field crates such as `mersenne-31/`, `baby-bear/`, `koala-bear/`, `goldilocks/`, `bn254/` and `monty-31/`, proof system crates such as `uni-stark/`, `multi-stark/` and `batch-stark/`, commitment schemes in `fri/`, `stir/`, `whir/` and `binary-pcs/`, primitives in `sumcheck/`, `lookup/`, `challenger/`, `merkle-tree/`, `interpolation/`, `dft/` and `circle/`, and hash implementations with their AIRs in `poseidon1/`, `poseidon2/`, `rescue/`, `blake3/`, `keccak/`, `monolith/`, `sha256/` and `blake2s/`.
The status checklist is the most useful page in the repository
Rather than a feature list, the README offers a checklist with checkboxes, and the unchecked boxes are as informative as the checked ones.
The field section is complete for the 31 bit families. Mersenne31 has a complex extension field and a roughly 128 bit extension field, and it has AVX2, AVX-512 and NEON backends. The general 31 bit fields, BabyBear and KoalaBear, have a roughly 128 bit extension field with the same three instruction set backends. Goldilocks has a roughly 128 bit extension field. The binary tower fields run from GF(2) up through GF(4) to GF(2^128), and GF(2^128) has a GHASH polynomial-basis representation with SIMD packings.
The commitment section shows FRI-based, STIR-based and WHIR-based polynomial commitment schemes, plus a multilinear PCS over binary tower fields in the Binius style, using additive-domain proximity. Three items are unchecked: the tensor PCS, the univariate to multivariate adapter, and the multivariate to univariate adapter.
The PIOP section has univariate STARK, multivariate STARK in the SuperSpartan style over AIRs, and batched STARK with shared PCS openings across multiple instances. PLONK is unchecked.
Under interactive proof primitives, the checked items are Sumcheck with generic-degree support, a small-value optimization, HVZK masking and ring switching, LogUp lookup arguments in both local and cross-AIR form, and a typed Fiat-Shamir transcript layer tied to a DSFS IETF draft.
The security section lists a composable soundness analysis for FRI, STIR and WHIR based STARKs, and the codes section has Brakedown and Reed-Solomon. Interpolation has Barycentric interpolation, the radix-2 DIT FFT, the radix-2 Bowers FFT, the Mersenne circle group FFT, and the additive NTT of Lin, Chung and Han over the binary tower fields, with the four-step FFT still unchecked.
The hashes are Rescue, Poseidon, Poseidon2, BLAKE3, Keccak-256, SHA-256 and Monolith, with one unchecked item, modifications to tune BLAKE3 for hashing small leaves.
Read this way, the repository tells you exactly how far along each track is, which is more than most cryptography projects bother to publish.
The binary field example is the shortest path to a proof
The README gives one concrete example, and it is the one to start with because it is a single command.
cargo run --release -p p3-multi-stark --example prove_binary_fieldThe example proves a nonlinear recurrence over `BinaryField128` using the multilinear STARK prover and `BinaryPcs`, with Keccak Merkle commitments and a binary challenger. It serializes the proof and then verifies it with a fresh transcript, which is the detail that makes the example worth reading, because verifying against a fresh transcript is what stops a prover from reusing a transcript it has already seen.
The README also states the limit of the example plainly. It is not zero knowledge, and characteristic-two LogUp lookups are unsupported and rejected, with the example using ordinary AIR constraints instead.
That is an important property of the project as a whole rather than a limitation of the demo. The LogUp lookup argument is a listed primitive, but the binary-field path does not support it, and the code refuses the case rather than silently producing a weaker proof.
For a reader who wants to understand the layout, the example file is named in the README as `multi-stark/examples/prove_binary_field.rs`, and the surrounding crates it names, `p3-multi-stark`, the multilinear STARK prover and `BinaryPcs`, are the same pieces that a real system would assemble.
The benchmark CLI shows how the pieces compose
The benchmark section is the clearest illustration of what a toolkit like this is for, because it lets you swap every component and measure the result.
The example given proves 2 to the 20 Poseidon2 permutations of width 16, using the `KoalaBear` field, the `Radix2DitParallel` DFT and `KeccakF` as the Merkle tree hash.
RUSTFLAGS="-Ctarget-cpu=native" cargo run --example prove_prime_field_31 --release --features parallel -- --field koala-bear --objective poseidon-2-permutations --log-trace-length 17 --discrete-fourier-transform radix-2-dit-parallel --merkle-hash keccak-fThe `RUSTFLAGS` setting asks the compiler to target the host CPU, which matters because the whole point of the AVX2, AVX-512 and NEON backends is to use the instructions the machine has, and the `parallel` feature turns on the multi-threaded paths.
The options are listed in full, and the list reads like a catalogue of the choices a system designer makes. The `--field` option takes `mersenne-31`, `koala-bear` or `baby-bear`. The `--objective` takes `blake-3-permutations`, `poseidon-2-permutations` or `keccak-f-permutations`. The `--log-trace-length` takes any integer between 0 and 255, and the README explains how the number of proven permutations follows from it, being the trace length, eight times the trace length, or the trace length over 24, for BLAKE3, Poseidon2 and Keccak-f respectively. The `--discrete-fourier-transform` option takes `radix-2-dit-parallel`, `recursive-dft` or `small-batch-dft`, and the README notes it should be omitted when the field is `mersenne-31` because the circle STARK currently supports only a single discrete Fourier transform. The `--merkle-hash` option takes `poseidon-2` or `keccak-f`.
A toolkit whose benchmark harness is a matrix of swappable components is a different thing from a library with one configuration, and that is what makes the numbers comparable between projects.
prove_hash_binary and the security ceiling it enforces
The second example is the more interesting one, because it proves standard hash functions rather than a toy recurrence.
`prove_hash_binary` proves Keccak-f permutations, BLAKE3 compressions or SHA-256 compressions over `BinaryField128` with the multilinear STARK prover. The traces are bit valued, and they are committed through the `BooleanTracePcs`, which opens the current and the next row of every column. The README notes that every objective generates its trace already packed into bits.
RUSTFLAGS="-Ctarget-cpu=native" cargo run --example prove_hash_binary --release --features parallel -- --objective keccak-f-permutations --log-trace-length 14 --security-bits 96The options here are more security relevant than in the prime field example. The `--objective` option takes the four hash objectives. The `--log-trace-length` is required, and the README explains why the numbers differ per objective: the binary Keccak-f AIR uses 25 rows per permutation, one per round plus the output row, so the Keccak-f objective proves 2 to the log trace length over 25 permutations, while the three compression objectives each prove 2 to the log trace length compressions, one row per compression. The `--format` option switches standard output between `human` and `json`, with the JSON form carrying the same measurements in one object per run while progress lines and tracing spans go to standard error. The `--representation` option chooses the field representation the zerocheck prover runs its later rounds in, with `auto` as the default, and the README is careful to say that every choice proves and verifies the same statement and emits a byte-identical proof, so it is a performance trade-off only.
The last group tunes the commitment scheme, with `--log-inv-rate`, `--pcs-pow-bits`, `--security-bits` defaulting to 100, `--folding` and `--merkle-arity` which is 2 or 4 with a default of 4.
And then there is the ceiling. The README states that the Boolean commitment packs each trace's bits into `BinaryField128` elements and reduces column claims through a bit-ring switch, which caps the proven security at roughly 125 minus the sum of the log trace length, the ceiling of the log base two of the width, minus seven, and the log inverse rate, with the width being 1625 for Keccak-f and 11536 for BLAKE3.
That is a number a user has to respect rather than a knob, and it is exactly the kind of thing a toolkit that lets you pick the trace length freely has to publish.
Fifty crates, per-crate release tags and release candidates
The Cargo workspace lists its members individually, and there are more than fifty of them, from `air/` at the bottom of the stack through the field crates, the commitment schemes, the AIR definitions and the proof systems.
The workspace configuration is strict in a way that shows what the maintainers care about. The resolver is 2, `rust_2018_idioms` is denied, `unused_must_use` is denied, the Rust 2024 incompatible pattern lint is a warning, and rustdoc lints are a warning. Clippy runs with `all` and `nursery` at warning level, plus a set of pedantic lints such as `semicolon_if_nothing_returned`, `match_bool` and `needless_pass_by_value`, and a short list of `allow` entries for the ones that get in the way. The dependency versions are pinned exactly, for instance blake2 at 0.11.0, blake3 at 1.8.4, clap at 4.6.1 and criterion at 0.8.
The release history shows how that workspace ships. The three most recent tags are `p3-zk-codes-v0.9.0-rc.2`, `p3-word-v0.9.0-rc.2` and `p3-word-backend-v0.9.0-rc.2`, all published on 2026-10-16. Two things follow. The versions are per crate rather than one version for the repository, which is how a workspace of independently usable parts should be released. And the recent ones are release candidates, so the current line is 0.9.0-rc.2 for those crates.
The repository root carries the release machinery, with a `create_release.sh` script, a `release-plz.toml` configuration, a `cliff.toml` for changelog generation and a `RELEASING.md`, plus a `CHANGELOG.md` and a `CONTRIBUTING.md`. There is also an `audits/` directory, which for a cryptography library is the most reassuring directory name in the tree, since it is where composability and security review notes would live.
Editorial conclusion
Plonky3 fits a team building a STARK based zero knowledge virtual machine or another polynomial IOP system and wanting proven components for fields, commitment schemes, sumcheck and lookup arguments rather than writing them from scratch. Skip it if you need a finished proving system, since the README's checklist still shows PLONK, the tensor commitment scheme and the univariate to multivariate adapters as unfinished. Verify first which crate versions you depend on, since releases are cut per crate and the recent ones are release candidates, and check the security ceiling formula before choosing a trace length for a hash permutation.
Frequently asked questions
What is Plonky3 and what is it used for?
Plonky3 is a Rust toolkit providing primitives, such as polynomial commitment schemes, for implementing polynomial IOPs. The README says it is mainly used to power STARK-based zkVMs, though in principle it may be used for PLONK-based circuits or other PIOPs.
How do I run the binary field example in Plonky3?
The README gives the command `cargo run --release -p p3-multi-stark --example prove_binary_field`, which proves a nonlinear recurrence over `BinaryField128` using the multilinear STARK prover and `BinaryPcs` with Keccak Merkle commitments, then verifies the serialized proof with a fresh transcript.
Which fields does Plonky3 support and what are the vectorisation options?
The status list shows Mersenne31, the general 31 bit fields BabyBear and KoalaBear, Goldilocks, and binary tower fields from GF(2) up to GF(2^128). AVX2, AVX-512 and NEON backends are listed for the 31 bit families, and GF(2^128) has a GHASH polynomial-basis representation with SIMD packings.
What is unfinished in Plonky3?
The README's status checklist marks the tensor PCS, the univariate to multivariate adapter and the multivariate to univariate adapter as unfinished, PLONK as unfinished under PIOPs, the four-step FFT as unfinished under interpolation, and modifications to tune BLAKE3 for hashing small leaves as unfinished under hashes.
What licence does Plonky3 use?
It is dual licensed, with both `LICENSE-APACHE` and `LICENSE-MIT` at the top of the repository and a badge for each in the README, so the code can be used under either Apache-2.0 or MIT.
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/plonky3-plonky3)Was this useful?