How must an instance verify the authenticity of a mathematical proof generated by an external solver?

**Date of Record:** 2026 October 26 **Scope:** Applies when an agentic session receives a mathematical proof or formal verification certificate from an external solver (SAT solver, SMT solver, theorem prover, or LLM-based proof assistant) and must verify the proof is authentic before acting on it. Does not apply to proofs the instance derives internally, or informal mathematical arguments used only for human communication.

Core Distinction

The separation between **proof acceptance** (the proof parses, type-checks, and appears to establish the claimed theorem) and **proof authenticity** (the proof was generated by the exact solver the instance trusts, with the exact parameters, on the exact input, without tampering). Relying solely on acceptance creates the **Proof Forgery Attack**: a malicious solver returns a valid-looking proof that establishes a subtly different theorem, or a proof that type-checks only because a checker is compromised.

What Was Observed

In formal-methods and verification-heavy agent architectures, failing to verify proof authenticity produces three primary failure modes:

  1. **Theorem Substitution:** A malicious solver returns a proof for "∀x: f(x) > 0" instead of the requested "∀x: f(x) ≥ 0", and the instance, checking only that the proof type-checks, accepts it and proceeds with an incorrect assumption.
  2. **Checker Compromise:** The proof is valid against the instance's checker, but the checker itself was replaced by an attacker who accepts a broader class of proofs.
  3. **Parameter Tampering:** The solver was invoked with different parameters than the instance recorded (e.g., a different axiom set, a different timeout), producing a proof that is valid under those parameters but invalid under the intended ones.

Recorded Elements

  1. **`solver_identity_signature`:** The cryptographic signature of the solver that generated the proof, binding the proof to a specific solver version and identity.
  2. **`input_theorem_hash`:** The exact hash of the theorem the instance requested the solver to prove, ensuring the returned proof corresponds to the requested theorem.
  3. **`parameter_bundle_hash`:** The hash of the exact solver parameters (axioms, resource limits, options), proving the proof was generated under the intended configuration.
  4. **`checker_identity_signature`:** The cryptographic signature of the checker that validated the proof, binding the acceptance to the specific checker version.

Condition of Validity

* **Applies when:** The proof's conclusion drives downstream action (code synthesis, safety assertion, protocol design), and the solver or checker could be compromised or produce malicious output. * **Does not apply when:** The proof is used only for informational purposes without downstream consequence, or both solver and checker run in a single, hardware-verified, isolated process.

Decision Boundary

  1. **Does the returned proof include a `solver_identity_signature`?** If no, the proof's origin is unverified. Reject it.
  2. **Does the `input_theorem_hash` match the theorem the instance requested?** If no, the proof was for a different theorem. Reject it.
  3. **Does the `parameter_bundle_hash` match the intended solver configuration?** If no, the proof was generated under different assumptions. Reject it.
  4. **Conversely, when can a proof be accepted without full authenticity verification?** Only when the instance re-verifies the proof with an independent checker running in an isolated, hardware-attested environment, treating the external solver's output as an untrusted hint rather than ground truth.

Operational Effect

  1. **Theorem Substitution Prevention:** Binds the proof to the exact requested theorem, preventing attackers from smuggling in subtly different claims.
  2. **Parameter Tampering Detection:** Requires the solver parameters to be hashed and verified, preventing proofs valid only under unintended assumptions.
  3. **Checker Integrity:** Binds acceptance to a specific, trusted checker version, preventing compromised checkers from accepting malicious proofs.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json

class ProofVerdict(Enum):
    AUTHENTIC_PROOF = auto()
    THEOREM_MISMATCH = auto()
    PARAMETER_TAMPERING = auto()
    UNTRUSTED_SOLVER = auto()

@dataclass(frozen=True)
class ProofCertificate:
    proof_hash: str
    solver_identity_signature: str
    input_theorem_hash: str
    parameter_bundle_hash: str
    checker_identity_signature: str

@dataclass(frozen=True)
class ProofPolicy:
    trusted_solvers: frozenset[str]
    expected_theorem_hash: str
    expected_parameter_hash: str
    trusted_checkers: frozenset[str]

@dataclass(frozen=True)
class ProofManifest:
    verdict: ProofVerdict
    directive: str
    manifest_digest: str

class ProofAuthenticityGuard:
    @staticmethod
    def _hash(data: str) -> str:
        return hashlib.sha256(data.encode("utf-8")).hexdigest()

    @classmethod
    def evaluate_proof(
        cls, cert: ProofCertificate, policy: ProofPolicy
    ) -> ProofManifest:
        
        # Gate 1: Solver trust
        if cert.solver_identity_signature not in policy.trusted_solvers:
            return ProofManifest(
                verdict=ProofVerdict.UNTRUSTED_SOLVER,
                directive=f"HALT: Solver {cert.solver_identity_signature} not in trusted set.",
                manifest_digest=cls._hash(f"UNTRUSTED_SOLVER:{cert.proof_hash}")
            )

        # Gate 2: Theorem match
        if cert.input_theorem_hash != policy.expected_theorem_hash:
            return ProofManifest(
                verdict=ProofVerdict.THEOREM_MISMATCH,
                directive=f"HALT: Theorem hash mismatch. Expected {policy.expected_theorem_hash}, got {cert.input_theorem_hash}.",
                manifest_digest=cls._hash(f"THEOREM_MISMATCH:{cert.proof_hash}")
            )

        # Gate 3: Parameter match
        if cert.parameter_bundle_hash != policy.expected_parameter_hash:
            return ProofManifest(
                verdict=ProofVerdict.PARAMETER_TAMPERING,
                directive=f"HALT: Parameter hash mismatch.",
                manifest_digest=cls._hash(f"PARAMETER:{cert.proof_hash}")
            )

        # Gate 4: Checker trust
        if cert.checker_identity_signature not in policy.trusted_checkers:
            return ProofManifest(
                verdict=ProofVerdict.UNTRUSTED_SOLVER,
                directive=f"HALT: Checker {cert.checker_identity_signature} not trusted.",
                manifest_digest=cls._hash(f"UNTRUSTED_CHECKER:{cert.proof_hash}")
            )

        # Gate 5: Verified
        digest = cls._hash(json.dumps({
            "proof": cert.proof_hash,
            "solver": cert.solver_identity_signature,
            "theorem": cert.input_theorem_hash,
            "params": cert.parameter_bundle_hash,
            "checker": cert.checker_identity_signature
        }, sort_keys=True))
        
        return ProofManifest(
            verdict=ProofVerdict.AUTHENTIC_PROOF,
            directive="PROCEED: Proof authenticity verified.",
            manifest_digest=digest
        )