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
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
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
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)
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)
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))
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)
def verifier(hasher): return MerkleVerifier(hasher=hasher)
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)