Files
SeedPass/src/tests/test_fuzz_key_derivation.py
T
google-labs-jules[bot]andPR0M3TH3AN 8e33f9c5e1 Fix formatting, linting, and logic errors from codebase scan
- Apply black formatting to 17 files.
- Fix F821 undefined name errors in:
  - src/main.py: Add missing `queue` import.
  - src/seedpass/core/encryption.py: Fix `JSONDecodeError` reference.
  - src/utils/__init__.py: Fix exception variable scope in fallback code.
  - src/utils/key_derivation.py: Add `TYPE_CHECKING` imports.
  - src/seedpass/core/config_manager.py: Add `TYPE_CHECKING` imports.
- Initialize torch environment and TODO file.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-16 18:09:48 +00:00

80 lines
2.5 KiB
Python

import os
from pathlib import Path
from hypothesis import given, strategies as st, settings, HealthCheck
from mnemonic import Mnemonic
import hashlib
import base64
import os
from utils.key_derivation import (
derive_key_from_password,
derive_key_from_password_argon2,
derive_index_key,
KdfConfig,
)
from utils.fingerprint import generate_fingerprint
from seedpass.core.encryption import EncryptionManager
cfg_values = st.one_of(
st.integers(min_value=0, max_value=100),
st.text(min_size=0, max_size=20),
st.booleans(),
)
@given(
password=st.text(min_size=8, max_size=32),
seed_bytes=st.binary(min_size=16, max_size=16),
config=st.dictionaries(st.text(min_size=1, max_size=10), cfg_values, max_size=5),
mode=st.sampled_from(["pbkdf2", "argon2"]),
)
@settings(
deadline=None,
max_examples=20,
suppress_health_check=[HealthCheck.function_scoped_fixture],
)
def test_fuzz_key_round_trip(password, seed_bytes, config, mode, tmp_path: Path):
"""Ensure EncryptionManager round-trips arbitrary data."""
seed_phrase = Mnemonic("english").to_mnemonic(seed_bytes)
fp = generate_fingerprint(seed_phrase)
if mode == "argon2":
cfg = KdfConfig(
params={"time_cost": 1, "memory_cost": 8, "parallelism": 1},
salt_b64=base64.b64encode(
hashlib.sha256(fp.encode()).digest()[:16]
).decode(),
)
key = derive_key_from_password_argon2(password, cfg)
else:
key = derive_key_from_password(password, fp, iterations=1)
cfg = KdfConfig(
name="pbkdf2",
params={"iterations": 1},
salt_b64=base64.b64encode(
hashlib.sha256(fp.encode()).digest()[:16]
).decode(),
)
enc_mgr = EncryptionManager(key, tmp_path)
# Parent seed round trip
enc_mgr.encrypt_parent_seed(seed_phrase, kdf=cfg)
assert enc_mgr.decrypt_parent_seed() == seed_phrase
# JSON data round trip
enc_mgr.save_json_data(config, Path("config.enc"))
loaded = enc_mgr.load_json_data(Path("config.enc"))
assert loaded == config
# Binary data round trip
blob = os.urandom(32)
enc_mgr.encrypt_and_save_file(blob, Path("blob.enc"))
assert enc_mgr.decrypt_file(Path("blob.enc")) == blob
# Index key derived from seed also decrypts
index_key = derive_index_key(seed_phrase)
idx_mgr = EncryptionManager(index_key, tmp_path)
idx_mgr.save_json_data(config)
assert idx_mgr.load_json_data() == config