mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-09 15:58:48 +00:00
refactor: rename entropy length parameter
This commit is contained in:
@@ -51,26 +51,34 @@ class BIP85:
|
|||||||
raise Bip85Error(f"Error initializing BIP32 context: {e}")
|
raise Bip85Error(f"Error initializing BIP32 context: {e}")
|
||||||
|
|
||||||
def derive_entropy(
|
def derive_entropy(
|
||||||
self, index: int, bytes_len: int, app_no: int = 39, words_len: int | None = None
|
self,
|
||||||
|
index: int,
|
||||||
|
entropy_bytes: int,
|
||||||
|
app_no: int = 39,
|
||||||
|
word_count: int | None = None,
|
||||||
) -> bytes:
|
) -> bytes:
|
||||||
"""
|
"""Derive entropy using the BIP-85 HMAC-SHA512 method.
|
||||||
Derives entropy using BIP-85 HMAC-SHA512 method.
|
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
index (int): Index for the child entropy.
|
index (int): Index for the child entropy.
|
||||||
bytes_len (int): Number of bytes to derive for the entropy.
|
entropy_bytes (int): Number of bytes of entropy to derive.
|
||||||
app_no (int): Application number (default 39 for BIP39)
|
app_no (int): Application number (default 39 for BIP39).
|
||||||
|
word_count (int | None): Number of words used in the derivation path
|
||||||
|
for BIP39. If ``None`` and ``app_no`` is ``39``, ``word_count``
|
||||||
|
defaults to ``entropy_bytes``. The final segment of the
|
||||||
|
derivation path becomes ``m/83696968'/39'/0'/word_count'/index'``.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bytes: Derived entropy.
|
bytes: Derived entropy of length ``entropy_bytes``.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
SystemExit: If derivation fails or entropy length is invalid.
|
SystemExit: If derivation fails or the derived entropy length is
|
||||||
|
invalid.
|
||||||
"""
|
"""
|
||||||
if app_no == 39:
|
if app_no == 39:
|
||||||
if words_len is None:
|
if word_count is None:
|
||||||
words_len = bytes_len
|
word_count = entropy_bytes
|
||||||
path = f"m/83696968'/{app_no}'/0'/{words_len}'/{index}'"
|
path = f"m/83696968'/{app_no}'/0'/{word_count}'/{index}'"
|
||||||
elif app_no == 32:
|
elif app_no == 32:
|
||||||
path = f"m/83696968'/{app_no}'/{index}'"
|
path = f"m/83696968'/{app_no}'/{index}'"
|
||||||
else:
|
else:
|
||||||
@@ -86,17 +94,17 @@ class BIP85:
|
|||||||
hmac_result = hmac.new(hmac_key, k, hashlib.sha512).digest()
|
hmac_result = hmac.new(hmac_key, k, hashlib.sha512).digest()
|
||||||
logging.debug(f"HMAC-SHA512 result: {hmac_result.hex()}")
|
logging.debug(f"HMAC-SHA512 result: {hmac_result.hex()}")
|
||||||
|
|
||||||
entropy = hmac_result[:bytes_len]
|
entropy = hmac_result[:entropy_bytes]
|
||||||
|
|
||||||
if len(entropy) != bytes_len:
|
if len(entropy) != entropy_bytes:
|
||||||
logging.error(
|
logging.error(
|
||||||
f"Derived entropy length is {len(entropy)} bytes; expected {bytes_len} bytes."
|
f"Derived entropy length is {len(entropy)} bytes; expected {entropy_bytes} bytes."
|
||||||
)
|
)
|
||||||
print(
|
print(
|
||||||
f"{Fore.RED}Error: Derived entropy length is {len(entropy)} bytes; expected {bytes_len} bytes."
|
f"{Fore.RED}Error: Derived entropy length is {len(entropy)} bytes; expected {entropy_bytes} bytes."
|
||||||
)
|
)
|
||||||
raise Bip85Error(
|
raise Bip85Error(
|
||||||
f"Derived entropy length is {len(entropy)} bytes; expected {bytes_len} bytes."
|
f"Derived entropy length is {len(entropy)} bytes; expected {entropy_bytes} bytes."
|
||||||
)
|
)
|
||||||
|
|
||||||
logging.debug(f"Derived entropy: {entropy.hex()}")
|
logging.debug(f"Derived entropy: {entropy.hex()}")
|
||||||
@@ -107,14 +115,17 @@ class BIP85:
|
|||||||
raise Bip85Error(f"Error deriving entropy: {e}")
|
raise Bip85Error(f"Error deriving entropy: {e}")
|
||||||
|
|
||||||
def derive_mnemonic(self, index: int, words_num: int) -> str:
|
def derive_mnemonic(self, index: int, words_num: int) -> str:
|
||||||
bytes_len = {12: 16, 18: 24, 24: 32}.get(words_num)
|
entropy_bytes = {12: 16, 18: 24, 24: 32}.get(words_num)
|
||||||
if not bytes_len:
|
if not entropy_bytes:
|
||||||
logging.error(f"Unsupported number of words: {words_num}")
|
logging.error(f"Unsupported number of words: {words_num}")
|
||||||
print(f"{Fore.RED}Error: Unsupported number of words: {words_num}")
|
print(f"{Fore.RED}Error: Unsupported number of words: {words_num}")
|
||||||
raise Bip85Error(f"Unsupported number of words: {words_num}")
|
raise Bip85Error(f"Unsupported number of words: {words_num}")
|
||||||
|
|
||||||
entropy = self.derive_entropy(
|
entropy = self.derive_entropy(
|
||||||
index=index, bytes_len=bytes_len, app_no=39, words_len=words_num
|
index=index,
|
||||||
|
entropy_bytes=entropy_bytes,
|
||||||
|
app_no=39,
|
||||||
|
word_count=words_num,
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
mnemonic = Bip39MnemonicGenerator(Bip39Languages.ENGLISH).FromEntropy(
|
mnemonic = Bip39MnemonicGenerator(Bip39Languages.ENGLISH).FromEntropy(
|
||||||
@@ -130,7 +141,7 @@ class BIP85:
|
|||||||
def derive_symmetric_key(self, index: int = 0, app_no: int = 2) -> bytes:
|
def derive_symmetric_key(self, index: int = 0, app_no: int = 2) -> bytes:
|
||||||
"""Derive 32 bytes of entropy for symmetric key usage."""
|
"""Derive 32 bytes of entropy for symmetric key usage."""
|
||||||
try:
|
try:
|
||||||
key = self.derive_entropy(index=index, bytes_len=32, app_no=app_no)
|
key = self.derive_entropy(index=index, entropy_bytes=32, app_no=app_no)
|
||||||
logging.debug(f"Derived symmetric key: {key.hex()}")
|
logging.debug(f"Derived symmetric key: {key.hex()}")
|
||||||
return key
|
return key
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@@ -85,7 +85,7 @@ class KeyManager:
|
|||||||
# Derive entropy for Nostr key (32 bytes)
|
# Derive entropy for Nostr key (32 bytes)
|
||||||
entropy_bytes = self.bip85.derive_entropy(
|
entropy_bytes = self.bip85.derive_entropy(
|
||||||
index=index,
|
index=index,
|
||||||
bytes_len=32,
|
entropy_bytes=32,
|
||||||
app_no=NOSTR_KEY_APP_ID,
|
app_no=NOSTR_KEY_APP_ID,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ class KeyManager:
|
|||||||
"""Derive Nostr keys using the legacy application ID."""
|
"""Derive Nostr keys using the legacy application ID."""
|
||||||
try:
|
try:
|
||||||
entropy = self.bip85.derive_entropy(
|
entropy = self.bip85.derive_entropy(
|
||||||
index=0, bytes_len=32, app_no=LEGACY_NOSTR_KEY_APP_ID
|
index=0, entropy_bytes=32, app_no=LEGACY_NOSTR_KEY_APP_ID
|
||||||
)
|
)
|
||||||
return Keys(priv_k=entropy.hex())
|
return Keys(priv_k=entropy.hex())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@@ -461,7 +461,7 @@ class EntryManager:
|
|||||||
|
|
||||||
seed_bytes = Bip39SeedGenerator(parent_seed).Generate()
|
seed_bytes = Bip39SeedGenerator(parent_seed).Generate()
|
||||||
bip85 = BIP85(seed_bytes)
|
bip85 = BIP85(seed_bytes)
|
||||||
entropy = bip85.derive_entropy(index=index, bytes_len=32)
|
entropy = bip85.derive_entropy(index=index, entropy_bytes=32)
|
||||||
keys = Keys(priv_k=entropy.hex())
|
keys = Keys(priv_k=entropy.hex())
|
||||||
npub = Keys.hex_to_bech32(keys.public_key_hex(), "npub")
|
npub = Keys.hex_to_bech32(keys.public_key_hex(), "npub")
|
||||||
nsec = Keys.hex_to_bech32(keys.private_key_hex(), "nsec")
|
nsec = Keys.hex_to_bech32(keys.private_key_hex(), "nsec")
|
||||||
@@ -539,7 +539,7 @@ class EntryManager:
|
|||||||
bip85 = BIP85(seed_bytes)
|
bip85 = BIP85(seed_bytes)
|
||||||
|
|
||||||
key_idx = int(entry.get("index", index))
|
key_idx = int(entry.get("index", index))
|
||||||
entropy = bip85.derive_entropy(index=key_idx, bytes_len=32)
|
entropy = bip85.derive_entropy(index=key_idx, entropy_bytes=32)
|
||||||
keys = Keys(priv_k=entropy.hex())
|
keys = Keys(priv_k=entropy.hex())
|
||||||
npub = Keys.hex_to_bech32(keys.public_key_hex(), "npub")
|
npub = Keys.hex_to_bech32(keys.public_key_hex(), "npub")
|
||||||
nsec = Keys.hex_to_bech32(keys.private_key_hex(), "nsec")
|
nsec = Keys.hex_to_bech32(keys.private_key_hex(), "nsec")
|
||||||
|
@@ -280,13 +280,15 @@ class PasswordManager:
|
|||||||
)
|
)
|
||||||
|
|
||||||
@requires_unlocked
|
@requires_unlocked
|
||||||
def get_bip85_entropy(self, purpose: int, index: int, bytes_len: int = 32) -> bytes:
|
def get_bip85_entropy(
|
||||||
|
self, purpose: int, index: int, entropy_bytes: int = 32
|
||||||
|
) -> bytes:
|
||||||
"""Return deterministic entropy via the cached BIP-85 function."""
|
"""Return deterministic entropy via the cached BIP-85 function."""
|
||||||
|
|
||||||
if self.bip85 is None:
|
if self.bip85 is None:
|
||||||
raise RuntimeError("BIP-85 is not initialized")
|
raise RuntimeError("BIP-85 is not initialized")
|
||||||
return self.bip85.derive_entropy(
|
return self.bip85.derive_entropy(
|
||||||
index=index, bytes_len=bytes_len, app_no=purpose
|
index=index, entropy_bytes=entropy_bytes, app_no=purpose
|
||||||
)
|
)
|
||||||
|
|
||||||
@requires_unlocked
|
@requires_unlocked
|
||||||
@@ -1243,11 +1245,13 @@ class PasswordManager:
|
|||||||
self._bip85_cache = {}
|
self._bip85_cache = {}
|
||||||
orig_derive = self.bip85.derive_entropy
|
orig_derive = self.bip85.derive_entropy
|
||||||
|
|
||||||
def cached_derive(index: int, bytes_len: int, app_no: int = 39) -> bytes:
|
def cached_derive(
|
||||||
|
index: int, entropy_bytes: int, app_no: int = 39
|
||||||
|
) -> bytes:
|
||||||
key = (app_no, index)
|
key = (app_no, index)
|
||||||
if key not in self._bip85_cache:
|
if key not in self._bip85_cache:
|
||||||
self._bip85_cache[key] = orig_derive(
|
self._bip85_cache[key] = orig_derive(
|
||||||
index=index, bytes_len=bytes_len, app_no=app_no
|
index=index, entropy_bytes=entropy_bytes, app_no=app_no
|
||||||
)
|
)
|
||||||
return self._bip85_cache[key]
|
return self._bip85_cache[key]
|
||||||
|
|
||||||
@@ -2727,14 +2731,14 @@ class PasswordManager:
|
|||||||
from bip_utils import Bip39SeedGenerator
|
from bip_utils import Bip39SeedGenerator
|
||||||
|
|
||||||
words = int(entry.get("word_count", entry.get("words", 24)))
|
words = int(entry.get("word_count", entry.get("words", 24)))
|
||||||
bytes_len = {12: 16, 18: 24, 24: 32}.get(words, 32)
|
entropy_bytes = {12: 16, 18: 24, 24: 32}.get(words, 32)
|
||||||
seed_bytes = Bip39SeedGenerator(self.parent_seed).Generate()
|
seed_bytes = Bip39SeedGenerator(self.parent_seed).Generate()
|
||||||
bip85 = BIP85(seed_bytes)
|
bip85 = BIP85(seed_bytes)
|
||||||
entropy = bip85.derive_entropy(
|
entropy = bip85.derive_entropy(
|
||||||
index=int(entry.get("index", index)),
|
index=int(entry.get("index", index)),
|
||||||
bytes_len=bytes_len,
|
entropy_bytes=entropy_bytes,
|
||||||
app_no=39,
|
app_no=39,
|
||||||
words_len=words,
|
word_count=words,
|
||||||
)
|
)
|
||||||
print(color_text(f"Entropy: {entropy.hex()}", "deterministic"))
|
print(color_text(f"Entropy: {entropy.hex()}", "deterministic"))
|
||||||
except Exception as e: # pragma: no cover - best effort
|
except Exception as e: # pragma: no cover - best effort
|
||||||
|
@@ -126,7 +126,7 @@ class PasswordGenerator:
|
|||||||
|
|
||||||
def _derive_password_entropy(self, index: int) -> bytes:
|
def _derive_password_entropy(self, index: int) -> bytes:
|
||||||
"""Derive deterministic entropy for password generation."""
|
"""Derive deterministic entropy for password generation."""
|
||||||
entropy = self.bip85.derive_entropy(index=index, bytes_len=64, app_no=32)
|
entropy = self.bip85.derive_entropy(index=index, entropy_bytes=64, app_no=32)
|
||||||
logger.debug("Entropy derived for password generation.")
|
logger.debug("Entropy derived for password generation.")
|
||||||
|
|
||||||
hkdf = HKDF(
|
hkdf = HKDF(
|
||||||
@@ -433,7 +433,7 @@ class PasswordGenerator:
|
|||||||
|
|
||||||
def derive_ssh_key(bip85: BIP85, idx: int) -> bytes:
|
def derive_ssh_key(bip85: BIP85, idx: int) -> bytes:
|
||||||
"""Derive 32 bytes of entropy suitable for an SSH key."""
|
"""Derive 32 bytes of entropy suitable for an SSH key."""
|
||||||
return bip85.derive_entropy(index=idx, bytes_len=32, app_no=32)
|
return bip85.derive_entropy(index=idx, entropy_bytes=32, app_no=32)
|
||||||
|
|
||||||
|
|
||||||
def derive_ssh_key_pair(parent_seed: str, index: int) -> tuple[str, str]:
|
def derive_ssh_key_pair(parent_seed: str, index: int) -> tuple[str, str]:
|
||||||
@@ -499,7 +499,7 @@ def derive_pgp_key(
|
|||||||
import hashlib
|
import hashlib
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
entropy = bip85.derive_entropy(index=idx, bytes_len=32, app_no=32)
|
entropy = bip85.derive_entropy(index=idx, entropy_bytes=32, app_no=32)
|
||||||
created = datetime.datetime(2000, 1, 1, tzinfo=datetime.timezone.utc)
|
created = datetime.datetime(2000, 1, 1, tzinfo=datetime.timezone.utc)
|
||||||
|
|
||||||
if key_type.lower() == "rsa":
|
if key_type.lower() == "rsa":
|
||||||
|
@@ -501,8 +501,10 @@ async def test_generate_password_no_special_chars(client):
|
|||||||
return b"\x00" * 32
|
return b"\x00" * 32
|
||||||
|
|
||||||
class DummyBIP85:
|
class DummyBIP85:
|
||||||
def derive_entropy(self, index: int, bytes_len: int, app_no: int = 32) -> bytes:
|
def derive_entropy(
|
||||||
return bytes(range(bytes_len))
|
self, index: int, entropy_bytes: int, app_no: int = 32
|
||||||
|
) -> bytes:
|
||||||
|
return bytes(range(entropy_bytes))
|
||||||
|
|
||||||
api.app.state.pm.password_generator = PasswordGenerator(
|
api.app.state.pm.password_generator = PasswordGenerator(
|
||||||
DummyEnc(), "seed", DummyBIP85()
|
DummyEnc(), "seed", DummyBIP85()
|
||||||
@@ -529,8 +531,10 @@ async def test_generate_password_allowed_chars(client):
|
|||||||
return b"\x00" * 32
|
return b"\x00" * 32
|
||||||
|
|
||||||
class DummyBIP85:
|
class DummyBIP85:
|
||||||
def derive_entropy(self, index: int, bytes_len: int, app_no: int = 32) -> bytes:
|
def derive_entropy(
|
||||||
return bytes((index + i) % 256 for i in range(bytes_len))
|
self, index: int, entropy_bytes: int, app_no: int = 32
|
||||||
|
) -> bytes:
|
||||||
|
return bytes((index + i) % 256 for i in range(entropy_bytes))
|
||||||
|
|
||||||
api.app.state.pm.password_generator = PasswordGenerator(
|
api.app.state.pm.password_generator = PasswordGenerator(
|
||||||
DummyEnc(), "seed", DummyBIP85()
|
DummyEnc(), "seed", DummyBIP85()
|
||||||
|
52
src/tests/test_bip85_derivation_path.py
Normal file
52
src/tests/test_bip85_derivation_path.py
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
from local_bip85.bip85 import BIP85
|
||||||
|
|
||||||
|
|
||||||
|
class DummyChild:
|
||||||
|
def PrivateKey(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def Raw(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def ToBytes(self):
|
||||||
|
return b"\x00" * 32
|
||||||
|
|
||||||
|
|
||||||
|
class DummyCtx:
|
||||||
|
def __init__(self):
|
||||||
|
self.last_path = None
|
||||||
|
|
||||||
|
def DerivePath(self, path: str):
|
||||||
|
self.last_path = path
|
||||||
|
return DummyChild()
|
||||||
|
|
||||||
|
|
||||||
|
def test_derivation_paths_for_entropy_lengths():
|
||||||
|
bip85 = BIP85(b"\x00" * 64)
|
||||||
|
ctx = DummyCtx()
|
||||||
|
bip85.bip32_ctx = ctx
|
||||||
|
|
||||||
|
vectors = [
|
||||||
|
(16, 12),
|
||||||
|
(24, 18),
|
||||||
|
(32, 24),
|
||||||
|
]
|
||||||
|
|
||||||
|
for entropy_bytes, word_count in vectors:
|
||||||
|
bip85.derive_entropy(
|
||||||
|
index=0,
|
||||||
|
entropy_bytes=entropy_bytes,
|
||||||
|
app_no=39,
|
||||||
|
word_count=word_count,
|
||||||
|
)
|
||||||
|
assert ctx.last_path == f"m/83696968'/39'/0'/{word_count}'/0'"
|
||||||
|
|
||||||
|
|
||||||
|
def test_default_word_count_from_entropy_bytes():
|
||||||
|
bip85 = BIP85(b"\x00" * 64)
|
||||||
|
ctx = DummyCtx()
|
||||||
|
bip85.bip32_ctx = ctx
|
||||||
|
|
||||||
|
bip85.derive_entropy(index=5, entropy_bytes=20, app_no=39)
|
||||||
|
|
||||||
|
assert ctx.last_path == "m/83696968'/39'/0'/20'/5'"
|
@@ -21,8 +21,8 @@ class DummyEnc:
|
|||||||
|
|
||||||
|
|
||||||
class DummyBIP85:
|
class DummyBIP85:
|
||||||
def derive_entropy(self, index: int, bytes_len: int, app_no: int = 32) -> bytes:
|
def derive_entropy(self, index: int, entropy_bytes: int, app_no: int = 32) -> bytes:
|
||||||
return bytes((index + i) % 256 for i in range(bytes_len))
|
return bytes((index + i) % 256 for i in range(entropy_bytes))
|
||||||
|
|
||||||
|
|
||||||
def make_manager(tmp_path: Path) -> PasswordManager:
|
def make_manager(tmp_path: Path) -> PasswordManager:
|
||||||
|
@@ -13,8 +13,8 @@ class DummyEnc:
|
|||||||
|
|
||||||
|
|
||||||
class DummyBIP85:
|
class DummyBIP85:
|
||||||
def derive_entropy(self, index: int, bytes_len: int, app_no: int = 32) -> bytes:
|
def derive_entropy(self, index: int, entropy_bytes: int, app_no: int = 32) -> bytes:
|
||||||
return bytes((index + i) % 256 for i in range(bytes_len))
|
return bytes((index + i) % 256 for i in range(entropy_bytes))
|
||||||
|
|
||||||
|
|
||||||
def make_generator(policy=None):
|
def make_generator(policy=None):
|
||||||
|
@@ -8,8 +8,8 @@ class DummyEnc:
|
|||||||
|
|
||||||
|
|
||||||
class DummyBIP85:
|
class DummyBIP85:
|
||||||
def derive_entropy(self, index: int, bytes_len: int, app_no: int = 32) -> bytes:
|
def derive_entropy(self, index: int, entropy_bytes: int, app_no: int = 32) -> bytes:
|
||||||
return bytes((index + i) % 256 for i in range(bytes_len))
|
return bytes((index + i) % 256 for i in range(entropy_bytes))
|
||||||
|
|
||||||
|
|
||||||
def make_generator():
|
def make_generator():
|
||||||
|
@@ -14,8 +14,8 @@ class DummyEnc:
|
|||||||
|
|
||||||
|
|
||||||
class DummyBIP85:
|
class DummyBIP85:
|
||||||
def derive_entropy(self, index: int, bytes_len: int, app_no: int = 32) -> bytes:
|
def derive_entropy(self, index: int, entropy_bytes: int, app_no: int = 32) -> bytes:
|
||||||
return bytes((index + i) % 256 for i in range(bytes_len))
|
return bytes((index + i) % 256 for i in range(entropy_bytes))
|
||||||
|
|
||||||
|
|
||||||
def make_generator():
|
def make_generator():
|
||||||
|
@@ -15,8 +15,8 @@ class DummyEnc:
|
|||||||
|
|
||||||
|
|
||||||
class DummyBIP85:
|
class DummyBIP85:
|
||||||
def derive_entropy(self, index: int, bytes_len: int, app_no: int = 32) -> bytes:
|
def derive_entropy(self, index: int, entropy_bytes: int, app_no: int = 32) -> bytes:
|
||||||
return bytes((index + i) % 256 for i in range(bytes_len))
|
return bytes((index + i) % 256 for i in range(entropy_bytes))
|
||||||
|
|
||||||
|
|
||||||
def make_generator():
|
def make_generator():
|
||||||
|
@@ -12,8 +12,8 @@ class DummyEnc:
|
|||||||
|
|
||||||
|
|
||||||
class DummyBIP85:
|
class DummyBIP85:
|
||||||
def derive_entropy(self, index: int, bytes_len: int, app_no: int = 32) -> bytes:
|
def derive_entropy(self, index: int, entropy_bytes: int, app_no: int = 32) -> bytes:
|
||||||
return bytes((index + i) % 256 for i in range(bytes_len))
|
return bytes((index + i) % 256 for i in range(entropy_bytes))
|
||||||
|
|
||||||
|
|
||||||
def make_generator():
|
def make_generator():
|
||||||
|
@@ -15,8 +15,8 @@ class DummyEnc:
|
|||||||
|
|
||||||
|
|
||||||
class DummyBIP85:
|
class DummyBIP85:
|
||||||
def derive_entropy(self, index: int, bytes_len: int, app_no: int = 32) -> bytes:
|
def derive_entropy(self, index: int, entropy_bytes: int, app_no: int = 32) -> bytes:
|
||||||
return bytes((index + i) % 256 for i in range(bytes_len))
|
return bytes((index + i) % 256 for i in range(entropy_bytes))
|
||||||
|
|
||||||
|
|
||||||
def make_generator(policy=None):
|
def make_generator(policy=None):
|
||||||
|
@@ -14,8 +14,8 @@ class DummyEnc:
|
|||||||
|
|
||||||
|
|
||||||
class DummyBIP85:
|
class DummyBIP85:
|
||||||
def derive_entropy(self, index: int, bytes_len: int, app_no: int = 32) -> bytes:
|
def derive_entropy(self, index: int, entropy_bytes: int, app_no: int = 32) -> bytes:
|
||||||
return bytes((index + i) % 256 for i in range(bytes_len))
|
return bytes((index + i) % 256 for i in range(entropy_bytes))
|
||||||
|
|
||||||
|
|
||||||
def make_generator(policy=None):
|
def make_generator(policy=None):
|
||||||
|
@@ -9,10 +9,10 @@ class SlowBIP85:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.calls = 0
|
self.calls = 0
|
||||||
|
|
||||||
def derive_entropy(self, index: int, bytes_len: int, app_no: int = 39) -> bytes:
|
def derive_entropy(self, index: int, entropy_bytes: int, app_no: int = 39) -> bytes:
|
||||||
self.calls += 1
|
self.calls += 1
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
return b"\x00" * bytes_len
|
return b"\x00" * entropy_bytes
|
||||||
|
|
||||||
|
|
||||||
def _setup_manager(bip85: SlowBIP85) -> PasswordManager:
|
def _setup_manager(bip85: SlowBIP85) -> PasswordManager:
|
||||||
@@ -21,10 +21,12 @@ def _setup_manager(bip85: SlowBIP85) -> PasswordManager:
|
|||||||
pm.bip85 = bip85
|
pm.bip85 = bip85
|
||||||
orig = bip85.derive_entropy
|
orig = bip85.derive_entropy
|
||||||
|
|
||||||
def cached(index: int, bytes_len: int, app_no: int = 39) -> bytes:
|
def cached(index: int, entropy_bytes: int, app_no: int = 39) -> bytes:
|
||||||
key = (app_no, index)
|
key = (app_no, index)
|
||||||
if key not in pm._bip85_cache:
|
if key not in pm._bip85_cache:
|
||||||
pm._bip85_cache[key] = orig(index=index, bytes_len=bytes_len, app_no=app_no)
|
pm._bip85_cache[key] = orig(
|
||||||
|
index=index, entropy_bytes=entropy_bytes, app_no=app_no
|
||||||
|
)
|
||||||
return pm._bip85_cache[key]
|
return pm._bip85_cache[key]
|
||||||
|
|
||||||
bip85.derive_entropy = cached
|
bip85.derive_entropy = cached
|
||||||
|
Reference in New Issue
Block a user