{"id":13612834,"url":"https://github.com/dsprenkels/sss","last_synced_at":"2025-04-06T00:08:58.030Z","repository":{"id":37484335,"uuid":"87306299","full_name":"dsprenkels/sss","owner":"dsprenkels","description":"Library for the Shamir secret sharing scheme","archived":false,"fork":false,"pushed_at":"2022-03-18T23:43:10.000Z","size":110,"stargazers_count":368,"open_issues_count":6,"forks_count":81,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-03-29T23:08:47.723Z","etag":null,"topics":["cryptography","shamir-secret-sharing"],"latest_commit_sha":null,"homepage":"","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/dsprenkels.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}},"created_at":"2017-04-05T12:23:47.000Z","updated_at":"2025-03-25T22:15:25.000Z","dependencies_parsed_at":"2022-08-08T20:30:35.284Z","dependency_job_id":null,"html_url":"https://github.com/dsprenkels/sss","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsprenkels%2Fsss","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsprenkels%2Fsss/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsprenkels%2Fsss/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsprenkels%2Fsss/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dsprenkels","download_url":"https://codeload.github.com/dsprenkels/sss/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247415967,"owners_count":20935387,"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":["cryptography","shamir-secret-sharing"],"created_at":"2024-08-01T20:00:35.130Z","updated_at":"2025-04-06T00:08:58.010Z","avatar_url":"https://github.com/dsprenkels.png","language":"C","funding_links":[],"categories":["C"],"sub_categories":[],"readme":"# Shamir secret sharing library\n\n[![Build Status](https://travis-ci.org/dsprenkels/sss.svg?branch=master)](https://travis-ci.org/dsprenkels/sss)\n\n`sss` is a library that exposes an API to split secret data buffers into\na number of different _shares_. With the possession of some or all of these\nshares, the original secret can be restored. It is the schoolbook example of\na cryptographic _threshold scheme_. This library has a [command line\ninterface][sss-cli]. ([web demo])\n\n[sss-cli]: https://github.com/dsprenkels/sss-cli\n\n## Table of contents\n\n1. [Introduction](#introduction)\n2. [Download](#download)\n3. [Usage](#usage)\n\t1. [Example](#example)\n  \t2. [How to Run Program (above)](#How-to-Run-program-(above))\n4. [Bindings](#bindings)\n5. [Technical details](#technical-details)\n6. [Comparison of secret sharing libraries](#comparison-of-secret-sharing-libraries)\n7. [Questions](#questions)\n\n## Introduction\n\nAn example use case is a beer brewery which has a vault which contains their\nprecious super secret recipe. The 5 board members of this brewery do not trust\nall the others well enough that they won't secretly break into the vault and\nsell the recipe to a competitor. So they split the code into 5 shares, and\nallow 4 shares to restore the original code. Now they are sure that the\nmajority of the staff will know when the vault is opened, but they can still\nopen the vault when one of the staff members is abroad or sick at home.\n\nAs often with crypto libraries, there is a lot of Shamir secret sharing code\naround that *does not meet cryptographic standards* (a.k.a. is insecure).\nSome details—like integrity checks and side-channel resistance—are often\nforgotten. But these slip-ups can often fully compromise the security of the\nscheme.\nWith this in mind, I have made this library to:\n- Be side channel resistant (timing, branch, cache)\n- Secure the shared secret with a MAC\n- Use the platform (OS) randomness source\n\nIt should be safe to use this library in \"the real world\". I currently regard\nthe API as being stable. Should there be any breaking changes, then I will\nupdate the version number conforming to the [semantic versioning spec][semver].\n\n[semver]: http://semver.org/\n\n## Download\n\nI have released version 0.1.0 of this library, which can be downloaded from\nthe [releases](https://github.com/dsprenkels/sss/releases) page. However, I\nactually recommend cloning the library with git, to also get the necesarry\nsubmodules:\n\n```shell\ngit clone --recursive https://github.com/dsprenkels/sss.git\n```\n\nThe current version is version 0.1.0, which should be stable enough for now.\nThe functionality may still change before version 1.0.0, although I will\nstill fix any security issues before that.\n\n## Usage\n\nSecrets are provided as arrays of 64 bytes long. This should be big enough to\nstore generally small secrets. If you wish to split larger chunks of data, you\ncan use symmetric encryption and split the key instead. Shares are generated\nfrom secret data using `sss_create_shares` and shares can be combined again\nusing the `sss_combine_shares` functions. The shares are octet strings of\n113 bytes each.\n\nThis library is implemented in such a way that the maximum number of shares\nis 255.\n\nMoreover, every share includes an ID, which is implemented as a counter.\nThis ID is not considered a secret by the library, and an participants may be\nable to infer the amount of shares from these ids (for example, if I have a\nshare with ID=3, I expect that ID∈{1,2} will also exist.\nIf you require random share IDs, then you should generate 255 different\nshares, and randomly throw away the excess shares.\n\n### Example\n\n```c\n#include \"sss.h\"\n#include \"randombytes.h\"\n#include \u003cassert.h\u003e\n#include \u003cstring.h\u003e\n\nint main()\n{\n\tuint8_t data[sss_MLEN], restored[sss_MLEN];\n\tsss_Share shares[5];\n\tsize_t idx;\n\tint tmp;\n\n\t// Read a message to be shared\n\tstrncpy(data, \"Tyler Durden isn't real.\", sizeof(data));\n\n\t// Split the secret into 5 shares (with a recombination theshold of 4)\n\tsss_create_shares(shares, data, 5, 4);\n\n\t// Combine some of the shares to restore the original secret\n\ttmp = sss_combine_shares(restored, shares, 4);\n\tassert(tmp == 0);\n\tassert(memcmp(restored, data, sss_MLEN) == 0);\n}\n```\n\n## How to Run program (above)\n\n1. clone from git by bellow command. (As It is recommended. If you clone make sure that file under subdirectory also came with it)\n```shell\ngit clone --recursive https://github.com/dsprenkels/sss.git\n```\n\n2. go inside sss directory and run make command\n```shell\nmake\n```\n\n3. copy the example provided in readme as above and save it as demo.c\n\n4. compile demo.c by running bellow commnad\n```shell\ngcc demo.c -o demo randombytes.o sss.o hazmat.o tweetnacl.o\n```\n\n5. execute program by bellow command\n```shell\n./demo\n```\n\n## Bindings\n\nI have currently written bindings for the following languages:\n\n- [Node.js](https://github.com/dsprenkels/sss-node)\n- [Go](https://github.com/dsprenkels/sss-go)\n- [Rust](https://github.com/dsprenkels/sss-rs)\n- [WASM](https://github.com/3box/sss-wasm)\n- [Android](https://github.com/dsprenkels/sss-android)¹\n- [Haskell](https://github.com/dsprenkels/sss-hs)¹\n- [Swift](https://github.com/dsprenkels/sss-swift)¹\n\u003e ¹ No releases yet.\n\nThere are also contributed bindings:\n\n- [Nim](https://github.com/markspanbroek/sss.nim)\n- [Erlang](https://github.com/arekinath/esss)\n\n## Technical details\n\nShamir secret sharing works by generating a polynomial (e.g. _33x³ + 8x² + 29x +\n42_). The lowest term is the secret and is just filled in. All the\nother terms are generated randomly. Then we can pick points on the polynomial\nby filling in values for _x_. Each point is put in a share. Afterwards, with _k_\npoints we can use interpolation to restore a _k_-degree polynomial.\n\nIn practice there is a wrapper around the secret-sharing part (this is done\nbecause of crypto-technical reasons). This wrapper uses the XSalsa20/Poly1305\nauthenticated encryption scheme. Because of this, the shares are always a little\nbit larger than the original data.\n\nThis library uses a custom [`randombytes`][randombytes] function to generate a\nrandom encapsulation key, which talks directly to the operating system. When\nusing the high level API, you are not allowed to choose your own key. It _must_\nbe uniformly random, because regularities in shared secrets can be exploited.\n\nWith the low level API (`hazmat.h`) you _can_ choose to secret-share a piece of\ndata of exactly 32 bytes. This produces a set of shares that are much shorter\nthan the high-level shares (namely 33 bytes each). However, keep in mind that\nthis module is called `hazmat.h` (for \"hazardous materials\") for a reason.\nPlease only use this if you _really_ know what you are doing. Raw \"textbook\"\nShamir secret sharing is only safe when using a uniformly random secret (with\n128 bits of entropy). Note also that it is entirely insecure for integrity.\nPlease do not use the low-level API unless you _really_ have no other choice.\n\n## Comparison of secret-sharing libraries\n\nIf you would like your library to be added here, please open a pull request. :)\n\n| Library         | Side-channels | Tamper-resistant | Secret length |\n|-----------------|---------------|------------------|---------------|\n| [B. Poettering] | Insecure¹     | Insecure         | 128 bytes     |\n| [libgfshare]    | Insecure²     | Insecure         | ∞             |\n| [blockstack]    | ??³           | Insecure         | 160 bytes     |\n| [sssa-golang]   | Secure        | Secure⁴          | ∞             |\n| [sssa-ruby]     | ??³           | Secure⁴          | ∞             |\n| [snipsco]       | Secure        | Insecure         | Note⁶         |\n| [c-sss]         | Insecure⁷     | Insecure         | ∞             |\n| [timtiemens]    | Insecure⁸     | Note⁹            | 512 bytes     |\n| [dsprenkels]    | Secure        | Secure⁵          | 64 bytes      |\n\n### Notes\n\nIt is important to note that a limited secret length does not mean\nthat it is impossible to share longer secrets. The way this is done is\nby secret sharing a random key and using this key to encrypt the real\nsecret. This is a lot faster and the security is not reduced. (This is\nactually how [sss-cli] produces variable-length shares.)\n\n1. Uses the GNU gmp library.\n2. Uses lookup tables for GF(256) multiplication.\n3. This library is implemented in a high level scripting library which does not\n   guarantee that its basic operators execute in constant-time.\n4. Uses randomized *x*-coordinates.\n5. Uses randomized *y*-coordinates.\n6. When using the [snipsco] library you will have to specify your own prime.\n   Computation time is _O(p²)_, so on a normal computer you will be limited to\n   a secret size of ~1024 bytes.\n7. As mentioned by the [documentation](https://github.com/fletcher/c-sss#security-issues).\n8. Uses Java `BigInteger` class.\n9. Basic usage of this tool does not protect the integrity of the secrets.\n   However, the project's readme file advises the user to use a hybrid\n   encryption scheme and secret share the key. Through destroying the ephemeral\n   key, the example that is listed in the readme file protects prevents an\n   attacker from arbitrarily inserting a secret. However, inserting a garbled\n   secret is still possible. To prevent this the user should use a AEAD scheme\n   (like AES-GCM or ChaCha20-Poly1305) instead of AES-CBC.\n\n[B. Poettering]: http://point-at-infinity.org/ssss/\n[libgfshare]: https://github.com/jcushman/libgfshare\n[blockstack]: https://github.com/blockstack/secret-sharing\n[sssa-golang]: https://github.com/SSSaaS/sssa-golang\n[sssa-ruby]: https://github.com/SSSaaS/sssa-ruby\n[snipsco]: https://github.com/snipsco/rust-threshold-secret-sharing\n[c-sss]: https://github.com/fletcher/c-sss\n[timtiemens]: https://github.com/timtiemens/secretshare\n[dsprenkels]: https://github.com/dsprenkels/sss\n\n\n## Questions\n\n### I do not know a lot about secret sharing. Is Shamir secret sharing useful for me?\n\nIt depends. In the case of threshold schemes (that's what this is) there are\ntwo types:\n\n1. The share-holders _cannot_ verify that their shares are valid.\n2. The share-holders _can_ verify that their shares are valid.\n\nShamir's scheme is of the first type. This immediately implies that the dealer\ncould cheat. Indeed, they can distribute a number of shares which are just\nrandom strings. The only way the participants could know is by banding together\nand trying to restore the secret. This would show the secret, which would make\nthe scheme totally pointless.\n\n**Use Shamir secret sharing only if the dealer _and_ the participants have no\nreason to corrupt any shares.**\n\nExamples where this is _not_ the case:\n\n- When the secret hides something that is embarrasing for one of the\n  participants.\n- When the shared secret is something like a testament, and the participants\n  are the heirs. If one of the heirs inherits more wealth when the secret is\n  not disclosed, they can corrupt their share (and it would be impossible to\n  check this from the share alone).\n\nIn these cases, you will need a scheme of the second type. See the next\nquestion.\n\n### Wait, I need verifiable shares! What should I use instead?\n\nThere are two straightforward options:\n\n1. When the secret is fully random—for example, a cryptographic key—use\n   **Feldman verifiable secret sharing**.\n2. When the secret is not fully random—it _could_ be a message, a number,\n   etc.—use **Pedersen verifiable secret sharing**.\n\n### Other\n\nFor other questions, feel free to open an issue or send me an email on my Github\nassociated e-mail address.\n\n[web demo]: http://bakaoh.com/sss-wasm/\n[randombytes]: https://github.com/dsprenkels/randombytes\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdsprenkels%2Fsss","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdsprenkels%2Fsss","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdsprenkels%2Fsss/lists"}