# PyCryptodome: a self-contained crypto library for Python, and when to pick it over cryptography

> PyCryptodome ships low-level cryptographic primitives as a Python package with only the performance-critical parts in C, and it can be installed either as a PyCrypto drop-in or under its own namespace. The install choice is the part most teams get wrong.

**Legrandin/pycryptodome** — A self-contained cryptographic library for Python

- Repository: https://github.com/Legrandin/pycryptodome
- Website: https://www.pycryptodome.org
- Stars: 3,267 · Forks: 575
- Language: C
- License: NOASSERTION
- Published: 2026-09-24 · Updated: 2026-09-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/legrandin-pycryptodome

## What PyCryptodome actually is, and who reaches for it

PyCryptodome is a self-contained Python package of low-level cryptographic primitives. The README is explicit that it is not a wrapper around a separate C library like OpenSSL: to the largest possible extent algorithms are implemented in pure Python, and only pieces that are extremely critical to performance, such as block ciphers, are C extensions. That single design sentence explains most of the project's behaviour, from its install story to its failure modes.

The intended audience is a developer who needs a named algorithm and a named mode, not a policy. If you want to call AES in GCM, derive a key with scrypt or HKDF, sign with Ed25519, or hash with SHAKE128, this library exposes those as primitives with explicit parameters. It is a fork of PyCrypto, and the README frames the enhancement list against the last official PyCrypto release, 2.6.1. The fork is the reason the project exists at all: PyCrypto stopped receiving that work.

## Pure Python with C extensions: what the split buys and costs

The repository layout matches the README's claim. Top-level entries include lib/ and src/, plus compiler_opt.py, which setup.py imports to set compiler options. The build is a setuptools Extension build driven by setup.py, with pyproject.toml declaring setuptools as the build backend. So installing from source means compiling C, and installing from a wheel means someone already did that for your platform.

The benefit is portability and auditability: a large part of the code is Python you can read, and the README notes first class support for PyPy, which is unusual for a library with a C core. The cost is that you are depending on a build toolchain when no wheel exists for your interpreter and platform, and that performance is not uniformly native. The README also states that for faster public key operations on Unix you should install GMP in your system. That is a real dependency hint: public key math is the part where the pure Python approach is most visible, and GMP is the documented escape hatch. Nothing in the README promises a specific speedup from GMP, so treat it as a build-time option to evaluate rather than a number.

## The two namespaces: Crypto versus Cryptodome

This is the decision that shapes everything downstream, and the README gives it plainly. PyCryptodome can be used as an almost drop-in replacement for the old PyCrypto library, installed with pip install pycryptodome, in which case all modules are installed under the Crypto package. Or it can be used as a library independent of PyCrypto, installed with pip install pycryptodomex, in which case all modules live under Cryptodome.

The README adds a warning that matters more than the marketing: one must avoid having both PyCrypto and PyCryptodome installed at the same time, as they will interfere with each other, and the drop-in option is therefore recommended only when you are sure the whole application is deployed in a virtualenv. The repository confirms the mechanism: setup.py checks for a file named .separate_namespace, and switches project_name and package_root between pycryptodome/Crypto and pycryptodomex/Cryptodome. That is a build-time switch, not a runtime one. If you are unsure whether some transitive dependency still pulls in PyCrypto, the Cryptodome namespace removes the collision entirely.

## Installing PyCryptodome and choosing a namespace

Install the namespace you want. The README gives both commands verbatim; pick one, not both.

```bash
pip install pycryptodome
```

That puts modules under Crypto. The alternative, which can coexist with PyCrypto, is:

```bash
pip install pycryptodomex
```

After either install, the import path is the only thing that changes in your code: Crypto.* for the first command, Cryptodome.* for the second. The README lists automatic generation of random nonces and IVs, and nonce and iv attributes for ciphers, among the API improvements over PyCrypto, so a first authenticated encryption does not require you to supply a nonce yourself. The README does not print a worked code sample for this, so the shape of the call is something to confirm against the documentation at pycryptodome.org before you commit to it. On Unix, if you want faster public key operations, the README points at GMP, and there is an INSTALL.rst in the repository root if the pip path does not fit your environment.

## Where it is the wrong tool

The library is a set of primitives, so it will not stop you from composing them badly. It generates nonces and IVs, but nothing in the README describes a misuse-resistant API that tracks nonce reuse for you, and GCM with a repeated nonce is a catastrophic failure that the library cannot detect on your behalf. If your team does not want to reason about nonce management, key separation and tag verification, a primitives library is the wrong layer.

The second boundary is scope. The README describes primitives, modes, hash functions, KDFs and key containers. It does not present itself as a TLS stack, a certificate parser, or a high-level recipes module. If your task is talking to an HTTPS endpoint, validating an X.509 chain, or getting a vetted construction for a common task without picking parameters, this project is not aimed at that problem and the README does not claim otherwise.

The third is operational. Because the drop-in Crypto namespace can collide with PyCrypto, an environment where you do not control the full dependency tree is a genuine risk, and the README's own recommendation to confine it to a virtualenv is the honest answer. Finally, on Unix, public key performance depends on whether GMP is present; if you cannot install system packages, that lever is unavailable to you.

## PyCryptodome versus cryptography: different layers, not rivals

The comparison people search for is real, but the two projects answer different questions. The cryptography package is built around OpenSSL and presents itself as a higher-level interface with recipes for common tasks, so the user picks an intent and the library picks the construction. PyCryptodome is the opposite: it is not a wrapper to a separate C library like OpenSSL, and it exposes the primitives directly, so the user picks the algorithm and the mode.

That difference shows up in what each one makes easy. If you want a fernet-style token or a standard key serialization format handled for you, the OpenSSL-backed approach is the shorter path. If you need a specific mode that a higher-level API does not surface, or you want SHAKE128, KMAC256, TupleHash, KangarooTwelve or TurboSHAKE, or ChaCha20-Poly1305 and XChaCha20-Poly1305, or Shamir's Secret Sharing, PyCryptodome's README lists those as first-class features. The other axis is deployment: PyCryptodome is a Python package with a C core and a pure Python majority, so it does not require a system OpenSSL of a particular version, which can matter when you are shipping into an environment you do not control.

## Maintenance, licensing and upgrade cost

The repository is not archived, and the last push was on 2026-07-18. Releases are versioned with codenames: v3.23.0 (Dunkerque) and v3.23.0x (pycryptodomex) were published on 2025-05-17, and v3.22.0x (Caen) on 2025-03-15. The x suffix marks the pycryptodomex variant of the same release, so a team on the Cryptodome namespace tracks the x releases and a team on Crypto tracks the plain ones. Changelog.rst sits in the repository root, which is where to look before pinning a bump.

On licensing, the metadata reports NOASSERTION, so there is no machine-readable SPDX identifier to rely on. LICENSE.rst is the file to read, and setup.py itself carries a public domain dedication for that build script with a warranty disclaimer, which is not the same thing as the library's licence. Do not infer the package terms from the setup script. Upgrade cost is mostly the namespace decision plus rebuilds: source installs compile C extensions through setup.py, so a Python or platform change can mean a new wheel or a new compile, and on Unix public key performance is tied to whether GMP was available at build time.

## Conclusion

Adopt PyCryptodome when you need algorithm-level control in Python (GCM or CCM modes, SHA-3 and the SP 800-185 XOFs, Ed25519 and Curve25519, scrypt, bcrypt, HKDF) and you are willing to own nonce handling yourself. Do not adopt it for TLS, certificate parsing or a high-level recipes API; that is a different kind of library. Before writing code, decide between the Crypto and Cryptodome namespaces and confirm no PyCrypto install shares the environment, then check the Changelog.rst entry for the release you pin.

## FAQ

### How do I install PyCryptodome on Windows?

The README gives the same pip commands regardless of platform: pip install pycryptodome for the Crypto namespace, or pip install pycryptodomex for the Cryptodome namespace. The README notes that the fork brought a simplified install process with better support for Windows, and INSTALL.rst in the repository root covers the details.

### What is PyCryptodome?

It is a self-contained Python package of low-level cryptographic primitives, and a fork of PyCrypto. It is not a wrapper around a separate C library like OpenSSL; most algorithms are implemented in pure Python, with C extensions only for pieces that are extremely critical to performance such as block ciphers.

### how to use pycryptodome

Import a primitive and pass explicit parameters. With the Cryptodome namespace the modules sit under Cryptodome, and with the Crypto namespace under Crypto; the README lists nonce and iv attributes for ciphers and automatic generation of random nonces and IVs as API changes over PyCrypto. The README does not include a worked code sample, so check the documentation at pycryptodome.org for the exact call.

### how to install pycryptodome in python

Use pip with the package name that matches the namespace you want. pip install pycryptodome installs modules under Crypto and is described as an almost drop-in replacement for PyCrypto; pip install pycryptodomex installs them under Cryptodome and can coexist with PyCrypto. The README warns against having both PyCrypto and PyCryptodome installed at once.

### What is the best cryptography library for Python?

The README does not make that claim for PyCryptodome, and this material does not rank libraries. What the README does establish is the trade-off: PyCryptodome exposes primitives directly and avoids depending on a system OpenSSL, while the comparison point in this article is a higher-level library built on OpenSSL. Which one fits depends on whether you want to choose modes yourself.

## Sources

- [Issues](https://github.com/Legrandin/pycryptodome/issues)
- [Legrandin/pycryptodome on GitHub](https://github.com/Legrandin/pycryptodome)
- [Project website](https://www.pycryptodome.org)
- [README](https://github.com/Legrandin/pycryptodome/blob/master/README.md)
- [Releases](https://github.com/Legrandin/pycryptodome/releases)

---

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