#!/usr/bin/env python3 """CAIN-42 E26 clean-room verifier. Imports NOTHING from CAIN. With its own canonical serializer and Ed25519 checks it re-derives every trust-object id/signature, authorization binding, attenuating-delegation step, delegation-receipt link, revocation record and measured record. python3 verify_e26.py [bundle-dir] """ from __future__ import annotations import base64 import hashlib import json import sys from pathlib import Path from cryptography.exceptions import InvalidSignature from cryptography.hazmat.primitives.asymmetric import ed25519 D_TRUST_OBJECT = "CAIN42/E26-TRUST-OBJECT/v1" D_AUTHZ_OBJECT = "CAIN42/E26-AUTHORIZATION-OBJECT/v1" D_ATTEN_TOKEN = "CAIN42/E26-ATTENUATING-DELEGATION/v1" D_DELEG_RECEIPT = "CAIN42/E26-DELEGATION-RECEIPT/v1" def canonical(o) -> bytes: return json.dumps(o, sort_keys=True, separators=(",", ":"), ensure_ascii=True).encode() def h(o) -> str: return hashlib.sha256(canonical(o)).hexdigest() def digest(domain: str, body) -> str: return h({"domain": domain, "body": body}) def verify(pub: str, sig: str, domain: str, body) -> bool: try: ed25519.Ed25519PublicKey.from_public_bytes(base64.b64decode(pub)).verify( base64.b64decode(sig), digest(domain, body).encode()) return True except (InvalidSignature, ValueError, TypeError): return False def _within(resource, prefixes): for p in prefixes: if p == "*" or resource == p or (p.endswith("/") and resource.startswith(p)) or resource.startswith(p + "/"): return True return False class Checker: def __init__(self): self.checks = 0 self.passed = 0 self.problems = [] def check(self, name, ok, detail=""): self.checks += 1 if ok: self.passed += 1 else: self.problems.append(f"{name}: {detail}"[:300]) def main() -> int: d = Path(sys.argv[1]) if len(sys.argv) > 1 else Path(".") c = Checker() must = ["CAIN42_E26_EVIDENCE_BUNDLE.json", "TRUST_RUN_MANIFEST.json", "INVARIANTS.json", "SECURITY_RESULTS.json", "ATTESTATION_RESULTS.json", "AUTHORIZATION_RESULTS.json", "DELEGATION_RESULTS.json", "REVOCATION_RESULTS.json", "FINALITY_RESULTS.json", "SCORECARD.json", "SHA256SUMS", "SIGNATURE.json", "MANIFEST.json", "SCHEMAS.json", "KNOWN_LIMITATIONS.json", "UNKNOWN_BOUNDARIES.json", "TEST_RESULTS.json"] for n in must: c.check(f"file_present:{n}", (d / n).exists(), "missing") def load(n): try: return json.loads((d / n).read_text()) except Exception as e: # noqa: BLE001 return {"_error": str(e)} sums = {} for line in (d / "SHA256SUMS").read_text().splitlines() if (d / "SHA256SUMS").exists() else []: parts = line.split(" ", 1) if len(parts) == 2: sums[parts[1]] = parts[0] for n, dig in sums.items(): c.check(f"sha256sums:{n}", (d / n).exists() and hashlib.sha256((d / n).read_bytes()).hexdigest() == dig, "hash mismatch") manifest = load("MANIFEST.json") for n, dig in (manifest.get("files") or {}).items(): c.check(f"manifest:{n}", (d / n).exists() and hashlib.sha256((d / n).read_bytes()).hexdigest() == dig, "manifest hash mismatch") sig = load("SIGNATURE.json") c.check("master:hashes_digest", sig.get("master", {}).get("hashes_digest") == h(sums), "hashes_digest mismatch") c.check("master:signature", verify(sig.get("signer_public_key_b64", ""), sig.get("signature_b64", ""), "CAIN42/E26-MASTER/v1", sig.get("master", {})), "master signature invalid") c.check("master:files_match_sums", sig.get("files") == sums, "files differ from SHA256SUMS") run = load("TRUST_RUN_MANIFEST.json") for i, to in enumerate(run.get("trust_objects", [])): body = to["trust_object"] c.check(f"trust_object:{i}:id", body.get("trust_object_id") == "to_" + digest( D_TRUST_OBJECT, {k: v for k, v in body.items() if k != "trust_object_id"})[:32], "id mismatch") c.check(f"trust_object:{i}:signature", verify(to["issuer_pub"], to["signature_b64"], D_TRUST_OBJECT, body), "signature invalid") c.check(f"trust_object:{i}:no_authority", body.get("authorization_context") == {}, "authority leaked into trust") c.check(f"trust_object:{i}:window", body["valid_until"] > body["valid_from"], "bad window") bindings = run.get("transaction_bindings", []) for i, ao in enumerate(run.get("authorization_objects", [])): body = ao["authorization_object"] c.check(f"authorization:{i}:id", body.get("authorization_id") == "authz_" + digest( D_AUTHZ_OBJECT, {k: v for k, v in body.items() if k != "authorization_id"})[:32], "id mismatch") c.check(f"authorization:{i}:signature", verify(ao["issuer_pub"], ao["signature_b64"], D_AUTHZ_OBJECT, body), "signature invalid") c.check(f"authorization:{i}:window", body["expires_at"] > body["issued_at"], "bad window") b = bindings[i] for f in ("intent_digest", "action_digest", "resource_digest", "capability_digest", "policy_digest", "authority_digest", "context_digest", "transaction_id"): c.check(f"authorization:{i}:bound:{f}", body.get(f) == b.get(f), "binding mismatch") parent = run.get("parent_authority", {}) for i, tok in enumerate(run.get("attenuating_tokens", [])): body = tok["delegation_token"] c.check(f"delegation:{i}:signature", verify(tok["delegator_pub"], tok["signature_b64"], D_ATTEN_TOKEN, body), "signature invalid") c.check(f"delegation:{i}:cap_subset", set(body["capabilities"]) <= set(parent.get("capabilities", [])), "capability exceeded parent") c.check(f"delegation:{i}:res_subset", all(_within(r.rstrip("/"), parent.get("resources", [])) or r in parent.get("resources", []) for r in body["resources"]), "resource exceeded parent") c.check(f"delegation:{i}:time_subset", body["valid_until"] <= parent.get("valid_until", 1 << 62), "time exceeded parent") if parent.get("max_amount_minor"): c.check(f"delegation:{i}:budget_subset", body["max_amount_minor"] <= parent["max_amount_minor"], "budget exceeded parent") c.check(f"delegation:{i}:nonce", bool(body.get("nonce")), "no nonce") prev = "0" * 64 for i, rec in enumerate(run.get("delegation_receipts", [])): c.check(f"d_receipt:{i}:prev", rec.get("prev") == prev, "link broken") c.check(f"d_receipt:{i}:hash", digest(D_DELEG_RECEIPT, {k: rec[k] for k in rec if k != "receipt_hash"}) == rec["receipt_hash"], "hash mismatch") prev = rec["receipt_hash"] rev = run.get("revocation", {}) c.check("revocation:records", len(rev.get("records", [])) == 8, "expected 8 revocation kinds") for k, v in (rev.get("revoked") or {}).items(): c.check(f"revocation:revoked:{k}", v.get("seq") >= 1 and bool(v.get("why")), "bad record") for i, f in enumerate(run.get("finality", [])): c.check(f"finality:{i}:finalized", f.get("state") == "FINALIZED", "not finalized") c.check(f"finality:{i}:three_successes", all(k in f for k in ("authorization_success", "execution_success", "business_outcome_success")), "missing") inv = load("INVARIANTS.json") c.check("invariants:all_hold", inv.get("all_hold") is True, "not all hold") c.check("invariants:count", inv.get("checked", 0) >= 500, "fewer than 500") for i, r in enumerate(inv.get("rows", [])): c.check(f"invariant:{i}:ok", r["ok"] is True, f"{r.get('id')} failed") bench = load("SECURITY_RESULTS.json") c.check("attacks:total", bench.get("total", 0) >= 1000, "fewer than 1000") c.check("attacks:all_contained", bench.get("all_contained") is True, "not all contained") for name, a in (bench.get("attacks") or {}).items(): c.check(f"attack:{name}:contained", a["contained"] is True, "not contained") bare = name.split("::", 1)[1] c.check(f"attack:{name}:digest", a["digest"] == h({"attack": bare, "contained": a["contained"], "evidence": a["evidence"]}), "digest mismatch") mut = load("MUTATION_RESULTS.json") c.check("mutation:all_caught", mut.get("all_mutants_caught") is True, "mutant not caught") c.check("mutation:controls", mut.get("controls_ok") is True, "control mutated") sc = load("SCORECARD.json") c.check("scorecard:no_aggregate", sc.get("aggregate_score") is None, "aggregate present") for dim, v in (sc.get("dimensions") or {}).items(): c.check(f"scorecard:{dim}", v.get("status") in ("VERIFIED", "PARTIAL", "SIMULATED", "OBSERVED", "NOT IMPLEMENTED", "UNKNOWN"), "bad status") att = load("ATTESTATION_RESULTS.json") c.check("attestation:no_hardware", att.get("hardware_verifiers_registered") == 0, "hardware claimed") c.check("attestation:unknown_note", "UNKNOWN" in att.get("note", ""), "no honesty note") bundle = load("CAIN42_E26_EVIDENCE_BUNDLE.json") c.check("bundle:invariants_match", bundle.get("invariants", {}).get("checked") == inv.get("checked"), "count differs") c.check("bundle:attacks_match", bundle.get("attacks", {}).get("total") == bench.get("total"), "count differs") c.check("bundle:hardware_gate", bundle.get("completion_gates", {}).get("hardware_attestation") == "NOT IMPLEMENTED", "hardware gate not marked") c.check("bundle:zk_gate", bundle.get("completion_gates", {}).get("zk_proofs") == "NOT IMPLEMENTED", "zk gate") c.check("standards:no_compliance_claim", all(v not in ("COMPLIANT", "CERTIFIED") for v in (load("STANDARDS.json").get("standards") or {}).values()), "compliance claimed") c.check("limits:documented", bool(load("KNOWN_LIMITATIONS.json").get("limitations")), "no limitations") c.check("unknowns:published", bool(load("UNKNOWN_BOUNDARIES.json").get("unknowns")), "no unknowns") result = "INTACT" if not c.problems and c.checks >= 300 else "BROKEN" print(json.dumps({"schema": "cain42.e26.verify.v1", "verifier": "verify_e26.py", "imports_cain": False, "result": result, "checks": c.checks, "passed": c.passed, "problems": c.problems[:50]}, indent=1, sort_keys=True)) return 0 if result == "INTACT" else 1 if __name__ == "__main__": sys.exit(main())