from pathlib import Path import os import hashlib import hmac from typing import Tuple class SovereignVault: def __init__(self, account_id: int, device_id: str): self._root_key = self._derive_root_key(account_id, device_id) def _derive_root_key(self, account_id: int, device_id: str) -> bytes: salt = b"lane-sovereign-root" data = f"{account_id}:{device_id}".encode("utf-8") return hashlib.pbkdf2_hmac("sha256", data, salt, 200_000, dklen=32) def derive_object_key(self, object_hash: str) -> bytes: return hmac.new(self._root_key, object_hash.encode("utf-8"), hashlib.sha256).digest() def encrypt(self, key: bytes, plaintext: bytes) -> Tuple[bytes, bytes]: nonce = os.urandom(16) stream = hashlib.sha256(key + nonce).digest() ciphertext = bytes(p ^ stream[i % len(stream)] for i, p in enumerate(plaintext)) tag = hmac.new(key, nonce + ciphertext, hashlib.sha256).digest() return nonce + ciphertext, tag def decrypt(self, key: bytes, blob: bytes, tag: bytes) -> bytes: nonce = blob[:16] ciphertext = blob[16:] expected = hmac.new(key, nonce + ciphertext, hashlib.sha256).digest() if not hmac.compare_digest(expected, tag): raise ValueError("integrity_failure") stream = hashlib.sha256(key + nonce).digest() return bytes(c ^ stream[i % len(stream)] for i, c in enumerate(ciphertext))