orion is a pure Rust crypto library that forbids unsafe and ships post-quantum hybrids
Usable, easy and safe pure-Rust crypto
At a glance
- What is it?
- orion gives Rust programs ML-DSA, ML-KEM, X-Wing, HPKE, ChaCha20-Poly1305, BLAKE3 and the usual hashing and KDF set, with unsafe code forbidden at the crate level. It has not been through a third-party security audit, and the README says so plainly, which is the first thing to weigh before you ship it.
- Who is it for?
- Adopt orion when you need modern key establishment and signatures, including post-quantum hybrids, in a Rust codebase that wants no unsafe code and a no_std path. Do not adopt it where an audited implementation is a procurement requirement, because the README states the library has not undergone any third-party security audit and that usage is at own risk.
- Can I use it commercially?
- Yes. MIT 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 7 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
Unsafe code is forbidden, not merely avoided
Orion is a cryptography library written in pure Rust, and the repository description is a claim worth unpacking: usable, easy and safe pure-Rust crypto. The About section says the library aims to provide easy and usable crypto while trying to minimize the use of unsafe code.
Minimize is one word, and the badge tells you what actually happened. The safety dance badge reads unsafe-forbidden, which is the badge the Rust Secure Code project awards to crates whose CI enforces a ban on unsafe code. That is a stronger position than a code review that happens to find no unsafe blocks, since the rule is enforced automatically and cannot be quietly reintroduced in a patch.
The crate is published on crates.io as orion, is MIT licensed, and is at version 0.18.0. The manifest puts it on edition 2024 with a rust-version of 1.87, and the README adds the detail that the majority of testing happens with the latest stable Rust.
The audience is Rust developers who need cryptography without pulling in a C library or a dependency tree of bindings, and specifically teams that have a policy against unsafe code in their build. That is a real category: a security-sensitive Rust service where the review rules say no unsafe, and where a pure Rust implementation is the only option that satisfies them.
One thing the README does not claim is audit. It states that this library has not undergone any third-party security audit and that usage is at own risk.
Post-quantum algorithms and the hybrids built on them
The algorithm list is the substance of the crate, and the post-quantum section comes first, which is unusual for a general purpose crypto library.
For signatures there is ML-DSA. For key encapsulation there are two entries, X-Wing and ML-KEM. And there is HPKE, hybrid public key encryption, in two flavours, X-Wing/(ML-KEM768, X25519) with HKDF-SHA256 and ChaCha20Poly1305, and the same KEM pairing with SHAKE256 and ChaCha20Poly1305.
The structure of those names is the whole idea of a hybrid. X-Wing is the KEM, ML-KEM768 is the post-quantum half, X25519 is the traditional elliptic curve half, and the two are combined so that a session key is secure if either component survives. That is the correct approach for a period when you cannot be sure which of the two will fall, and it is why an implementation that offers only traditional X25519 is not enough for a forward looking deployment.
The traditional algorithms are all present as well. AEAD is (X)ChaCha20-Poly1305. Hashing covers BLAKE3, BLAKE2b, SHA2 and SHA3, with SHAKE128, SHAKE256 and BLAKE3 as extendable output functions. The KDF set is HKDF, PBKDF2, Argon2 in its id and i variants, and scrypt. ECDH is X25519, the MACs are HMAC and Poly1305, the stream ciphers are (X)ChaCha20, and there is a traditional HPKE suite with DHKEM(X25519, HKDF-SHA256) and a matching KEM.
One entry is marked experimental, which the README explains is enabled with the experimental feature and may contain breaking changes in any non SemVer-breaking crate release. That is the committing AEAD, (X)ChaCha20-Poly1305-BLAKE2b, which is the key-committing variant named in the repository topics.
safe_api by default, and the hazardous tier underneath it
The feature list in the README is a description of the library's safety design more than a list of switches, and the Cargo manifest encodes the same thing.
The default features are safe_api and zeroize, and the safe_api feature pulls in getrandom, ct-codecs and the optional alloc of zeroize:
[features]
default = ["safe_api", "zeroize"]
zeroize = ["dep:zeroize"]
safe_api = ["getrandom", "ct-codecs", "zeroize?/alloc"]
alloc = ["zeroize?/alloc"]
serde = ["dep:serde", "alloc"]
experimental = []
ct-test = []The zeroize feature toggles whether sensitive key data is zeroized internally, and it is enabled by default, which is the correct default for a crypto crate. The serde feature automatically enables the alloc feature, so enabling serialization cannot leave you without the allocator support it needs.
The alloc feature has a specific meaning that is easy to miss. Argon2 in hazardous mode is available when default or safe_api is not available. In other words, the fastest way to get Argon2, the memory hard KDF, is to opt out of the safe API and use the hazardous path instead.
The no_std story is implicit rather than a feature you turn on. It is the state you get by disabling default features and selecting nothing else, and it represents no heap allocations at all. That is what lets the crate run on a target without an allocator, which is a common requirement for embedded Rust.
Finally, ct-test exposes some internal functionality that is only relevant for testing, and it exists because the dudect harness in the sibling repository needs it. A feature that only exists to make an external test suite work is a good sign about how the project treats constant-time behaviour.
Building the docs, running the tests, and building the benchmarks
Everything needed to work on the crate is a cargo command, and the README documents each one.
The tests are the plain case:
cargo testThe documentation can be built locally with a special cfg flag that the docs.rs build uses, and it needs nightly for that:
RUSTDOCFLAGS='--cfg docsrs' cargo +nightly doc --no-deps --all-featuresAnd the benchmarks run through Criterion, with all the benchmark files in the benches directory:
cargo benchThe manifest sets profile.dev to opt-level = 1, which is a deliberate choice for a crypto crate. At the default unoptimised debug level, constant-time code paths are measured in a way that does not resemble production, and the arithmetic is slow enough that timing behaviour in a debug build says little about timing behaviour in a release build. Compiling at optimisation level 1 in development keeps the timings closer to release while retaining debug assertions.
The dependency set is short and tells you what the crate trusts. subtle provides constant-time primitives, zeroize handles memory scrubbing, fiat-crypto supplies the formally verified arithmetic used by the X25519 and Poly1305 implementations, getrandom provides randomness, and ct-codecs provides constant-time encoding. All of them are default-features = false, so nothing is pulled in that the crate has not opted into.
The dev dependencies are the usual test furniture, with quickcheck for property based testing, criterion for the benchmarks, rand for test randomness, and hex and serde_json for test data. The manifest also declares a single example, migration17to18, which points at a migration file under doc/0.18 and requires the safe_api feature, so the upgrade path from the previous major is runnable as code rather than only described in prose.
Fuzzing and constant-time testing are separate projects
The testing setup is split across several repositories, and the split is itself informative.
Fuzzing is done with honggfuzz-rs in the orion-fuzz repository, and the README points at that repository for how to start fuzzing Orion. Constant-time execution tests live in orion-dudect and orion-sidefuzz, and there is a separate badge for the dudect workflow in the orion-dudect repository, running weekly rather than on every commit.
Dudect is the technique of statistical testing for whether execution time depends on secret data, which is how a library checks that its comparisons and branches do not leak through timing. Running it in a separate repository means the harness, the statistical thresholds and the corpus live outside the library, so a change to the library cannot quietly relax the test.
The main repository has its own badges that describe the rest of the discipline: daily tests, an audit check workflow, and coverage through codecov. The audit check is the cargo-deny configuration that ships as deny.toml, which is how a crate blocks dependencies with problems such as licences or unmaintained versions, and it explains why the deny.toml file sits in the repository root.
The wiki holds the details, with a page on the testing suite and another on benchmarks, and the benchmark overview lives there rather than in the README. The README is a signpost, not the manual, which is normal for a crypto crate where the wiki carries the usage guidance.
No audit, an MSRV that can move, and a 0.x version number
Three caveats belong in any honest assessment of orion.
The first is the audit. The README states that the library has not undergone any third-party security audit and that usage is at own risk, and it points at SECURITY.md for recommendations on correct use and for reporting security issues, with more detail in the wiki's security page. That is an unusually direct statement, and it is the correct one: a cryptographic library without an external review is a different kind of object from a library with one, and the difference is on you to weigh.
What the crate does have is verification of a narrower kind. Orion uses formally verified arithmetic, generated by Fiat Crypto, for the X25519 and Poly1305 implementations. That is a strong guarantee about the arithmetic, and it is not a guarantee about the protocol composition, the key handling or the API misuse surface.
The second caveat is the minimum supported Rust version. Rust 1.87 or later is supported, but the MSRV may be changed at any point and will not be considered a SemVer breaking change. So a dependency bump can break your build without the crate's version changing, which is unusual and worth pinning the toolchain if that matters to you.
The third is the version number itself. Orion is at 0.18.0, published on 2026-08-30, with a release candidate a day earlier and 0.17.15 in June. A 0.x version carries no stability promise under Cargo's own versioning rules, and the repository is not archived with the last push on 2026-10-16. The licence is MIT, with the text in the LICENSE file, which is permissive for commercial and non-commercial use alike.
Where orion is the wrong tool
The first wrong case is a procurement requirement for an audited implementation. If your organisation requires a third-party security audit before a primitive reaches production, or if your customers require it, this crate does not clear that bar, because the README says outright that no audit has been done. The alternative is a widely deployed implementation with published audits and years of field use, and the difference in approach is that those projects are reviewed by people other than their authors.
The second wrong case is a protocol you already have. If your system already uses a specific TLS stack, a specific KDF or a specific AEAD scheme, adding a second crypto library mostly adds a place for mistakes. The case for orion is strongest where the application needs something the standard stack does not offer, for example a post-quantum hybrid KEM for a protocol that has to interoperate with a peer doing the same, or Argon2 in a no_std build where a C binding is not an option.
The third is a team without the appetite for the surrounding work. The crate is only half of the picture. The real protection comes from the fuzzing campaigns, the dudect runs, the audit checks and the wiki guidance on correct use, and those are things you either adopt or you do not. A crate you pull in and call once, with no review of how the API is used, has not bought you much regardless of how carefully the arithmetic is written.
The realistic alternative, for the same goal of pure Rust crypto without unsafe, is to depend on a set of smaller specialist crates, each for one algorithm, and accept that you now own the composition. Orion's argument is the opposite one: that the composition is where mistakes happen, and that a single crate with one safe API, one feature set and one test discipline is easier to use correctly than five crates used together by hand.
Editorial conclusion
Adopt orion when you need modern key establishment and signatures, including post-quantum hybrids, in a Rust codebase that wants no unsafe code and a no_std path. Do not adopt it where an audited implementation is a procurement requirement, because the README states the library has not undergone any third-party security audit and that usage is at own risk. Before you depend on it, run cargo test and the dudect and fuzzing suites, read SECURITY.md for the recommendations on correct use, and note that the minimum supported Rust version is 1.87 and that the README says the MSRV may change at any point without being treated as a SemVer breaking change.
Frequently asked questions
What is orion and what does it provide?
Orion is a pure Rust cryptography library offering ML-DSA signatures, ML-KEM and X-Wing key encapsulation, hybrid HPKE suites, (X)ChaCha20-Poly1305 AEAD, BLAKE3, BLAKE2b, SHA2, SHA3, HKDF, PBKDF2, Argon2, scrypt, X25519 and the usual MACs and stream ciphers.
Is orion audited?
No. The README states that the library has not undergone any third-party security audit and that usage is at own risk, and it points to SECURITY.md and the wiki for recommendations on correct use. What it does have is formally verified arithmetic from Fiat Crypto for the X25519 and Poly1305 implementations.
How do I use orion without the standard library?
The no_std mode is implicit rather than a feature you switch on. It is what you get by disabling default features and selecting no additional features, and it means no heap allocations, which suits embedded targets. Enabling the alloc feature switches on allocator support, and Argon2 in hazardous mode becomes available when safe_api is not.
How is orion tested?
The repository has daily test, audit check and coverage workflows, fuzzing is done with honggfuzz-rs in the orion-fuzz repository, and constant-time execution tests live in orion-dudect and orion-sidefuzz. The ct-test feature exists so the dudect harness can reach internal functionality.
What Rust version does orion require?
The manifest sets rust-version to 1.87 and the README says Rust 1.87 or later is supported, with the majority of testing on the latest stable Rust. The MSRV may be changed at any point and the README says that will not be considered a SemVer breaking change.
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/orion-rs-orion)Was this useful?