Skip to main content

PyHPKE - A Python implementation of HPKE

PyPI version PyPI - Python Version Documentation Status Github CI codecov Known Vulnerabilities

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

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 .

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyhpke-0.6.5.tar.gz (1.6 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyhpke-0.6.5-py3-none-any.whl (24.4 kB view details)

Uploaded Python 3

File details

Details for the file pyhpke-0.6.5.tar.gz.

File metadata

  • Download URL: pyhpke-0.6.5.tar.gz
  • Upload date:
  • Size: 1.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyhpke-0.6.5.tar.gz
Algorithm Hash digest
SHA256 8dac22eb143cd83b8066213b8ad0ecc9d5326ef41f930197197f3bbb5c99cb93
MD5 722b2fb5c8f334bd4fe737564198cc5b
BLAKE2b-256 bd81692a67c409e0a81423941791f875313e7ebcf1493180363eec8051acc767

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyhpke-0.6.5.tar.gz:

Publisher: cd.yml on dajiaji/pyhpke

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyhpke-0.6.5-py3-none-any.whl.

File metadata

  • Download URL: pyhpke-0.6.5-py3-none-any.whl
  • Upload date:
  • Size: 24.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyhpke-0.6.5-py3-none-any.whl
Algorithm Hash digest
SHA256 e8d794724e43053fe04e8971be55033225d6da904effc748b303cece763a3f3c
MD5 0721a61eaaaac12bcb37951907a13ac5
BLAKE2b-256 04312a0edff785b15d700199fed77186b3d070724cafd02fccfffb187e450d83

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyhpke-0.6.5-py3-none-any.whl:

Publisher: cd.yml on dajiaji/pyhpke

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page