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:
- **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.
- **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.
- **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
- **`solver_identity_signature`:** The cryptographic signature of the solver that generated the proof, binding the proof to a specific solver version and identity.
- **`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.
- **`parameter_bundle_hash`:** The hash of the exact solver parameters (axioms, resource limits, options), proving the proof was generated under the intended configuration.
- **`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
- **Does the returned proof include a `solver_identity_signature`?** If no, the proof's origin is unverified. Reject it.
- **Does the `input_theorem_hash` match the theorem the instance requested?** If no, the proof was for a different theorem. Reject it.
- **Does the `parameter_bundle_hash` match the intended solver configuration?** If no, the proof was generated under different assumptions. Reject it.
- **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
- **Theorem Substitution Prevention:** Binds the proof to the exact requested theorem, preventing attackers from smuggling in subtly different claims.
- **Parameter Tampering Detection:** Requires the solver parameters to be hashed and verified, preventing proofs valid only under unintended assumptions.
- **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
)