PyHPKE - A Python implementation of HPKE
PyHPKE is a HPKE (Hybrid Public Key Encryption) implementation written in Python.
You can install PyHPKE with pip:
$ pip install pyhpke
And then, you can use it as follows:
from pyhpke import AEADId, CipherSuite, KDFId, KEMId, KEMKey
# The sender side:
suite_s = CipherSuite.new(
KEMId.DHKEM_P256_HKDF_SHA256, KDFId.HKDF_SHA256, AEADId.AES128_GCM
)
pkr = KEMKey.from_jwk( # from_pem is also available.
{
"kid": "01",
"kty": "EC",
"crv": "P-256",
"x": "Ze2loSV3wrroKUN_4zhwGhCqo3Xhu1td4QjeQ5wIVR0",
"y": "HlLtdXARY_f55A3fnzQbPcm6hgr34Mp8p-nuzQCE0Zw",
}
)
enc, sender = suite_s.create_sender_context(pkr)
ct = sender.seal(b"Hello world!")
# The recipient side:
suite_r = CipherSuite.new(
KEMId.DHKEM_P256_HKDF_SHA256, KDFId.HKDF_SHA256, AEADId.AES128_GCM
)
skr = KEMKey.from_jwk(
{
"kid": "01",
"kty": "EC",
"crv": "P-256",
"x": "Ze2loSV3wrroKUN_4zhwGhCqo3Xhu1td4QjeQ5wIVR0",
"y": "HlLtdXARY_f55A3fnzQbPcm6hgr34Mp8p-nuzQCE0Zw",
"d": "r_kHyZ-a06rmxM3yESK84r1otSg-aQcVStkRhA-iCM8",
}
)
recipient = suite_r.create_recipient_context(enc, skr)
pt = recipient.open(ct)
assert pt == b"Hello world!"
# deriving a KEMKeyPair
keypair = suite_s.kem.derive_key_pair(b"some_ikm_bytes_used_for_key_derivation")
Index
- Installation
- Supported HPKE Modes and Cipher Suites
- Warnings and Restrictions
- Usage
- API Reference
- Test
- Security
- Contributing
Installation
You can install PyHPKE with pip:
$ pip install pyhpke
Supported HPKE Modes and Cipher Suites
PyHPKE supports all of the HPKE modes and cipher suites defined in RFC9180 below.
- modes
- ✅ Base
- ✅ PSK
- ✅ Auth
- ✅ AuthPSK
- KEMs (Key Encapsulation Machanisms)
- ✅ DHKEM (P-256, HKDF-SHA256)
- ✅ DHKEM (P-384, HKDF-SHA384)
- ✅ DHKEM (P-521, HKDF-SHA512)
- ✅ DHKEM (X25519, HKDF-SHA256)
- ✅ DHKEM (X448, HKDF-SHA512)
- KDFs (Key Derivation Functions)
- ✅ HKDF-SHA256
- ✅ HKDF-SHA384
- ✅ HKDF-SHA512
- AEADs (Authenticated Encryption with Associated Data)
- ✅ AES-128-GCM
- ✅ AES-256-GCM
- ✅ ChaCha20Poly1305
- ✅ Export Only
Warnings and Restrictions
Although this library has been passed all of the following official test vectors, it has not been formally audited.
Usage
from pyhpke import AEADId, CipherSuite, KDFId, KEMId, KEMKey
# The sender side:
suite_s = CipherSuite.new(
KEMId.DHKEM_P256_HKDF_SHA256, KDFId.HKDF_SHA256, AEADId.AES128_GCM
)
pkr = KEMKey.from_jwk(
{
"kid": "01",
"kty": "EC",
"crv": "P-256",
"x": "Ze2loSV3wrroKUN_4zhwGhCqo3Xhu1td4QjeQ5wIVR0",
"y": "HlLtdXARY_f55A3fnzQbPcm6hgr34Mp8p-nuzQCE0Zw",
}
)
enc, sender = suite_s.create_sender_context(pkr)
ct = sender.seal(b"Hello world!")
# The recipient side:
suite_r = CipherSuite.new(
KEMId.DHKEM_P256_HKDF_SHA256, KDFId.HKDF_SHA256, AEADId.AES128_GCM
)
skr = KEMKey.from_jwk(
{
"kid": "01",
"kty": "EC",
"crv": "P-256",
"x": "Ze2loSV3wrroKUN_4zhwGhCqo3Xhu1td4QjeQ5wIVR0",
"y": "HlLtdXARY_f55A3fnzQbPcm6hgr34Mp8p-nuzQCE0Zw",
"d": "r_kHyZ-a06rmxM3yESK84r1otSg-aQcVStkRhA-iCM8",
}
)
recipient = suite_r.create_recipient_context(enc, skr)
pt = recipient.open(ct)
assert pt == b"Hello world!"
API Reference
See Documentation.
Test
You can run tests from the project root after cloning with:
$ tox
Security
If you discover a security issue, please report it via a GitHub issue and avoid disclosing exploit details publicly until we respond.
This project has not been formally audited; use it according to your risk assessment.
The Snyk badge reports results based on requirements.txt exported from uv.lock and reflects dependency scanning only.
See SECURITY.md for our security policy and reporting guidance.
Contributing
We welcome all kind of contributions, filing issues, suggesting new features or sending PRs.
Development environment
$ uv sync --frozen
$ uv run pre-commit install
Dependency updates
[tool.uv] in pyproject.toml pins exclude-newer = "2 days", so resolution only
considers packages uploaded more than two days ago. This gives newly published
releases a verification window before we depend on them, and it applies to every
uv command automatically — no extra flags needed.
After changing dependencies, re-export requirements.txt, which is what the
dependency scanners read:
$ uv add <package> # or: uv lock --upgrade
$ uv export --format requirements-txt --locked -o requirements.txt
Scanning
$ uv run pip-audit
$ uv run pip-licenses
$ trivy fs --severity HIGH,CRITICAL .
Metadata
Release files for pyhpke 0.6.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pyhpke-0.6.5.tar.gz | 1.6 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pyhpke-0.6.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.7 MB
Release files / pyhpke-0.6.5.tar.gz
| Download URL | pyhpke-0.6.5.tar.gz |
|---|---|
| Size | 1.6 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8dac22eb143cd83b8066213b8ad0ecc9d5326ef41f930197197f3bbb5c99cb93
|
|
BLAKE2b-256 checksum How to use checksums |
bd81692a67c409e0a81423941791f875313e7ebcf1493180363eec8051acc767
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 16, 2026.
Transparency logRelease files / pyhpke-0.6.5-py3-none-any.whl
| Download URL | pyhpke-0.6.5-py3-none-any.whl |
|---|---|
| Size | 24.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e8d794724e43053fe04e8971be55033225d6da904effc748b303cece763a3f3c
|
|
BLAKE2b-256 checksum How to use checksums |
04312a0edff785b15d700199fed77186b3d070724cafd02fccfffb187e450d83
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 16, 2026.
Transparency log