Update to support looking up mnemonic by just the first 4 letters of each word (#16704)

Co-authored-by: Kyle Altendorf <sda@fstab.net>
This commit is contained in:
Chris Marslender 2023-11-01 09:52:52 -07:00 committed by GitHub
parent 0a4d649fdf
commit 53435588a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 93 additions and 25 deletions

View File

@ -87,11 +87,31 @@ def bytes_to_mnemonic(mnemonic_bytes: bytes) -> str:
return " ".join(mnemonics)
def bytes_from_mnemonic(mnemonic_str: str) -> bytes:
def mnemonic_from_short_words(mnemonic_str: str) -> str:
"""
Since the first 4 letters of each word is unique (or the full word, if less than 4 characters), and its common
practice to only store the first 4 letters of each word in many offline storage solutions, also support looking
up words by the first 4 characters
"""
mnemonic: List[str] = mnemonic_str.split(" ")
if len(mnemonic) not in [12, 15, 18, 21, 24]:
raise ValueError("Invalid mnemonic length")
four_char_dict = {word[:4]: word for word in bip39_word_list().splitlines()}
full_words: List[str] = []
for word in mnemonic:
full_word = four_char_dict.get(word[:4])
if full_word is None:
raise ValueError(f"{word!r} is not in the mnemonic dictionary; may be misspelled")
full_words.append(full_word)
return " ".join(full_words)
def bytes_from_mnemonic(mnemonic_str: str) -> bytes:
full_mnemonic_str = mnemonic_from_short_words(mnemonic_str)
mnemonic: List[str] = full_mnemonic_str.split(" ")
word_list = {word: i for i, word in enumerate(bip39_word_list().splitlines())}
bit_array = BitArray()
for i in range(0, len(mnemonic)):
@ -123,6 +143,10 @@ def mnemonic_to_seed(mnemonic: str) -> bytes:
"""
Uses BIP39 standard to derive a seed from entropy bytes.
"""
# If there are only ASCII characters (as typically expected in a seed phrase), we can check if its just shortened
# 4 letter versions of each word
if not any(ord(c) >= 128 for c in mnemonic):
mnemonic = mnemonic_from_short_words(mnemonic)
salt_str: str = "mnemonic"
salt = unicodedata.normalize("NFKD", salt_str).encode("utf-8")
mnemonic_normalized = unicodedata.normalize("NFKD", mnemonic).encode("utf-8")

View File

@ -1,6 +1,7 @@
from __future__ import annotations
import json
import pathlib
import random
from dataclasses import replace
from typing import Callable, List, Optional, Tuple
@ -8,6 +9,7 @@ from typing import Callable, List, Optional, Tuple
import pytest
from blspy import AugSchemeMPL, G1Element, PrivateKey
import tests
from chia.simulator.keyring import TempKeyring
from chia.types.blockchain_format.sized_bytes import bytes32
from chia.util.errors import (
@ -26,6 +28,7 @@ from chia.util.keychain import (
bytes_from_mnemonic,
bytes_to_mnemonic,
generate_mnemonic,
mnemonic_from_short_words,
mnemonic_to_seed,
)
@ -165,6 +168,23 @@ class TestKeychain:
assert bytes_to_mnemonic(entropy_bytes) == mnemonic
assert mnemonic_to_seed(mnemonic) == seed
def test_bip39_test_vectors_short(self):
"""
Tests that the first 4 letters of each mnemonic phrase matches as if it were the full phrase
"""
test_vectors_path = pathlib.Path(tests.__file__).parent.joinpath("util", "bip39_test_vectors.json")
with open(test_vectors_path) as f:
all_vectors = json.load(f)
for idx, [entropy_hex, full_mnemonic, seed, short_mnemonic] in enumerate(all_vectors["english"]):
entropy_bytes = bytes.fromhex(entropy_hex)
seed = bytes.fromhex(seed)
assert mnemonic_from_short_words(short_mnemonic) == full_mnemonic
assert bytes_from_mnemonic(short_mnemonic) == entropy_bytes
assert bytes_to_mnemonic(entropy_bytes) == full_mnemonic
assert mnemonic_to_seed(short_mnemonic) == seed
def test_utf8_nfkd(self):
# Test code from trezor:
# Copyright (c) 2013 Pavol Rusnak

View File

@ -3,122 +3,146 @@
[
"00000000000000000000000000000000",
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
"5eb00bbddcf069084889a8ab9155568165f5c453ccb85e70811aaed6f6da5fc19a5ac40b389cd370d086206dec8aa6c43daea6690f20ad3d8d48b2d2ce9e38e4"
"5eb00bbddcf069084889a8ab9155568165f5c453ccb85e70811aaed6f6da5fc19a5ac40b389cd370d086206dec8aa6c43daea6690f20ad3d8d48b2d2ce9e38e4",
"aban aban aban aban aban aban aban aban aban aban aban abou"
],
[
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f",
"legal winner thank year wave sausage worth useful legal winner thank yellow",
"878386efb78845b3355bd15ea4d39ef97d179cb712b77d5c12b6be415fffeffe5f377ba02bf3f8544ab800b955e51fbff09828f682052a20faa6addbbddfb096"
"878386efb78845b3355bd15ea4d39ef97d179cb712b77d5c12b6be415fffeffe5f377ba02bf3f8544ab800b955e51fbff09828f682052a20faa6addbbddfb096",
"lega winn than year wave saus wort usef lega winn than yell"
],
[
"80808080808080808080808080808080",
"letter advice cage absurd amount doctor acoustic avoid letter advice cage above",
"77d6be9708c8218738934f84bbbb78a2e048ca007746cb764f0673e4b1812d176bbb173e1a291f31cf633f1d0bad7d3cf071c30e98cd0688b5bcce65ecaceb36"
"77d6be9708c8218738934f84bbbb78a2e048ca007746cb764f0673e4b1812d176bbb173e1a291f31cf633f1d0bad7d3cf071c30e98cd0688b5bcce65ecaceb36",
"lett advi cage absu amou doct acou avoi lett advi cage abov"
],
[
"ffffffffffffffffffffffffffffffff",
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong",
"b6a6d8921942dd9806607ebc2750416b289adea669198769f2e15ed926c3aa92bf88ece232317b4ea463e84b0fcd3b53577812ee449ccc448eb45e6f544e25b6"
"b6a6d8921942dd9806607ebc2750416b289adea669198769f2e15ed926c3aa92bf88ece232317b4ea463e84b0fcd3b53577812ee449ccc448eb45e6f544e25b6",
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wron"
],
[
"000000000000000000000000000000000000000000000000",
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
"4975bb3d1faf5308c86a30893ee903a976296609db223fd717e227da5a813a34dc1428b71c84a787fc51f3b9f9dc28e9459f48c08bd9578e9d1b170f2d7ea506"
"4975bb3d1faf5308c86a30893ee903a976296609db223fd717e227da5a813a34dc1428b71c84a787fc51f3b9f9dc28e9459f48c08bd9578e9d1b170f2d7ea506",
"aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban agen"
],
[
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f",
"legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will",
"b059400ce0f55498a5527667e77048bb482ff6daa16c37b4b9e8af70c85b3f4df588004f19812a1a027c9a51e5e94259a560268e91cd10e206451a129826e740"
"b059400ce0f55498a5527667e77048bb482ff6daa16c37b4b9e8af70c85b3f4df588004f19812a1a027c9a51e5e94259a560268e91cd10e206451a129826e740",
"lega winn than year wave saus wort usef lega winn than year wave saus wort usef lega will"
],
[
"808080808080808080808080808080808080808080808080",
"letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always",
"04d5f77103510c41d610f7f5fb3f0badc77c377090815cee808ea5d2f264fdfabf7c7ded4be6d4c6d7cdb021ba4c777b0b7e57ca8aa6de15aeb9905dba674d66"
"04d5f77103510c41d610f7f5fb3f0badc77c377090815cee808ea5d2f264fdfabf7c7ded4be6d4c6d7cdb021ba4c777b0b7e57ca8aa6de15aeb9905dba674d66",
"lett advi cage absu amou doct acou avoi lett advi cage absu amou doct acou avoi lett alwa"
],
[
"ffffffffffffffffffffffffffffffffffffffffffffffff",
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when",
"d2911131a6dda23ac4441d1b66e2113ec6324354523acfa20899a2dcb3087849264e91f8ec5d75355f0f617be15369ffa13c3d18c8156b97cd2618ac693f759f"
"d2911131a6dda23ac4441d1b66e2113ec6324354523acfa20899a2dcb3087849264e91f8ec5d75355f0f617be15369ffa13c3d18c8156b97cd2618ac693f759f",
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when"
],
[
"0000000000000000000000000000000000000000000000000000000000000000",
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
"408b285c123836004f4b8842c89324c1f01382450c0d439af345ba7fc49acf705489c6fc77dbd4e3dc1dd8cc6bc9f043db8ada1e243c4a0eafb290d399480840"
"408b285c123836004f4b8842c89324c1f01382450c0d439af345ba7fc49acf705489c6fc77dbd4e3dc1dd8cc6bc9f043db8ada1e243c4a0eafb290d399480840",
"aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban art"
],
[
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f",
"legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title",
"761914478ebf6fe16185749372e91549361af22b386de46322cf8b1ba7e92e80c4af05196f742be1e63aab603899842ddadf4e7248d8e43870a4b6ff9bf16324"
"761914478ebf6fe16185749372e91549361af22b386de46322cf8b1ba7e92e80c4af05196f742be1e63aab603899842ddadf4e7248d8e43870a4b6ff9bf16324",
"lega winn than year wave saus wort usef lega winn than year wave saus wort usef lega winn than year wave saus wort titl"
],
[
"8080808080808080808080808080808080808080808080808080808080808080",
"letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless",
"848bbe19cad445e46f35fd3d1a89463583ac2b60b5eb4cfcf955731775a5d9e17a81a71613fed83f1ae27b408478fdec2bbc75b5161d1937aa7cdf4ad686ef5f"
"848bbe19cad445e46f35fd3d1a89463583ac2b60b5eb4cfcf955731775a5d9e17a81a71613fed83f1ae27b408478fdec2bbc75b5161d1937aa7cdf4ad686ef5f",
"lett advi cage absu amou doct acou avoi lett advi cage absu amou doct acou avoi lett advi cage absu amou doct acou bles"
],
[
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote",
"e28a37058c7f5112ec9e16a3437cf363a2572d70b6ceb3b6965447623d620f14d06bb321a26b33ec15fcd84a3b5ddfd5520e230c924c87aaa0d559749e044fef"
"e28a37058c7f5112ec9e16a3437cf363a2572d70b6ceb3b6965447623d620f14d06bb321a26b33ec15fcd84a3b5ddfd5520e230c924c87aaa0d559749e044fef",
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote"
],
[
"9e885d952ad362caeb4efe34a8e91bd2",
"ozone drill grab fiber curtain grace pudding thank cruise elder eight picnic",
"e2f88a043776c828063d4c3c97173944d32cf847a925b6e40b0b8bd0b4bead3ba734bdda5250d4698b310a71c9934e1a48e562315ce22bf85f89459df0e73a6c"
"e2f88a043776c828063d4c3c97173944d32cf847a925b6e40b0b8bd0b4bead3ba734bdda5250d4698b310a71c9934e1a48e562315ce22bf85f89459df0e73a6c",
"ozon dril grab fibe curt grac pudd than crui elde eigh picn"
],
[
"6610b25967cdcca9d59875f5cb50b0ea75433311869e930b",
"gravity machine north sort system female filter attitude volume fold club stay feature office ecology stable narrow fog",
"31736b4f31612ece84404c74a5d3b938a092480eb89c11b81491f1a3657eb2fe50024610fbe814df55913a87ef741020fcf076a75a29aea0aba638126ba4c8bb"
"31736b4f31612ece84404c74a5d3b938a092480eb89c11b81491f1a3657eb2fe50024610fbe814df55913a87ef741020fcf076a75a29aea0aba638126ba4c8bb",
"grav mach nort sort syst fema filt atti volu fold club stay feat offi ecol stab narr fog"
],
[
"68a79eaca2324873eacc50cb9c6eca8cc68ea5d936f98787c60c7ebc74e6ce7c",
"hamster diagram private dutch cause delay private meat slide toddler razor book happy fancy gospel tennis maple dilemma loan word shrug inflict delay length",
"17e4b5661796eeff8904550f8572289317ece7c1cc1316469f8f4c986c1ffd7b9f4c3aeac3e1713ffc21fa33707d09d57a2ece358d72111ef7c7658e7b33f2d5"
"17e4b5661796eeff8904550f8572289317ece7c1cc1316469f8f4c986c1ffd7b9f4c3aeac3e1713ffc21fa33707d09d57a2ece358d72111ef7c7658e7b33f2d5",
"hams diag priv dutc caus dela priv meat slid todd razo book happ fanc gosp tenn mapl dile loan word shrug infl dela leng"
],
[
"c0ba5a8e914111210f2bd131f3d5e08d",
"scheme spot photo card baby mountain device kick cradle pact join borrow",
"00e1e39a39e23735adab690d0ffbefda6cacc063b4a5fcc605de060bd370adc54c94370d966b9a3fae5ed16bd58a02224cbefca4146a083951b70be2a2ce3dcc"
"00e1e39a39e23735adab690d0ffbefda6cacc063b4a5fcc605de060bd370adc54c94370d966b9a3fae5ed16bd58a02224cbefca4146a083951b70be2a2ce3dcc",
"sche spot phot card baby moun devi kick crad pact join borr"
],
[
"6d9be1ee6ebd27a258115aad99b7317b9c8d28b6d76431c3",
"horn tenant knee talent sponsor spell gate clip pulse soap slush warm silver nephew swap uncle crack brave",
"e893fc34fa2a78ceaaea78c246b69257ad283fa538d88f3c4520beb618a2062b8ec4920ed1793fff6ad443523ed18c03da433004d0a1e9497e194621607bc9e2"
"e893fc34fa2a78ceaaea78c246b69257ad283fa538d88f3c4520beb618a2062b8ec4920ed1793fff6ad443523ed18c03da433004d0a1e9497e194621607bc9e2",
"horn tena knee tale spon spel gate clip puls soap slus warm silv neph swap uncl crac brav"
],
[
"9f6a2878b2520799a44ef18bc7df394e7061a224d2c33cd015b157d746869863",
"panda eyebrow bullet gorilla call smoke muffin taste mesh discover soft ostrich alcohol speed nation flash devote level hobby quick inner drive ghost inside",
"3e066d7dee2dbf8fcd3fe240a3975658ca118a8f6f4ca81cf99104944604b05a5090a79d99e545704b914ca0397fedb82fd00fd6a72098703709c891a065ee49"
"3e066d7dee2dbf8fcd3fe240a3975658ca118a8f6f4ca81cf99104944604b05a5090a79d99e545704b914ca0397fedb82fd00fd6a72098703709c891a065ee49",
"pand eyeb bull gori call smok muff tast mesh disc soft ostr alco spee nati flas devo leve hobb quic inne driv ghos insi"
],
[
"23db8160a31d3e0dca3688ed941adbf3",
"cat swing flag economy stadium alone churn speed unique patch report train",
"7ea73b3a398f8a71f7dde589d972b0358d3fa8b9e91317ecc544e42752b1bb251a1926b1f4c69eec0a80c0396aa0f7df29f7d73411d3106eba539f3d584fcdf8"
"7ea73b3a398f8a71f7dde589d972b0358d3fa8b9e91317ecc544e42752b1bb251a1926b1f4c69eec0a80c0396aa0f7df29f7d73411d3106eba539f3d584fcdf8",
"cat swin flag econ stad alon chur spee uniq patc repo trai"
],
[
"8197a4a47f0425faeaa69deebc05ca29c0a5b5cc76ceacc0",
"light rule cinnamon wrap drastic word pride squirrel upgrade then income fatal apart sustain crack supply proud access",
"d0ca8861283a7124515e825b7a06de8e0ad0dd5ac7888013efe6e3c300d4745bbd2c729f3355d769d23718579e7b735999a8f0b38e22b5bff45c9085af449056"
"d0ca8861283a7124515e825b7a06de8e0ad0dd5ac7888013efe6e3c300d4745bbd2c729f3355d769d23718579e7b735999a8f0b38e22b5bff45c9085af449056",
"ligh rule cinn wrap dras word prid squi upgr then inco fata apar sust crac supp prou acce"
],
[
"066dca1a2bb7e8a1db2832148ce9933eea0f3ac9548d793112d9a95c9407efad",
"all hour make first leader extend hole alien behind guard gospel lava path output census museum junior mass reopen famous sing advance salt reform",
"fc795be0c3f18c50dddb34e72179dc597d64055497ecc1e69e2e56a5409651bc139aae8070d4df0ea14d8d2a518a9a00bb1cc6e92e053fe34051f6821df9164c"
"fc795be0c3f18c50dddb34e72179dc597d64055497ecc1e69e2e56a5409651bc139aae8070d4df0ea14d8d2a518a9a00bb1cc6e92e053fe34051f6821df9164c",
"all hour make firs lead exte hole alie behi guar gosp lava path outp cens muse juni mass reop famo sing adva salt refo"
],
[
"f30f8c1da665478f49b001d94c5fc452",
"vessel ladder alter error federal sibling chat ability sun glass valve picture",
"e2d7f9a462875c1325f44f321392edc8eaafebf1547c89d72d10b41b4ee23af3fb0ab010f39f5cbea3b3aa671161b58262b6a508bcbe2d34ee272a942534d45f"
"e2d7f9a462875c1325f44f321392edc8eaafebf1547c89d72d10b41b4ee23af3fb0ab010f39f5cbea3b3aa671161b58262b6a508bcbe2d34ee272a942534d45f",
"vess ladd alte erro fede sibl chat abil sun glas valv pict"
],
[
"c10ec20dc3cd9f652c7fac2f1230f7a3c828389a14392f05",
"scissors invite lock maple supreme raw rapid void congress muscle digital elegant little brisk hair mango congress clump",
"a555426999448df9022c3afc2ed0e4aebff3a0ac37d8a395f81412e14994efc960ed168d39a80478e0467a3d5cfc134fef2767c1d3a27f18e3afeb11bfc8e6ad"
"a555426999448df9022c3afc2ed0e4aebff3a0ac37d8a395f81412e14994efc960ed168d39a80478e0467a3d5cfc134fef2767c1d3a27f18e3afeb11bfc8e6ad",
"scis invi lock mapl supr raw rapi void cong musc digi eleg litt bris hair mang cong clum"
],
[
"f585c11aec520db57dd353c69554b21a89b20fb0650966fa0a9d6f74fd989d8f",
"void come effort suffer camp survey warrior heavy shoot primary clutch crush open amazing screen patrol group space point ten exist slush involve unfold",
"b873212f885ccffbf4692afcb84bc2e55886de2dfa07d90f5c3c239abc31c0a6ce047e30fd8bf6a281e71389aa82d73df74c7bbfb3b06b4639a5cee775cccd3c"
"b873212f885ccffbf4692afcb84bc2e55886de2dfa07d90f5c3c239abc31c0a6ce047e30fd8bf6a281e71389aa82d73df74c7bbfb3b06b4639a5cee775cccd3c",
"void come effo suff camp surv warr heav shoo prim clut crus open amaz scre patr grou spac poin ten exis slus invo unfo"
]
]
}