forked from str4d/zcash-pow
-
Notifications
You must be signed in to change notification settings - Fork 0
/
print-soln.py
executable file
·60 lines (51 loc) · 2.04 KB
/
print-soln.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
60
#!/usr/bin/env python2
import argparse
from binascii import unhexlify
from pyblake2 import blake2b
import struct
from pow import (
hash_xi,
print_hash,
xor,
zcash_person,
)
class node(object):
def __init__(self, h, children=[], xi=None):
self.hash = h
self.children = children
self.xi = xi
def __repr__(self, level=[]):
ret = ('\t' if level else '') + \
''.join(['|\t' if x else '\t' for x in level[:-1]]) + \
print_hash(self.hash) + \
(' (%d)' % self.xi if self.xi is not None else '') + \
'\n'
for child in self.children[:-1]:
ret += child.__repr__(level+[True])
for child in self.children[-1:]:
ret += child.__repr__(level+[False])
return ret
def generate_hashes(n, k, header):
digest = blake2b(digest_size=n/8, person=zcash_person(n, k))
digest.update(header[:140])
numIndices = ord(header[140]) if ord(header[140]) < 256 else struct.unpack('<H', header[141:143])
assert numIndices == 2**k, 'Block header does not match Equihash parameters'
i = 143 if ord(header[140]) == 256 else 141
soln = [struct.unpack('<I', header[i:i+4])[0] for i in range(i, i+numIndices*4, 4)]
hashes = [hash_xi(digest.copy(), xi).digest() for xi in soln]
return soln, hashes
def print_hashes(soln, hashes):
nodes = [node(x, xi=y) for x, y in zip(hashes, soln)]
while len(nodes) > 1:
nodes = [node(xor(nodes[i].hash, nodes[i+1].hash), nodes[i:i+2]) for i in range(0, len(nodes), 2)]
print soln
print nodes[0]
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Visualise an Equihash solution')
parser.add_argument('n', type=int,
help='Equihash parameter N')
parser.add_argument('k', type=int,
help='Equihash parameter K')
parser.add_argument('header', help='a block or block header in hexadecimal')
args = parser.parse_args()
print_hashes(*generate_hashes(args.n, args.k, unhexlify(args.header)))