pqblocks-jose¶
Post-quantum hybrid JOSE library supporting ML-KEM and ML-DSA JWE and JWS tokens.
At a glance
| Area | PQ cryptography |
| Import | import pqblocks_jose |
| Command line | pqblocks-jose |
| Version | 0.1.0 (Alpha) |
| Python | >=3.11 |
| Native dependency | liboqs |
| Repository | PQBlocks/hybrid-jose |
| Licence | Apache-2.0 |
What is pqblocks-jose?¶
Post-quantum hybrid JOSE (Javascript Object Signing and Encryption) library providing hybrid JWS (JSON Web Signature) and hybrid JWE (JSON Web Encryption) tokens.
pqblocks-jose combines NIST post-quantum primitives (FIPS 203 ML-KEM-768 and FIPS 204 ML-DSA-65) with classical counterparts (X25519, Ed25519) to ensure security against both quantum and classical adversaries without compromising backwards security.
Install¶
PyPI release staged
pqblocks-jose installs from its GitHub repository while the PyPI release is staged. The import name and API are identical either way.
Native dependency: liboqs
The post-quantum primitives come from liboqs (Open Quantum Safe). The package README explains how the library is located: install notes.
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.
from pqblocks_jose import Policy, generate_keypair, encode_jws, decode_jws, encrypt_jwe, decrypt_jwe
# 1. Define an enforceable policy
policy = Policy(
version=1,
kem="X25519+MLKEM768", # Hybrid KEM for JWE
sig="MLDSA65+Ed25519", # Hybrid signature for JWS
kdf="HKDF-SHA256", # Mandatory KDF enforcement
max_token_bytes=8192, # Header-safe limit
kdf_info="JOSE_PostQuantum_Traditional_Hybrid X25519MLKEM768",
sig_alg_std="ML-DSA-65-Ed25519"
)
# 2. Generate hybrid keypairs
sign_keypair = generate_keypair("ML-DSA-65-Ed25519", seed=12345)
enc_keypair = generate_keypair("X25519+MLKEM768", seed=12345)
# 3. Sign & verify a JWS token
payload = {"sub": "alice@example.com", "iat": 1700000000, "aud": "api.internal"}
jws_result = encode_jws(payload, policy, private_key=sign_keypair.private_key)
# Verify with public key
verification = decode_jws(
token=jws_result.compact_serialization,
policy=policy,
public_key=sign_keypair.public_key
)
print(f"JWS verified: {verification.signature_verified}")
print(f"JWS token size: {len(jws_result.compact_serialization)} bytes")
# 4. Encrypt & decrypt a JWE token
plaintext = b"session_key:random123nonce"
jwe_result = encrypt_jwe(plaintext, policy, public_key=enc_keypair.public_key)
# Decrypt with private key
decryption = decrypt_jwe(
token=jwe_result.compact_serialization,
policy=policy,
private_key=enc_keypair.private_key
)
print(f"JWE decrypted matches: {decryption.plaintext == plaintext}")
Remove the seed in production
This quickstart passes seed= so its output is reproducible. Production keys must come from the operating system's random source: call the key generator without seed.
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.
-
What it does, install, usage and API.
-
Correct imports, pitfalls and rules for coding assistants.
-
What it protects, hostile input, constant-time and audit status.
-
Test suites, coverage, vectors and what is not covered.
-
Measured performance, including where it loses.
-
Primary sources and the method-to-code map.
-
Self-verification results, defects found and limits.
-
Worked scenarios and when to pick something else.
-
Every release and what changed.
Related packages in PQ cryptography¶
pqblocks-core: Post-quantum hybrid cryptography core SDK with C shared libraries and policy enforcement.pqblocks-files: Hybrid post-quantum file encryption: ML-KEM-768 plus X25519 key encapsulation with chunked ChaCha20-Poly1305 in the…pqblocks-primitives: Production-ready integrated post-quantum cryptographic primitives (ML-KEM, ML-DSA, SLH-DSA, and hybrid schemes).