# CIRCL: Cloudflare's Go library, where the post-quantum algorithms sit next to a SIDH you should not use

> CIRCL is a collection of cryptographic primitives in Go covering post-quantum key encapsulation and signatures, elliptic curves, HPKE, VDAF and zero-knowledge proofs. It carries its own security disclaimer, a named list of packages that are not constant time, and a deprecated SIDH entry, and those three facts should shape any adoption decision.

**cloudflare/circl** — CIRCL: Cloudflare Interoperable Reusable Cryptographic Library

- Repository: https://github.com/cloudflare/circl
- Website: http://blog.cloudflare.com/introducing-circl
- Stars: 1,737 · Forks: 229
- Language: Go
- License: NOASSERTION
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/cloudflare-circl

## A collection of packages, not one library with one contract

CIRCL expands to Cloudflare Interoperable, Reusable Cryptographic Library, and the README describes it as a collection of cryptographic primitives written in Go whose goal is to serve as a tool for experimental deployment of algorithms targeting post-quantum and elliptic curve cryptography.

The repository layout tells you how to consume it. There is no top-level package with a single API. Instead the tree is a set of directories that each map to a cryptographic family: `kem/`, `sign/`, `dh/`, `group/`, `hpke/`, `oprf/`, `blindsign/`, `tss/`, `zk/`, `xof/`, `cipher/`, `abe/`, `ot/`, `vdaf/`, `pki/`, `pke/`, `ecc/`, `math/`, `internal/` and `simd/`. You import the subpackage you need, for example `github.com/cloudflare/circl/kem/mlkem`, and inherit only its guarantees.

That structure is the library's main ergonomic fact. It also means `go.mod` pulls three dependencies for all of it: `github.com/bwesterb/go-ristretto` at v1.2.4, `golang.org/x/crypto` at v0.54.0 and `golang.org/x/sys` at v0.47.0, with `go 1.25.0` declared.

Installation is a single fetch:

```sh
go get -u github.com/cloudflare/circl
```

The README also points to the Cloudflare Go fork for integrating CIRCL natively into the Go standard library itself, which is the distribution route Cloudflare's own products use.

## The security disclaimer is unusually direct

Most crypto libraries have a security policy. CIRCL has a paragraph that should be read before anything else.

The README states the library is offered as-is and without a guarantee, that changes to the code, repository and API are expected in the future, and that caution should be taken before using it in a production application since part of its content is experimental. Security issues go through the project's Security Policy.

This is not boilerplate in the usual sense. The repository contains algorithm implementations that are still IETF drafts, an entry for partially blind RSA citing `draft-cfrg-partially-blind-rsa`, X-Wing as `draft-connolly-cfrg-xwing-kem`, and Prio3 as a `draft-irtf-cfrg-vdaf`. The stated purpose is experimental deployment, which is a different goal from production readiness, and the disclaimer exists because the boundary is real.

Licensing is a separate question from that disclaimer, and it is unusual. GitHub classifies the licence as custom rather than a recognised identifier, so the LICENSE file at the repository root is the authority and anyone deploying this needs to read it rather than assume Apache-2.0 or BSD from other Cloudflare projects. That is not legal advice; it is a reason to open the file before vendoring.

## Seven packages are documented as leaking timing information

This is the most actionable section in the README and the reason to read it rather than skim the feature tables.

The README states that not every package in CIRCL is constant time, and names those that document at the top of their `doc.go` or main source file the specific operations known to leak timing information: `group/`, `oprf/`, `blindsign/blindrsa/partiallyblindrsa/`, `secretsharing/`, `tss/rsa/`, `zk/dl/`, `zk/dleq/` and `ecc/p384/`.

That is eight paths listed, spanning prime groups, oblivious PRFs, blind signatures, secret sharing, threshold RSA, two zero-knowledge proof packages and the P-384 curve implementation. For several of these, timing leakage is inherent to what the primitive does rather than an implementation defect: a threshold or blind signature scheme that varies in time with a secret share is a different statement from a scalar multiplication that branches.

The practical rule that follows: if your threat model includes a local attacker measuring your process, read the `doc.go` of the exact package you import before you claim constant-time behaviour. A blanket statement about the library is not supportable from the README.

Note the interaction with the algorithm tables. `P-384` appears both under prime groups in `./group` and separately in the miscellaneous curves list, and it is `ecc/p384/` that appears on the timing list.

## Post-quantum KEMs and signatures, including one that is struck through

The post-quantum section is where most adoption interest sits, and the presentation is blunt about what is safe to reach for.

Key encapsulation: `kem/mlkem` provides ML-KEM in modes 512, 768 and 1024 per FIPS 203, and `kem/kyber` provides the Kyber KEM in the same three modes. `kem/xwing` is X-Wing, `kem/frodo` is FrodoKEM in mode 640-SHAKE, and `dh/csidh` is CSIDH, a post-quantum commutative group action.

Then there is the entry that tells you how to read the rest:

- (insecure, deprecated) `kem/sike`: Supersingular Key Encapsulation with primes p434, p503, p751

SIKE is present in the tree, labelled insecure and deprecated, with strikethrough formatting in the README. That is a deliberate warning, not an oversight. An implementer scanning package names in `kem/` will find it, so the label exists to prevent that.

Signatures: `sign/dilithium` in modes 2, 3 and 5, `sign/mldsa` for ML-DSA in modes 44, 65 and 87 per FIPS 204, and `sign/slhdsa` with twelve parameter sets, both pure and pre-hash signing, per FIPS 205.

The mix of FIPS finalised algorithms and drafts in adjacent bullet points is the real state of the field, and CIRCL's choice is to ship both and label them.

## Beyond KEMs: HPKE, VOPRF, VDAF and threshold signatures

The rest of the surface is protocol work that sits above a single primitive, and this is where CIRCL differs from a pure algorithm library.

`hpke/` implements Hybrid Public-Key Encryption per RFC 9180, which is the composition a lot of services actually want: an authenticated key exchange whose KEM component can be swapped for a post-quantum one without changing the caller. `oprf/` is VOPRF per RFC 9497, and `blindsign/blindrsa` is RSA blind signatures per RFC 9474, with a partially blind variant under `blindsign/blindrsa/partiallyblindrsa/`.

`tss/rsa` provides threshold RSA signatures following Shoup's Eurocrypt 2000 result, and `abe/cpabe` is ciphertext-policy attribute-based encryption per ia.cr/2019/966. `vdaf/prio3` is the Prio3 verifiable distributed aggregation function.

Prio3 is the one to notice if your interest is measurement rather than transport. A verifiable distributed aggregation function lets several clients encode inputs so the server can aggregate them without learning individual values, and having it in the same module as the KEMs means a project doing both ends of an attested metrics pipeline can share a dependency.

Zero-knowledge proofs are present as `zk/dl` for Schnorr discrete log knowledge per RFC 8235, `zk/dleq` for discrete log equality per RFC 9497, and `zk/qndleq` for the same in the subgroup of squares in (Z/nZ)*.

## Make targets, benchmarks, and the purego escape hatch

Development is driven by the Makefile rather than by a CI script you invoke, and one option in it changes what code compiles.

`make build` runs `go build ./...` and `make test` runs `go vet ./...` followed by `go test ./...`. `make bench` uses `BENCH_OPTS ?= -bench=. -run="^_" -benchmem`, with the comment in the file explaining that the `-run="^_"` pattern exists so benchmarks do not run tests, since no test name begins with an underscore. `make cover` produces a coverage profile with `-covermode=atomic` and renders HTML.

The switch worth knowing is `NOASM`. Setting it adds `--tags purego` to the build options, which selects the pure Go implementations instead of the assembly ones. That matters for cross compilation, for platforms without the SIMD paths, and for auditing, since it removes a category of code from your review. The `simd/` directory in the tree is where that code lives, and the miscellaneous list mentions a SIMD Keccak f1600 permutation.

Two build modes are also defined for embedding: `make circl_static` produces `circl_static.exe` with `-buildmode=default`, and `make circl_plugin` produces `circl_plugin.so` with `-buildmode=plugin`. Both run `go clean -cache -modcache` first, so a build is a full cache reset rather than an incremental compile. The input file for both is generated by `go run .etc/all_imports.go`.

## Conclusion

CIRCL fits a Go team that needs to evaluate post-quantum algorithms, ML-KEM, ML-DSA, SLH-DSA, HPKE or Prio3 in one dependency rather than a scattered set, and that can read each package's own doc.go to know which operations are constant time. It does not fit an application that requires a blanket constant-time guarantee across the whole dependency tree, because the README names eight packages that leak timing information, or one that needs a stability promise, since the disclaimer states the code and API are expected to change. Verify first that `go test./...` passes in your Go version, that Go 1.25.0 or later is available as `go.mod` requires, and that the specific package you intend to import is not on the documented non constant time list.

## FAQ

### How do I install CIRCL?

Run `go get -u github.com/cloudflare/circl`. The README also points to the Cloudflare Go fork, at github.com/cloudflare/go/tree/cf, for integrating CIRCL natively into Go.

### Is CIRCL safe for production use?

The README's security disclaimer says the library is offered as-is without a guarantee, that code and API changes are expected, and that caution is needed before production use because part of the content is experimental.

### Which CIRCL packages are not constant time?

The README names `group/`, `oprf/`, `blindsign/blindrsa/partiallyblindrsa/`, `secretsharing/`, `tss/rsa/`, `zk/dl/`, `zk/dleq/` and `ecc/p384/` as documenting operations that are known to leak timing information.

### Does CIRCL implement SIKE, and should I use it?

The `kem/sike` package exists with primes p434, p503 and p751, but the README marks it insecure and deprecated.

### What post-quantum algorithms does CIRCL support?

ML-KEM in modes 512, 768 and 1024 per FIPS 203, Kyber KEM in the same modes, X-Wing, FrodoKEM, CSIDH, and for signatures Dilithium, ML-DSA in modes 44, 65 and 87 per FIPS 204, and SLH-DSA with twelve parameter sets per FIPS 205.

### How do I run CIRCL's tests and benchmarks?

Use the Makefile: `make test` runs `go vet ./...` and `go test ./...`, and `make bench` runs benchmarks with `-bench=. -run="^_" -benchmem`. Setting `NOASM=1` adds the `purego` build tag.

## Sources

- [cloudflare/circl on GitHub](https://github.com/cloudflare/circl)
- [Issues](https://github.com/cloudflare/circl/issues)
- [Project website](http://blog.cloudflare.com/introducing-circl)
- [README](https://github.com/cloudflare/circl/blob/main/README.md)
- [Releases](https://github.com/cloudflare/circl/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/cloudflare-circl
