custom
code
sovereign-compute
pax-coder / scripts /verify-clone-pq
SNAPKITTYWEST's picture
chore: push pax-coder from SNAPKITTYWEST GitHub
ef6eb55 verified
Raw
History Blame Contribute Delete
8.91 kB
#!/usr/bin/env python3
"""
PAX-Coder Post-Quantum Clone Integrity Verification
Upgrades verify-clone to ML-DSA-44 (CRYSTALS-Dilithium, NIST FIPS 204).
Ed25519 signatures on release manifests are vulnerable to harvest-now-
decrypt-later attacks by quantum adversaries. This script verifies the
release manifest signature using ML-DSA-44 β€” Shor-resistant, 128-bit
post-quantum security.
Exit codes:
0 = Integrity verified (ML-DSA-44 signature valid)
1 = Integrity verification failed
2 = Script error
Requirements:
pip install dilithium-py pydantic
Environment:
PAX_MLDSA_PUBLIC_KEY_HEX β€” authority ML-DSA-44 public key (2624 hex chars)
OR sovereign/mldsa_authority.pub
Authors: Ahmad Ali Parr, Jessica L. Williams (SNAPKITTYWEST)
"""
import hashlib
import json
import os
import subprocess
import sys
from pathlib import Path
from typing import Optional
# ── ML-DSA-44 constants ───────────────────────────────────────────────────────
MLDSA_PK_BYTES = 1312
MLDSA_SIG_BYTES = 2420
MLDSA_PK_HEX = MLDSA_PK_BYTES * 2
MLDSA_SIG_HEX = MLDSA_SIG_BYTES * 2
EXIT_OK = 0
EXIT_FAILED = 1
EXIT_ERROR = 2
# ── ML-DSA-44 verify ──────────────────────────────────────────────────────────
def mldsa_verify(pk: bytes, msg: bytes, sig: bytes) -> bool:
try:
from dilithium_py.dilithium import Dilithium2
return Dilithium2.verify(pk, msg, sig)
except ImportError:
pass
# Fallback: pax_verify_mldsa binary (from worm-engines Rust build)
binary = os.environ.get("PAX_MLDSA_VERIFY_BIN", "pax_verify_mldsa")
try:
import tempfile
with tempfile.TemporaryDirectory() as d:
pk_p = Path(d) / "pk.bin"; pk_p.write_bytes(pk)
msg_p = Path(d) / "msg.bin"; msg_p.write_bytes(msg)
sig_p = Path(d) / "sig.bin"; sig_p.write_bytes(sig)
r = subprocess.run([binary, str(pk_p), str(msg_p), str(sig_p)],
capture_output=True, timeout=10)
return r.returncode == 0
except Exception:
return False
# ── Helpers ───────────────────────────────────────────────────────────────────
def sha256_file(path: Path) -> str:
return hashlib.sha256(path.read_bytes()).hexdigest()
def sha256_dir(repo_root: Path) -> str:
"""Deterministic SHA-256 of all tracked files (git ls-files order)."""
try:
r = subprocess.run(["git", "ls-files", "-z"],
capture_output=True, cwd=repo_root, timeout=30)
files = [f for f in r.stdout.split(b"\x00") if f]
except Exception:
return ""
h = hashlib.sha256()
for f in sorted(files):
path = repo_root / f.decode()
if path.is_file():
h.update(f + b"\x00")
h.update(path.read_bytes())
return h.hexdigest()
def git_head(repo_root: Path) -> Optional[str]:
try:
r = subprocess.run(["git", "rev-parse", "HEAD"],
capture_output=True, text=True, cwd=repo_root, timeout=10)
return r.stdout.strip() if r.returncode == 0 else None
except Exception:
return None
# ── Main verification ─────────────────────────────────────────────────────────
def verify(repo_root: Path) -> int:
sovereign = repo_root / "sovereign"
print("========================================")
print("PAX-CODER PQ CLONE VERIFICATION")
print("ML-DSA-44 / NIST FIPS 204")
print("========================================")
print()
# [1] Release metadata
print("[1] Reading release metadata...")
release_file = sovereign / "release.json"
if not release_file.exists():
print(" ERROR: sovereign/release.json not found")
return EXIT_FAILED
try:
release = json.loads(release_file.read_text())
except json.JSONDecodeError as e:
print(f" ERROR: Cannot parse release.json: {e}")
return EXIT_ERROR
print(f" Repository: {release.get('repository','')}")
print(f" Version: {release.get('release_version','')}")
print(f" Timestamp: {release.get('release_timestamp_utc','')}")
print(" OK")
print()
# [2] Git commit
print("[2] Verifying git commit...")
current = git_head(repo_root)
if current is None:
print(" ERROR: Not a git repository")
return EXIT_ERROR
expected = release.get("git_commit", "")
if current != expected:
print(f" FAILED: Commit mismatch")
print(f" Expected: {expected}")
print(f" Current: {current}")
return EXIT_FAILED
print(f" OK: {current[:12]}")
print()
# [3] Manifest hash
print("[3] Verifying manifest hash...")
manifest_file = sovereign / "manifest.json"
expected_hash = release.get("manifest_sha256", "")
if manifest_file.exists() and expected_hash:
computed = sha256_file(manifest_file)
if computed != expected_hash:
print(f" FAILED: Manifest hash mismatch")
print(f" Expected: {expected_hash}")
print(f" Computed: {computed}")
return EXIT_FAILED
print(f" OK: {computed[:16]}...")
else:
print(" SKIP: No manifest.json or no expected hash")
print()
# [4] File tree hash
print("[4] Verifying tracked file tree...")
expected_tree = release.get("tree_sha256", "")
if expected_tree:
computed_tree = sha256_dir(repo_root)
if computed_tree != expected_tree:
print(" FAILED: File tree hash mismatch β€” files may have been tampered")
return EXIT_FAILED
print(f" OK: {computed_tree[:16]}...")
else:
print(" SKIP: No tree_sha256 in release.json")
print()
# [5] ML-DSA-44 release signature
print("[5] Verifying ML-DSA-44 release signature...")
sig_file = sovereign / "release.sig.hex"
sig_hex = os.environ.get("PAX_RELEASE_SIG_HEX", "")
if not sig_hex and sig_file.exists():
sig_hex = sig_file.read_text().strip()
if not sig_hex:
print(" SKIP: No ML-DSA-44 release signature found")
print(" Set PAX_RELEASE_SIG_HEX or create sovereign/release.sig.hex")
print(" (Clone integrity cannot be fully verified without signature)")
print()
print("========================================")
print("STATUS: PARTIAL β€” commit + hash verified")
print(" ML-DSA-44 signature not present")
print("========================================")
return EXIT_OK
pk_hex = os.environ.get("PAX_MLDSA_PUBLIC_KEY_HEX", "")
if not pk_hex:
pk_file = sovereign / "mldsa_authority.pub"
if pk_file.exists():
pk_hex = pk_file.read_text().strip()
if not pk_hex:
print(" ERROR: No ML-DSA-44 authority public key")
print(" Set PAX_MLDSA_PUBLIC_KEY_HEX or create sovereign/mldsa_authority.pub")
return EXIT_ERROR
if len(sig_hex) != MLDSA_SIG_HEX:
print(f" ERROR: Signature must be {MLDSA_SIG_HEX} hex chars (ML-DSA-44)")
return EXIT_FAILED
# Message signed: canonical JSON of release metadata
message = json.dumps(release, separators=(",",":"), sort_keys=True).encode()
try:
pk = bytes.fromhex(pk_hex)
sig = bytes.fromhex(sig_hex)
except ValueError:
print(" ERROR: Non-hex characters in key or signature")
return EXIT_ERROR
if mldsa_verify(pk, message, sig):
print(" OK: ML-DSA-44 signature VALID")
else:
print(" FAILED: ML-DSA-44 signature INVALID")
print(" This clone may have been tampered with or is unsigned")
return EXIT_FAILED
print()
print("========================================")
print("STATUS: AUTHENTIC PAX-CODER RELEASE")
print(" ML-DSA-44 verified (FIPS 204)")
print("========================================")
return EXIT_OK
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--repo-root", type=Path,
default=Path(__file__).resolve().parent)
args = parser.parse_args()
sys.exit(verify(args.repo_root))