Simple Merkle Hash Tree implemented in Python

来源:互联网 发布:管家婆软件怎么样 编辑:程序博客网 时间:2024/06/01 14:46

Merkle Hash Tree (MHT): The Merkle Hash Tree is a method for collectively authenticating a
set of messages [Merkle, 1989]. Consider the example in Figure 2.1, where the owner of messages
m1,m2,m3,m4 wishes to authenticate them. The MHT is built bottom-up, by first computing the
leaf nodes Ni as the digests H(mi) of the messages, where H(.) is a one-way hash function. The
value of each internal node is derived from its two child nodes, e.g., N1,2 = H(N1|N2), where |
denotes concatenation. Finally, the digest N1,2,3,4 of the root node is signed. The tree can be used
to authenticate any subset of the data values, in conjunction with a verification object (VO). For
example, to authenticate m1, the VO contains N2,N3,4 and the signed root N1,2,3,4. Upon receipt of
m1, any addressee may verify its authenticity by first computing H(m1) and then checking whether
H(H(H(m1)|N2)|N3,4) matches the signed root N1,2,3,4. If so, m1 is accepted; otherwise, m1, N2,
N3,4 and/or the signed root have been tampered with. The MHT is a binary tree, although it can
be extended to multiway trees and directed acyclic graphs [Martel et al., 2004].
Example of Merkle Hash Tree
Figure 2.1: Example of a Merkle Hash Tree.

# -*- coding: utf-8 -*-"""Created on Tue Aug 29 14:42:07 2017@author: Sean Chang"""import hashlib#the node class of binary merkle hash treeclass MerkleNode(object):    def __init__(self,left=None,right=None,data=None):        self.left = left        self.right = right        #data stores the hash value        self.data = data#build the tree recursivelydef createTree(nodes):    list_len = len(nodes)    if list_len == 0:        return 0    else:        while list_len %2 != 0:            nodes.extend(nodes[-1:])            list_len = len(nodes)        secondary = []        #combine two nodes in pair        for k in [nodes[x:x+2] for x in range(0,list_len,2)]:            d1 = k[0].data.encode()            d2 = k[1].data.encode()            md5 = hashlib.md5()            md5.update(d1+d2)            newdata = md5.hexdigest()            #print("nodehash:",newdata)            node = MerkleNode(left=k[0],right=k[1],data=newdata)            secondary.append(node)        if len(secondary) == 1:            return secondary[0]        else:            return createTree(secondary)#dfs traverse the whole tree with In-Order Traversedef dfs(root):    if  root != None:        print("data:",root.data)        dfs(root.left)        dfs(root.right)#BFS the whole tree by using a queuedef bfs(root):    print('start bfs')    queue = []    queue.append(root)    while(len(queue)>0):        e = queue.pop(0)        print(e.data)        if e.left != None:            queue.append(e.left)        if e.right != None:            queue.append(e.right)if __name__ == "__main__":    blocks = ['A','B','C','D','E']    nodes = []    print("leaf hash")    for e in blocks:        md5 = hashlib.md5()        md5.update(e.encode())        d=md5.hexdigest()        nodes.append(MerkleNode(data=d))        print(d)    root = createTree(nodes)    bfs(root)