6 # create_key create 128 bits entropy
8 hex_str = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"]
11 # create interger in range [1,15]
12 num = random.randint(0,15)
13 entropy_str += hex_str[num]
17 # entropy_to_mnemonic create mnemonic from 128 bits entropy(the entropy_str length is 32)
19 # verify or get more test data, please ref: https://gist.github.com/zcc0721/63aeb5143807950f7b7051fadc08cef0
21 # entropy_str: 1db8b283eb4623e749732a341396e0c9
22 # mnemonic_str: buffalo sheriff path story giraffe victory chair grab cross original return napkin
24 # entropy_str: 4d33735a9e92f634d22aecbb4044038d
25 # mnemonic_str: essay oppose stove diamond control bounce emerge frown robust acquire abstract brick
27 # entropy_str: 089fe9bf0cac76760bc4b131d938669e
28 # mnemonic_str: ancient young hurt bone shuffle deposit congress normal crack six boost despair
29 def entropy_to_mnemonic(entropy_str):
33 # create a 12 elements mnemonic_list
35 for _ in range(mnemonic_length):
36 mnemonic_list.append('')
38 entropy_bytes = bytes.fromhex(entropy_str)
39 checksum = hashlib.sha256(entropy_bytes).hexdigest()[:1]
40 new_entropy_str = "0" + entropy_str + checksum
41 new_entropy_bytes = bytes.fromhex(new_entropy_str)
42 new_entropy_int = int.from_bytes(new_entropy_bytes, byteorder='big')
44 file = open('./app/model/english_mnemonic.txt', mode='r')
45 word_list = file.readlines()
48 for i in range(11, -1, -1):
49 word_index = new_entropy_int % 2048
50 new_entropy_int = new_entropy_int >> 11
51 mnemonic_list[i] = word_list[word_index]
54 mnemonic_str += mnemonic_list[i][:-1]
57 return mnemonic_str[:-1]
59 # mnemonic_to_seed create seed from mnemonic
60 # You can find more details from: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki#from-mnemonic-to-seed
61 # You can verify or get more test data from: https://gist.github.com/zcc0721/4918e891073a9ca6c444ec7490298e82
63 # mnemonic_str: ancient young hurt bone shuffle deposit congress normal crack six boost despair
64 # seed_str: afa3a86bbec2f40bb32833fc6324593824c4fc7821ed32eac1f762b5893e56745f66a6c6f2588b3d627680aa4e0e50efd25065097b3daa8c6a19d606838fe7d4
66 # mnemonic_str: rich decrease live pluck friend recipe burden minor similar agent tired horror
67 # seed_str: b435f948bd3748ede8f9d6f59728d669939e79c6c885667a5c138e05bbabde1de0dcfcbe0c6112022fbbf0da522f4e224a9c2381016380688b51886248b3156f
69 # mnemonic_str: enough ginger just mutual fit trash loop mule peasant lady market hub
70 # seed_str: ecc2bbb6c0492873cdbc81edf56bd896d3b644047879840e357be735b7fa7b6f4af1be7b8d71cc649ac4ca3816f9ccaf11bf49f4effb845f3c19e16eaf8bfcda
71 def mnemonic_to_seed(mnemonic_str):
72 password_str = mnemonic_str
74 seed_str = pbkdf2.PBKDF2(password_str, salt_str, iterations=2048, digestmodule=hashlib.sha512, macmodule=hmac).hexread(64)
78 # seed_to_root_xprv create rootxprv from seed
79 # seed_str length is 512 bits.
80 # root_xprv length is 512 bits.
81 # You can verify or get more test data from: https://gist.github.com/zcc0721/0aa1b971f4bf93d8f67e25f57b8b97ee
83 # seed_str: afa3a86bbec2f40bb32833fc6324593824c4fc7821ed32eac1f762b5893e56745f66a6c6f2588b3d627680aa4e0e50efd25065097b3daa8c6a19d606838fe7d4
84 # root_xprv: 302a25c7c0a68a83fa043f594a2db8b44bc871fced553a8a33144b31bc7fb84887c9e75915bb6ba3fd0b9f94a60b7a5897ab9db6a48f888c2559132dba9152b0
86 # seed_str: b435f948bd3748ede8f9d6f59728d669939e79c6c885667a5c138e05bbabde1de0dcfcbe0c6112022fbbf0da522f4e224a9c2381016380688b51886248b3156f
87 # root_xprv: 6032adeb967ac5ccbf988cf8190817bf9040c8cfd9cdfe3d5e400effb2946946d478b61cc6be936f367ae769eb1dc65c473ee73cac2eb43cf6d5e7c62b7f0062
89 # seed_str: ecc2bbb6c0492873cdbc81edf56bd896d3b644047879840e357be735b7fa7b6f4af1be7b8d71cc649ac4ca3816f9ccaf11bf49f4effb845f3c19e16eaf8bfcda
90 # root_xprv: a01d6b741b0e74b8d0836ac22b675bbf8e108148ef018d1b000aef1a899a134bd316c0f59e7333520ae1a429504073b2773869e95aa95bb3a4fa0ec76744025c
91 def seed_to_root_xprv(seed_str):
92 hc_str = hmac.HMAC(b'Root', bytes.fromhex(seed_str), digestmod=hashlib.sha512).hexdigest()
93 hc_0_int = int.from_bytes(bytes.fromhex(hc_str[0:2]), byteorder='big') & 248
94 hc_0_str = "%0.2x" % hc_0_int
95 new_hc_str = hc_0_str + hc_str[2:]
96 hc_31_int = int.from_bytes(bytes.fromhex(new_hc_str[62:64]), byteorder='big') & 31
97 hc_31_str = "%0.2x" % hc_31_int
98 new_hc_str = new_hc_str[:62] + hc_31_str + new_hc_str[64:]
99 hc_31_int = int.from_bytes(bytes.fromhex(new_hc_str[62:64]), byteorder='big') | 64
100 hc_31_str = "%0.2x" % hc_31_int
101 new_hc_str = new_hc_str[:62] + hc_31_str + new_hc_str[64:]
102 root_xprv_str = new_hc_str