pqblocks-csr-pop
ML-KEM (FIPS 203) PKCS#10 Certificate Signing Request (CSR) generator with RFC 9883 Proof of Possession (PoP).
Overview
pqblocks-csr-pop is a specialized post-quantum PKI library for generating and validating PKCS#10 Certification Requests (CSRs) carrying ML-KEM (Module-Lattice-Based Key-Encapsulation Mechanism, FIPS 203) public keys.
Because KEM keys cannot sign their own CSRs (unlike RSA, ECDSA, or ML-DSA), standards such as RFC 9883 require an explicit Proof of Possession (PoP) structure. pqblocks-csr-pop constructs and verifies DER-encoded PKCS#10 requests carrying the statementOfPossession attribute attested by an Ed25519 or classical key.
Standards Alignment
- NIST FIPS 203: Module-Lattice-Based Key-Encapsulation Mechanism Standard (ML-KEM-768, ML-KEM-1024).
- RFC 9883: Use of the Proof of Possession (PoP) Attribute in PKCS#10 Certification Requests.
- RFC 2986 / PKCS#10: Certification Request Syntax Specification Version 1.7.
- RFC 5280: X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile.
Installation
pip install pqblocks-csr-pop
Dependencies
Requires Python 3.11+ and cryptography>=50.0.0 (with built-in ML-KEM support). No C compilation or external system libraries required.
Quickstart
import datetime
from cryptography import x509
from cryptography.hazmat.primitives.asymmetric import ed25519
from cryptography.x509.oid import NameOID
from pqblocks_csr_pop.csr_builder import build_csr_with_pop, parse_csr, verify_csr_signature
from pqblocks_csr_pop.mlkem import mlkem_keygen
# 1. Attestor Identity (e.g. Host/Device Ed25519 key)
attestor_key = ed25519.Ed25519PrivateKey.generate()
ca_name = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "Device Attestor")])
now = datetime.datetime.now(datetime.timezone.utc)
attestor_cert = (
x509.CertificateBuilder()
.subject_name(ca_name).issuer_name(ca_name)
.public_key(attestor_key.public_key())
.serial_number(x509.random_serial_number())
.not_valid_before(now - datetime.timedelta(days=1))
.not_valid_after(now + datetime.timedelta(days=365))
.sign(attestor_key, None)
)
# 2. Generate ML-KEM Keypair (FIPS 203 ML-KEM-768)
ek, dk = mlkem_keygen("ML-KEM-768")
# 3. Construct PKCS#10 CSR with RFC 9883 PoP Extension
subject = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "pqc-server.internal.net")])
csr_der = build_csr_with_pop(ek, "ML-KEM-768", subject, attestor_key, attestor_cert)
# 4. CA parses CSR and verifies PoP signature
parsed = parse_csr(csr_der)
valid = verify_csr_signature(csr_der, attestor_cert)
assert valid
print(f"CSR verified successfully: {len(csr_der)} bytes DER")
Performance Summary
Measured on Linux x86_64 across 500 timed runs per operation:
| Operation | Parameter Set | Mean Latency | Median Latency | Throughput |
|---|---|---|---|---|
| Key Generation | ML-KEM-768 | 0.306 ms | 0.298 ms | ~3,260 ops/sec |
| Key Generation | ML-KEM-1024 | 0.370 ms | 0.386 ms | ~2,700 ops/sec |
| Build CSR with PoP | ML-KEM-768 | 0.083 ms | 0.071 ms | ~12,120 ops/sec |
| Build CSR with PoP | ML-KEM-1024 | 0.089 ms | 0.075 ms | ~11,300 ops/sec |
| Parse CSR | RFC 9883 Structure | 0.024 ms | 0.027 ms | ~41,130 ops/sec |
| Verify Signature | Ed25519 Attestor | 0.174 ms | 0.147 ms | ~5,730 ops/sec |
For complete benchmark methodology, see BENCHMARKS.md.
Security & Verification
- KAT Corpora: Tested against official NIST ACVP ML-KEM vectors and Google Wycheproof test vectors (
mlkem_768_test,mlkem_768_keygen_seed_test,mlkem_768_encaps_test). - Comprehensive Test Suite: 438 automated unit, property, and golden verification tests passing across Python 3.11–3.14.
- Cryptographic Backend: Relies on OpenSSL 3.0+ backend via
cryptography.
For details, see SECURITY_NOTES.md and TESTING.md.
License
Metadata
Release files for pqblocks-csr-pop 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pqblocks_csr_pop-0.1.0.tar.gz | 65.7 kB | Without provenance | Details for pqblocks_csr_pop-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pqblocks_csr_pop-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for pqblocks_csr_pop-0.1.0-py3-none-any.whl |
Total release size: 97.6 kB
Release files / pqblocks_csr_pop-0.1.0.tar.gz
| Download URL | pqblocks_csr_pop-0.1.0.tar.gz |
|---|---|
| Size | 65.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0246d6fe1883f8b320beb21ed57f35506b7cc8ad9032e98d3d87e74243c27512
|
|
BLAKE2b-256 checksum How to use checksums |
2c9931b4ad3569167ffb9348782e11187f5ced0f3e9ca85b2bf0b921e806589e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / pqblocks_csr_pop-0.1.0-py3-none-any.whl
| Download URL | pqblocks_csr_pop-0.1.0-py3-none-any.whl |
|---|---|
| Size | 31.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
dad6dd3696211ba09e527ae8cae7d0384a569ebe136034623bb9181c51f1553f
|
|
BLAKE2b-256 checksum How to use checksums |
431bba7267d9875d4da3d5be26520b23f5aa16d539cbcc3bfb15355b46844744
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Security for pqblocks-csr-pop 0.1.0
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.