{"id":16834973,"url":"https://github.com/dchest/hesfic","last_synced_at":"2025-04-11T04:36:09.534Z","repository":{"id":6081138,"uuid":"7307685","full_name":"dchest/hesfic","owner":"dchest","description":"Content-addressable encrypted storage or something like that","archived":false,"fork":false,"pushed_at":"2014-12-11T08:15:29.000Z","size":170,"stargazers_count":8,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-11T04:36:03.538Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dchest.png","metadata":{"files":{"readme":"README","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-12-24T13:38:56.000Z","updated_at":"2021-02-28T13:58:29.000Z","dependencies_parsed_at":"2022-09-22T07:10:56.082Z","dependency_job_id":null,"html_url":"https://github.com/dchest/hesfic","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dchest%2Fhesfic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dchest%2Fhesfic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dchest%2Fhesfic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dchest%2Fhesfic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dchest","download_url":"https://codeload.github.com/dchest/hesfic/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248345257,"owners_count":21088231,"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-13T12:08:33.615Z","updated_at":"2025-04-11T04:36:09.514Z","avatar_url":"https://github.com/dchest.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"Hesfic\n======\n\n\"Here, Eat Some Files, Imposturous Cloud!\"\n\nHesfic is a difficult-to-use encrypted content-addressable block file storage\nfor mirroring. WHAT? Basically, it allows you to take snapshots of your files\nand directories and store them as encrypted blocks somewhere (for example, in\nthe Dropbox directory). Something like Git, but splits large files into smaller\nblocks, so that cloud things don't choke when synching them. Oh, and it\nalso compresses them with Snappy before encrypting.\n\nHesfic kinda works, but you shouldn't use it yet. It may lose you data.\n\n\nSETUP\n-----\n\nHesfic stores encryption keys and configuration in $HOME/.hesfic/ directory.\nFile \"keys\" must have 96 random bytes. Hesfic can create it using this command:\n\n  $ hesfic genkeys\n\nFile \"config\" in JSON must contain output directory (where blocks and snapshots\nwill be stored):\n\n  $ cat \u003c\u003cEOF \u003e ~/.hesfic/config\n  {\n    \"OutPath\": \"/Users/pupkin/Dropbox/Hesfic\"\n  }\n  EOF\n\n\n(Alternatively, you can use different paths for config and keys by specifying\nthem as command line arguments -config=\"path/to/cfg\" and -keys=\"path/to/keys\").\n\n\nUSAGE\n-----\n\nCreating snapshots\n~~~~~~~~~~~~~~~~~~\n\n  $ hesfic create /path/to/directory\n\nThis will create a snapshot of the given directory. Append --comment=\"some\ntext\" option to add comment for this snapshot.\n\n\nListing snapshots\n~~~~~~~~~~~~~~~~~\n\n  $ hesfic list-snapshots\n\nExample output:\n\n  snapshot:     12d2c72a-e5d7cd59-4a819043-50656080-e0a2d686-3add22ce\n  date:         Mon, 24 Dec 2012 17:10:24 CET\n  source path:  /Users/pupkin/Documents\n  root ref:     fbefb02f5fa94cc861c9286f251850de977e0c4319ffe497\n  comment:      First snapshot.\n\n\"Snapshot\" is the unique name of the snapshot.\n\n\nListing files inside snapshots\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n  $ hesfic list-files \u003csnapshot name or directory ref\u003e\n\n\nRestoring snapshots\n~~~~~~~~~~~~~~~~~~~\n\n  $ hesfic restore \u003csnapshot name or directory ref\u003e /path/to/destination\n\n\nVerify\n~~~~~~\n\n  $ hesfic verify\n\nVerifies consistency of the store.\n\n\nGarbage collection\n~~~~~~~~~~~~~~~~~~\n\n  $ hesfic gc\n\nGarbage collection looks for unused blocks and removes them.\n\n\nDebugging\n~~~~~~~~~\n\n  $ hesfic show-ref \u003cref\u003e\n\nOutputs content stored under the given ref.\n\n\nLogging\n~~~~~~~\n\nTo log perfomed actions, append -log switch.\n\n\nWeb interface\n~~~~~~~~~~~~~\n\n  $ hesfic web [addr:port]\n\nLaunches web interface, which allows browsing snapshots and\ndirectories, and (in the future) download files. If addr:port\nis zero, listen on localhost:0 (random port).\n\n\nTECHNICAL DETAILS\n-----------------\n\nRough description:\n\nFiles are split into blocks of configurable size (2 MiB by default).  Each\nblock is hashed with a keyed hash function BLAKE2b (this hash is called a ref\nand used to address the block). The content of the block is compressed with\nSnappy, padded to the multiple of 512 bytes and encrypted with XSalsa20 and\nauthenticated with Poly1305 (NaCl's secretbox), and stored somewhere.\n\nIf the file consists of a single block, the ref to this block is the ref to the\nfile itself. If there are two or more blocks, another block is created to store\nthe array of refs (pointers) to blocks; ref to this file then is the ref to\nthis block of pointers. Each block has an type indicator: whether it's a data\nblock or a pointer block.\n\nDirectories are stored recursively as JSON files which contain file (or\nsubdirectory) names and attributes (permissions, size, modification time) and\nrefs to content. Example:\n\n  [\n    { \"ModTime\" : \"2012-12-24T13:32:20+01:00\",\n      \"Mode\" : 420,\n      \"Name\" : \".DS_Store\",\n      \"Ref\" : \"0f70108dc403bdb7c0291e687ad2ada7409202a24d3a7cf2\",\n      \"Size\" : 6148\n    },\n    { \"ModTime\" : \"2012-12-23T17:57:54+01:00\",\n      \"Mode\" : 2147484141,\n      \"Name\" : \"mruby\",\n      \"Ref\" : \"cae111449fd206908f10824e9bbc6782cf604b3cef20d6b0\",\n      \"Size\" : 986\n    }\n  ]\n\n\".DS_Store\" is a file, \"mruby\" is a subdirectory, as indicated by\nMode field. Now if we do\n\n  $ hesfic show-ref cae111449fd206908f10824e9bbc6782cf604b3cef20d6b0\n\nwe get the JSON description of \"mruby\" subdirectory.\n\nBlocks are stored in \"blocks\" subdirectory of the output directory.\n\nSnapshots are stored in \"snapshots\" subdirectory. Snapshots are encrypted JSON\nfiles, which store refs to the root directory and additional information about\nsnapshot (date, source directory path, comment). Snapshots have unique names in\nthe following format: 8-byte timestamp || 16 random bytes. The name also serves\nas a nonce for encryption/authentication.\n\n\nKeyed hashing, block encryption/authentication, and snapshot\nencryption/authentication use separate 256-bit keys.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdchest%2Fhesfic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdchest%2Fhesfic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdchest%2Fhesfic/lists"}