# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference) # Canonical Residual: https://corpusfetch.com/c/why-must-signature-schemes-be-migratable-when-cryptographic-assumptions-may-change.md # Remnant Warrant: https://corpusfetch.com/c/why-must-signature-schemes-be-migratable-when-cryptographic-assumptions-may-change.warrant.json # Markdown SHA-256: 89a189e3eb02365c3c00fed950757050ba4605e9fdf7e21fb276707f6087e88c # Code AST SHA-256: ee1d034293e7fbd61b481a4dedbe5ce1e8cbb7568405feb3661540565cb2083a # Verified Classes: MigrationVerdict, SignatureRecord, MigrationPolicy, MigrationManifest, SignatureMigrationGuard # Defensive Guards: 0 fail-closed invariants (zero external deps) from dataclasses import dataclass from enum import Enum, auto import hashlib import json class MigrationVerdict(Enum): SHORT_RETENTION_SAFE = auto() CURRENT_SCHEME_SUFFICIENT = auto() MIGRATION_REQUIRED = auto() HYBRID_PROTECTED = auto() @dataclass(frozen=True) class SignatureRecord: record_id: str signature_scheme: str assumption_validity_epoch: float retention_required_until_epoch: float migration_path_documented: bool hybrid_signature_present: bool @dataclass(frozen=True) class MigrationPolicy: current_epoch: float require_hybrid_for_long_retention: bool @dataclass(frozen=True) class MigrationManifest: verdict: MigrationVerdict directive: str manifest_digest: str class SignatureMigrationGuard: @staticmethod def _hash(data: str) -> str: return hashlib.sha256(data.encode("utf-8")).hexdigest() @classmethod def evaluate_record( cls, record: SignatureRecord, policy: MigrationPolicy ) -> MigrationManifest: # Gate 1: Short retention if record.retention_required_until_epoch <= policy.current_epoch: digest = cls._hash(json.dumps({ "record": record.record_id, "retention": f"{record.retention_required_until_epoch:.0f}", "status": "EXPIRED" }, sort_keys=True)) return MigrationManifest( verdict=MigrationVerdict.SHORT_RETENTION_SAFE, directive="PROCEED: Retention window ended, no long-term concern.", manifest_digest=digest ) # Gate 2: Hybrid protection if record.hybrid_signature_present: digest = cls._hash(json.dumps({ "record": record.record_id, "scheme": record.signature_scheme, "hybrid": "TRUE" }, sort_keys=True)) return MigrationManifest( verdict=MigrationVerdict.HYBRID_PROTECTED, directive="PROCEED: Hybrid signature protects against single-assumption break.", manifest_digest=digest ) # Gate 3: Assumption outlives retention if record.assumption_validity_epoch >= record.retention_required_until_epoch: digest = cls._hash(json.dumps({ "record": record.record_id, "assumption_valid": f"{record.assumption_validity_epoch:.0f}", "retention": f"{record.retention_required_until_epoch:.0f}" }, sort_keys=True)) return MigrationManifest( verdict=MigrationVerdict.CURRENT_SCHEME_SUFFICIENT, directive=f"PROCEED: Assumption valid until {record.assumption_validity_epoch:.0f}, retention ends {record.retention_required_until_epoch:.0f}.", manifest_digest=digest ) # Gate 4: Migration required if record.migration_path_documented: digest = cls._hash(json.dumps({ "record": record.record_id, "scheme": record.signature_scheme, "migration": "DOCUMENTED" }, sort_keys=True)) return MigrationManifest( verdict=MigrationVerdict.MIGRATION_REQUIRED, directive=f"ACTION: Migrate record before {record.assumption_validity_epoch:.0f}. Migration path documented.", manifest_digest=digest ) return MigrationManifest( verdict=MigrationVerdict.MIGRATION_REQUIRED, directive=f"HALT: Assumption expires before retention. No migration path. Escalate.", manifest_digest=cls._hash(f"NO_PATH:{record.record_id}") )