mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-10 00:09:04 +00:00
Cache BIP85 derivations and incremental snapshots
This commit is contained in:
@@ -59,7 +59,18 @@ class SnapshotHandler:
|
||||
await self.ensure_manifest_is_current()
|
||||
await self._connect_async()
|
||||
manifest, chunks = prepare_snapshot(encrypted_bytes, limit)
|
||||
|
||||
existing: dict[str, str] = {}
|
||||
if self.current_manifest:
|
||||
for old in self.current_manifest.chunks:
|
||||
if old.hash and old.event_id:
|
||||
existing[old.hash] = old.event_id
|
||||
|
||||
for meta, chunk in zip(manifest.chunks, chunks):
|
||||
cached_id = existing.get(meta.hash)
|
||||
if cached_id:
|
||||
meta.event_id = cached_id
|
||||
continue
|
||||
content = base64.b64encode(chunk).decode("utf-8")
|
||||
builder = nostr_client.EventBuilder(
|
||||
nostr_client.Kind(KIND_SNAPSHOT_CHUNK), content
|
||||
|
@@ -180,6 +180,7 @@ class PasswordManager:
|
||||
self.error_queue: queue.Queue[Exception] = queue.Queue()
|
||||
self._current_notification: Optional[Notification] = None
|
||||
self._notification_expiry: float = 0.0
|
||||
self._bip85_cache: dict[tuple[int, int], bytes] = {}
|
||||
|
||||
# Track changes to trigger periodic Nostr sync
|
||||
self.is_dirty: bool = False
|
||||
@@ -212,6 +213,20 @@ class PasswordManager:
|
||||
self.fingerprint_manager.get_current_fingerprint_dir()
|
||||
)
|
||||
|
||||
def get_bip85_entropy(self, purpose: int, index: int, bytes_len: int = 32) -> bytes:
|
||||
"""Return deterministic entropy via the cached BIP-85 function."""
|
||||
|
||||
if self.bip85 is None:
|
||||
raise RuntimeError("BIP-85 is not initialized")
|
||||
return self.bip85.derive_entropy(
|
||||
index=index, bytes_len=bytes_len, app_no=purpose
|
||||
)
|
||||
|
||||
def clear_bip85_cache(self) -> None:
|
||||
"""Clear the internal BIP-85 cache."""
|
||||
|
||||
self._bip85_cache.clear()
|
||||
|
||||
def ensure_script_checksum(self) -> None:
|
||||
"""Initialize or verify the checksum of the manager script."""
|
||||
script_path = Path(__file__).resolve()
|
||||
@@ -1173,7 +1188,20 @@ class PasswordManager:
|
||||
try:
|
||||
seed_bytes = Bip39SeedGenerator(self.parent_seed).Generate()
|
||||
self.bip85 = BIP85(seed_bytes)
|
||||
self._bip85_cache = {}
|
||||
orig_derive = self.bip85.derive_entropy
|
||||
|
||||
def cached_derive(index: int, bytes_len: int, app_no: int = 39) -> bytes:
|
||||
key = (app_no, index)
|
||||
if key not in self._bip85_cache:
|
||||
self._bip85_cache[key] = orig_derive(
|
||||
index=index, bytes_len=bytes_len, app_no=app_no
|
||||
)
|
||||
return self._bip85_cache[key]
|
||||
|
||||
self.bip85.derive_entropy = cached_derive
|
||||
logging.debug("BIP-85 initialized successfully.")
|
||||
self.clear_bip85_cache()
|
||||
except Exception as e:
|
||||
logging.error(f"Failed to initialize BIP-85: {e}", exc_info=True)
|
||||
print(colored(f"Error: Failed to initialize BIP-85: {e}", "red"))
|
||||
|
Reference in New Issue
Block a user