예제 #1
0
    def verifyMerkleProof(*replies: Tuple[Reply]) -> bool:
        """
        Verifies the correctness of the merkle proof provided in the reply from
        the node. Returns True if verified to be correct, throws an exception
        otherwise.

        :param replies: One or more replies for which Merkle Proofs have to be
        verified
        :raises ProofError: The proof is invalid
        :return: True
        """
        verifier = MerkleVerifier()
        serializer = ledger_txn_serializer
        ignored = {F.auditPath.name, F.seqNo.name, F.rootHash.name}
        for r in replies:
            seqNo = r[f.RESULT.nm][F.seqNo.name]
            rootHash = Ledger.strToHash(
                r[f.RESULT.nm][F.rootHash.name])
            auditPath = [Ledger.strToHash(a) for a in
                         r[f.RESULT.nm][F.auditPath.name]]
            filtered = dict((k, v) for (k, v) in r[f.RESULT.nm].items()
                            if k not in ignored)
            result = serializer.serialize(filtered)
            verifier.verify_leaf_inclusion(result, seqNo - 1,
                                           auditPath,
                                           STH(tree_size=seqNo,
                                               sha256_root_hash=rootHash))
        return True
예제 #2
0
    def verifyMerkleProof(*replies: Tuple[Reply]) -> bool:
        """
        Verifies the correctness of the merkle proof provided in the reply from
        the node. Returns True if verified to be correct, throws an exception
        otherwise.

        :param replies: One or more replies for which Merkle Proofs have to be
        verified
        :raises ProofError: The proof is invalid
        :return: True
        """
        sth = namedtuple("sth", ["tree_size", "sha256_root_hash"])
        verifier = MerkleVerifier()
        serializer = JsonSerializer()
        for r in replies:
            seqNo = r[f.RESULT.nm][F.seqNo.name]
            rootHash = base64.b64decode(r[f.RESULT.nm][F.rootHash.name].encode())
            auditPath = [base64.b64decode(
                a.encode()) for a in r[f.RESULT.nm][F.auditPath.name]]
            filtered = ((k, v) for (k, v) in r[f.RESULT.nm].iteritems()
                        if k not in
                        [F.auditPath.name, F.seqNo.name, F.rootHash.name])
            result = serializer.serialize(dict(filtered))
            verifier.verify_leaf_inclusion(result, seqNo-1,
                                           auditPath,
                                           sth(tree_size=seqNo,
                                               sha256_root_hash=rootHash))
        return True
예제 #3
0
    def verifyMerkleProof(*replies: Tuple[Reply]) -> bool:
        """
        Verifies the correctness of the merkle proof provided in the reply from
        the node. Returns True if verified to be correct, throws an exception
        otherwise.

        :param replies: One or more replies for which Merkle Proofs have to be
        verified
        :raises ProofError: The proof is invalid
        :return: True
        """
        verifier = MerkleVerifier()
        fields = getTxnOrderedFields()
        serializer = CompactSerializer(fields=fields)
        for r in replies:
            seqNo = r[f.RESULT.nm][F.seqNo.name]
            rootHash = base64.b64decode(
                r[f.RESULT.nm][F.rootHash.name].encode())
            auditPath = [
                base64.b64decode(a.encode())
                for a in r[f.RESULT.nm][F.auditPath.name]
            ]
            filtered = (
                (k, v) for (k, v) in r[f.RESULT.nm].iteritems()
                if k not in [F.auditPath.name, F.seqNo.name, F.rootHash.name])
            result = serializer.serialize(dict(filtered))
            verifier.verify_leaf_inclusion(
                result, seqNo - 1, auditPath,
                STH(tree_size=seqNo, sha256_root_hash=rootHash))
        return True
예제 #4
0
 def addLedger(self,
               typ: int,
               ledger: Ledger,
               preCatchupStartClbk: Callable = None,
               postCatchupStartClbk: Callable = None,
               preCatchupCompleteClbk: Callable = None,
               postCatchupCompleteClbk: Callable = None,
               postTxnAddedToLedgerClbk: Callable = None):
     if typ in self.ledgers:
         logger.error(
             "{} already present in ledgers so cannot replace that "
             "ledger".format(typ))
         return
     self.ledgers[typ] = {
         "ledger": ledger,
         "state": LedgerState.not_synced,
         "canSync": False,
         "preCatchupStartClbk": preCatchupStartClbk,
         "postCatchupStartClbk": postCatchupStartClbk,
         "preCatchupCompleteClbk": preCatchupCompleteClbk,
         "postCatchupCompleteClbk": postCatchupCompleteClbk,
         "postTxnAddedToLedgerClbk": postTxnAddedToLedgerClbk,
         "verifier": MerkleVerifier(ledger.hasher)
     }
     self.stashedLedgerStatuses[typ] = deque()
     self.ledgerStatusOk[typ] = set()
     self.recvdConsistencyProofs[typ] = {}
     self.catchUpTill[typ] = None
     self.receivedCatchUpReplies[typ] = []
     self.recvdCatchupRepliesFrm[typ] = {}
     self.consistencyProofsTimers[typ] = None
     self.catchupReplyTimers[typ] = None
    def addLedger(self, ledger_id: int, ledger: Ledger,
                  preCatchupStartClbk: Optional[Callable] = None,
                  postCatchupCompleteClbk: Optional[Callable] = None,
                  postTxnAddedToLedgerClbk: Optional[Callable] = None):

        if ledger_id in self.ledgerRegistry:
            logger.error("{} already present in ledgers so cannot replace that ledger".format(ledger_id))
            return

        self.ledgerRegistry[ledger_id] = LedgerInfo(
            ledger_id,
            ledger=ledger,
            preCatchupStartClbk=preCatchupStartClbk,
            postCatchupCompleteClbk=postCatchupCompleteClbk,
            postTxnAddedToLedgerClbk=postTxnAddedToLedgerClbk,
            verifier=MerkleVerifier(ledger.hasher)
        )

        self._node_leecher.register_ledger(ledger_id)
예제 #6
0
    def addLedger(self,
                  iD: int,
                  ledger: Ledger,
                  preCatchupStartClbk: Callable = None,
                  postCatchupCompleteClbk: Callable = None,
                  postTxnAddedToLedgerClbk: Callable = None):

        if iD in self.ledgerRegistry:
            logger.error("{} already present in ledgers "
                         "so cannot replace that ledger".format(iD))
            return

        self.ledgerRegistry[iD] = LedgerInfo(
            iD,
            ledger=ledger,
            preCatchupStartClbk=preCatchupStartClbk,
            postCatchupCompleteClbk=postCatchupCompleteClbk,
            postTxnAddedToLedgerClbk=postTxnAddedToLedgerClbk,
            verifier=MerkleVerifier(ledger.hasher))

        cons_proof_inbox_tx, cons_proof_inbox_rx = create_direct_channel()
        cons_proof_service = ConsProofService(ledger_id=iD,
                                              config=self.config,
                                              input=cons_proof_inbox_rx,
                                              output=self._leecher_outbox,
                                              timer=self._timer,
                                              metrics=self.metrics,
                                              provider=self._provider)

        catchup_rep_inbox_tx, catchup_rep_inbox_rx = create_direct_channel()
        catchup_rep_service = CatchupRepService(ledger_id=iD,
                                                config=self.config,
                                                input=catchup_rep_inbox_rx,
                                                output=self._leecher_outbox,
                                                timer=self._timer,
                                                metrics=self.metrics,
                                                provider=self._provider)

        self._leechers[iD] = self.LedgerLeecherService(
            cons_proof_inbox=cons_proof_inbox_tx,
            cons_proof_service=cons_proof_service,
            catchup_rep_inbox=catchup_rep_inbox_tx,
            catchup_rep_service=catchup_rep_service)
예제 #7
0
    def addLedger(self,
                  iD: int,
                  ledger: Ledger,
                  preCatchupStartClbk: Callable = None,
                  postCatchupStartClbk: Callable = None,
                  preCatchupCompleteClbk: Callable = None,
                  postCatchupCompleteClbk: Callable = None,
                  postTxnAddedToLedgerClbk: Callable = None):

        if iD in self.ledgerRegistry:
            logger.error("{} already present in ledgers "
                         "so cannot replace that ledger".format(iD))
            return

        self.ledgerRegistry[iD] = LedgerInfo(
            iD,
            ledger=ledger,
            preCatchupStartClbk=preCatchupStartClbk,
            postCatchupStartClbk=postCatchupStartClbk,
            preCatchupCompleteClbk=preCatchupCompleteClbk,
            postCatchupCompleteClbk=postCatchupCompleteClbk,
            postTxnAddedToLedgerClbk=postTxnAddedToLedgerClbk,
            verifier=MerkleVerifier(ledger.hasher))
예제 #8
0
def testLocate(hasherAndTree, addTxns, storeHashes):
    h, m = hasherAndTree

    mhs = storeHashes
    txnCount, auditPaths = addTxns

    verifier = MerkleVerifier()
    startingTime = time.perf_counter()
    for d in range(50):
        print()
        pos = d + 1
        print("Audit Path for Serial No: {}".format(pos))
        leafs, nodes = mhs.getPath(pos)
        calculatedAuditPath = []
        for i, leaf_pos in enumerate(leafs):
            hexLeafData = hexlify(mhs.readLeaf(leaf_pos))
            print("leaf: {}".format(hexLeafData))
            calculatedAuditPath.append(hexLeafData)
        for node_pos in nodes:
            node = mhs.readNode(node_pos)
            hexNodeData = hexlify(node)
            print("node: {}".format(hexNodeData))
            calculatedAuditPath.append(hexNodeData)
        print("{} -> leafs: {}, nodes: {}".format(pos, leafs, nodes))
        print("Audit path built using formula {}".format(calculatedAuditPath))
        print("Audit path received while appending leaf {}".format(
            auditPaths[d]))

        # Testing equality of audit path calculated using formula and audit path
        #  received while inserting leaf into the tree
        assert calculatedAuditPath == auditPaths[d]
        auditPathLength = verifier.audit_path_length(d, d + 1)
        assert auditPathLength == len(calculatedAuditPath)

        # Testing root hash generation
        leafHash = storeHashes.readLeaf(d + 1)
        rootHashFrmCalc = hexlify(
            verifier._calculate_root_hash_from_audit_path(
                leafHash, d, [unhexlify(h) for h in calculatedAuditPath],
                d + 1))
        rootHash = hexlify(
            verifier._calculate_root_hash_from_audit_path(
                leafHash, d, [unhexlify(h) for h in auditPaths[d]], d + 1))
        assert rootHash == rootHashFrmCalc

        print("Root hash from audit path built using formula {}".format(
            calculatedAuditPath))
        print("Root hash from audit path received while appending leaf {}".
              format(auditPaths[d]))

        print("Leaf hash length is {}".format(len(leafHash)))
        print("Root hash length is {}".format(len(rootHash)))

        # Testing verification, do not need `assert` since
        # `verify_leaf_hash_inclusion` will throw an exception
        sthFrmCalc = STH(d + 1, unhexlify(rootHashFrmCalc))
        verifier.verify_leaf_hash_inclusion(
            leafHash, d, [unhexlify(h) for h in calculatedAuditPath],
            sthFrmCalc)
        sth = STH(d + 1, unhexlify(rootHash))
        verifier.verify_leaf_hash_inclusion(
            leafHash, d, [unhexlify(h) for h in auditPaths[d]], sth)
    print(time.perf_counter() - startingTime)
예제 #9
0
def verifier(hasher):
    return MerkleVerifier(hasher=hasher)
예제 #10
0
def testLocate(hasherAndTree, addTxns, storeHashes):
    h, m = hasherAndTree

    mhs = storeHashes
    txnCount, auditPaths = addTxns

    verifier = MerkleVerifier()
    startingTime = time.perf_counter()
    for d in range(50):
        print()
        pos = d + 1
        print("Audit Path for Serial No: {}".format(pos))
        leafs, nodes = mhs.getPath(pos)
        calculatedAuditPath = []
        for i, leaf_pos in enumerate(leafs):
            hexLeafData = hexlify(mhs.readLeaf(leaf_pos))
            print("leaf: {}".format(hexLeafData))
            calculatedAuditPath.append(hexLeafData)
        for node_pos in nodes:
            node = mhs.readNode(node_pos)
            hexNodeData = hexlify(node)
            print("node: {}".format(hexNodeData))
            calculatedAuditPath.append(hexNodeData)
        print("{} -> leafs: {}, nodes: {}".format(pos, leafs, nodes))
        print("Audit path built using formula {}".format(calculatedAuditPath))
        print("Audit path received while appending leaf {}".format(
            auditPaths[d]))

        # Testing equality of audit path calculated using formula and audit path
        #  received while inserting leaf into the tree
        assert calculatedAuditPath == auditPaths[d]
        auditPathLength = verifier.audit_path_length(d, d + 1)
        assert auditPathLength == len(calculatedAuditPath)

        # Testing root hash generation
        leafHash = storeHashes.readLeaf(d + 1)
        rootHashFrmCalc = hexlify(verifier._calculate_root_hash_from_audit_path(
            leafHash, d, [unhexlify(h) for h in calculatedAuditPath], d + 1))
        rootHash = hexlify(verifier._calculate_root_hash_from_audit_path(
            leafHash, d, [unhexlify(h) for h in auditPaths[d]], d + 1))
        assert rootHash == rootHashFrmCalc

        print("Root hash from audit path built using formula {}".
              format(calculatedAuditPath))
        print("Root hash from audit path received while appending leaf {}".
              format(auditPaths[d]))

        print("Leaf hash length is {}".format(len(leafHash)))
        print("Root hash length is {}".format(len(rootHash)))

        # Testing verification, do not need `assert` since
        # `verify_leaf_hash_inclusion` will throw an exception
        sthFrmCalc = STH(d + 1, unhexlify(rootHashFrmCalc))
        verifier.verify_leaf_hash_inclusion(
            leafHash, d,
            [unhexlify(h) for h in calculatedAuditPath],
            sthFrmCalc)
        sth = STH(d + 1, unhexlify(rootHash))
        verifier.verify_leaf_hash_inclusion(
            leafHash, d,
            [unhexlify(h) for h in auditPaths[d]], sth)
    print(time.perf_counter() - startingTime)