Skip to content

pqblocks-wire

Length-prefixed container format (PQCWF1) for ML-KEM ciphertexts and ML-DSA / SLH-DSA signatures, with thin wrappers over liboqs-python and pyca/cryptography; it implements no primitive itself.

Install from GitHub Area Status Python Licence Source

At a glance

Area Interoperability
Import import pqblocks_wire
Command line library only
Version 0.1.0 (Alpha)
Python >=3.11
Native dependency liboqs
Repository PQBlocks/pqc-wireformat
Licence Apache-2.0

What is pqblocks-wire?

A small, length-prefixed binary frame (PQCWF1) that carries an ML-KEM ciphertext, an ML-DSA signature, an SLH-DSA signature and a payload, with a strict parser. It also has thin wrappers for ML-KEM / ML-DSA / SLH-DSA key generation, encapsulation and signing, a composite ML-DSA-65 + Ed25519 signature, and an X25519 + ML-KEM-768 hybrid secret.

When to use it: you need to move post-quantum ciphertexts and signatures between Python services in one self-describing blob, and you control both ends.

Standards involved: the primitives are FIPS 203 (ML-KEM), FIPS 204 (ML-DSA) and FIPS 205 (SLH-DSA). This package does not implement them: it calls liboqs through liboqs-python. X25519 and Ed25519 come from pyca/cryptography. The frame format is this package's own and is not an IETF or NIST format.

Install

pip install git+https://github.com/PQBlocks/pqc-wireformat
uv add git+https://github.com/PQBlocks/pqc-wireformat

PyPI release staged

pqblocks-wire 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.

quickstart.py
from pqblocks_wire import (generate_mlkem_keypair, encapsulate_mlkem, decapsulate_mlkem,
                           encode_wire_format, decode_wire_format)

pk, sk = generate_mlkem_keypair("ML-KEM-768")
ct, ss_sender = encapsulate_mlkem(pk, "ML-KEM-768")
frame = encode_wire_format(mlkem_ciphertext=ct, payload=b"hello")      # 1109 bytes
received = decode_wire_format(frame)
ss_receiver = decapsulate_mlkem(sk, received.mlkem_ciphertext, "ML-KEM-768")
print(ss_sender == ss_receiver, received.payload)                    # True b'hello'

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-jwe: Compact five-part wire format, with a serializer and structural parser, for hybrid ML-KEM-768 + X25519 JWE-style…
  • pqblocks-tls-interop: TLS 1.3 hybrid key exchange (X25519MLKEM768 / RFC 10024) endpoint probe, downgrade detector, and key material validator.