示例#1
0
    def insert(self, index: str, data: str) -> bool:
        # Do the first level hash of data and insert into index-th leaf
        node_id = util.bitarray(index)
        self.cache[node_id] = self._hash(data)

        # Do a normal update up the tree
        curr_id = node_id.copy()
        while (curr_id.length() > 0):
            # Get both the parent and sibling ids
            s_id, is_left = self._sibling(curr_id)
            p_id = self._parent(curr_id)

            # Get the digest of the current node and sibling
            curr_digest = self.cache[curr_id]
            s_digest = None
            if s_id in self.cache:
                s_digest = self.cache[s_id]
            else:
                s_digest = self._empty_cache(s_id.length())

            # Hash the digests of the left and right children
            if is_left:
                p_digest = self._hash(s_digest + curr_digest)
            else:
                p_digest = self._hash(curr_digest + s_digest)
            self.cache[p_id] = p_digest

            # Traverse up the tree by making the current node the parent node
            curr_id = p_id

        # Update root
        self.root_digest = self.cache[curr_id]
        return True
示例#2
0
    def generate_proof(self, index: str) -> list:
        copath = list()
        curr_id = util.bitarray(index)
        proof = Proof(index=curr_id)
        proof.proof_type = curr_id in self.cache

        if not proof.proof_type:
            curr_id = self._get_empty_ancestor(curr_id)
        proof.proof_id = curr_id

        # Our stopping condition is length > 0 so we don't add the root to the copath
        while (curr_id.length() > 0):
            # Append the sibling to the copath and advance current node
            s_id, is_left = self._sibling(curr_id)
            s_digest = None

            # Check to see if sibling is cache otherwise set to empty value of appropriate length
            if s_id in self.cache:
                s_digest = self.cache[s_id]
            else:
                s_digest = self._empty_cache(len(s_id))

            copath.append((s_id, s_digest))
            curr_id = self._parent(curr_id)

        proof.copath = copath
        return proof
示例#3
0
 def _percolate(self, leaf_id: str, leaf_data: str) -> None:
     node_id = util.bitarray(leaf_id)
     node_digest = self._hash(leaf_data)
     self.cache[node_id] = node_digest
     sibling_id, is_left = self._sibling(node_id)
     if sibling_id in self.cache:
         sibling_digest = self.cache[sibling_id]
     else:
         sibling_digest = self._empty_cache(sibling_id.length())
     done = False
     while not done:
         parent_id = self._parent(node_id)
         parent_conflict = self._is_conflict(parent_id)
         if not parent_conflict:
             if is_left:
                 parent_digest = self._hash(sibling_digest + node_digest)
             else:
                 parent_digest = self._hash(node_digest + sibling_digest)
             self.cache[parent_id] = parent_digest
             node_id = parent_id
             node_digest = parent_digest
             sibling_id, is_left = self._sibling(node_id)
             if sibling_id in self.cache:
                 sibling_digest = self.cache[sibling_id]
             else:
                 sibling_digest = self._empty_cache(sibling_id.length())
         else:
             done = True
     return
示例#4
0
    def batch_insert(self, transactions: dict) -> bool:
        leaves = sorted(transactions.items(), key=lambda leaf: leaf[0])
        self.conflicts = util.find_conflicts(list(transactions.keys()))

        for i in range(len(leaves)):
            self._percolate(leaves[i][0], leaves[i][1])

        self.root_digest = self.cache[util.bitarray()]
        return True
示例#5
0
文件: test_smt.py 项目: ramjk/angela
 def test_membership_small(self):
     index = bitarray('101').to01()
     self.T.insert(index, b"angela")
     proof = self.T.generate_proof(index)
     self.assertTrue(self.T.verify_proof(proof))