Library / SDK
open-quantum-safe/liboqs avatar
open-quantum-safe/liboqs

liboqs: a C library for prototyping post-quantum cryptography

C library for prototyping and experimenting with quantum-resistant cryptography

3,073 stars780 forksCNOASSERTION

At a glance

What is it?
liboqs collects quantum-safe KEMs and signature schemes behind one C API, with a test harness and benchmarking routines. It is a prototyping library, not a drop-in replacement for your TLS stack, and the README is explicit about that boundary.
Who is it for?
Adopt liboqs when you need to call ML-KEM, ML-DSA or SLH-DSA from C or C++ code, or when you are building an integration such as the OQS OpenSSL 3 Provider and need the underlying primitives. Do not adopt it as a production replacement for your existing TLS or PKI stack: the README describes it as a library for prototyping and experimenting, and the per-algorithm table shows several families at Tier 3 (Community) with no active upstream maintenance.
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 1 day ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What liboqs solves, and who it is actually for

Post-quantum algorithms arrive as a pile of separate reference implementations, each with its own build system, its own parameter sets and its own idea of what a key looks like. liboqs exists to flatten that pile. The README lists three things it provides: a collection of open source implementations of quantum-safe key encapsulation mechanisms and digital signature algorithms, a common API for those algorithms, and a test harness with benchmarking routines. The common API is the part that matters most. You write one call site against the liboqs KEM or signature interface, and the algorithm selection becomes a runtime or build-time choice rather than a rewrite.

The intended audience is narrow and the README says so. liboqs is described as part of the Open Quantum Safe project, whose stated aim is to develop and integrate quantum-safe cryptography into applications to facilitate deployment and testing in real world contexts. The integrations themselves live elsewhere: the OQS OpenSSL 3 Provider for TLS, X.509 and S/MIME, and the oqs-demos repository for other post-quantum-enabled demos. If you want post-quantum TLS in a running server, liboqs is the layer underneath that work, not the thing you configure. If you are writing C or C++ code that needs to call ML-KEM directly, or you are building one of those integrations, liboqs is aimed at you.

One API over many algorithm families, and what the tier column means

The architecture is a thin uniform layer over a set of vendored or upstream implementations. The README's algorithm table is the clearest view of this. Each row names an algorithm family, its standardization status, the primary implementation it comes from, an upstream maintenance note, and an OQS tier. BIKE, for example, is listed as not selected by NIST, sourced from awslabs/bike-kem, with upstream maintenance marked TBD and OQS tier Tier 3 (Community). Classic McEliece is under ISO consideration, taken from a pinned PQClean commit, and its upstream maintenance is recorded as No active maintenance, also Tier 3. FrodoKEM is under ISO consideration, comes from a pinned microsoft/PQCrypto-LWEKE commit, has upstream maintenance described as best effort, and sits at Tier 2 (Supported).

That table is the honest part of the project and worth reading before you pick an algorithm. A family can be present in the build, callable through the same API as everything else, and still be Tier 3 with no active upstream maintenance. The API uniformity hides that distinction, so the tier column and the per-algorithm pages under docs/algorithms are where you find it. Names standardized by NIST, ML-KEM, ML-DSA and SLH-DSA, are declared stable, and the README states that if NIST changes implementation details liboqs will adjust so users are protected from such changes. Every other name is subject to change. That is a real API stability boundary, and it runs through the middle of the algorithm list.

Building liboqs on Linux or macOS and calling a KEM

The README's Quickstart section splits into Linux and Mac, Windows, and cross compilation. The Linux and macOS path is the CMake route. The repository's requirements.txt header gives the Python side of the setup, noting that it should be installed with pip3 install --require-hashes -r requirements.txt and that those dependencies are required for running the test suite and build tooling. Treat that file as the pinned set for the test harness rather than something your application links against.

bash
pip3 install --require-hashes -r requirements.txt

After the build completes you have the library and, in the same build tree, the test and benchmarking binaries the README refers to. Running the test suite is the first real use: it exercises the algorithm implementations through the common API and tells you which ones your configuration actually contains. That last point is not cosmetic. The README states that which algorithms are built can be controlled via OQS_ALGS_ENABLED, documented in CONFIGURE.md, and that by default liboqs is built supporting every algorithm in the table, including experimental ones. A default build is therefore wider than most applications want, and the README does not spell out the accepted values for OQS_ALGS_ENABLED in the excerpt available here; CONFIGURE.md is the file to read for that. What the README does make clear is the trade-off: the default gives you everything, and narrowing the build is a configuration decision you make deliberately.

Platform and support limits the README states outright

liboqs documents its own constraints under a Limitations and Security heading with two subsections, Platform limitations and Support limitations. The existence of that section, and its placement in the README rather than in a footnote, is the right signal to a reader deciding whether to depend on the library. The excerpt available here does not reproduce the contents of either subsection, so the specific platform list and the specific support boundaries are things to read in the repository rather than infer. PLATFORMS.md is a top-level file and is the natural place to look for the platform detail.

The practical failure mode is a build that succeeds on a developer machine and then behaves differently elsewhere, because the algorithm set, the platform support and the upstream maintenance status of a given family all vary independently. A second failure mode is subtler: because the API is uniform, code that calls a Tier 3 community algorithm looks exactly like code that calls ML-KEM. Nothing in the call site records the difference. If your selection logic is driven by a string name, a typo or a stale name silently selects a different family. The README's warning that all non-NIST-standardized names are subject to change makes that a maintenance problem, not just a correctness one.

When liboqs is the wrong layer to reach for

If your goal is quantum-safe TLS between two services, liboqs is the wrong starting point. The README positions the OpenSSL 3 Provider as the component that integrates liboqs into TLS, X.509 and S/MIME. Going directly to liboqs means you are implementing the protocol integration yourself, including the parts the provider already handles. The same applies to S/MIME and certificate handling.

If your application is not written in C or C++, liboqs is also the wrong layer, though the RELATED SEARCHES list shows people asking about liboqs from Python, Go, Rust, Java, Node and JS. The README excerpt describes a C library with a common API for the algorithms; it does not describe official bindings for those languages. The cpp/ directory at the top level indicates C++ support in the repository, and zephyr/ indicates a Zephyr integration, but the README does not present either as a general-purpose binding story. Anyone reaching for liboqs from a managed language should confirm what bindings exist and who maintains them before designing around the library.

Finally, if you need a stable, long-lived ABI with a frozen algorithm set, the project's own framing works against you. It is described as a library for prototyping and experimenting, it ships experimental algorithms by default, and it reserves the right to adjust implementations when NIST changes details. Those are reasonable properties for a prototyping library and poor ones for a frozen dependency.

The real alternative: OpenSSL's own post-quantum work versus the OQS provider

The most direct comparison is with OpenSSL itself, and the RELATED SEARCHES list shows people searching for exactly that comparison. The difference is architectural. OpenSSL is a general-purpose cryptographic library and TLS implementation that has been adding post-quantum algorithm support into its own codebase. liboqs is a standalone C library that implements the algorithms and exposes them through its own API, with integration into OpenSSL happening through a separate project, the OQS OpenSSL 3 Provider.

That split has consequences. Using the OQS provider means installing liboqs and the provider together, and the algorithm set you get in TLS is tied to the liboqs build you produced, including the effect of OQS_ALGS_ENABLED. Using OpenSSL's native support means one dependency instead of two, but you get whatever algorithms that release carries rather than the full liboqs table with its per-family tier annotations. Neither approach is strictly better. If you want to experiment across a wide set of families, including ones NIST did not select, liboqs is the broader surface. If you want the smallest dependency graph for a conventional TLS deployment, the provider-plus-liboqs pair is more moving parts than a single library.

Licence, release cadence and the cost of keeping up

The repository's licence field reports NOASSERTION, which means the automated classifier could not map the licence to a known identifier. The top-level LICENSE.txt file is the authoritative text, and the README has a License section that points there. Read LICENSE.txt directly rather than relying on the repository metadata: the difference between a permissive licence and a copyleft one changes what you can do with a linked library, and the metadata alone does not tell you which it is. This is a factual gap in the repository listing, not a legal opinion.

The last push to the default branch was on 2026-09-23, and the most recent release is 0.16.0 from 2026-07-09, preceded by 0.16.0-rc1 on 2026-06-24 and 0.15.0 on 2025-11-14. That is a release cadence of roughly two minor versions a year, with release candidates published before the final tags. The upgrade cost is concentrated in the algorithm name surface. NIST-standardized names are stable by policy; everything else can change between releases. An application that hardcodes algorithm name strings for non-standardized families should expect to touch those strings when it moves between minor versions, and should check ALGORITHMS.md and the per-algorithm pages under docs/algorithms at each upgrade. RELEASE.md is a top-level file and is the place to check for the project's own release process.

Editorial conclusion

Adopt liboqs when you need to call ML-KEM, ML-DSA or SLH-DSA from C or C++ code, or when you are building an integration such as the OQS OpenSSL 3 Provider and need the underlying primitives. Do not adopt it as a production replacement for your existing TLS or PKI stack: the README describes it as a library for prototyping and experimenting, and the per-algorithm table shows several families at Tier 3 (Community) with no active upstream maintenance. Before you commit, check ALGORITHMS.md for the tier of the specific variant you plan to call, and check CONFIGURE.md for how OQS_ALGS_ENABLED changes which algorithms end up in the build.

Frequently asked questions

What is liboqs?

liboqs is an open source C library for quantum-safe cryptographic algorithms, providing implementations of key encapsulation mechanisms and digital signature algorithms behind a common API, plus a test harness and benchmarking routines. It is part of the Open Quantum Safe project, which is supported by the Post-Quantum Cryptography Alliance as part of the Linux Foundation.

How do I install liboqs?

The README's Quickstart section covers Linux and macOS, Windows, and cross compilation. On Linux and macOS the path is to clone the repository, create a build directory, and run cmake followed by ninja; the repository's requirements.txt covers the Python dependencies needed for the test suite and build tooling.

How do I use liboqs?

You call the algorithms through liboqs's common API for KEMs and signature schemes, and the README points to the test harness and benchmarking routines as the way to exercise what your build contains. Which algorithms are present depends on the build, since OQS_ALGS_ENABLED controls the set and the default includes every algorithm in the table, including experimental ones.

liboqs vs openssl: what is the difference?

liboqs is a standalone C library that implements quantum-safe algorithms behind its own API, while OpenSSL is a general-purpose cryptographic library and TLS implementation. The OQS project integrates liboqs into OpenSSL through the separate OQS OpenSSL 3 Provider, so using post-quantum algorithms in TLS through that route means installing both components.

Is TLS 1.3 quantum-safe?

The README does not present liboqs as a TLS implementation. It describes the OQS OpenSSL 3 Provider as the component that integrates liboqs into protocols like TLS, X.509 and S/MIME, so any post-quantum TLS behaviour comes from that provider rather than from liboqs alone.

Official sources

  1. Issues
  2. open-quantum-safe/liboqs on GitHub
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/open-quantum-safe-liboqs.svg)](https://hysenlabs.com/projects/open-quantum-safe-liboqs)