lbry-sdk/lbry/wallet/mnemonic.py

58 lines
1.4 KiB
Python
Raw Normal View History

2018-05-25 08:03:25 +02:00
import hashlib
2020-05-10 00:33:23 +02:00
import asyncio
2018-05-25 08:03:25 +02:00
import unicodedata
from binascii import hexlify
2020-05-10 00:33:23 +02:00
from secrets import randbits
2018-05-25 08:03:25 +02:00
from lbry.crypto.hash import hmac_sha512
2020-05-10 00:33:23 +02:00
from . import words
2018-05-25 08:03:25 +02:00
2020-05-10 00:33:23 +02:00
def get_languages():
return words.languages
2018-05-25 08:03:25 +02:00
2020-05-18 14:26:36 +02:00
def normalize(phrase: str) -> str:
return ' '.join(unicodedata.normalize('NFKD', phrase).lower().split())
2018-05-25 08:03:25 +02:00
2020-05-18 14:26:36 +02:00
def is_phrase_valid(language, phrase):
2020-05-10 00:33:23 +02:00
local_words = getattr(words, language)
2020-05-18 14:26:36 +02:00
for word in normalize(phrase).split():
2020-05-10 00:33:23 +02:00
if word not in local_words:
return False
2020-05-18 14:26:36 +02:00
return bool(phrase)
2018-05-25 08:03:25 +02:00
2020-05-18 14:26:36 +02:00
def sync_generate_phrase(language: str) -> str:
2020-05-10 00:33:23 +02:00
local_words = getattr(words, language)
entropy = randbits(132)
nonce = 0
while True:
nonce += 1
i = entropy + nonce
w = []
while i:
w.append(local_words[i % 2048])
i //= 2048
seed = ' '.join(w)
if hexlify(hmac_sha512(b"Seed version", seed.encode())).startswith(b"01"):
break
return seed
2018-05-25 08:03:25 +02:00
2020-05-18 14:26:36 +02:00
def sync_derive_key_from_phrase(phrase: str) -> bytes:
return hashlib.pbkdf2_hmac('sha512', normalize(phrase).encode(), b'lbryum', 2048)
2018-05-25 08:03:25 +02:00
2020-05-18 14:26:36 +02:00
async def generate_phrase(language: str) -> str:
2020-05-10 00:33:23 +02:00
return await asyncio.get_running_loop().run_in_executor(
2020-05-18 14:26:36 +02:00
None, sync_generate_phrase, language
2020-05-10 00:33:23 +02:00
)
2018-05-25 08:03:25 +02:00
2020-05-18 14:26:36 +02:00
async def derive_key_from_phrase(phrase: str) -> bytes:
2020-05-10 00:33:23 +02:00
return await asyncio.get_running_loop().run_in_executor(
2020-05-18 14:26:36 +02:00
None, sync_derive_key_from_phrase, phrase
2020-05-10 00:33:23 +02:00
)