{"id":18679020,"url":"https://github.com/jjyr/mmr-c","last_synced_at":"2025-11-07T13:30:43.009Z","repository":{"id":146980602,"uuid":"220979804","full_name":"jjyr/mmr-c","owner":"jjyr","description":"Merkle mountain range in C","archived":false,"fork":false,"pushed_at":"2019-11-25T13:50:51.000Z","size":64,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-12-27T21:41:55.448Z","etag":null,"topics":["c","merkle-mountain-range","mmr"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jjyr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-11-11T12:46:26.000Z","updated_at":"2020-06-21T09:26:36.000Z","dependencies_parsed_at":null,"dependency_job_id":"eb1ac897-6ed4-4c0b-94c0-1d8e850fe330","html_url":"https://github.com/jjyr/mmr-c","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jjyr%2Fmmr-c","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jjyr%2Fmmr-c/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jjyr%2Fmmr-c/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jjyr%2Fmmr-c/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jjyr","download_url":"https://codeload.github.com/jjyr/mmr-c/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239530699,"owners_count":19654333,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","merkle-mountain-range","mmr"],"created_at":"2024-11-07T09:42:06.924Z","updated_at":"2025-11-07T13:30:42.963Z","avatar_url":"https://github.com/jjyr.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Merkle mountain range\n\nMerkle mountain range in C.\n\nYou can check [unit tests](https://github.com/jjyr/mmr-c/blob/master/test_runner.c) to learn the usage.\n\n## Construct\n\n``` txt\n# An 11 leaves MMR\n\n          14\n       /       \\\n     6          13\n   /   \\       /   \\\n  2     5     9     12     17\n / \\   /  \\  / \\   /  \\   /  \\\n0   1 3   4 7   8 10  11 15  16 18\n```\n\nIn MMR, we use the insertion order to reference leaves and nodes.\nwe inserting a new leaf to MMR by the following:\n\n1. insert leaf or node to next position.\n2. if the current position has a left sibling, we merge the left and right nodes to produce a new parent node, then go back to step 1 to insert the node.\n\nFor example, we insert a leaf to the example MMR:\n\n1. insert leaf to next position: `19`.\n2. now check the left sibling `18` and calculate parent node: `merge(mmr[18], mmr[19])`.\n3. insert parent node to position `20`.\n4. the node `20` also has a left sibling `17`, calculate parent node: `merge(mmr[17], mmr[20])`.\n5. insert new node to next position `21`.\n6. the node `20` have no left sibling, complete the insertion.\n\nExample MMR after insertion of a new leaf:\n\n``` txt\n          14\n       /       \\\n     6          13            21\n   /   \\       /   \\         /   \\\n  2     5     9     12     17     20\n / \\   /  \\  / \\   /  \\   /  \\   /  \\\n0   1 3   4 7   8 10  11 15  16 18  19\n```\n\n## Merkle root\n\nAn MMR is constructed by one or more sub merkle trees (or mountains). Each sub merkle tree's root is a peak in MMR, we calculate the MMR root by bagging these peaks from right to left.\n\nFor example, we have a MMR with 3 peaks: `14, 17, 18`, we bagging thses peaks from right to left to get the root: `merge(merge(mmr[18], mmr[17]), mmr[14])`.\n\n## Merkle proof\n\nThe merkle proof is an array of hashes constructed by the follows parts:\n\n1. A merkle proof from the leaf's sibling to the peak that contains the leaf.\n2. A hash that bagging all right-hand side peaks, skip this part if no right-hand peaks.\n3. Hashes of all left-hand peaks, the from right to left, skip this part if no left-hand peaks.\n\nWe can reconstruct the merkle root from the proofs. Pre calculate the peaks positions from the size of MMR may help us do the bagging.\n\n## References\n\n* [Merkle mountain range](https://github.com/opentimestamps/opentimestamps-server/blob/master/doc/merkle-mountain-range.md)\n* [Grin Doc](https://github.com/mimblewimble/grin/blob/master/doc/mmr.md#structure)\n* [MMR implement in Rust](https://github.com/nervosnetwork/merkle-mountain-range)\n\n## LICENSE\n\nMIT\n\n## AUTHOR\n\nJiang Jinyang \u003cjjyruby@gmail.com\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjjyr%2Fmmr-c","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjjyr%2Fmmr-c","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjjyr%2Fmmr-c/lists"}