{"id":15902831,"url":"https://github.com/erikh/go-hashchain","last_synced_at":"2025-08-09T05:33:53.974Z","repository":{"id":149994762,"uuid":"618306290","full_name":"erikh/go-hashchain","owner":"erikh","description":"Chain of hashes for verifying a file's generational change","archived":false,"fork":false,"pushed_at":"2023-04-01T13:12:07.000Z","size":12,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-08T10:42:37.999Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","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/erikh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2023-03-24T07:26:15.000Z","updated_at":"2023-03-24T07:36:41.000Z","dependencies_parsed_at":"2023-05-05T12:47:23.975Z","dependency_job_id":null,"html_url":"https://github.com/erikh/go-hashchain","commit_stats":{"total_commits":7,"total_committers":1,"mean_commits":7.0,"dds":0.0,"last_synced_commit":"88e1356ff5205dd0a3c0a162fb7cbb4ccba4991e"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikh%2Fgo-hashchain","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikh%2Fgo-hashchain/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikh%2Fgo-hashchain/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikh%2Fgo-hashchain/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/erikh","download_url":"https://codeload.github.com/erikh/go-hashchain/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246884767,"owners_count":20849554,"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":[],"created_at":"2024-10-06T12:00:21.586Z","updated_at":"2025-04-02T20:14:08.912Z","avatar_url":"https://github.com/erikh.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"## go-hashchain: Verify a file changed the same way over generations\n\nhashchain is not blockchain or a merkle tree, it is something much simpler. I\nneeded to track whether a file changed over a time the same way over many\ngenerations. The verifiability of the \"chain\" is not as important as the\nchanges that the chain consists of.\n\nThus, this library was born. It's crypto built on somewhat solid foundations\nbut it's still _my_ crypto and I am _not_ a cryptographer. I don't suggest you\nuse it without evaluating what you need it for with a very critical eye.\n\n### Usage\n\n```go\n// let's make two chains so we can show some things.\nc1 := \u0026Chain{}\nc2 := \u0026Chain{}\n\n// the sum is yielded for the current provided buffer as a convenience for\n// third-party tracking. Any hash.Hash interface works as a digest algorithm.\n\n// we'll sum the same thing twice at first\nsum, err := c1.Add(bytes.NewBuffer([]byte(\"buffer\")), sha512.New())\nif err != nil {\n  log.Fatal(err)\n}\n\nsum, err = c2.Add(bytes.NewBuffer([]byte(\"buffer\")), sha512.New())\nif err != nil {\n  log.Fatal(err)\n}\n\n// and one more time, for posterity's sake\nsum, err = c1.Add(bytes.NewBuffer([]byte(\"buffer2\")), sha512.New())\nif err != nil {\n  log.Fatal(err)\n}\n\nsum, err = c2.Add(bytes.NewBuffer([]byte(\"buffer2\")), sha512.New())\nif err != nil {\n  log.Fatal(err)\n}\n\n// and now, we'll generate a mismatch\nsum, err = c1.Add(bytes.NewBuffer([]byte(\"buffer1-1\")), sha512.New())\nif err != nil {\n  log.Fatal(err)\n}\n\nsum, err = c2.Add(bytes.NewBuffer([]byte(\"buffer1-2\")), sha512.New())\nif err != nil {\n  log.Fatal(err)\n}\n\n// difference functions. if the chains don't match at all, you'll get an error\n\n// will return a chain containing c2's hashes, starting right after the first hash\nchain, err := c1.FirstMatch(c2)\n\n// will return a chain containing c2's hashes, starting right after the last hash\nchain, err = c1.LastMatch(c2)\n\n// we can tell the chains are different by comparing the sum of the entire chain:\n\nfmt.Println(c1.Sum(sha512.New()) == c2.Sum(sha512.New()))\n```\n\n### Author\n\nErik Hollensbe \u003cerik+github@hollensbe.org\u003e\n\n### License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferikh%2Fgo-hashchain","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ferikh%2Fgo-hashchain","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferikh%2Fgo-hashchain/lists"}