예제 #1
0
def reverse_mnemonic(mnemonic, filepath):
    """
    Get initial entropy from mnemonic and wordlist.

    :param mnemonic: mnemonic as a string
    :param filepath: filepath of the wordlist
    :return: entropy as a hex string
    """
    if type(mnemonic) is not str:
        raise ValueError('mnemonic has to be a string; the given type was {}'.format(type(mnemonic)))

    mnemonic_list = mnemonic.split(' ')
    possible_ms_values = [x // 32 * 33 // 11 for x in POSSIBLE_ENT_VALUES]
    if len(mnemonic_list) not in possible_ms_values:
        raise ValueError('number of words in the mnemonic has to be in {}; the given number of words was {}'.format(
            possible_ms_values, len(mnemonic_list)))

    wordlist = get_wordlist(filepath)
    if len(wordlist) != 2048:
        raise ValueError('the wordlist has to have 2048 words; the given wordlist had {} words'.format(len(wordlist)))
    indices = [wordlist.index(w) for w in mnemonic_list]

    indices_bytes = [i.to_bytes(length=2, byteorder='big') for i in indices]

    indices_bits = [bytes_to_bits(b)[-11:] for b in indices_bytes]
    bit_string = ''.join(indices_bits)
    cs = len(bit_string) // 33
    bit_string = bit_string[:len(bit_string) - cs]

    return int(bit_string, 2).to_bytes(length=len(bit_string) // 8, byteorder='big').hex()
예제 #2
0
def generate_mnemonic(ent, filepath):
    """
    Generate a mnemonic from the given wordlist and for the given entropy length.

    :param ent: entropy length; type int; possible values from POSSIBLE_ENT_VALUES
    :param filepath: filepath of the wordlist
    :return: mnemonic
    """
    if type(ent) is not int:
        raise ValueError('ent (entropy length) has to be int; the given type was {}'.format(type(ent)))
    if ent not in POSSIBLE_ENT_VALUES:
        raise ValueError(
            'ent (entropy length) has to be in {}; the given values was {}'.format(POSSIBLE_ENT_VALUES, ent))

    mnemonic = compose_mnemonic(generate_indices(ent), get_wordlist(filepath))
    return mnemonic
예제 #3
0
def get_mnemonic_from_entropy_bytes(entropy_bytes, filepath):
    """
    Get the mnemonic for the given entropy and wordlist.

    :param entropy_bytes: bytes encoding the entropy bytes
    :param filepath: filepath of the wordlist
    :return: mnemonic
    """
    if type(entropy_bytes) is not bytes:
        raise ValueError('entropy_bytes has to be bytes object; the given type was {}'.format(type(entropy_bytes)))
    if len(entropy_bytes) * 8 not in POSSIBLE_ENT_VALUES:
        raise ValueError(
            'eight multiple of entropy_bytes length has to be in {}; '
            'the eight multiple of length of the given values was {}'.format(
                POSSIBLE_ENT_VALUES, 8 * len(entropy_bytes)))

    mnemonic = compose_mnemonic(get_indices_from_entropy(entropy_bytes), get_wordlist(filepath))
    return mnemonic
예제 #4
0
def generate_seed(mnemonic, passphrase='', filepath='../wordlists/english.txt'):
    """
    Get the seed from a mnemonic
    :param mnemonic: mnemonic as a string
    :param passphrase: passphrase as a string
    :param filepath: path to the used wordlist
    :return: seed as a hex string
    """

    wordlist = get_wordlist(filepath)
    split_mnemonic = mnemonic.split()
    for member in split_mnemonic:
        if member not in wordlist:
            raise ValueError("the given mnemonic contains illegal(s) word(s)")

    nfkd_mnemonic = bytes(unicodedata.normalize('NFKD', mnemonic), encoding='utf-8')
    concat = 'mnemonic' + passphrase
    nfkd_salt = bytes(unicodedata.normalize('NFKD', concat), encoding='utf-8')
    seed = pbkdf2_hmac('sha512', nfkd_mnemonic, nfkd_salt, 2048, 64).hex()

    return seed