kxco-verify (Python)
Receiver-side verifier for the KXCO hybrid HMAC + ML-DSA-65 webhook signature scheme. Wire-format compatible with @kxco/post-quantum (npm), the Go verifier, and the Rust verifier.
Install
pip install kxco-verify # core (HMAC, envelope, fingerprint)
pip install kxco-verify[oqs] # adds liboqs-python for ML-DSA
pip install kxco-verify[pqcrypto] # adds pqcrypto for ML-DSA
The HMAC, envelope, fingerprint, and timestamp paths use only the Python standard library. ML-DSA verification is lazy-loaded: it only requires a PQC backend when verify_pq is actually called. The pinned public key decides the parameter set: 1952 bytes is ML-DSA-65 and 2592 bytes is ML-DSA-87.
Quick start (FastAPI)
from fastapi import FastAPI, Request, HTTPException
import os
import kxco_verify as kx
PINNED_KID = "aa29f37ab7f4b2cf" # current KXCO production kid (refresh from /.well-known if rotated)
PINNED_PUBKEY = bytes.fromhex("...3904 hex chars...")
HMAC_SECRET = os.environ["KXCO_WEBHOOK_SECRET"].encode()
app = FastAPI()
@app.post("/webhooks/kxco")
async def webhook(request: Request):
raw_body = await request.body()
headers = {k.lower(): v for k, v in request.headers.items()}
result = kx.verify_delivery(
headers=headers,
raw_body=raw_body,
hmac_secret=HMAC_SECRET,
pq_public_key=PINNED_PUBKEY,
pinned_kid=PINNED_KID,
)
if not result.ok:
raise HTTPException(401, "invalid signature")
return {"ok": True}
Running tests
cd python
python test_kxco_verify.py
Expected: All 11 vector tests passed. Without an ML-DSA backend installed, the cryptographic ML-DSA cases are reported as SKIP; set KXCO_REQUIRE_PQ_BACKEND=1 to make a missing backend fail instead.
This verifies that the Python implementation produces identical outputs to vectors.json — the same file used by the JavaScript, Go, and Rust verifiers.
License
MIT.
Metadata
Release files for kxco-verify 1.2.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 | |
|---|---|---|---|
| kxco_verify-1.2.0.tar.gz | 6.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| kxco_verify-1.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 11.9 kB
Release files / kxco_verify-1.2.0.tar.gz
| Download URL | kxco_verify-1.2.0.tar.gz |
|---|---|
| Size | 6.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
72a24cd5c8f1e74b6f84e59e963ef0ccc05c41fde2b0ab3598935b5072c5c40d
|
|
BLAKE2b-256 checksum How to use checksums |
c1dc3dac245faf807cced84a1b82843f83187a37d17bd9cee92786212f61d119
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.
Transparency logRelease files / kxco_verify-1.2.0-py3-none-any.whl
| Download URL | kxco_verify-1.2.0-py3-none-any.whl |
|---|---|
| Size | 5.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
30449f493f2bb0d8e4737fcfff7c7c18a18426d6d2b234f91153002494ea9295
|
|
BLAKE2b-256 checksum How to use checksums |
d64af5b390581a9c4d137982d272a8c9a279c3b15c1dbd6d776686d5163fd9ef
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.
Transparency log