lambdaworks: building SNARK and STARK provers out of Rust primitives
lambdaworks offers implementations for both SNARKs and STARKs provers, along with the flexibility to leverage their individual components for constructing customized SNARKs.
At a glance
- What is it?
- lambdaworks is a Rust library of cryptographic primitives that several proving systems are assembled from, with GPU backends for FFT and Merkle tree work. Its README and workspace manifest still pin version 0.13.0 while published releases have reached v0.15.0, and most of its examples are marked as not production ready.
- Who is it for?
- Adopt lambdaworks when you are building a proving system in Rust and want to own the field, curve and proving layers instead of binding to one framework, particularly if you need CUDA or Metal acceleration that the README says most competing Rust options do not offer. Do not adopt it for signing, encryption or a finished application that only needs to verify a proof, since the library gives you components rather than a product.
- 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 last received commits 69 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 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A workspace of primitives rather than a single prover
lambdaworks describes itself as a library of cryptographic primitives used to build proving systems, and the workspace manifest makes that concrete. The crates directory is split into crates/math, crates/crypto, crates/gpu and a provers directory, with adapters for other ecosystems. The README frames the goal plainly: a library usable in production rather than one confined to academic research, offering main building blocks and proof systems instead of a catalogue of every research result in the zero-knowledge space.
That split has consequences for how you adopt it. Nothing forces you to use the bundled provers. The README states that you can use Circom to generate circuits and then prove execution with the Groth16 prover, and that the STARK prover can be used to define an algebraic intermediate representation and prove program execution. Frontend compatibility is treated as a first class concern rather than an afterthought, which is what the adapter crates exist to serve.
The math crate is the foundation underneath. It is where field elements, elliptic curves and polynomials live, and the quick start in the README is written entirely against it, which tells you where the project expects most of your reading to start.
The workspace member list is a map of the proving systems
The Cargo.toml workspace enumerates the members explicitly, and the list is the fastest way to see the scope. Besides crates/math, crates/crypto, crates/gpu and crates/provers/stark, it contains crates/provers/plonk, crates/provers/groth16 and crates/provers/sumcheck, plus a GKR prover with a GKR-Logup variant. Two adapter crates sit inside the Groth16 directory, arkworks-adapter and circom-adapter, and a winterfell_adapter crate connects the STARK side to another prover implementation.
Then there is the sumcheck and GKR grouping, which matters because it separates the recursive argument machinery from the two families the README headlines. Groth16 and Plonk live under provers as complete systems, while sumcheck, GKR and GKR-Logup read as components that a custom proof system would compose. The README explicitly says the library offers flexibility to use individual components for building customised SNARKs, and the workspace layout is the proof of that claim.
The version field in the workspace package is worth noting for a different reason. Cargo.toml sets version 0.13.0 across the workspace and pins each internal dependency to 0.13.0 with path plus version entries, so the crates release together as one versioned line rather than independently.
Adding lambdaworks and running your first field computation
The quick start is a Cargo dependency entry followed by a short program. Two crates are needed for arithmetic work, and the versions the README shows are the 0.13.0 line:
[dependencies]
lambdaworks-math = "0.13.0"
lambdaworks-crypto = "0.13.0"With that in place, the README shows curve operations against the BLS12-381 short Weierstrass curve, using the generator point and scalar multiplication, then converting the result to affine coordinates:
use lambdaworks_math::elliptic_curve::{
short_weierstrass::curves::bls12_381::curve::BLS12381Curve,
traits::IsEllipticCurve,
};
// Get the generator point
let g = BLS12381Curve::generator();
// Scalar multiplication
let g2 = g.operate_with_self(2u64);
let g3 = g.operate_with(&g2);
// Convert to affine coordinates
let g3_affine = g3.to_affine();The same pattern appears for field arithmetic and for polynomials, where the README evaluates a polynomial built from coefficients and then interpolates one from point and value pairs. If you are coming from a higher level zk framework, this is the part that will feel unfamiliar: you are handed generic types parameterised over a field, not a prover object with a friendly method surface.
GPU work for FFT and Merkle trees sits behind feature flags
The performance section lists five specific things: hand-tuned x86-64 assembly for field arithmetic on supported platforms, a CUDA backend for Merkle tree construction and FFT operations, a Metal backend for Apple Silicon covering FFT and field operations, a sparse polynomial representation for coefficients that are mostly zero, and optimised FFT including Circle FFT and NTT implementations with field-specific tuning.
Building the CUDA side is a separate step rather than something Cargo does for you. The Makefile compiles shader files under math/src/gpu/cuda/shaders into PTX with nvcc, and the workspace carries a crates/gpu member for the Rust side of that work. The CUDA feature is also a separate lint pass in the Makefile, where clippy runs with the cuda feature enabled and warnings treated as errors, which means the GPU code is expected to stay warning clean under a different configuration from the default build.
There is a portability angle too. Most of the math and crypto crates are said to support no_std without allocation when the default features are turned off, with a few functions and modules requiring an alloc feature instead. Both crates also support the wasm32-unknown-unknown target, and the README points at the Cairo Prover wasm-pack verifier as an example of deploying a verifier in a browser. For embedded or in-browser use, that combination of no-default-features and wasm is the configuration to test first.
The developer workflow is a Makefile over nightly cargo
Day to day commands live in a Makefile rather than in documentation prose. Targets cover cargo test, clippy across the workspace with warnings denied, a docker-shell target that builds an image named rust-curves and opens a shell inside it, nix-shell for the Nix based environment, benchmarks through cargo criterion, a single bench target that takes a bench name, coverage through cargo llvm-cov nextest writing lcov.info, and a docs target that runs mdbook serve inside the docs directory.
Two targets stand apart because they need a nightly toolchain. The fuzzer targets run cargo +nightly fuzz, one against a directory of fuzz targets and others against specific targets such as deserialize_stark_proof, and there is a separate CUDA fuzz target run from the fuzz/cuda_fuzz directory. A flamegraph target compiles a bench with debug symbols for profiling, which is a good sign that the maintainers profile rather than guess.
The Dockerfile at the repository root is short and worth reading as a historical artefact: it is built FROM rust:1.66, copies the source into a working directory and ends with CMD cargo test. That base image is well behind the nightly toolchain the fuzzing targets require, so treat the container as the reproducible test environment rather than the environment for every task.
The repository also carries an ensure-no_std directory excluded from the workspace, which is how the no_std claim gets checked separately from the main build.
The README still points at 0.13.0 while releases reach v0.15.0
Here is the sharpest wrinkle in the project right now. The workspace manifest sets version 0.13.0, the quick start shows lambdaworks-math and lambdaworks-crypto at 0.13.0, and the release history shows v0.13.0 tagged Elliptic Eclair on 2025-09-29. Later releases exist: v0.14.0, named Reckless Ramen, on 2026-02-06, and v0.15.0, named Krusty Katsudon, on 2026-05-18. The last push to the repository was on 2026-08-14.
So the published release line has moved two minor versions past the version that the documentation and the manifest still name. The manifest version is a workspace-level string, so it does not necessarily mean the crates on crates.io stopped at 0.13.0, but it does mean the quick start as written will pull an older line than the newest release. Anyone starting today should read the version numbers in the quick start as illustrative rather than as the current release.
The naming convention is also worth noting: every release carries a food themed codename, which makes upgrades easy to talk about but means version numbers alone are not a changelog. The repository does include a References.md file alongside the crates, and the hosted documentation at the project's documentation site is where the per crate detail is expected to live.
The README also states plainly that most of the mini apps in the examples directory are educational and must not be used in production, which sets the correct expectation for the code you will be reading there.
Where lambdaworks sits against a ready made proving framework
The README names its comparison points itself. It observes that some zero-knowledge libraries have nice APIs and are easy to work with but are not written in Rust, while others are written in Rust but have poor programming and engineering practices. It also notes that most of them do not support CUDA, Metal, WebGPU or distributed FFT calculations using schedulers like Dask. Names such as gnark and Halo 2 appear in that passage as examples of the good API but non-Rust camp.
That is the real differentiator and also the source of the trade-off. lambdaworks gives you primitive level control, GPU backends and the freedom to assemble a custom proof system, but you write more of the proving logic yourself and you inherit the obligation to understand the algebra. A ready made framework gives you a finished prover with a higher level API and constrains you to its design.
The adapters are the pragmatic middle path. A circom-adapter for Groth16 and a winterfell_adapter for STARK let you keep an existing frontend or another prover implementation while moving the heavy arithmetic onto these primitives, which is a less risky way to evaluate the library than rewriting a proof system from the start.
Editorial conclusion
Adopt lambdaworks when you are building a proving system in Rust and want to own the field, curve and proving layers instead of binding to one framework, particularly if you need CUDA or Metal acceleration that the README says most competing Rust options do not offer. Do not adopt it for signing, encryption or a finished application that only needs to verify a proof, since the library gives you components rather than a product. Verify first that the crate version you pull matches the published release line, because the README and the workspace manifest still name 0.13.0 while v0.15.0 exists, and check whether the examples you copy, which the README warns must not be used in production, still compile against your toolchain.
Frequently asked questions
What is lambdaworks used for?
lambdaworks provides Rust implementations of the cryptographic primitives behind zero-knowledge proving systems, plus backends for several proof systems. The workspace ships math and crypto crates alongside Groth16, Plonk, STARK, sumcheck, GKR and GKR-Logup provers.
How do I add lambdaworks to a Rust project?
The README quick start adds two Cargo dependencies, lambdaworks-math and lambdaworks-crypto, both shown at version 0.13.0. Note that published releases have since reached v0.15.0, so check the version you actually pull.
Does lambdaworks support no_std and WebAssembly?
The README states that most of the math and crypto crates support no_std without allocation using the no-default-features setting, with some functions and modules requiring the alloc feature. It also says both crates support the wasm32-unknown-unknown target.
Does lambdaworks have GPU acceleration?
Yes. The README lists a CUDA backend for Merkle tree construction and FFT operations and a Metal backend for Apple Silicon covering FFT and field operations, alongside hand-tuned x86-64 assembly for field arithmetic. The CUDA shaders are compiled to PTX with nvcc through a Makefile target.
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/lambdaclass-lambdaworks)Was this useful?