curve25519-dalek, three Rust crates for the curve your signatures probably use
A pure-Rust implementation of group operations on Ristretto and Curve25519
At a glance
- What is it?
- The dalek-cryptography workspace holds a pure-Rust implementation of the group arithmetic on Curve25519 and Ristretto, plus the EdDSA signature scheme and the Diffie-Hellman key exchange built on it. The interesting detail is the release line: a 4.0.0 pre-release from 2022 that is still what the crates point at.
- Who is it for?
- Adopt these crates if you are implementing Ed25519 signatures or X25519 key exchange in Rust and want a fixed, self-contained implementation of one curve rather than a general purpose elliptic curve toolkit. Do not adopt them for arbitrary curves, since the point of the workspace is that the mathematics is narrow and auditable.
- 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 44 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
- dalek-cryptography/curve25519-dalek1,208 ★ · +6
| Repository | 2026-10-19 | 2026-11-07 |
|---|---|---|
| dalek-cryptography/curve25519-dalek | 1.2k | 1.2k |
6 Stars in the last 19 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
One workspace, three crates, and a deliberate layering
This repository holds pure-Rust crates for elliptic curve cryptography, and the split into three published crates is the design decision that matters.
The base layer is curve25519-dalek, a library for arithmetic over the Curve25519 and Ristretto elliptic curves and their associated scalars. Everything else in the workspace is built on top of that arithmetic.
The second layer is ed25519-dalek, an implementation of the EdDSA digital signature scheme over Curve25519. It is the crate people reach for when they want to sign and verify, and it depends on the group operations rather than reimplementing them.
The third is x25519-dalek, an implementation of elliptic curve Diffie-Hellman key exchange over Curve25519. It is the same curve and the same underlying arithmetic, exposed for a different protocol.
There is also a fourth crate in the workspace, curve25519-dalek-derive, which is described as nothing more than a helper crate holding some macros that make curve25519-dalek easier to write. It exists so the main crate can derive implementations for its own types without the main crate having to depend on a proc macro crate from elsewhere.
The layering is what makes the workspace reviewable. The mathematics lives in one place, and each protocol crate is a thin, purpose-specific layer on top. A change to the group arithmetic is auditable on its own, and the protocol layers are small enough to read in an afternoon.
The pure-Rust part is not a footnote. It means the whole chain, from the field arithmetic up to the signature scheme, is Rust with no C dependency, which is a meaningful property for anything that has to be built reproducibly or audited in one language.
Ristretto and the curve sit side by side, and the difference is deliberate
The description of the base crate names two things, Curve25519 and Ristretto, and it is worth being precise about why both are there.
Curve25519 is the curve itself, a Montgomery curve, and the topic list of the repository includes both montgomery and edwards-curve, which reflects the two coordinate systems that appear in this family of work.
Ristretto is a group abstraction built on top of Curve25519 that gives a clean, prime-order group interface, with the point encodings designed so that different representatives of the same group element do not produce different byte strings. In practical terms it is the version you use when you want a signature or a key exchange to be canonical, so that there is no ambiguity in what gets signed and no second valid encoding of the same value to worry about.
Having both in one crate means a consumer can pick the abstraction that matches the protocol, and the arithmetic underneath is shared.
That choice also has a cost that the documentation is upfront about elsewhere in the ecosystem: Ristretto is not Ed25519, and the two are not interchangeable. A signature that is described as Ristretto based is not the same artefact as an Ed25519 signature, and mixing the two in a protocol that expects one of them is a mistake that type safety will not catch for you.
The ed25519-dalek crate, being the EdDSA scheme over Curve25519, is the place where the Ed25519 specific behaviour lives, which is why the group layer can offer Ristretto alongside the raw curve without the two leaking into each other.
The workspace patches crates.io with its own directories
The workspace manifest contains a detail that is easy to miss and that tells you how the project is developed.
[patch.crates-io]
curve25519-dalek-derive = { path = "./curve25519-dalek-derive" }
curve25519-dalek = { path = "./curve25519-dalek" }
x25519-dalek = { path = "./x25519-dalek" }Cargo's patch mechanism redirects a dependency on a crates.io package to a local path for everyone who builds inside this workspace. The effect here is that the curve25519-dalek and x25519-dalek crates, plus the derive helper, always build against the code in this repository rather than against the versions already on crates.io.
Without it, developing the base crate and the protocol crates together would be awkward, because each would resolve the others from the registry. With it, a change to the group arithmetic is immediately visible to the signature and key exchange crates in the same checkout, which is exactly what you want when the change is in the mathematics.
The workspace also sets resolver to version 2, which is the resolver version that fixes how feature unification is computed across a workspace, and it lists the four members explicitly. The dev profile carries its own optimisation setting.
[profile.dev]
opt-level = 2That line is a small statement about priorities. Debug builds are still unoptimised for debug information, but the actual code generation is optimised at level 2, which keeps the arithmetic reasonably fast even in a test run or a debug build you are profiling. For a cryptography crate, that is a sensible trade, since a test suite that runs in minutes rather than hours is a test suite people actually run.
The release line has been a pre-release since 2022
The one published release in the list is 4.0.0-pre.5, dated 2022-12-14. There is no final 4.0.0 in that list, and the last push to the repository was on 2026-09-24, with the repository not archived.
Put those two facts side by side and the picture is clear. The code is being worked on, the branch is moving, and the published artefact is a pre-release from more than three years earlier. Opting into 4.0.0-pre.5 is a deliberate choice someone has to make, since most dependency setups do not select a pre-release version by default.
Whether that is a problem depends on what you are doing with it. For a production system, depending on a pre-release line is a legitimate concern about stability guarantees and about whether the version you pin is the version the maintainers consider current. For research, for a prototype, or for a system where you intend to track the branch rather than the registry, it is a much smaller concern.
The repository does ship a Cargo.lock, and the crates carry continuous integration badges pointing at per-crate workflow files, one each for curve25519-dalek, ed25519-dalek and x25519-dalek, so each crate is built and tested on its own rather than only as part of the workspace. Documentation is published to docs.rs for all three, with the crates.io listing and the docs link shown side by side in the project table.
The upgrade question for an adopter is therefore concrete: check what version your lock file actually resolves to, and decide whether you are tracking the registry or the branch.
A custom licence and a stricter code of conduct
Two governance details are worth reading before you depend on this code.
The first is the licence. The repository's licence is recorded as a custom one that GitHub cannot classify, which in practice means it is not a standard SPDX identifier such as MIT, Apache-2.0 or BSD-3-Clause, and the LICENSE file is the authoritative text. For a cryptography crate, a licence that is not a standard permissive grant is a question worth answering before it enters a dependency tree, and the answer is in the file rather than in a badge.
The second is the code of conduct. The project follows the Rust Code of Conduct, and it adds clauses of its own. The first is a privacy and anonymity commitment: the rights of contributors and community members to privacy and anonymity are respected, and if someone wishes to contribute under a pseudonym different from their primary identity, that wish is respected by all contributors.
That is a stronger commitment than the base conduct requires, and it is the kind of clause that matters in a project that attracts contributors who are not using their real names.
The rest of the repository is conventional. There is a CONTRIBUTING.md that contributors are pointed to, an AGENTS.md at the top level, a.typos.toml for spelling checks, a docs directory for the project documentation, and a.github directory for the workflows and templates.
The absence of a homepage in the project metadata is a minor point, but it is worth noting that the crates.io listings and the docs.rs pages are where the documentation for this project actually lives, not a project site.
A fixed curve implementation versus a general purpose elliptic curve library
The real alternative to this workspace is a general purpose elliptic curve toolkit, the kind of crate that lets you instantiate a curve from its parameters and then do arithmetic on it.
The difference in approach is the entire point of this project. A general purpose library gives you flexibility: many curves, many hash to curve options, many encodings, configurable field implementations. In exchange you get a large surface area, and the security of any single use depends on the configuration you chose, including the parameters you supplied.
A fixed implementation does the opposite. The curve, the group abstraction and the encodings are decided for you, and the choices are made by people who have spent a long time on that one set of mathematics. The result is a much smaller amount of code to review and a much smaller number of ways to misuse the API, at the cost of a fixed set of algorithms.
That is a good trade for the two protocols most Rust projects actually need. If you want Ed25519 signatures, you want the EdDSA scheme over Curve25519, and the interesting research questions about it were settled years ago. If you want key exchange, you want X25519. Paying for a general purpose library in order to get those two is a poor trade, both in dependency weight and in the number of decisions you have to get right.
The cost of the fixed approach appears when you need something outside the two protocols, at which point you are reading the curve arithmetic yourself rather than configuring it, and that is a real cost, but it is a cost with a clear price.
Editorial conclusion
Adopt these crates if you are implementing Ed25519 signatures or X25519 key exchange in Rust and want a fixed, self-contained implementation of one curve rather than a general purpose elliptic curve toolkit. Do not adopt them for arbitrary curves, since the point of the workspace is that the mathematics is narrow and auditable. Before you depend on it, check which version the crates.io dependency resolves to, because the only published release in the list is a 4.0.0 pre-release from 2022-12-14 while the branch has moved on, read the LICENSE file directly because the licence is a custom one that GitHub cannot classify, and confirm that your own audit of the dependency chain accepts a pre-release line in production.
Frequently asked questions
What crates does the curve25519-dalek repository publish?
curve25519-dalek for arithmetic over the Curve25519 and Ristretto curves and their scalars, ed25519-dalek for the EdDSA digital signature scheme over Curve25519, and x25519-dalek for elliptic curve Diffie-Hellman key exchange. A fourth crate, curve25519-dalek-derive, holds helper macros.
Is the implementation pure Rust?
Yes. The repository describes its contents as pure-Rust crates for elliptic curve cryptography, and the workspace builds all four members from source with no C dependency.
What is the latest published version of these crates?
The only release in the list is 4.0.0-pre.5, dated 2022-12-14, while the last push to the repository was on 2026-09-24 and the repository is not archived. Each crate has its own continuous integration workflow and its own docs.rs page.
What licence applies to the dalek crates?
The repository records a custom licence that GitHub cannot classify, so the LICENSE file is the authoritative text. The project follows the Rust Code of Conduct with additional clauses on privacy and anonymity for contributors.
How does the workspace make the crates build against each other?
The workspace manifest uses Cargo's patch mechanism to point the crates.io entries for curve25519-dalek, curve25519-dalek-derive and x25519-dalek at their local directories, so a checkout always builds the crates against the code in the repository. The dev profile also sets opt-level = 2.
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/dalek-cryptography-curve25519-dalek)Star history chart for your README
[](https://hysenlabs.com/projects/dalek-cryptography-curve25519-dalek)Was this useful?