diff --git a/requirements.txt b/requirements.txt index 029b0983..34cf5663 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -embit==0.6.1 +embit==0.7.0 numpy==1.21.1 picamera==1.13 Pillow==8.2.0 diff --git a/src/seedsigner/models/seed.py b/src/seedsigner/models/seed.py index f050e1b8..7a848ecd 100644 --- a/src/seedsigner/models/seed.py +++ b/src/seedsigner/models/seed.py @@ -1,16 +1,13 @@ import unicodedata from binascii import hexlify -from embit import bip39, bip32 +from embit import bip39, bip32, bip85 from embit.networks import NETWORKS from typing import List from seedsigner.models.settings import SettingsConstants from seedsigner.helpers import embit_utils -import hashlib -import hmac - class InvalidSeedException(Exception): pass @@ -37,7 +34,7 @@ class Seed: @staticmethod def get_wordlist(wordlist_language_code: str = SettingsConstants.WORDLIST_LANGUAGE__ENGLISH) -> List[str]: - # TODO: Support other bip-39 wordlist languages! + # TODO: Support other BIP-39 wordlist languages! if wordlist_language_code == SettingsConstants.WORDLIST_LANGUAGE__ENGLISH: return bip39.WORDLIST else: @@ -101,7 +98,7 @@ class Seed: def set_wordlist_language_code(self, language_code: str): - # TODO: Support other bip-39 wordlist languages! + # TODO: Support other BIP-39 wordlist languages! raise Exception("Not yet implemented!") @@ -114,32 +111,12 @@ class Seed: return embit_utils.get_xpub(seed_bytes=self.seed_bytes, derivation_path=wallet_path, embit_network=SettingsConstants.map_network_to_embit(network)) - # Derives a BIP85 mnemonic (seed word) from the master seed words using embit functions def get_bip85_child_mnemonic(self, bip85_index: int, bip85_num_words: int, network: str = SettingsConstants.MAINNET): - - # Calculate the master bip32 root key from the parents bip39 seed_bytes (the mnemonic entropy) + """Derives the seed's nth BIP-85 child mnemonic""" root = bip32.HDKey.from_seed(self.seed_bytes, version=NETWORKS[SettingsConstants.map_network_to_embit(network)]["xprv"]) - # TODO: Support other bip-39 wordlist languages! - # As per the BIP85 spec, 39 is the application number used for bip39 mnemonic, - # we use the selected word count and the index to form the full path. - path = "m/83696968'/39'/0'/{bip85_num_words}'/{bip85_index}'".format( - bip85_num_words=bip85_num_words, - bip85_index=bip85_index) - - # Derive the child xprv (HDKey) using the path format defined above - xprv = root.derive(path) - - # The xprv.secret plus the BIP85 key is hashed together using hmac sha512. - entropy = hmac.new(key=b'bip-entropy-from-k', msg=xprv.secret, digestmod=hashlib.sha512).digest() - - # Calculate number of bytes to retain for the entropy - # 24 words the width is 32bytes (256bits) - # 12 words the width is 16bytes (128bits) - width = round(bip85_num_words / 12 * 16) - - # Return the derived BIP85 child mnemonic using the truncated derived entropy - return bip39.mnemonic_from_bytes(entropy[:width]) + # TODO: Support other BIP-39 wordlist languages! + return bip85.derive_mnemonic(root, bip85_num_words, bip85_index) ### override operators