commit 567130f4a37e55769b1b8f8f22348b25affa230b
parent 4bda6f5e61da3df0f2cd678c542fffd49045ee9c
Author: ThomasV <thomasv@electrum.org>
Date: Thu, 10 Dec 2020 14:43:29 +0100
Merge pull request #6838 from SomberNight/202012_seed_type_old_2fa
mnemonic: tighten seed_type check for old "2fa" type seeds
Diffstat:
2 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/electrum/mnemonic.py b/electrum/mnemonic.py
@@ -241,13 +241,17 @@ def is_old_seed(seed: str) -> bool:
def seed_type(x: str) -> str:
+ num_words = len(x.split())
if is_old_seed(x):
return 'old'
- elif is_new_seed(x):
+ elif is_new_seed(x, version.SEED_PREFIX):
return 'standard'
elif is_new_seed(x, version.SEED_PREFIX_SW):
return 'segwit'
- elif is_new_seed(x, version.SEED_PREFIX_2FA):
+ elif is_new_seed(x, version.SEED_PREFIX_2FA) and (num_words == 12 or num_words >= 20):
+ # Note: in Electrum 2.7, there was a breaking change in key derivation
+ # for this seed type. Unfortunately the seed version/prefix was reused,
+ # and now we can only distinguish them based on number of words. :(
return '2fa'
elif is_new_seed(x, version.SEED_PREFIX_2FA_SW):
return '2fa_segwit'
diff --git a/electrum/plugins/trustedcoin/trustedcoin.py b/electrum/plugins/trustedcoin/trustedcoin.py
@@ -575,20 +575,25 @@ class TrustedCoinPlugin(BasePlugin):
raise Exception(f'unexpected seed type: {t}')
words = seed.split()
n = len(words)
- # old version use long seed phrases
- if n >= 20:
- # note: pre-2.7 2fa seeds were typically 24-25 words, however they
- # could probabilistically be arbitrarily shorter due to a bug. (see #3611)
- # the probability of it being < 20 words is about 2^(-(256+12-19*11)) = 2^(-59)
- if passphrase != '':
- raise Exception('old 2fa seed cannot have passphrase')
- xprv1, xpub1 = self.get_xkeys(' '.join(words[0:12]), t, '', "m/")
- xprv2, xpub2 = self.get_xkeys(' '.join(words[12:]), t, '', "m/")
- elif not t == '2fa' or n == 12:
+ if t == '2fa':
+ if n >= 20: # old scheme
+ # note: pre-2.7 2fa seeds were typically 24-25 words, however they
+ # could probabilistically be arbitrarily shorter due to a bug. (see #3611)
+ # the probability of it being < 20 words is about 2^(-(256+12-19*11)) = 2^(-59)
+ if passphrase != '':
+ raise Exception('old 2fa seed cannot have passphrase')
+ xprv1, xpub1 = self.get_xkeys(' '.join(words[0:12]), t, '', "m/")
+ xprv2, xpub2 = self.get_xkeys(' '.join(words[12:]), t, '', "m/")
+ elif n == 12: # new scheme
+ xprv1, xpub1 = self.get_xkeys(seed, t, passphrase, "m/0'/")
+ xprv2, xpub2 = self.get_xkeys(seed, t, passphrase, "m/1'/")
+ else:
+ raise Exception(f'unrecognized seed length for "2fa" seed: {n}')
+ elif t == '2fa_segwit':
xprv1, xpub1 = self.get_xkeys(seed, t, passphrase, "m/0'/")
xprv2, xpub2 = self.get_xkeys(seed, t, passphrase, "m/1'/")
else:
- raise Exception('unrecognized seed length: {} words'.format(n))
+ raise Exception(f'unexpected seed type: {t}')
return xprv1, xpub1, xprv2, xpub2
def create_keystore(self, wizard, seed, passphrase):