commit f767d41409ad20e60bf535fb78468f276679b6fb
parent 75e30ddc9dd97f11db19d609d0d1d4780dc3885a
Author: SomberNight <somber.night@protonmail.com>
Date: Wed, 14 Nov 2018 18:58:27 +0100
tests: spanish test case for mnemonic.py, and refactoring
Diffstat:
2 files changed, 103 insertions(+), 51 deletions(-)
diff --git a/electrum/tests/test_mnemonic.py b/electrum/tests/test_mnemonic.py
@@ -1,68 +1,120 @@
+from typing import NamedTuple, Optional
+
from electrum import keystore
from electrum import mnemonic
from electrum import old_mnemonic
from electrum.util import bh2u, bfh
from electrum.bitcoin import is_new_seed
-from electrum.version import SEED_PREFIX_SW
+from electrum.version import SEED_PREFIX_SW, SEED_PREFIX
from . import SequentialTestCase
-from .test_wallet_vertical import UNICODE_HORROR
-
-
-SEED_WORDS_JAPANESE = 'なのか ひろい しなん まなぶ つぶす さがす おしゃれ かわく おいかける けさき かいとう さたん'
-assert bh2u(SEED_WORDS_JAPANESE.encode('utf8')) == 'e381aae381aee3818b20e381b2e3828de3818420e38197e381aae3829320e381bee381aae381b5e3829920e381a4e381b5e38299e3819920e38195e3818be38299e3819920e3818ae38197e38283e3828c20e3818be3828fe3818f20e3818ae38184e3818be38191e3828b20e38191e38195e3818d20e3818be38184e381a8e3818620e38195e3819fe38293'
-
-SEED_WORDS_CHINESE = '眼 悲 叛 改 节 跃 衡 响 疆 股 遂 冬'
-assert bh2u(SEED_WORDS_CHINESE.encode('utf8')) == 'e79cbc20e682b220e58f9b20e694b920e88a8220e8b78320e8a1a120e5938d20e7968620e882a120e9818220e586ac'
-
-PASSPHRASE_CHINESE = '给我一些测试向量谷歌'
-assert bh2u(PASSPHRASE_CHINESE.encode('utf8')) == 'e7bb99e68891e4b880e4ba9be6b58be8af95e59091e9878fe8b0b7e6ad8c'
+from .test_wallet_vertical import UNICODE_HORROR, UNICODE_HORROR_HEX
+
+
+class SeedTestCase(NamedTuple):
+ words: str
+ bip32_seed: str
+ lang: Optional[str] = 'en'
+ words_hex: Optional[str] = None
+ entropy: Optional[int] = None
+ passphrase: Optional[str] = None
+ passphrase_hex: Optional[str] = None
+ seed_version: str = SEED_PREFIX
+
+
+SEED_TEST_CASES = {
+ 'english': SeedTestCase(
+ words='wild father tree among universe such mobile favorite target dynamic credit identify',
+ seed_version=SEED_PREFIX_SW,
+ bip32_seed='aac2a6302e48577ab4b46f23dbae0774e2e62c796f797d0a1b5faeb528301e3064342dafb79069e7c4c6b8c38ae11d7a973bec0d4f70626f8cc5184a8d0b0756'),
+ 'english_with_passphrase': SeedTestCase(
+ words='wild father tree among universe such mobile favorite target dynamic credit identify',
+ seed_version=SEED_PREFIX_SW,
+ passphrase='Did you ever hear the tragedy of Darth Plagueis the Wise?',
+ bip32_seed='4aa29f2aeb0127efb55138ab9e7be83b36750358751906f86c662b21a1ea1370f949e6d1a12fa56d3d93cadda93038c76ac8118597364e46f5156fde6183c82f'),
+ 'japanese': SeedTestCase(
+ lang='ja',
+ words='なのか ひろい しなん まなぶ つぶす さがす おしゃれ かわく おいかける けさき かいとう さたん',
+ words_hex='e381aae381aee3818b20e381b2e3828de3818420e38197e381aae3829320e381bee381aae381b5e3829920e381a4e381b5e38299e3819920e38195e3818be38299e3819920e3818ae38197e38283e3828c20e3818be3828fe3818f20e3818ae38184e3818be38191e3828b20e38191e38195e3818d20e3818be38184e381a8e3818620e38195e3819fe38293',
+ entropy=1938439226660562861250521787963972783469,
+ bip32_seed='d3eaf0e44ddae3a5769cb08a26918e8b308258bcb057bb704c6f69713245c0b35cb92c03df9c9ece5eff826091b4e74041e010b701d44d610976ce8bfb66a8ad'),
+ 'japanese_with_passphrase': SeedTestCase(
+ lang='ja',
+ words='なのか ひろい しなん まなぶ つぶす さがす おしゃれ かわく おいかける けさき かいとう さたん',
+ words_hex='e381aae381aee3818b20e381b2e3828de3818420e38197e381aae3829320e381bee381aae381b5e3829920e381a4e381b5e38299e3819920e38195e3818be38299e3819920e3818ae38197e38283e3828c20e3818be3828fe3818f20e3818ae38184e3818be38191e3828b20e38191e38195e3818d20e3818be38184e381a8e3818620e38195e3819fe38293',
+ entropy=1938439226660562861250521787963972783469,
+ passphrase=UNICODE_HORROR,
+ passphrase_hex=UNICODE_HORROR_HEX,
+ bip32_seed='251ee6b45b38ba0849e8f40794540f7e2c6d9d604c31d68d3ac50c034f8b64e4bc037c5e1e985a2fed8aad23560e690b03b120daf2e84dceb1d7857dda042457'),
+ 'chinese': SeedTestCase(
+ lang='zh',
+ words='眼 悲 叛 改 节 跃 衡 响 疆 股 遂 冬',
+ words_hex='e79cbc20e682b220e58f9b20e694b920e88a8220e8b78320e8a1a120e5938d20e7968620e882a120e9818220e586ac',
+ seed_version=SEED_PREFIX_SW,
+ entropy=3083737086352778425940060465574397809099,
+ bip32_seed='0b9077db7b5a50dbb6f61821e2d35e255068a5847e221138048a20e12d80b673ce306b6fe7ac174ebc6751e11b7037be6ee9f17db8040bb44f8466d519ce2abf'),
+ 'chinese_with_passphrase': SeedTestCase(
+ lang='zh',
+ words='眼 悲 叛 改 节 跃 衡 响 疆 股 遂 冬',
+ words_hex='e79cbc20e682b220e58f9b20e694b920e88a8220e8b78320e8a1a120e5938d20e7968620e882a120e9818220e586ac',
+ seed_version=SEED_PREFIX_SW,
+ entropy=3083737086352778425940060465574397809099,
+ passphrase='给我一些测试向量谷歌',
+ passphrase_hex='e7bb99e68891e4b880e4ba9be6b58be8af95e59091e9878fe8b0b7e6ad8c',
+ bip32_seed='6c03dd0615cf59963620c0af6840b52e867468cc64f20a1f4c8155705738e87b8edb0fc8a6cee4085776cb3a629ff88bb1a38f37085efdbf11ce9ec5a7fa5f71'),
+ 'spanish': SeedTestCase(
+ lang='es',
+ words='almíbar tibio superar vencer hacha peatón príncipe matar consejo polen vehículo odisea',
+ words_hex='616c6d69cc8162617220746962696f20737570657261722076656e63657220686163686120706561746fcc816e20707269cc816e63697065206d6174617220636f6e73656a6f20706f6c656e2076656869cc8163756c6f206f6469736561',
+ entropy=3423992296655289706780599506247192518735,
+ bip32_seed='18bffd573a960cc775bbd80ed60b7dc00bc8796a186edebe7fc7cf1f316da0fe937852a969c5c79ded8255cdf54409537a16339fbe33fb9161af793ea47faa7a'),
+ 'spanish_with_passphrase': SeedTestCase(
+ lang='es',
+ words='almíbar tibio superar vencer hacha peatón príncipe matar consejo polen vehículo odisea',
+ words_hex='616c6d69cc8162617220746962696f20737570657261722076656e63657220686163686120706561746fcc816e20707269cc816e63697065206d6174617220636f6e73656a6f20706f6c656e2076656869cc8163756c6f206f6469736561',
+ entropy=3423992296655289706780599506247192518735,
+ passphrase='araña difícil solución término cárcel',
+ passphrase_hex='6172616ecc83612064696669cc8163696c20736f6c7563696fcc816e207465cc81726d696e6f206361cc817263656c',
+ bip32_seed='363dec0e575b887cfccebee4c84fca5a3a6bed9d0e099c061fa6b85020b031f8fe3636d9af187bf432d451273c625e20f24f651ada41aae2c4ea62d87e9fa44c'),
+ 'spanish2': SeedTestCase(
+ lang='es',
+ words='equipo fiar auge langosta hacha calor trance cubrir carro pulmón oro áspero',
+ words_hex='65717569706f20666961722061756765206c616e676f7374612068616368612063616c6f72207472616e63652063756272697220636172726f2070756c6d6fcc816e206f726f2061cc81737065726f',
+ seed_version=SEED_PREFIX_SW,
+ entropy=448346710104003081119421156750490206837,
+ bip32_seed='001ebce6bfde5851f28a0d44aae5ae0c762b600daf3b33fc8fc630aee0d207646b6f98b18e17dfe3be0a5efe2753c7cdad95860adbbb62cecad4dedb88e02a64'),
+ 'spanish3': SeedTestCase(
+ lang='es',
+ words='vidrio jabón muestra pájaro capucha eludir feliz rotar fogata pez rezar oír',
+ words_hex='76696472696f206a61626fcc816e206d756573747261207061cc816a61726f206361707563686120656c756469722066656c697a20726f74617220666f676174612070657a2072657a6172206f69cc8172',
+ seed_version=SEED_PREFIX_SW,
+ entropy=3444792611339130545499611089352232093648,
+ passphrase='¡Viva España! repiten veinte pueblos y al hablar dan fe del ánimo español... ¡Marquen arado martillo y clarín',
+ passphrase_hex='c2a1566976612045737061c3b16121207265706974656e207665696e746520707565626c6f73207920616c206861626c61722064616e2066652064656c20c3a16e696d6f2065737061c3b16f6c2e2e2e20c2a14d61727175656e20617261646f206d617274696c6c6f207920636c6172c3ad6e',
+ bip32_seed='c274665e5453c72f82b8444e293e048d700c59bf000cacfba597629d202dcf3aab1cf9c00ba8d3456b7943428541fed714d01d8a0a4028fc3a9bb33d981cb49f'),
+}
class Test_NewMnemonic(SequentialTestCase):
def test_mnemonic_to_seed_basic(self):
+ # note: not a valid electrum seed
seed = mnemonic.Mnemonic.mnemonic_to_seed(mnemonic='foobar', passphrase='none')
self.assertEqual('741b72fd15effece6bfe5a26a52184f66811bd2be363190e07a42cca442b1a5bb22b3ad0eb338197287e6d314866c7fba863ac65d3f156087a5052ebc7157fce',
bh2u(seed))
- def test_mnemonic_to_seed_japanese(self):
- words = SEED_WORDS_JAPANESE
- self.assertTrue(is_new_seed(words))
-
- m = mnemonic.Mnemonic(lang='ja')
- self.assertEqual(1938439226660562861250521787963972783469, m.mnemonic_decode(words))
-
- seed = mnemonic.Mnemonic.mnemonic_to_seed(mnemonic=words, passphrase='')
- self.assertEqual('d3eaf0e44ddae3a5769cb08a26918e8b308258bcb057bb704c6f69713245c0b35cb92c03df9c9ece5eff826091b4e74041e010b701d44d610976ce8bfb66a8ad',
- bh2u(seed))
-
- def test_mnemonic_to_seed_japanese_with_unicode_horror(self):
- words = SEED_WORDS_JAPANESE
- self.assertTrue(is_new_seed(words))
-
- seed = mnemonic.Mnemonic.mnemonic_to_seed(mnemonic=words, passphrase=UNICODE_HORROR)
- self.assertEqual('251ee6b45b38ba0849e8f40794540f7e2c6d9d604c31d68d3ac50c034f8b64e4bc037c5e1e985a2fed8aad23560e690b03b120daf2e84dceb1d7857dda042457',
- bh2u(seed))
-
- def test_mnemonic_to_seed_chinese(self):
- words = SEED_WORDS_CHINESE
- self.assertTrue(is_new_seed(words, prefix=SEED_PREFIX_SW))
-
- m = mnemonic.Mnemonic(lang='zh')
- self.assertEqual(3083737086352778425940060465574397809099, m.mnemonic_decode(words))
-
- seed = mnemonic.Mnemonic.mnemonic_to_seed(mnemonic=words, passphrase='')
- self.assertEqual('0b9077db7b5a50dbb6f61821e2d35e255068a5847e221138048a20e12d80b673ce306b6fe7ac174ebc6751e11b7037be6ee9f17db8040bb44f8466d519ce2abf',
- bh2u(seed))
-
- def test_mnemonic_to_seed_chinese_with_passphrase(self):
- words = SEED_WORDS_CHINESE
- passphrase = PASSPHRASE_CHINESE
- self.assertTrue(is_new_seed(words, prefix=SEED_PREFIX_SW))
- seed = mnemonic.Mnemonic.mnemonic_to_seed(mnemonic=words, passphrase=passphrase)
- self.assertEqual('6c03dd0615cf59963620c0af6840b52e867468cc64f20a1f4c8155705738e87b8edb0fc8a6cee4085776cb3a629ff88bb1a38f37085efdbf11ce9ec5a7fa5f71',
- bh2u(seed))
+ def test_mnemonic_to_seed(self):
+ for test_name, test in SEED_TEST_CASES.items():
+ if test.words_hex is not None:
+ self.assertEqual(test.words_hex, bh2u(test.words.encode('utf8')), msg=test_name)
+ self.assertTrue(is_new_seed(test.words, prefix=test.seed_version), msg=test_name)
+ m = mnemonic.Mnemonic(lang=test.lang)
+ if test.entropy is not None:
+ self.assertEqual(test.entropy, m.mnemonic_decode(test.words), msg=test_name)
+ if test.passphrase_hex is not None:
+ self.assertEqual(test.passphrase_hex, bh2u(test.passphrase.encode('utf8')), msg=test_name)
+ seed = mnemonic.Mnemonic.mnemonic_to_seed(mnemonic=test.words, passphrase=test.passphrase)
+ self.assertEqual(test.bip32_seed, bh2u(seed), msg=test_name)
def test_random_seeds(self):
iters = 10
diff --git a/electrum/tests/test_wallet_vertical.py b/electrum/tests/test_wallet_vertical.py
@@ -19,8 +19,8 @@ from . import SequentialTestCase
from .test_bitcoin import needs_test_with_all_ecc_implementations
-_UNICODE_HORROR_HEX = 'e282bf20f09f988020f09f98882020202020e3818620e38191e3819fe381be20e3828fe3828b2077cda2cda2cd9d68cda16fcda2cda120ccb8cda26bccb5cd9f6eccb4cd98c7ab77ccb8cc9b73cd9820cc80cc8177cd98cda2e1b8a9ccb561d289cca1cda27420cca7cc9568cc816fccb572cd8fccb5726f7273cca120ccb6cda1cda06cc4afccb665cd9fcd9f20ccb6cd9d696ecda220cd8f74cc9568ccb7cca1cd9f6520cd9fcd9f64cc9b61cd9c72cc95cda16bcca2cca820cda168ccb465cd8f61ccb7cca2cca17274cc81cd8f20ccb4ccb7cda0c3b2ccb5ccb666ccb82075cca7cd986ec3adcc9bcd9c63cda2cd8f6fccb7cd8f64ccb8cda265cca1cd9d3fcd9e'
-UNICODE_HORROR = bfh(_UNICODE_HORROR_HEX).decode('utf-8')
+UNICODE_HORROR_HEX = 'e282bf20f09f988020f09f98882020202020e3818620e38191e3819fe381be20e3828fe3828b2077cda2cda2cd9d68cda16fcda2cda120ccb8cda26bccb5cd9f6eccb4cd98c7ab77ccb8cc9b73cd9820cc80cc8177cd98cda2e1b8a9ccb561d289cca1cda27420cca7cc9568cc816fccb572cd8fccb5726f7273cca120ccb6cda1cda06cc4afccb665cd9fcd9f20ccb6cd9d696ecda220cd8f74cc9568ccb7cca1cd9f6520cd9fcd9f64cc9b61cd9c72cc95cda16bcca2cca820cda168ccb465cd8f61ccb7cca2cca17274cc81cd8f20ccb4ccb7cda0c3b2ccb5ccb666ccb82075cca7cd986ec3adcc9bcd9c63cda2cd8f6fccb7cd8f64ccb8cda265cca1cd9d3fcd9e'
+UNICODE_HORROR = bfh(UNICODE_HORROR_HEX).decode('utf-8')
assert UNICODE_HORROR == '₿ 😀 😈 う けたま わる w͢͢͝h͡o͢͡ ̸͢k̵͟n̴͘ǫw̸̛s͘ ̀́w͘͢ḩ̵a҉̡͢t ̧̕h́o̵r͏̵rors̡ ̶͡͠lį̶e͟͟ ̶͝in͢ ͏t̕h̷̡͟e ͟͟d̛a͜r̕͡k̢̨ ͡h̴e͏a̷̢̡rt́͏ ̴̷͠ò̵̶f̸ u̧͘ní̛͜c͢͏o̷͏d̸͢e̡͝?͞'