From 244d2de211875bd393c0d38225f77f31a18e6c9c Mon Sep 17 00:00:00 2001 From: Rajasree2004 Date: Sat, 25 Oct 2025 16:14:03 +0530 Subject: [PATCH 1/3] Add Merkle Tree construction and verification algorithm --- blockchain/merkle_tree.py | 94 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 blockchain/merkle_tree.py diff --git a/blockchain/merkle_tree.py b/blockchain/merkle_tree.py new file mode 100644 index 000000000000..32222723c15d --- /dev/null +++ b/blockchain/merkle_tree.py @@ -0,0 +1,94 @@ +""" +Merkle Tree Construction and Verification + +This module implements the construction of a Merkle Tree and +verification of inclusion proofs for blockchain data integrity. + +Each leaf is a SHA-256 hash of a transaction, and internal nodes are +computed by hashing the concatenation of their child nodes. + +References: +https://en.wikipedia.org/wiki/Merkle_tree +""" + +import hashlib + + +def sha256(data: str) -> str: + """Compute SHA-256 hash of a string.""" + return hashlib.sha256(data.encode()).hexdigest() + + +def build_merkle_tree(leaves: list[str]) -> list[list[str]]: + """ + Build a Merkle Tree from the given leaf nodes. + + Args: + leaves: List of data strings (transactions). + + Returns: + A list of lists representing tree levels, + with the last level containing the Merkle root. + + >>> len(build_merkle_tree(["a", "b", "c", "d"])[-1][0]) + 64 + """ + if not leaves: + raise ValueError("Leaf list cannot be empty.") + + current_level = [sha256(x) for x in leaves] + tree = [current_level] + + while len(current_level) > 1: + next_level = [] + for i in range(0, len(current_level), 2): + left = current_level[i] + right = current_level[i + 1] if i + 1 < len(current_level) else left + next_level.append(sha256(left + right)) + current_level = next_level + tree.append(current_level) + + return tree + + +def merkle_root(leaves: list[str]) -> str: + """ + Return the Merkle root hash for a given list of data. + + >>> r = merkle_root(["tx1", "tx2", "tx3"]) + >>> isinstance(r, str) + True + """ + return build_merkle_tree(leaves)[-1][0] + + +def verify_proof(leaf: str, proof: list[str], root: str) -> bool: + """ + Verify inclusion of a leaf using a Merkle proof. + + Args: + leaf: Original data string. + proof: List of sibling hashes up the path. + root: Expected Merkle root hash. + + Returns: + True if proof is valid, else False. + + >>> data = ["a", "b", "c", "d"] + >>> tree = build_merkle_tree(data) + >>> root = tree[-1][0] + >>> leaf = "a" + >>> proof = [sha256("b"), sha256(sha256("c") + sha256("d"))] + >>> verify_proof(leaf, proof, root) + True + """ + computed_hash = sha256(leaf) + for sibling in proof: + combined = sha256(computed_hash + sibling) + computed_hash = combined + return computed_hash == root + + +if __name__ == "__main__": + import doctest + doctest.testmod() From 825b730384f5812760b0933119f65cc6611ad5a4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 25 Oct 2025 10:48:32 +0000 Subject: [PATCH 2/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- blockchain/merkle_tree.py | 1 + 1 file changed, 1 insertion(+) diff --git a/blockchain/merkle_tree.py b/blockchain/merkle_tree.py index 32222723c15d..68ea280647bc 100644 --- a/blockchain/merkle_tree.py +++ b/blockchain/merkle_tree.py @@ -91,4 +91,5 @@ def verify_proof(leaf: str, proof: list[str], root: str) -> bool: if __name__ == "__main__": import doctest + doctest.testmod() From ee5b1bf171faf5ce4433b0cb5ea7091bdfef58c2 Mon Sep 17 00:00:00 2001 From: Rajasree2004 Date: Sat, 25 Oct 2025 16:21:52 +0530 Subject: [PATCH 3/3] Added doctest to sha256 function in merkle tree --- blockchain/merkle_tree.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/blockchain/merkle_tree.py b/blockchain/merkle_tree.py index 32222723c15d..32ded6118df1 100644 --- a/blockchain/merkle_tree.py +++ b/blockchain/merkle_tree.py @@ -15,7 +15,19 @@ def sha256(data: str) -> str: - """Compute SHA-256 hash of a string.""" + """ + Compute the SHA-256 hash of the given string. + + Args: + data (str): Input string. + + Returns: + str: Hexadecimal SHA-256 hash of the input. + + Example: + >>> sha256("abc") + 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad' + """ return hashlib.sha256(data.encode()).hexdigest()