{"id":13734107,"url":"https://github.com/kerukuro/digestpp","last_synced_at":"2025-05-08T10:31:10.954Z","repository":{"id":26505540,"uuid":"108105774","full_name":"kerukuro/digestpp","owner":"kerukuro","description":"C++11 header-only message digest library","archived":false,"fork":false,"pushed_at":"2024-07-12T07:37:15.000Z","size":7794,"stargazers_count":197,"open_issues_count":4,"forks_count":47,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-11-15T02:34:33.984Z","etag":null,"topics":["blake","blake2","blake2x","cshake","groestl","hash","kangarootwelve","kmac","kupyna","marsupilamifourteen","sha1","sha256","sha3","sha512","sha512-256","shake","skein","sm3","whirlpool","xof"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kerukuro.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":"2017-10-24T09:32:06.000Z","updated_at":"2024-11-12T22:19:37.000Z","dependencies_parsed_at":"2024-11-15T02:42:29.852Z","dependency_job_id":null,"html_url":"https://github.com/kerukuro/digestpp","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/kerukuro%2Fdigestpp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kerukuro%2Fdigestpp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kerukuro%2Fdigestpp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kerukuro%2Fdigestpp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kerukuro","download_url":"https://codeload.github.com/kerukuro/digestpp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253045664,"owners_count":21845748,"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":["blake","blake2","blake2x","cshake","groestl","hash","kangarootwelve","kmac","kupyna","marsupilamifourteen","sha1","sha256","sha3","sha512","sha512-256","shake","skein","sm3","whirlpool","xof"],"created_at":"2024-08-03T03:00:52.643Z","updated_at":"2025-05-08T10:31:09.397Z","avatar_url":"https://github.com/kerukuro.png","language":"C++","readme":"# digestpp\nExperimental C++11 header-only message digest library.\n\nDerived from cppcrypto in an attempt to devise a more modern yet flexible and universal C++ API for cryptographic hash functions.\n\nTested with g++ 6.4.0, clang 4.0.1 and Visual C++ 2017.\n\n## Examples\nCalculate BLAKE2b digest from a double quoted string and output it in hex format:\n````C++\ncout \u003c\u003c blake2b().absorb(\"The quick brown fox jumps over the lazy dog\").hexdigest();\n````\nCalculate BLAKE2b-256 digest from an std::string and output it in hex format:\n````C++\nstring str = \"The quick brown fox jumps over the lazy dog\";\ncout \u003c\u003c blake2b(256).absorb(str).hexdigest();\n````\nCalculate SHA-512 digest of a vector\u003cunsigned char\u003e and output it in hex format:\n````C++\nvector\u003cunsigned char\u003e v;\n// ...fill the vector\ncout \u003c\u003c sha512().absorb(v.begin(), v.end()).hexdigest();\n````\nCalculate SHA-512/256 digest of a C array and output it in hex format:\n````C++\nunsigned char c[32];\n// ...fill the array\ncout \u003c\u003c sha512(256).absorb(c, sizeof(c)).hexdigest();\n````\nCalculate SHA-256 digest of a file and output it in hex format:\n````C++\nifstream file(\"filename\", ios_base::in|ios_base::binary);\ncout \u003c\u003c sha256().absorb(file).hexdigest();\n````\nGenerate SHA3-224 digest using multiple calls to absorb():\n````C++\ncout \u003c\u003c sha3(224).absorb(\"The quick brown fox \").absorb(\"jumps over the lazy dog\").hexdigest();\n````\nOutput binary digest to a vector\u003cunsigned char\u003e:\n````C++\nvector\u003cunsigned char\u003e v;\nsha3(256).absorb(\"The quick brown fox jumps over the lazy dog\").digest(back_inserter(v));\n````\nOutput binary digest to a raw C array:\n````C++\nunsigned char buf[32];\nsha3(256).absorb(\"The quick brown fox jumps over the lazy dog\").digest(buf, sizeof(buf));\n````\nOutput binary digest to a stream:\n````C++\nstring str = \"The quick brown fox jumps over the lazy dog\";\nstring output;\nostringstream os(output);\nsha3(256).absorb(str).digest(ostream_iterator\u003cchar\u003e(os, \"\"));\n````\nGenerate long output using SHAKE-256 extendable output function using multiple calls to squeeze():\n````C++\nvector\u003cunsigned char\u003e v;\nshake256 xof;\nxof.absorb(\"The quick brown fox jumps over the lazy dog\");\nxof.squeeze(1000, back_inserter(v));\nxof.squeeze(1000, back_inserter(v));\nxof.squeeze(1000, back_inserter(v));\ncout \u003c\u003c \"Squeezed \" \u003c\u003c v.size() \u003c\u003c \" bytes.\" \u003c\u003c endl;\n````\nGenerate 64-byte digest using customizable cSHAKE-256 algorithm and print it in hex format:\n````C++\ncshake256 xof;\nxof.set_customization(\"Customization\");\ncout \u003c\u003c xof.absorb(\"The quick brown fox jumps over the lazy dog\").hexsqueeze(64);\n````\n\n## Hasher class\n\nHasher is a main class template implementing the public API for hashing.\n\nIt has two template parameters:\n- HashProvider is a class implementing the algorithm via traditional init/update/final interface. We provide our own implementations of hash functions listed in the next section, but using the traditional interface allows anyone to trivially implement the providers as wrappers over popular libraries, such as OpenSSL, Crypto++, Botan.\n- Mixin is a class template which can be used to inject additional functions to the public API of the hasher, for example for setting the customization string for cSHAKE, the salt for BLAKE, etc.\n\n````C++\ntemplate\u003cclass HashProvider, template \u003cclass\u003e class Mixin = detail::null_mixin\u003e\nclass hasher : public Mixin\u003cHashProvider\u003e\n{\npublic:\n    // Default constructor\n    // Used for hash functions with fixed output size, for hash functions with sensible\n    // default output size and for exendable output functions (XOFs).\n    template\u003ctypename H=HashProvider,\n        typename std::enable_if\u003cstd::is_default_constructible\u003cH\u003e::value\u003e::type* = nullptr\u003e\n    hasher();\n\n    // Constructor with hashsize parameter\n    // Used with hash functions which can produce hashes of different lengths.\n    // If the requested output size is not supported by the algorithm, std::runtime_error will be thrown.\n    template\u003ctypename H=HashProvider, typename std::enable_if\u003c!detail::is_xof\u003cH\u003e::value\u003e::type* = nullptr\u003e\n    hasher(size_t hashsize);\n\n     // Absorbs bytes from a C-style pointer to character buffer\n    template\u003ctypename T, typename std::enable_if\u003cdetail::is_byte\u003cT\u003e::value\u003e::type* = nullptr\u003e\n    inline hasher\u0026 absorb(const T* data, size_t len);\n\n    // Absorbs bytes from std::basic_string\n    template\u003ctypename T,\n        typename std::enable_if\u003cdetail::is_byte\u003cT\u003e::value\n            \u0026\u0026 !std::is_same\u003cT, std::string::value_type\u003e::value\u003e::type* = nullptr\u003e\n    inline hasher\u0026 absorb(const std::basic_string\u003cT\u003e\u0026 str);\n\n    // Absorbs bytes from std::string\n    inline hasher\u0026 absorb(const std::string\u0026 str);\n\n    // Absorbs bytes from std::istream\n    template\u003ctypename T, typename std::enable_if\u003cdetail::is_byte\u003cT\u003e::value\u003e::type* = nullptr\u003e;\n    inline hasher\u0026 absorb(std::basic_istream\u003cT\u003e\u0026 istr);\n\n    // Absorbs bytes from an iterator sequence\n    template\u003ctypename IT\u003e\n    inline hasher\u0026 absorb(IT begin, IT end);\n\n    // In case HashProvider is an extendable output function, squeeze \u003clen\u003e bytes from absorbed data\n    // into user-provided preallocated buffer.\n    template\u003ctypename T, typename H=HashProvider,\n        typename std::enable_if\u003cdetail::is_byte\u003cT\u003e::value \u0026\u0026 detail::is_xof\u003cH\u003e::value\u003e::type* = nullptr\u003e\n    inline void squeeze(T* buf, size_t len);\n\n    // In case HashProvider is an extendable output function, squeeze \u003clen\u003e bytes from absorbed data\n    // and write them into the output iterator.\n    template\u003ctypename OI, typename H=HashProvider,\n        typename std::enable_if\u003cdetail::is_xof\u003cH\u003e::value\u003e::type* = nullptr\u003e\n    inline void squeeze(size_t len, OI it);\n\n    // In case HashProvider is an extendable output function, squeeze \u003clen\u003e bytes from absorbed data\n    // and return them as a hex string.\n    template\u003ctypename H=HashProvider, typename std::enable_if\u003cdetail::is_xof\u003cH\u003e::value\u003e::type* = nullptr\u003e\n    inline std::string hexsqueeze(size_t len);\n\n    // In case HashProvider is a hash function, output binary digest to user-provided preallocated buffer.\n    template\u003ctypename T, typename H=HashProvider,\n        typename std::enable_if\u003cdetail::is_byte\u003cT\u003e::value \u0026\u0026 !detail::is_xof\u003cH\u003e::value\u003e::type* = nullptr\u003e\n    inline void digest(T* buf, size_t len) const;\n\n    // In case HashProvider is a hash function, generates binary digest from absorbed data\n    // and write it via output iterator.\n    template\u003ctypename OI, typename H=HashProvider,\n        typename std::enable_if\u003c!detail::is_xof\u003cH\u003e::value\u003e::type* = nullptr\u003e\n    inline void digest(OI it) const;\n\n    // In case HashProvider is a hash function, returns hex digest of absorbed data.\n    template\u003ctypename H=HashProvider, typename std::enable_if\u003c!detail::is_xof\u003cH\u003e::value\u003e::type* = nullptr\u003e\n    inline std::string hexdigest() const;\n\n    // Resets the state to start new digest computation.\n    // If resetParameters is true, all customization parameters such as salt will also be cleared.\n    inline void reset(bool resetParameters = false);\n};\n````\n\nIndividual hash algorithms are defined by typedefs, e.g.\n````C++\n    typedef hasher\u003cdetail::sha3_provider\u003e sha3;\n\n    typedef hasher\u003cdetail::blake_provider, detail::blake_mixin\u003e blake;\n\n    // ...\n````\n\n## Supported algorithms\n\n### Hash functions\n\nTypedef|Description|Supported output sizes|Optional parameters\n-------|-----------|----------------------|-------------------\nblake|Original BLAKE algorithm|224, 256, 384, 512|salt\nblake2b|BLAKE2b|8-512|salt, personalization, key\nblake2s|BLAKE2s|8-256|salt, personalization, key\nblake2xb|BLAKE2xb|arbitrary|salt, personalization, key\nblake2xs|BLAKE2xs|arbitrary|salt, personalization, key\necho|Echo|8-512|salt\nesch|Esch|256, 384|-\ngroestl|Grøstl|8-512|-\njh|JH|8-512|-\nkmac128|KMAC128|arbitrary|key, customization\nkmac256|KMAC256|arbitrary|key, customization\nkupyna|Kupyna|256, 512|-\nmd5|MD5|128|-\nsha1|SHA-1|160|-\nsha224|SHA-224|224|-\nsha256|SHA-256|256|-\nsha384|SHA-384|384|-\nsha512|SHA-512|8-512|-\nsha3|SHA-3|224, 256, 384, 512|-\nskein256|Skein256|arbitrary|personalization, key, nonce\nskein512|Skein512|arbitrary|personalization, key, nonce\nskein1024|Skein1024|arbitrary|personalization, key, nonce\nsm3|SM3|256|-\nstreebog|Streebog|256, 512|-\nwhirlpool|Whirlpool|512|-\n\n### Extendable output functions\n\nTypedef|Description|Optional parameters\n-------|-----------|-------------------\nblake2xb_xof|BLAKE2xb in XOF mode|salt, personalization, key\nblake2xs_xof|BLAKE2xs in XOF mode|salt, personalization, key\nesch256_xof|XOEsch256|-\nesch384_xof|XOEsch384|-\nk12|KangarooTwelve|customization\nm14|MarsupilamiFourteen|customization\nshake128|SHAKE-128|-\nshake256|SHAKE-256|-\ncshake128|cSHAKE-128|function name, customization\ncshake256|cSHAKE-256|function name, customization\nkmac128_xof|KMAC128 in XOF mode|key, customization\nkmac256_xof|KMAC256 in XOF mode|key, customization\nskein256_xof|Skein256 in XOF mode|personalization, key, nonce\nskein512_xof|Skein512 in XOF mode|personalization, key, nonce\nskein1024_xof|Skein1024 in XOF mode|personalization, key, nonce\n\n## Design rationale in questions and answers\n\nQ: What is the difference between a hash function with variable output size and an extendable output function (XOF)?\n\nA: Hash functions require the digest size to be known at the moment of initialization and normally produce unrelated outputs for different digest sizes. For example, `blake2b(256)` and `blake2b(512)` produce completely different digests. XOFs are functions that do not need to know the output size in advance and can produce outputs of unrestricted size. Bytes generated by XOFs depend only on the input data, but not on the digest size. It is generally recommended to use hash functions instead of XOFs when the output size is known in advance.\n\n\nQ: What is the difference between `digest()` and `squeeze()`?\n\nA. `digest()` is used with hash functions; it retrieves a digest of a certain length (defined by the algorithm or specified in the constructor). Calling `digest()` or `hexdigest()` does not change the internal state, so that these functions can be called more than once and will produce the same output. `squeeze()` is used with XOF functions; it can be called multiple times to squeeze an arbitrary number of output bytes. After each invocation of `squeeze()` the internal state changes so that the next call to `squeeze()` will generate different (additional) output bytes.\n\n\nQ: For hash functions with variable output size, why the output size is not a template parameter, e.g. `sha3\u003c256\u003e`?\n\nA: While it may seem cool to make the output size a template parameter, in some usage scenarios the required digest size is not known at compile time. One simple example is Argon2 password hashing algorithm, which requires us to hash its state using BLAKE2b with dynamically calculated digest size. We can't just use the largest digest size and truncate the result, because most hash functions (unlike XOFs) produce completely different digests depending on the requested output size. Using a template parameter for the digest size would encumber implementation of such algorithms. Additionally, some hash functions support arbitrary output sizes which are not limited by the security level (examples of such functions are Skein, BLAKE2x, ParallelHash). Some functions are specifically designed to be usable both in hashing and in XOF modes, where the required output size is not known in advance even at runtime. Taking all this factors in consideration, specifying the output size at compile time does not seem like a good design.\n\n\nQ: Why `hasher` does not support hashing non-byte types?\n\nA: Cryptographic hash functions are always defined for a sequence of bytes. We support only those data types that can be unambiguosly converted to bytes (sequences of `char`, `signed char`, or `unsigned char`). Other data types should be converted to a sequence of bytes in non-ambiguous way before they can be hashed (eg wide strings could be encoded using UTF-8 or another encoding), which is beyond the scope of the library.\n\n\nQ: Since the output size has to be provided to the constructor, why there are separate typedefs for `sha256` and `sha512` instead of one hasher with output size parameter: `sha2(256)` / `sha2(512)`?\n\nA: SHA-2 family of hash functions is special because SHA-512 can produce output of any size up to 512 bits (SHA-512/t), e.g. `sha512(256)` will calculate SHA-512/256. The resulting hash is different from SHA-256, but has the same length. Thus SHA-512 is an independent hash function supporting variable output sizes. On the other hand, the 32-bit version of SHA-2 is only defined for 224-bit and 256-bit outputs, and they are widely known as SHA-224 and SHA-256. We decided to use different typedefs for SHA-224 and SHA-256 because requiring users to use `sha256(224)` for getting SHA-224 digests would be confusing. Internally all SHA-2 functions are implemented using one template class.\n\n\nQ: Why there are separate typedefs for `skein256`, `skein512` and `skein1024` instead of one hasher with output size parameter: `skein(256)` / `skein(512)` / `skein(1024)`?\n\nA: Skein256, Skein512 and Skein1024 are different algorithms. Each of them can produce digests of any size. The outputs are unrelated, e.g. `skein256(256)` != `skein512(256)` != `skein1024(256)`. Internally all Skein variants are implemented using one template class.\n\n\nQ: Why there are so many typedefs for BLAKE2 hash function?\n\nA: BLAKE2 has many variants that produce incompatible digests for the same output sizes. We support different variants via different typedef. For the 512-bit version, `blake2b` is the oldest algorithm which can produce digests of any size up to 512 bits. `blake2xb` can be used to produce larger digests but requires the output size to be known in advance; it can't be merged with `blake2b` because their output are different for the same digest sizes. `blake2xb_xof` can be used in XOF mode when the output size is not known in advance. Then there is a 256-bit version `blake2s` which supports all these variants as well. Internally all BLAKE2 variants are implemented using one template class.\n\n## Known limitations\n\n* Included providers are written in standard C++ and may be slower than SIMD optimized implementations.\n* Only complete bytes are supported for input and output.\n* Big endian systems are not supported.\n* No attempts were made to make implementation of every algorithm constant time.\n\n## Reference documentation\n\nReference documentation is here: https://kerukuro.github.io/digestpp/\n\n\n\n","funding_links":[],"categories":["Cryptography","Cryptography and Security"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkerukuro%2Fdigestpp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkerukuro%2Fdigestpp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkerukuro%2Fdigestpp/lists"}