forked from fpgaminer/hash-phrase
-
Notifications
You must be signed in to change notification settings - Fork 1
/
hash-phrase.py
59 lines (39 loc) · 1.41 KB
/
hash-phrase.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# Released into the Public Domain by fpgaminer@bitcoin-mining.com
import hashlib
import math
import sys
from pbkdf2 import pbkdf2_hex
def load_dictionary (dictionary_file=None):
if dictionary_file is None:
dictionary_file = "words.txt"
with open (dictionary_file, 'rb') as f:
dictionary = f.read ().splitlines ()
return dictionary
def default_hasher (data):
return pbkdf2_hex (data, '', iterations=50000, keylen=32, hashfunc=hashlib.sha256)
def hash_phrase (data, minimum_entropy=64, dictionary=None, hashfunc=default_hasher):
# Dictionary
if dictionary is None:
dictionary = load_dictionary ()
dict_len = len (dictionary)
entropy_per_word = math.log (dict_len, 2)
num_words = int (math.ceil (minimum_entropy / entropy_per_word))
# Hash the data and convert to a big integer (converts as Big Endian)
hash = hashfunc (data)
available_entropy = len (hash) * 4
hash = int (hash, 16)
# Check entropy
if num_words * entropy_per_word > available_entropy:
raise Exception ("The output entropy of the specified hashfunc (%d) is too small." % available_entropy)
# Generate phrase
phrase = []
for i in range (num_words):
remainder = hash % dict_len
hash = hash / dict_len
phrase.append (dictionary[remainder])
return " ".join (phrase).lower().capitalize()
if __name__ == "__main__":
if len (sys.argv) != 2:
print "USAGE: hash-phrase.py DATA"
sys.exit (-1)
print hash_phrase (sys.argv[1])