src/pqc_hypervisor_attestation/region.py
1.8 KB · 58 lines · python Raw
1 """Memory region data structures."""
2
3 from __future__ import annotations
4
5 import hashlib
6 from dataclasses import asdict, dataclass
7 from datetime import datetime, timezone
8 from typing import Any
9
10
11 @dataclass(frozen=True)
12 class MemoryRegion:
13 """An addressable region of memory the attester will cover.
14
15 We use abstract addresses (strings or ints). In practice this is:
16 - guest-physical address + size for a VM
17 - process virtual address + size for a confidential container
18 - a model-weights object ID in a model-serving server
19 """
20
21 region_id: str # stable identifier (e.g. "model-weights-0")
22 description: str # human-readable description
23 address: int # base address (in abstract address space)
24 size: int # bytes
25 protection: str = "RO" # "R" | "RW" | "RO" | "RX"
26
27 def to_dict(self) -> dict[str, Any]:
28 return asdict(self)
29
30
31 @dataclass(frozen=True)
32 class RegionSnapshot:
33 """A SHA3-256 fingerprint of a region at a point in time.
34
35 Backends produce snapshots; attesters sign them.
36 """
37
38 region_id: str
39 content_hash: str # SHA3-256 of the exact bytes at `taken_at`
40 size: int
41 taken_at: str # ISO-8601
42
43 @staticmethod
44 def hash_bytes(data: bytes) -> str:
45 return hashlib.sha3_256(data).hexdigest()
46
47 @classmethod
48 def create(cls, region_id: str, content: bytes) -> RegionSnapshot:
49 return cls(
50 region_id=region_id,
51 content_hash=cls.hash_bytes(content),
52 size=len(content),
53 taken_at=datetime.now(timezone.utc).isoformat(),
54 )
55
56 def to_dict(self) -> dict[str, Any]:
57 return asdict(self)
58