Exemplo n.º 1
0
 def populate_tree(self, flag_bits, hashes):
     while self.root() is None:  # <1>
         if self.is_leaf():  # <2>
             flag_bits.pop(0)  # <3>
             self.set_current_node(hashes.pop(0))  # <4>
             self.up()
         else:
             left_hash = self.get_left_node()
             if left_hash is None:  # <5>
                 if flag_bits.pop(0) == 0:  # <6>
                     self.set_current_node(hashes.pop(0))
                     self.up()
                 else:
                     self.left()  # <7>
             elif self.right_exists():  # <8>
                 right_hash = self.get_right_node()
                 if right_hash is None:  # <9>
                     self.right()
                 else:  # <10>
                     self.set_current_node(merkle_parent(left_hash, right_hash))
                     self.up()
             else:  # <11>
                 self.set_current_node(merkle_parent(left_hash, left_hash))
                 self.up()
     if len(hashes) != 0:  # <12>
         raise RuntimeError('hashes not all consumed {}'.format(len(hashes)))
     for flag_bit in flag_bits:  # <13>
         if flag_bit != 0:
             raise RuntimeError('flag bits not all consumed')
Exemplo n.º 2
0
 def populate_tree(self, flag_bits, hashes):
     while self.root() is None:
         if self.is_leaf():
             flag_bits.pop(0)
             self.set_current_node(hashes.pop(0))
             self.up()
         else:
             left_hash = self.get_left_node()
             if left_hash is None:
                 if flag_bits.pop(0) == 0:  # pre-calculated hash
                     self.set_current_node(hashes.pop(0))
                     self.up()
                 else:
                     self.left()
             elif self.right_exists():
                 right_hash = self.get_right_node()
                 if right_hash is None:
                     self.right()
                 else:
                     self.set_current_node(
                         merkle_parent(left_hash, right_hash))
                     self.up()
             else:
                 self.set_current_node(merkle_parent(left_hash, left_hash))
                 self.up()
     if len(hashes) != 0:
         raise RuntimeError(f'hashes not all consumed {len(hashes)}')
     for flag_bit in flag_bits:
         if flag_bit != 0:
             raise RuntimeError('flag bits not all consumed')
Exemplo n.º 3
0
 def populate_tree(self, flag_bits, hashes):
     # populate until we have the root
     while self.root() is None:
         # if we are a leaf, we know this position's hash
         if self.is_leaf():
             # get the next bit from flag_bits: flag_bits.pop(0)
             flag_bits.pop(0)
             # set the current node in the merkle tree to the next hash: hashes.pop(0)
             self.set_current_node(hashes.pop(0))
             # go up a level
             self.up()
         # else
         else:
             # get the left hash
             left_hash = self.get_left_node()
             # Exercise 6.2: get the right hash
             # if we don't have the left hash
             if left_hash is None:
                 # if the next flag bit is 0, the next hash is our current node
                 if flag_bits.pop(0) == 0:
                     # set the current node to be the next hash
                     self.set_current_node(hashes.pop(0))
                     # sub-tree doesn't need calculation, go up
                     self.up()
                 # else
                 else:
                     # go to the left node
                     self.left()
             # Exercise 6.2: if we don't have the right hash
             # go to the right node
             # Exercise 6.2: else
             # combine the left and right hashes
             # we've completed this subtree, go up
             # Exercise 7.2: if the right hash exists
             elif self.right_exists():
                 # get the right hash
                 right_hash = self.get_right_node()
                 # if we don't have the right hash
                 if right_hash is None:
                     # go to the right node
                     self.right()
                 # else
                 else:
                     # combine the left and right hashes
                     self.set_current_node(
                         merkle_parent(left_hash, right_hash))
                     # we've completed this sub-tree, go up
                     self.up()
             # else
             else:
                 # combine the left hash twice
                 self.set_current_node(merkle_parent(left_hash, left_hash))
                 # we've completed this sub-tree, go up
                 self.up()
     if len(hashes) != 0:
         raise RuntimeError('hashes not all consumed {}'.format(
             len(hashes)))
     for flag_bit in flag_bits:
         if flag_bit != 0:
             raise RuntimeError('flag bits not all consumed')
Exemplo n.º 4
0
 def populate_tree(self, flag_bits, hashes):
     # populate until we have the root
     while self.root() is None:
         # if we are a leaf, we know this position's hash
         if self.is_leaf():
             # get the next bit from flag_bits: flag_bits.pop(0)
             flag_bit = flag_bits.pop(0)
             # get the current hash from hashes: hashes.pop(0)
             current_hash = hashes.pop(0)
             # set the current node in the merkle tree to the current hash
             self.set_current_node(current_hash)
             # if our flag bit is 1, add to the self.proved_txs array
             if flag_bit == 1:
                 self.proved_txs.append(current_hash[::-1])
             # go up a level
             self.up()
         # else
         else:
             # get the left hash
             left_hash = self.get_left_node()
             # if we don't have the left hash
             if left_hash is None:
                 # if the next flag bit is 0, the next hash is our current node
                 if flag_bits.pop(0) == 0:
                     # set the current node to be the next hash
                     self.set_current_node(hashes.pop(0))
                     # sub-tree doesn't need calculation, go up
                     self.up()
                 # else
                 else:
                     # go to the left node
                     self.left()
             elif self.right_exists():
                 # get the right hash
                 right_hash = self.get_right_node()
                 # if we don't have the right hash
                 if right_hash is None:
                     # go to the right node
                     self.right()
                 # else
                 else:
                     # combine the left and right hashes
                     self.set_current_node(
                         merkle_parent(left_hash, right_hash))
                     # we've completed this sub-tree, go up
                     self.up()
             # else
             else:
                 # combine the left hash twice
                 self.set_current_node(merkle_parent(left_hash, left_hash))
                 # we've completed this sub-tree, go up
                 self.up()
     if len(hashes) != 0:
         raise RuntimeError(f'hashes not all consumed {len(hashes)}')
     for flag_bit in flag_bits:
         if flag_bit != 0:
             raise RuntimeError('flag bits not all consumed')
Exemplo n.º 5
0
 def verify(self):
     '''Returns whether this proof is valid'''
     current = self.tx_hash[::-1]
     path = merkle_path(self.index, 2**len(self.merkle_proof))
     for i, proof_hash in enumerate(self.merkle_proof):
         if path[i] % 2 == 1:
             current = merkle_parent(proof_hash, current)
         else:
             current = merkle_parent(current, proof_hash)
     return current[::-1] == self.merkle_root
Exemplo n.º 6
0
 def populate_tree(self, flag_bits, hashes):
     # Loop until the root is calculated.
     while self.root() is None:
         # For leaf nodes, we are always given the hash.
         if self.is_leaf():
             # We remove the flag bit corresponding to this node.
             flag_bits.pop(0)
             # The hash at index 0 is the hash for this node.
             self.set_current_node(hashes.pop(0))
             self.up()
         else:
             left_hash = self.get_left_node()
             # If we don't have the left child value, there are 2 possibilities: 1) This node's value
             # may be in the hashes list or we need to calculate it.
             if left_hash is None:
                 # The next flag bit tells us whether we need to calculate this node or it is given to us.
                 # If the bit is a 0, it's hash is given to us. If it's a 1, we need to calculate it.
                 if flag_bits.pop(0) == 0:
                     self.set_current_node(hashes.pop(0))
                     # Now that we have set the value, we can go up and start working on the other side
                     # of the tree.
                     self.up()
                 # If the bit is not 0, we need to calculate this node's value, so we keep traversing to
                 # the left.
                 else:
                     self.left()
             # We check that the right node exists.
             elif self.right_exists():
                 right_hash = self.get_right_node()
                 # We have the left hash, but not the right. We traverse to the right node to get its value.
                 if right_hash is None:
                     self.right()
                 # We have both left and right hashes, so we calculate the parent to get the current node's value.
                 else:
                     self.set_current_node(
                         merkle_parent(left_hash, right_hash))
                     self.up()
             # We have the left node's value, but the right node does not exist. Thus, we calculate
             # the parent using the left node twice.
             else:
                 self.set_current_node(merkle_parent(left_hash, left_hash))
                 self.up()
     # All hashes must be consumed.
     if len(hashes) != 0:
         raise RuntimeError("Not all hashes were consumed.")
     # All flag bits must be consumed.
     for flag_bit in flag_bits:
         if flag_bit != 0:
             raise RuntimeError("All flag bits must be consumed.")
Exemplo n.º 7
0
 def test_merkle_parent(self):
     tx_hash0 = unhexlify(
         'c117ea8ec828342f4dfb0ad6bd140e03a50720ece40169ee38bdc15d9eb64cf5')
     tx_hash1 = unhexlify(
         'c131474164b412e3406696da1ee20ab0fc9bf41c8f05fa8ceea7a08d672d7cc5')
     want = unhexlify(
         '8b30c5ba100f6f2e5ad1e2a742e5020491240f8eb514fe97c713c31718ad7ecd')
     self.assertEqual(merkle_parent(tx_hash0, tx_hash1), want)
Exemplo n.º 8
0
 def verify(self):
     '''Returns whether this proof is valid'''
     # current hash starts with self.tx_hash, reversed
     current = self.tx_hash[::-1]
     # Get the Merkle Path for the index and 2**len(merkle_proof)
     path = merkle_path(self.index, 2**len(self.merkle_proof))
     # Loop through Merkle Path and proof hashes
     for proof_hash, index_at_level in zip(self.merkle_proof, path):
         # if index_at_level is odd, proof_hash goes on left
         if index_at_level % 2 == 1:
             # current hash becomes merkle parent of proof_hash and current
             current = merkle_parent(proof_hash, current)
         # if index_at_level is even, proof_hash goes on right
         else:
             # current hash becomes merkle parent of current and proof_hash
             current = merkle_parent(current, proof_hash)
     # if final result reversed is equal to merkle_root, return True
     return current[::-1] == self.merkle_root
Exemplo n.º 9
0
 def test_example_13(self):
     hex_hashes = [
         "9745f7173ef14ee4155722d1cbf13304339fd00d900b759c6f9d58579b5765fb",
         "5573c8ede34936c29cdfdfe743f7f5fdfbd4f54ba0705259e62f39917065cb9b",
         "82a02ecbb6623b4274dfcab82b336dc017a27136e08521091e443e62582e8f05",
         "507ccae5ed9b340363a0e6d765af148be9cb1c8766ccc922f83e4ae681658308",
         "a7a4aec28e7162e1e9ef33dfa30f0bc0526e6cf4b11a576f6c5de58593898330",
         "bb6267664bd833fd9fc82582853ab144fece26b7a8a5bf328f8a059445b59add",
         "ea6d7ac1ee77fbacee58fc717b990c4fcccf1b19af43103c090f601677fd8836",
         "457743861de496c429912558a106b810b0507975a49773228aa788df40730d41",
         "7688029288efc9e9a0011c960a6ed9e5466581abf3e3a6c26ee317461add619a",
         "b1ae7f15836cb2286cdd4e2c37bf9bb7da0a2846d06867a429f654b2e7f383c9",
         "9b74f89fa3f93e71ff2c241f32945d877281a6a50a6bf94adac002980aafe5ab",
         "b3a92b5b255019bdaf754875633c2de9fec2ab03e6b8ce669d07cb5b18804638",
         "b5c0b915312b9bdaedd2b86aa2d0f8feffc73a2d37668fd9010179261e25e263",
         "c9d52c5cb1e557b92c84c52e7c4bfbce859408bedffc8a5560fd6e35e10b8800",
         "c555bc5fc3bc096df0a0c9532f07640bfb76bfe4fc1ace214b8b228a1297a4c2",
         "f9dbfafc3af3400954975da24eb325e326960a25b87fffe23eef3e7ed2fb610e",
         "38faf8c811988dff0a7e6080b1771c97bcc0801c64d9068cffb85e6e7aacaf51",
     ]
     tree = MerkleTree(len(hex_hashes))
     tree.nodes[5] = [bytes.fromhex(h) for h in hex_hashes]
     while tree.root() is None:
         if tree.is_leaf():
             tree.up()
         else:
             left_hash = tree.get_left_node()
             if left_hash is None:
                 tree.left()
             elif tree.right_exists():
                 right_hash = tree.get_right_node()
                 if right_hash is None:
                     tree.right()
                 else:
                     tree.set_current_node(
                         merkle_parent(left_hash, right_hash))
                     tree.up()
             else:
                 tree.set_current_node(merkle_parent(left_hash, left_hash))
                 tree.up()
     self.assertEqual(
         tree.nodes[0][0].hex(),
         '0a313864f84b284ad13f7f93940d43459808c3c300ed274a90f265802ab10f91')
Exemplo n.º 10
0
 def verify(self):
     '''Returns whether this proof is valid'''
     # current hash starts with self.tx_hash, reversed
     current = self.tx_hash[::-1]
     # initialize the current_index to be the index at at base level
     current_index = self.index
     # Loop through proof hashes
     for proof_hash in self.merkle_proof:
         # if current_index is odd, proof_hash goes on left
         if current_index % 2 == 1:
             # current hash becomes merkle parent of proof_hash and current
             current = merkle_parent(proof_hash, current)
         # if current_index is even, proof_hash goes on right
         else:
             # current hash becomes merkle parent of current and proof_hash
             current = merkle_parent(current, proof_hash)
         # update the current_index to be integer divide by 2
         current_index //= 2
     # if final result reversed is equal to merkle_root, return True
     return current[::-1] == self.merkle_root
Exemplo n.º 11
0
    def create_merkle_proof(self, tx_hash):
        if self.tx_hashes is None:
            return None
        elif self.merkle_tree is None:
            self.calculate_merkle_tree()
        index = self.merkle_tree[0].index(tx_hash[::-1])
        current = self.merkle_tree[0][index]
        proof_hashes = []
        for level, level_index in enumerate(
                merkle_path(index, len(self.tx_hashes))):
            if level_index % 2 == 0:
                partner = self.merkle_tree[level][level_index + 1]
                current = merkle_parent(current, partner)
            else:
                partner = self.merkle_tree[level][level_index - 1]
                current = merkle_parent(partner, current)
            proof_hashes.append(partner)

        # sanity check
        if current != self.merkle_tree[-1][0]:
            raise RuntimeError('merkle tree looks invalid')
        return Proof(self.merkle_root, tx_hash, index, proof_hashes)
Exemplo n.º 12
0
 def test_example_7(self):
     hex_hashes = [
         '8b30c5ba100f6f2e5ad1e2a742e5020491240f8eb514fe97c713c31718ad7ecd',
         '7f4e6f9e224e20fda0ae4c44114237f97cd35aca38d83081c9bfd41feb907800',
         'ade48f2bbb57318cc79f3a8678febaa827599c509dce5940602e54c7733332e7',
         '68b3e2ab8182dfd646f13fdf01c335cf32476482d963f5cd94e934e6b3401069',
         '43e7274e77fbe8e5a42a8fb58f7decdb04d521f319f332d88e6b06f8e6c09e27',
     ]
     hashes = [bytes.fromhex(x) for x in hex_hashes]
     if len(hashes) % 2 == 1:
         hashes.append(hashes[-1])
     parent_level = []
     for i in range(0, len(hex_hashes), 2):
         parent = merkle_parent(hashes[i], hashes[i + 1])
         parent_level.append(parent)
     want = [
         '26906cb2caeb03626102f7606ea332784281d5d20e2b4839fbb3dbb37262dbc1',
         '717a0d17538ff5ad2c020bab38bdcde66e63f3daef88f89095f344918d5d4f96',
         'd6c56a5281021a587f5a1e0dd4674bff012c69d960136d96e6d72261d5b696ae',
     ]
     self.assertEqual([x.hex() for x in parent_level], want)
Exemplo n.º 13
0
 def test_example_4(self):
     hex_hashes = [
         'c117ea8ec828342f4dfb0ad6bd140e03a50720ece40169ee38bdc15d9eb64cf5',
         'c131474164b412e3406696da1ee20ab0fc9bf41c8f05fa8ceea7a08d672d7cc5',
         'f391da6ecfeed1814efae39e7fcb3838ae0b02c02ae7d0a5848a66947c0727b0',
         '3d238a92a94532b946c90e19c49351c763696cff3db400485b813aecb8a13181',
         '10092f2633be5f3ce349bf9ddbde36caa3dd10dfa0ec8106bce23acbff637dae',
     ]
     hashes = [bytes.fromhex(x) for x in hex_hashes]
     if len(hashes) % 2 == 1:
         hashes.append(hashes[-1])
     parent_level = []
     for i in range(0, len(hex_hashes), 2):
         parent = merkle_parent(hashes[i], hashes[i + 1])
         parent_level.append(parent)
     want = [
         '8b30c5ba100f6f2e5ad1e2a742e5020491240f8eb514fe97c713c31718ad7ecd',
         '7f4e6f9e224e20fda0ae4c44114237f97cd35aca38d83081c9bfd41feb907800',
         '3ecf6115380c77e8aae56660f5634982ee897351ba906a6837d15ebc3a225df0',
     ]
     self.assertEqual([x.hex() for x in parent_level], want)