Skip to content

Commit

Permalink
feat: add mnemonic generation from password
Browse files Browse the repository at this point in the history
  • Loading branch information
gtors committed Apr 18, 2024
1 parent b2e8fe8 commit 3bb235b
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 22 deletions.
16 changes: 11 additions & 5 deletions tonsdk_ng/crypto/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
from ._keystore import generate_keystore_key, generate_new_keystore
from ._mnemonic import mnemonic_is_valid, mnemonic_new, mnemonic_to_wallet_key
from ._mnemonic import (
mnemonic_from_password,
mnemonic_is_valid,
mnemonic_new,
mnemonic_to_wallet_key,
)
from ._utils import private_key_to_public_key, verify_sign

__all__ = [
"generate_key_pair",
"generate_keystore_key",
"generate_new_keystore",
"mnemonic_from_password",
"mnemonic_is_valid",
"mnemonic_new",
"mnemonic_to_wallet_key",
"mnemonic_is_valid",
"generate_new_keystore",
"generate_keystore_key",
"private_key_to_public_key",
"verify_sign",
"generate_key_pair",
]
39 changes: 22 additions & 17 deletions tonsdk_ng/crypto/_mnemonic.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import hashlib
import hmac
import random

from nacl.bindings import crypto_sign_seed_keypair

Expand All @@ -14,44 +15,35 @@ def mnemonic_is_valid(mnemo_words: list[str]) -> bool:
)


def mnemonic_to_entropy(mnemo_words: list[str], password: str | None = None):
# TODO: implement password
def mnemonic_to_entropy(mnemo_words: list[str]):
sign = hmac.new(
(" ".join(mnemo_words)).encode("utf-8"), bytes(0), hashlib.sha512
).digest()
return sign


def mnemonic_to_seed(
mnemo_words: list[str], seed: str, password: str | None = None
):
entropy = mnemonic_to_entropy(mnemo_words, password)
def mnemonic_to_seed(mnemo_words: list[str], seed: str):
entropy = mnemonic_to_entropy(mnemo_words)
return hashlib.pbkdf2_hmac("sha512", entropy, seed, PBKDF_ITERATIONS)


def mnemonic_to_private_key(
mnemo_words: list[str], password: str | None = None
) -> tuple[bytes, bytes]:
def mnemonic_to_private_key(mnemo_words: list[str]) -> tuple[bytes, bytes]:
"""
:rtype: (bytes(public_key), bytes(secret_key))
"""
seed = mnemonic_to_seed(mnemo_words, b"TON default seed", password)
seed = mnemonic_to_seed(mnemo_words, b"TON default seed")
return crypto_sign_seed_keypair(seed[:32])


def mnemonic_to_wallet_key(
mnemo_words: list[str], password: str | None = None
) -> tuple[bytes, bytes]:
def mnemonic_to_wallet_key(mnemo_words: list[str]) -> tuple[bytes, bytes]:
"""
:rtype: (bytes(public_key), bytes(secret_key))
"""
_, priv_k = mnemonic_to_private_key(mnemo_words, password)
_, priv_k = mnemonic_to_private_key(mnemo_words)
return crypto_sign_seed_keypair(priv_k[:32])


def mnemonic_new(
words_count: int = 24, password: str | None = None
) -> list[str]:
def mnemonic_new(words_count: int = 24) -> list[str]:
while True:
mnemo_arr = []

Expand All @@ -63,5 +55,18 @@ def mnemonic_new(
continue

break
return mnemo_arr


def mnemonic_from_password(password: str, words_count: int = 24) -> list[str]:
rnd = random.Random(password)

while True:
mnemo_arr = [rnd.choice(english) for _ in range(words_count)]

if not is_basic_seed(mnemonic_to_entropy(mnemo_arr)):
continue

break

return mnemo_arr

0 comments on commit 3bb235b

Please sign in to comment.