diff --git a/requirements.txt b/requirements.txt index a09bab39..1fb2f7b7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,4 +8,3 @@ RPi.GPIO==0.7.0 six==1.16.0 spidev==3.5 urtypes @ git+https://github.com/jreesun/urtypes.git@e0d0db277ec2339650343eaf7b220fffb9233241 -bip85==0.2.0 diff --git a/src/seedsigner/gui/screens/seed_screens.py b/src/seedsigner/gui/screens/seed_screens.py index 3043e138..cd9b5016 100644 --- a/src/seedsigner/gui/screens/seed_screens.py +++ b/src/seedsigner/gui/screens/seed_screens.py @@ -1744,7 +1744,7 @@ class BIP85SeedWordsScreen(WarningEdgesMixin, ButtonListScreen): #num_words = 12 # Can only render 4 words per screen words_per_page = 4 - mnemonic = self.seed.get_bip85_child(self.seed.bip85_index, self.seed.bip85_num_words).split() + mnemonic = self.seed.get_bip85_child_mnemonic(self.seed.bip85_index, self.seed.bip85_num_words).split() # Slice the mnemonic to our current 4-word section self.mnemonic = mnemonic[self.page_index*words_per_page:(self.page_index + 1)*words_per_page] self.body_x = 0 diff --git a/src/seedsigner/helpers/bip85.py b/src/seedsigner/helpers/bip85.py new file mode 100644 index 00000000..5360829e --- /dev/null +++ b/src/seedsigner/helpers/bip85.py @@ -0,0 +1,7 @@ +import hashlib +import hmac + +def hmac_sha512(message_k): + return hmac.new(key=b'bip-entropy-from-k', msg=message_k, digestmod=hashlib.sha512).digest() + + diff --git a/src/seedsigner/models/seed.py b/src/seedsigner/models/seed.py index 88edcdc5..219aff62 100644 --- a/src/seedsigner/models/seed.py +++ b/src/seedsigner/models/seed.py @@ -5,9 +5,8 @@ from binascii import hexlify from embit import bip39, bip32 from embit.networks import NETWORKS from typing import List -from bip85 import BIP85 -from bip85 import app +from seedsigner.helpers.bip85 import hmac_sha512 from seedsigner.models.settings import SettingsConstants class InvalidSeedException(Exception): @@ -121,20 +120,26 @@ class Seed: xprv = root.derive(wallet_path) xpub = xprv.to_public() return xpub - - def get_bip85_child(self, bip85_index: int, bip85_num_words: int, wallet_path: str = '/', network: str = SettingsConstants.MAINNET): - bip85_seed: str = "" - bip85 = BIP85() - - passphrase = self._passphrase - language = 'english' + # 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, wallet_path: str = '/', + network: str = SettingsConstants.MAINNET): + passphrase = self._passphrase + # language = 'english' + # lang_code = 0 + # Need to add language later for path, defaults to English (0) + path = "m/83696968'/39'/0'/{bip85_num_words}'/{bip85_index}'".format(bip85_num_words=bip85_num_words, + bip85_index=bip85_index) seed = bip39.mnemonic_to_seed(self.mnemonic_str, password=self._passphrase, wordlist=self.wordlist) xprv = embit.bip32.HDKey.from_seed(seed) - bip85_seed = app.bip39(xprv, language, bip85_num_words, bip85_index) - return bip85_seed - ### override operators + # Derive k + xprv = xprv.derive(path) + entropy = hmac_sha512(xprv.secret) + width = round(bip85_num_words / 12 * 16) + return bip39.mnemonic_from_bytes(entropy[:width]) + + ### override operators def __eq__(self, other): if isinstance(other, Seed): return self.seed_bytes == other.seed_bytes diff --git a/src/seedsigner/models/settings_definition.py b/src/seedsigner/models/settings_definition.py index cfb5742b..7556a2a3 100644 --- a/src/seedsigner/models/settings_definition.py +++ b/src/seedsigner/models/settings_definition.py @@ -397,7 +397,7 @@ class SettingsDefinition: attr_name=SettingsConstants.SETTING__GEN_BIP85, display_name="Generate BIP85", visibility=SettingsConstants.VISIBILITY__ADVANCED, - default_value=SettingsConstants.OPTION__ENABLED), + default_value=SettingsConstants.OPTION__DISABLED), SettingsEntry(category=SettingsConstants.CATEGORY__FEATURES, attr_name=SettingsConstants.SETTING__SIG_TYPES,