commit cef75e9e7ba3bf96415c2dac9e2e53a3c198f096
parent 1df007483e4c402cfcd8da098fd425142d9d3bcc
Author: ThomasV <thomasv@gitorious>
Date: Sat, 13 Sep 2014 19:31:05 +0200
new seed_version: remove whitespaces only between CJK characters
Diffstat:
4 files changed, 59 insertions(+), 17 deletions(-)
diff --git a/gui/qt/installwizard.py b/gui/qt/installwizard.py
@@ -16,7 +16,7 @@ from amountedit import AmountEdit
import sys
import threading
from electrum.plugins import run_hook
-
+from electrum.mnemonic import prepare_seed
MSG_ENTER_ANYTHING = _("Please enter a wallet seed, a master public key, a list of Bitcoin addresses, or a list of private keys")
MSG_SHOW_MPK = _("This is your master public key")
@@ -114,8 +114,7 @@ class InstallWizard(QDialog):
r = self.enter_seed_dialog(MSG_VERIFY_SEED, sid, func)
if not r:
return
-
- if r != seed:
+ if prepare_seed(r) != prepare_seed(seed):
QMessageBox.warning(None, _('Error'), _('Incorrect seed'), _('OK'))
return False
else:
diff --git a/lib/bitcoin.py b/lib/bitcoin.py
@@ -150,7 +150,7 @@ hmac_sha_512 = lambda x,y: hmac.new(x, y, hashlib.sha512).digest()
def is_new_seed(x, prefix=version.SEED_BIP44):
import mnemonic
- x = mnemonic.Mnemonic.prepare_seed(x)
+ x = mnemonic.prepare_seed(x)
s = hmac_sha_512("Seed version", x.encode('utf8')).encode('hex')
return s.startswith(prefix)
diff --git a/lib/mnemonic.py b/lib/mnemonic.py
@@ -32,6 +32,60 @@ from bitcoin import is_old_seed, is_new_seed
import version
+# http://www.asahi-net.or.jp/~ax2s-kmtn/ref/unicode/e_asia.html
+CJK_INTERVALS = [
+ (0x4E00, 0x9FFF, 'CJK Unified Ideographs'),
+ (0x3400, 0x4DBF, 'CJK Unified Ideographs Extension A'),
+ (0x20000, 0x2A6DF, 'CJK Unified Ideographs Extension B'),
+ (0x2A700, 0x2B73F, 'CJK Unified Ideographs Extension C'),
+ (0x2B740, 0x2B81F, 'CJK Unified Ideographs Extension D'),
+ (0xF900, 0xFAFF, 'CJK Compatibility Ideographs'),
+ (0x2F800, 0x2FA1D, 'CJK Compatibility Ideographs Supplement'),
+ (0x3190, 0x319F , 'Kanbun'),
+ (0x2E80, 0x2EFF, 'CJK Radicals Supplement'),
+ (0x2F00, 0x2FDF, 'CJK Radicals'),
+ (0x31C0, 0x31EF, 'CJK Strokes'),
+ (0x2FF0, 0x2FFF, 'Ideographic Description Characters'),
+ (0xE0100, 0xE01EF, 'Variation Selectors Supplement'),
+ (0x3100, 0x312F, 'Bopomofo'),
+ (0x31A0, 0x31BF, 'Bopomofo Extended'),
+ (0xFF00, 0xFFEF, 'Halfwidth and Fullwidth Forms'),
+ (0x3040, 0x309F, 'Hiragana'),
+ (0x30A0, 0x30FF, 'Katakana'),
+ (0x31F0, 0x31FF, 'Katakana Phonetic Extensions'),
+ (0x1B000, 0x1B0FF, 'Kana Supplement'),
+ (0xAC00, 0xD7AF, 'Hangul Syllables'),
+ (0x1100, 0x11FF, 'Hangul Jamo'),
+ (0xA960, 0xA97F, 'Hangul Jamo Extended A'),
+ (0xD7B0, 0xD7FF, 'Hangul Jamo Extended B'),
+ (0x3130, 0x318F, 'Hangul Compatibility Jamo'),
+ (0xA4D0, 0xA4FF, 'Lisu'),
+ (0x16F00, 0x16F9F, 'Miao'),
+ (0xA000, 0xA48F, 'Yi Syllables'),
+ (0xA490, 0xA4CF, 'Yi Radicals'),
+]
+
+def is_CJK(c):
+ n = ord(c)
+ for imin,imax,name in CJK_INTERVALS:
+ if n>=imin and n<=imax: return True
+ return False
+
+
+def prepare_seed(seed):
+ # normalize
+ seed = unicodedata.normalize('NFKD', unicode(seed))
+ # lower
+ seed = seed.lower()
+ # remove accents
+ seed = u''.join([c for c in seed if not unicodedata.combining(c)])
+ # normalize whitespaces
+ seed = u' '.join(seed.split())
+ # remove whitespaces between CJK
+ seed = u''.join([seed[i] for i in range(len(seed)) if not (seed[i] in string.whitespace and is_CJK(seed[i-1]) and is_CJK(seed[i+1]))])
+ return seed
+
+
filenames = {
'en':'english.txt',
'es':'spanish.txt',
@@ -63,19 +117,9 @@ class Mnemonic(object):
@classmethod
def mnemonic_to_seed(self, mnemonic, passphrase):
PBKDF2_ROUNDS = 2048
- mnemonic = self.prepare_seed(mnemonic)
+ mnemonic = prepare_seed(mnemonic)
return pbkdf2.PBKDF2(mnemonic, 'mnemonic' + passphrase, iterations = PBKDF2_ROUNDS, macmodule = hmac, digestmodule = hashlib.sha512).read(64)
- @classmethod
- def prepare_seed(self, seed):
- # normalize
- seed = unicodedata.normalize('NFKD', unicode(seed))
- # lower
- seed = seed.lower()
- # remove accents and whitespaces
- seed = u''.join([c for c in seed if not unicodedata.combining(c) and not c in string.whitespace])
- return seed
-
def mnemonic_encode(self, i):
n = len(self.wordlist)
words = []
@@ -120,4 +164,3 @@ class Mnemonic(object):
break
print_error('%d words'%len(seed.split()))
return seed
-
diff --git a/lib/version.py b/lib/version.py
@@ -1,6 +1,6 @@
ELECTRUM_VERSION = "2.0" # version of the client package
PROTOCOL_VERSION = '0.9' # protocol version requested
-NEW_SEED_VERSION = 9 # electrum versions >= 2.0
+NEW_SEED_VERSION = 10 # electrum versions >= 2.0
OLD_SEED_VERSION = 4 # electrum versions < 2.0