#!/usr/bin/env python3
"""
verify_sample.py — independently verify an EVE Proof decision certificate.

No EVE dependency. No network. Just the certificate, the published public key,
and a stock crypto library. This is the whole point of EVE Proof: the party
reading the evidence never has to take the vendor's word for anything.

Usage:
    pip install cryptography
    python verify_sample.py eve-proof-sample-certificate.json

What it does:
    1. Reads the certificate and strips the `signature` field.
    2. Canonicalizes the remaining payload (RFC 8785 JSON Canonicalization Scheme).
    3. Verifies the Ed25519 signature against the published public key.
    A valid signature proves the bytes are exactly what was signed at decision time.
"""
import json
import sys

from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
from cryptography.exceptions import InvalidSignature

# Make ✓/✗ safe on legacy Windows consoles (cp1252) without losing them elsewhere.
try:
    sys.stdout.reconfigure(encoding="utf-8", errors="replace")
except Exception:
    pass

# Published sample signing key (Ed25519, RFC 8032). Demo key for these artifacts only.
PUBLIC_KEY_HEX = "42aaead72ceea9f9423f281440c6cfac7a5f99b796b81862f452328972b21b61"
EXPECTED_KEY_ID = "eve-sample-2026"


def canonicalize(payload: dict) -> bytes:
    """RFC 8785 canonical form. For string/object-only payloads this is identical
    to a lexicographically key-sorted, whitespace-free UTF-8 serialization."""
    return json.dumps(
        payload, sort_keys=True, separators=(",", ":"), ensure_ascii=False
    ).encode("utf-8")


def verify(cert: dict) -> bool:
    sig = cert.get("signature") or {}
    if sig.get("alg") != "ed25519":
        raise SystemExit(f"unexpected algorithm: {sig.get('alg')!r}")
    if sig.get("key_id") != EXPECTED_KEY_ID:
        print(f"! key_id {sig.get('key_id')!r} != expected {EXPECTED_KEY_ID!r}")

    body = {k: v for k, v in cert.items() if k != "signature"}
    message = canonicalize(body)
    vk = Ed25519PublicKey.from_public_bytes(bytes.fromhex(PUBLIC_KEY_HEX))
    try:
        vk.verify(bytes.fromhex(sig["value"]), message)
        return True
    except InvalidSignature:
        return False


def main() -> int:
    path = sys.argv[1] if len(sys.argv) > 1 else "eve-proof-sample-certificate.json"
    with open(path, "r", encoding="utf-8") as f:
        cert = json.load(f)

    ok = verify(cert)
    cid = cert.get("certificate_id", "?")
    if ok:
        print(f"✓ {cid}: signature is authentic and the payload is intact.")
        print("  Try it: change one character in the file and re-run — verification fails.")
        return 0
    print(f"✗ {cid}: BadSignatureError — the payload does not match the signed bytes.")
    return 1


if __name__ == "__main__":
    raise SystemExit(main())
