mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-08 07:18:47 +00:00
81 lines
2.5 KiB
Python
81 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
|