Skip to content

pq-verify v2.6.5

Choose a tag to compare

@bigDSanalyst bigDSanalyst released this 14 Aug 04:31
· 143 commits to main since this release
11bf7d0

pq-verify v2.6.5

Now on PyPI, with SARIF output and a GitHub Action — pq-verify can run as a
CI gate rather than something someone remembers to invoke.

pip install "pq-verify[full]"
pq-verify --acvp-all            # 855/855, offline

Installable

pip install pq-verify now works. Previously installation required a git URL,
which is friction for anyone evaluating the tool and a non-starter for most
build systems.

The NIST vectors ship inside the package, so a fresh install verifies
855/855 offline with no configuration — no network, no notebook, no
service. Verified on a bare container with networking blocked.

CI integration

An official GitHub Action. Three lines in any repository that builds an ML-KEM
or ML-DSA implementation:

- uses: bigDSanalyst/pq-verify@v1
  with:
    library: build/libmlkem768.so
    symbol: PQCLEAN_MLKEM768_CLEAN_ntt

Findings surface as annotations on the pull request diff. fail-on-finding
(default true) fails the build when the transform diverges from the FIPS
reference. Outputs verified, findings and sarif-file for downstream steps.

SARIF 2.1.0 output

pq-verify --audit-so lib.so SYMBOL --sarif results.sarif --json results.json \
          --fail-on-finding

SARIF is ingested natively by GitHub Code Scanning, DefectDojo, Snyk and AWS
Security Hub. A verifier that reports only to a terminal cannot become part of
a security workflow; this puts findings where a team already looks.

Five rules are reported, each mapped to a specific failure mode:

Rule Meaning
PQV001 NTT output diverges from the FIPS reference
PQV002 Freivalds probabilistic check failed
PQV003 Root of unity has the wrong multiplicative order
PQV004 Non-circular known-answer test failed
PQV005 Boundary/edge-case vector failed

Output validated against the OASIS SARIF 2.1.0 schema.

Packaging fixes

  • pq_verify.vectors is now a declared package rather than an implicit data
    directory. A future setuptools discovery change could otherwise have shipped
    a wheel with no ACVP vectors — which would install cleanly and then fail
    every offline verification at runtime.
  • License metadata moved to the SPDX form (license = "MIT" plus
    license-files); the table form is deprecated and stops working in
    February 2027.
  • Removed dead *.c / *.cpp globs from MANIFEST.in. The six field-native
    engines are embedded as strings in core.py and compiled at runtime, so
    there are no C source files to package.

Result: the build emits no warnings, and both artifacts pass twine check.

Verification performed

  • Clean venv, pip install "pq-verify[full]" from PyPI → 2.6.5
  • 855/855 offline with networking blocked
  • 975/975 with slhdsa=True (adds FIPS 205 keyGen)
  • 18/18 pytest
  • SARIF written and schema-validated from the published wheel
  • Action definition validated against GitHub's Actions schema; CI gating
    confirmed to exit non-zero on a deliberately corrupted library and zero on a
    correct one

Independent audits

Unchanged from 2.6.4 and documented in AUDITS.md: liboqs
(mlkem-native / mldsa-native), PQClean, the pq-crystals reference, and a
BoringSSL vector cross-check — all verify clean, with negative controls that
correctly fail.

MIT · Nicholas Maino (iamweare) · DOI 10.5281/zenodo.21739511