{"id":27202498,"url":"https://github.com/rozbb/ct-merkle","last_synced_at":"2025-08-12T22:38:20.072Z","repository":{"id":39924648,"uuid":"490546169","full_name":"rozbb/ct-merkle","owner":"rozbb","description":"An implementation of the append-only log described in the Certificate Transparency specification (RFC 6962)","archived":false,"fork":false,"pushed_at":"2025-04-11T02:28:34.000Z","size":233,"stargazers_count":36,"open_issues_count":0,"forks_count":5,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-07-23T21:47:22.077Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rozbb.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-APACHE","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,"zenodo":null}},"created_at":"2022-05-10T04:52:41.000Z","updated_at":"2025-05-21T15:45:23.000Z","dependencies_parsed_at":"2024-11-11T20:25:18.526Z","dependency_job_id":"fe70dcf5-34dd-428b-adc9-101955ea5661","html_url":"https://github.com/rozbb/ct-merkle","commit_stats":{"total_commits":40,"total_committers":1,"mean_commits":40.0,"dds":0.0,"last_synced_commit":"9f816d6f33b53e6d879a38eedd307c2fa5a2f331"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/rozbb/ct-merkle","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rozbb%2Fct-merkle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rozbb%2Fct-merkle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rozbb%2Fct-merkle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rozbb%2Fct-merkle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rozbb","download_url":"https://codeload.github.com/rozbb/ct-merkle/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rozbb%2Fct-merkle/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270148188,"owners_count":24535695,"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","status":"online","status_checked_at":"2025-08-12T02:00:09.011Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2025-04-09T22:00:11.643Z","updated_at":"2025-08-12T22:38:20.042Z","avatar_url":"https://github.com/rozbb.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"CT Merkle\n=========\n[![Crate](https://img.shields.io/crates/v/ct-merkle.svg)](https://crates.io/crates/ct-merkle)\n[![Docs](https://docs.rs/ct-merkle/badge.svg)](https://docs.rs/ct-merkle)\n[![CI](https://github.com/rozbb/ct-merkle/workflows/CI/badge.svg)](https://github.com/rozbb/ct-merkle/actions)\n\nThis is an implementation of the Merkle tree functionality described in the [Certificate Transparency specification (RFC 6962)](https://datatracker.ietf.org/doc/html/rfc6962).\nTwo properties can be proven about trees:\n\n1. **Inclusion proofs** state that a particular item appears in a given tree at a given index.\n2. **Consistency proofs** state that one tree is a prefix of another tree, i.e., that tree #2 is the result of appending some number of items to the end of tree #1. The number of items can be 0.\n\nThis crate provides an append-only memory-backed Merkle tree with inclusion and consistency proof functionality, as well as functions for proof verification.\nIn addition, this crate provides functions for building proofs when the full tree does not fit in memory, e.g., in Certificate Transparency.\n\nCrate Features\n--------------\n\nDefault feature flags: none\n\nFeature flag list:\n\n* `std` - Implements `std::error::Error` for all error types\n* `serde` - Implements `serde::Serialize` and `serde::Deserialize` for `MemoryBackedTree`\n\nLicense\n-------\n\nLicensed under either of\n\n * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))\n * MIT license ([LICENSE-MIT](LICENSE-MIT))\n\nat your option.\n\n\nWarning\n-------\n\nThis code has not been audited in any sense of the word. Use it at your own peril.\n\n\nExample usage\n-------------\nBelow is an example of two ways to construct an inclusion proof.\n```rust\nuse ct_merkle::{\n    indices_for_inclusion_proof, InclusionProof,\n    mem_backed_tree::MemoryBackedTree\n};\nuse sha2::Sha256;\n\n// Make a new tree whose leaves are strings\nlet mut tree = MemoryBackedTree::\u003cSha256, String\u003e::new();\ntree.push(\"hello\".to_string());\ntree.push(\"world\".to_string());\nlet root = tree.root();\n\n// Prove inclusion of the last item in the tree\nlet items_pushed = tree.len();\nlet item_to_prove = items_pushed - 1;\nlet inclusion_proof = tree.prove_inclusion(item_to_prove as usize);\n// Verify the inclusion\nassert!(root\n    .verify_inclusion(\u0026\"world\", item_to_prove, \u0026inclusion_proof)\n    .is_ok());\n\n// Now imagine we don't have a memory-backed tree. We will get the indices for\n// the hashes to fetch and then build the proof\nlet indices_to_fetch = indices_for_inclusion_proof(items_pushed, item_to_prove);\n\n//\n// Imagine here we fetch the indices in order and place them into `digests`...\n//\n\nlet digests: Vec\u003c\u0026digest::Output\u003cSha256\u003e\u003e = inclusion_proof\n    .as_bytes()\n    .chunks(32)\n    .map(TryInto::try_into)\n    .collect::\u003cResult\u003cVec\u003c_\u003e, _\u003e\u003e()\n    .unwrap();\nlet inclusion_proof = InclusionProof::from_digests(digests);\n// Verify the inclusion\nassert!(root\n    .verify_inclusion(\u0026\"world\", item_to_prove, \u0026inclusion_proof)\n    .is_ok());\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frozbb%2Fct-merkle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frozbb%2Fct-merkle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frozbb%2Fct-merkle/lists"}