Bitcoin blog

Essence of Bitcoin is innovation that may be related to remittance and asset holding rights and liberation and freedom

Mnemonic code

Overview
Mnemonic code is English words representing random numbers used as Wallet master keys.
Passphrase is easy to remember for human beings(passphrase 12 to 24 words).
Mnemonic is used to regenerate the seed (master key), regenerating wallet and all keys from this seed.


mnemonic code example

ten enable powder skull spot volume tragic search engage faculty tag pencil 
crowd record business same pudding bulb swear pony blush noise divert typical 


Flow
1.Generate entropy of 128 bits to 256 bits
2.Get the first 4 bits of SHA 256 hash of random array(=checksum)
3.Add this checksum to the end of the random array
4.Divide this array into 11 bit portions
5.Use as an index of 2048 predetermined English word dictionaries
6.Generate 12 to 24 English words representing mnemonic code


Code
1.Generate entropy

from random import choice
from binascii import hexlify

for i in range(10):
    data = ''.join(chr(choice(range(0, 256))) for _ in range(8 * (i % 3 + 2)))
    data = data.encode('latin1')
    h = (hexlify(data))
    print(h.decode('utf8'))

data = ''.join(chr(choice(range(0, 256))) for _ in range(8 * (i % 3 + 2)))
→Random Unicode of 16,24,36bytes

data = data.encode('latin1')
→Encode roman font

h = (hexlify(data))
→Convert to hexadecimal

(h.decode('utf8'))
→Decode to utf-8


2.Generate English word dictionaries

#Reading to list of mnemonic code 
with open('english.txt', 'r') as f:
    wordlist = [w.strip() for w in f.readlines()]
    print(wordlist)

with open('english.txt', 'r') as f:
→Read predetermined dictionary of 2048 English words

wordlist = [w.strip() for w in f.readlines()]
→List of 2048 English words

※Please refer to this english.txt.


3.Generate mnemonic code word

def to_mnemonic(self, data):
        h = hashlib.sha256(data).hexdigest()
        b = bin(int(binascii.hexlify(data), 16))[2:].zfill(len(data) * 8) + \
            bin(int(h, 16))[2:].zfill(256)[:len(data) * 8 // 32]
        result = []
        
        for i in range(len(b) // 11):
            idx = int(b[i * 11:(i + 1) * 11], 2)
            result.append(self.wordlist[idx])
        result_phrase = ' '.join(result)
        return result_phrase

h = hashlib.sha256(data).hexdigest()
→Get SHA 256 hash of random array

bin(int(h, 16))[2:].zfill(256)[:len(data) * 8 // 32]
→Get the first 4 bits of SHA 256 hash of random array(checksum)

bin(int(binascii.hexlify(data), 16))[2:].zfill(len(data) * 8) + bin(int(h, 16))[2:].zfill(256)[:len(data) * 8 // 32]
→Add this checksum to the end of the random array

for i in range(len(b) // 11)
→Divide this array into 11 bit portions

idx = int(b[i * 11:(i + 1) * 11], 2)result.append(self.wordlist[idx])
→Generate 12 to 24 English words representing mnemonic code.


Seed
Seed (512 bits) is generated by using key extension function(PBKDF2) from mnemonic code.
The resulting seed is used to generate deterministic wallet and all keys.

def normalize_string(txt):
        if isinstance(txt, bytes):
            utxt = txt.decode('utf8')
        elif isinstance(txt, str):
            utxt = txt
        else:
            raise TypeError("String value expected")
        return unicodedata.normalize('NFKD', utxt)

def to_seed(mnemonic, passphrase=''):
        mnemonic = normalize_string(mnemonic)
        passphrase = normalize_string(passphrase)
        return PBKDF2(mnemonic, u'mnemonic' + passphrase, iterations=2048,
                      macmodule=hmac, digestmodule=hashlib.sha512).read(64)

def normalize_string(txt):
→Decode with utf-8 when text equal byte format
Unicode normalization(Normalization form compatibility decomposition)

PBKDF2(mnemonic, u'mnemonic' + passphrase, iterations=2048,macmodule=hmac, digestmodule=hashlib.sha512).read(64)
→PBKDF2 iterate hash function(hmac) thousands of times.by so doing, trying to spend time on brute force attack.
→pasword, pasward+slat(short string), iteration, macmodule, digestmodle


The code is used in this article,it have posted on GitHub.

Remove all ads