Merge pull request #83 from PR0M3TH3AN/codex/refactor-nostr-index-encryption-flow

Implement seed-based index key derivation
This commit is contained in:
thePR0M3TH3AN
2025-07-01 10:33:39 -04:00
committed by GitHub
2 changed files with 50 additions and 1 deletions

View File

@@ -1,6 +1,10 @@
import logging
import pytest
from utils.key_derivation import derive_key_from_password
from utils.key_derivation import (
derive_key_from_password,
derive_index_key_seed_only,
derive_index_key_seed_plus_pw,
)
def test_derive_key_deterministic():
@@ -16,3 +20,19 @@ def test_derive_key_empty_password_error():
with pytest.raises(ValueError):
derive_key_from_password("")
logging.info("Empty password correctly raised ValueError")
def test_seed_only_key_deterministic():
seed = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
k1 = derive_index_key_seed_only(seed)
k2 = derive_index_key_seed_only(seed)
assert k1 == k2
assert len(k1) == 44
def test_seed_plus_pw_differs_from_seed_only():
seed = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
pw = "hunter2"
k1 = derive_index_key_seed_only(seed)
k2 = derive_index_key_seed_plus_pw(seed, pw)
assert k1 != k2

View File

@@ -167,3 +167,32 @@ class KeyManager:
private_key_hex = entropy_bytes.hex()
keys = Keys(priv_key=private_key_hex)
return keys
def derive_index_key_seed_only(seed: str) -> bytes:
"""Derive a deterministic Fernet key from only the BIP-39 seed."""
seed_bytes = Bip39SeedGenerator(seed).Generate()
hkdf = HKDF(
algorithm=hashes.SHA256(),
length=32,
salt=None,
info=b"password-db",
backend=default_backend(),
)
key = hkdf.derive(seed_bytes)
return base64.urlsafe_b64encode(key)
def derive_index_key_seed_plus_pw(seed: str, password: str) -> bytes:
"""Derive the index key from seed and password combined."""
seed_bytes = Bip39SeedGenerator(seed).Generate()
pw_bytes = unicodedata.normalize("NFKD", password).encode("utf-8")
hkdf = HKDF(
algorithm=hashes.SHA256(),
length=32,
salt=None,
info=b"password-db",
backend=default_backend(),
)
key = hkdf.derive(seed_bytes + b"|" + pw_bytes)
return base64.urlsafe_b64encode(key)