コード例 #1
0
 def test_hash_full_non_empty(self):
     hasher = ledger.tree_hasher.TreeHasher()
     leaves = [c.encode() for c in "abcde"]
     for i in range(1, len(leaves) + 1):
         root_hash, hashes = hasher._hash_full(leaves, 0, i)
         self.assertEqual(hasher._hash_fold(hashes), root_hash)
         self.assertEqual(len(hashes), count_bits_set(i))
         if count_bits_set(i) == 1:  # 2^k
             self.assertEqual(hashes, (root_hash, ))
コード例 #2
0
 def test_hash_full_non_empty(self):
     hasher = ledger.tree_hasher.TreeHasher()
     leaves = [c.encode() for c in "abcde"]
     for i in range(1, len(leaves) + 1):
         root_hash, hashes = hasher._hash_full(leaves, 0, i)
         self.assertEqual(hasher._hash_fold(hashes), root_hash)
         self.assertEqual(len(hashes), count_bits_set(i))
         if count_bits_set(i) == 1:  # 2^k
             self.assertEqual(hashes, (root_hash,))
コード例 #3
0
ファイル: compact_merkle_tree.py プロジェクト: evernym/ledger
 def verifyConsistency(self, expectedLeafCount = -1) -> bool:
     if expectedLeafCount > 0 and expectedLeafCount != self.leafCount:
         raise ConsistencyVerificationFailed()
     expectedNodeCount = count_bits_set(self.leafCount)
     if not expectedNodeCount == self.nodeCount:
         raise ConsistencyVerificationFailed()
     return True
コード例 #4
0
ファイル: tree_hasher.py プロジェクト: Artemkaaas/plenum
 def hash_full_tree(self, leaves):
     """Hash a set of leaves representing a valid full tree."""
     root_hash, hashes = self._hash_full(leaves, 0, len(leaves))
     assert len(hashes) == count_bits_set(len(leaves))
     assert (self._hash_fold(hashes) == root_hash if hashes else
             root_hash == self.hash_empty())
     return root_hash
コード例 #5
0
 def verifyConsistency(self, expectedLeafCount=-1) -> bool:
     if expectedLeafCount > 0 and expectedLeafCount != self.leafCount:
         raise ConsistencyVerificationFailed()
     expectedNodeCount = count_bits_set(self.leafCount)
     if not expectedNodeCount == self.nodeCount:
         raise ConsistencyVerificationFailed()
     return True
コード例 #6
0
ファイル: compact_merkle_tree.py プロジェクト: evernym/ledger
 def _update(self, tree_size: int, hashes: Sequence[bytes]):
     bits_set = count_bits_set(tree_size)
     num_hashes = len(hashes)
     if num_hashes != bits_set:
         msgfmt = "number of hashes != bits set in tree_size: %s vs %s"
         raise ValueError(msgfmt % (num_hashes, bits_set))
     self.__tree_size = tree_size
     self.__hashes = tuple(hashes)
     # height of the smallest subtree, or 0 if none exists (empty tree)
     self.__mintree_height = lowest_bit_set(tree_size)
     self.__root_hash = None
コード例 #7
0
 def _update(self, tree_size: int, hashes: Sequence[bytes]):
     bits_set = count_bits_set(tree_size)
     num_hashes = len(hashes)
     if num_hashes != bits_set:
         msgfmt = "number of hashes != bits set in tree_size: %s vs %s"
         raise ValueError(msgfmt % (num_hashes, bits_set))
     self.__tree_size = tree_size
     self.__hashes = tuple(hashes)
     # height of the smallest subtree, or 0 if none exists (empty tree)
     self.__mintree_height = lowest_bit_set(tree_size)
     self.__root_hash = None
コード例 #8
0
    def getNodePosition(cls, start, height=None) -> int:
        """
        Calculates node position based on start and height

        :param start: The sequence number of the first leaf under this tree.
        :param height: Height of this node in the merkle tree
        :return: the node's position
        """
        pwr = highest_bit_set(start) - 1
        height = height or pwr
        if count_bits_set(start) == 1:
            adj = height - pwr
            return start - 1 + adj
        else:
            c = pow(2, pwr)
            return cls.getNodePosition(c, pwr) + \
                cls.getNodePosition(start - c, height)
コード例 #9
0
    def getNodePosition(cls, start, height=None) -> int:
        """
        Calculates node position based on start and height

        :param start: The sequence number of the first leaf under this tree.
        :param height: Height of this node in the merkle tree
        :return: the node's position
        """
        pwr = highest_bit_set(start) - 1
        height = height or pwr
        if count_bits_set(start) == 1:
            adj = height - pwr
            return start - 1 + adj
        else:
            c = pow(2, pwr)
            return cls.getNodePosition(c, pwr) + \
                cls.getNodePosition(start - c, height)
コード例 #10
0
    def _push_subtree(self, leaves: List[bytes]):
        """Extend with a full subtree <= the current minimum subtree.

        The leaves must form a full subtree, i.e. of size 2^k for some k. If
        there is a minimum subtree (i.e. __mintree_height > 0), then the input
        subtree must be smaller or of equal size to the minimum subtree.

        If the subtree is smaller (or no such minimum exists, in an empty
        tree), we can simply append its hash to self.hashes, since this
        maintains the invariant property of being sorted in descending
        size order.

        If the subtree is of equal size, we are in a similar situation to an
        addition carry. We handle it by combining the two subtrees into a
        larger subtree (of size 2^(k+1)), then recursively trying to add
        this new subtree back into the tree.

        Any collection of leaves larger than the minimum subtree must undergo
        additional partition to conform with the structure of a merkle tree,
        which is a more complex operation, performed by extend().
        """
        size = len(leaves)
        if count_bits_set(size) != 1:
            raise ValueError("invalid subtree with size != 2^k: %s" % size)
        # in general we want the highest bit, but here it's also the lowest bit
        # so just reuse that code instead of writing a new highest_bit_set()
        subtree_h, mintree_h = lowest_bit_set(size), self.__mintree_height
        if mintree_h > 0 and subtree_h > mintree_h:
            raise ValueError("subtree %s > current smallest subtree %s" %
                             (subtree_h, mintree_h))
        root_hash, hashes = self.__hasher._hash_full(leaves, 0, size)
        assert hashes == (root_hash, )

        if self.hashStore:
            for h in hashes:
                self.hashStore.writeLeaf(h)

        new_node_hashes = self.__push_subtree_hash(subtree_h, root_hash)

        nodes = [(self.tree_size, height, h) for h, height in new_node_hashes]
        if self.hashStore:
            for node in nodes:
                self.hashStore.writeNode(node)
コード例 #11
0
ファイル: compact_merkle_tree.py プロジェクト: evernym/ledger
    def _push_subtree(self, leaves: List[bytes]):
        """Extend with a full subtree <= the current minimum subtree.

        The leaves must form a full subtree, i.e. of size 2^k for some k. If
        there is a minimum subtree (i.e. __mintree_height > 0), then the input
        subtree must be smaller or of equal size to the minimum subtree.

        If the subtree is smaller (or no such minimum exists, in an empty tree),
        we can simply append its hash to self.hashes, since this maintains the
        invariant property of being sorted in descending size order.

        If the subtree is of equal size, we are in a similar situation to an
        addition carry. We handle it by combining the two subtrees into a larger
        subtree (of size 2^(k+1)), then recursively trying to add this new
        subtree back into the tree.

        Any collection of leaves larger than the minimum subtree must undergo
        additional partition to conform with the structure of a merkle tree,
        which is a more complex operation, performed by extend().
        """
        size = len(leaves)
        if count_bits_set(size) != 1:
            raise ValueError("invalid subtree with size != 2^k: %s" % size)
        # in general we want the highest bit, but here it's also the lowest bit
        # so just reuse that code instead of writing a new highest_bit_set()
        subtree_h, mintree_h = lowest_bit_set(size), self.__mintree_height
        if mintree_h > 0 and subtree_h > mintree_h:
            raise ValueError("subtree %s > current smallest subtree %s" % (
                subtree_h, mintree_h))
        root_hash, hashes = self.__hasher._hash_full(leaves, 0, size)
        assert hashes == (root_hash,)

        if self.hashStore:
            for h in hashes:
                self.hashStore.writeLeaf(h)

        new_node_hashes = self.__push_subtree_hash(subtree_h, root_hash)

        nodes = [(self.tree_size, height, h) for h, height in new_node_hashes]
        if self.hashStore:
            for node in nodes:
                self.hashStore.writeNode(node)