Skip to content

pqblocks-jwe

Compact five-part wire format, with a serializer and structural parser, for hybrid ML-KEM-768 + X25519 JWE-style tokens; it performs no encryption itself.

Install from GitHub Area Status Python Licence Source

At a glance

Area Interoperability
Import import pqblocks_jwe
Command line library only
Version 0.1.0 (Alpha)
Python >=3.11
Native dependency none
Repository PQBlocks/hybrid-jwe
Licence Apache-2.0

What is pqblocks-jwe?

A compact five-part wire format for hybrid post-quantum/classical (ML-KEM-768 + X25519) JWE-style tokens, plus a serializer and a structural parser (it does not validate alg or enc values). It does not encrypt anything.

Use it when you already produce the AEAD ciphertext and the hybrid KEM ciphertext yourself and need one deterministic, structurally validated token to carry them. To encrypt, decrypt or sign, you need a separate JOSE implementation. The PQBlocks one, pqblocks-jose, is not yet public.

Standards used: base64url (RFC 4648 §5) and JSON (RFC 8259), with a layout modelled on JWE compact serialization (RFC 7516). The layout is not RFC 7516 compact serialization, and standard JOSE libraries cannot read it.

Install

pip install git+https://github.com/PQBlocks/hybrid-jwe
uv add git+https://github.com/PQBlocks/hybrid-jwe

PyPI release staged

pqblocks-jwe installs from its GitHub repository while the PyPI release is staged. The import name and API are identical either way.

Quickstart

Executed, not just written

This is the quickstart from the package README. It was run against the package source when this page was generated.

quickstart.py
from pqblocks_jwe import ALG_HYBRID, ENC_A256GCM, parse_jwe, serialize_jwe

ciphertext = bytes(48)        # your AEAD output; this package does not encrypt
kem_ct = bytes(1088 + 32)     # your ML-KEM-768 ciphertext || X25519 ephemeral public key
header = {"alg": ALG_HYBRID, "enc": ENC_A256GCM, "kid": "recipient-1"}

token = serialize_jwe(ciphertext, header, {"cty": "application/json"}, b"settlement-v1", kem_ct)
parsed = parse_jwe(token)
assert parsed["header"]["alg"] == ALG_HYBRID   # parse_jwe does not check alg/enc for you
print(len(token), parsed["aad"], len(parsed["kem_ct"]))   # 1697 b'settlement-v1' 1120

Examples

Runnable scripts in the repository:

Documentation and evidence

Every PQBlocks package ships the same evidence set, so each claim can be checked against tests, sources and measurements.

  • Overview


    What it does, install, usage and API.

  • For AI agents


    Correct imports, pitfalls and rules for coding assistants.

  • Security notes


    What it protects, hostile input, constant-time and audit status.

  • Testing


    Test suites, coverage, vectors and what is not covered.

  • Benchmarks


    Measured performance, including where it loses.

  • Evidence


    Primary sources and the method-to-code map.

  • Verification report


    Self-verification results, defects found and limits.

  • Use cases


    Worked scenarios and when to pick something else.

  • Changelog


    Every release and what changed.

  • pqblocks-csr-pop: ML-KEM (FIPS 203) PKCS#10 Certificate Signing Request (CSR) generator with RFC 9883 Proof of Possession (PoP).
  • pqblocks-tls-interop: TLS 1.3 hybrid key exchange (X25519MLKEM768 / RFC 10024) endpoint probe, downgrade detector, and key material validator.
  • pqblocks-wire: Length-prefixed container format (PQCWF1) for ML-KEM ciphertexts and ML-DSA / SLH-DSA signatures, with thin wrappers…