From bd0b7e0d895c7f6b43600e91cb1b1d3169196554 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Sat, 3 Dec 2022 13:19:08 -0500 Subject: [PATCH 01/56] Update README to reflect changes. --- README.md | 49 ++++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 85294d6..15add65 100644 --- a/README.md +++ b/README.md @@ -6,18 +6,19 @@ Hash++ is a C++17 header-only library that allows a user to retrieve multiple types of hashes from data, files, and files in nested directories. The original purpose behind this library was to create a header-file only implementation of multiple different hash algorithms. You can find a list of the currently supported hash algorithms below.

Supported Algorithms

- + +| Algorithm | HMAC Support? | +| :-------------: | :-----------------: | +| MD5 | :heavy_check_mark: | +| MD4 | :heavy_check_mark: | +| MD2 | :heavy_check_mark: | +| SHA1 | :heavy_check_mark: | +| SHA2-224 | :heavy_check_mark: | +| SHA2-256 | :heavy_check_mark: | +| SHA2-384 | :heavy_check_mark: | +| SHA2-512 | :heavy_check_mark: | +| SHA2-512/224 | :heavy_check_mark: | +| SHA2-512/256 | :heavy_check_mark: | Hash++ also aims to be a suitable alternative to heavier, statically and dynamically-linked libraries such as OpenSSL and Crypto++. I created it keeping in mind the mindset of a programmer who simply wants a header-only file that lets them easily and comfortably "just hash sh*t." Does it really have to be that difficult? @@ -33,7 +34,7 @@ No, it doesn't. |------------------|---------------------------------------------| | 64-bit test: | | | | | [MD5] | 7846 ms | 7.846 s | 1,274,535 hashes/s | -| [MD4] | 5783 ms | 5.783 s | 1,729,206 hashes/s | +| [MD4] | 7846 ms | 7.846 s | 1,274,535 hashes/s | | [MD2] | 181315 ms | 181.315 s | 55,153 hashes/s | | [SHA1] | 8676 ms | 8.676 s | 1,152,605 hashes/s | | [SHA2-224] | 12370 ms | 12.370 s | 808,407 hashes/s | @@ -99,23 +100,25 @@ Below you can find the signatures of the only functions necessary to acco

You can find examples of Hash++ in use in the /examples and /tests directories.
-

getHash

-Retrieve a single hash from a single piece of data. +

getHash(...), getHMAC(...)

+Retrieve a single hash from a single piece of data, or retrieve an HMAC from a key-data pair. ```cpp -// function to return a resulting hash from selected ALGORITHM and passed data -static hashpp::hash getHash(hashpp::ALGORITHMS algorithm, const std::string& data) +static hashpp::hash getHash(hashpp::ALGORITHMS algorithm, const std::string& data); +static hashpp::hash getHMAC(hashpp::ALGORITHMS algorithm, const std::string& key, const std::string& data) ``` -

getHashes

-Retrieve a collection of hashes from multiple pieces of data. +

getHashes(...), getHMACs(...)

+Retrieve a collection of hashes from multiple pieces of data, or retrieve a collection of HMACs from multiple pieces of data. ```cpp -// function to return a collection of resulting hashes from selected ALGORITHMS and passed data -static hashpp::hashCollection getHashes(const std::vector>>& algorithmDataPairs) +static hashpp::hashCollection getHashes(const std::vector>>& algorithmDataPairs); +template static hashpp::hashCollection getHashes(hashpp::ALGORITHMS algorithm, const _Ts&... data); +static hashpp::hashCollection getHMACs(const std::vector>>>& algorithmKeyDataPairs); +template static hashpp::hashCollection getHMACs(hashpp::ALGORITHMS algorithm, const std::string& key, const _Ts&... data) ``` -

getFileHash

+

getFileHash(...)

Retrieve a single hash from a single file. ```cpp @@ -123,7 +126,7 @@ Retrieve a single hash from a single file. static hashpp::hash getFileHash(hashpp::ALGORITHMS algorithm, const std::string& path) ``` -

getFilesHashes

+

getFilesHashes(...)

Retrieve a collection of hashes from multiple files or files in nested directories. ```cpp From bf43ed704f3431de4130eb46c4ae9aa3ba3f6d60 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Sat, 3 Dec 2022 13:28:58 -0500 Subject: [PATCH 02/56] Add new features. - Add HMAC implementation for all hash algorithms. - Add various overloads for existing functions and new HMAC-related functions. - Add HMAC testing functions to optional metrics class. See file for more. --- include/hashpp.h | 1184 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1176 insertions(+), 8 deletions(-) diff --git a/include/hashpp.h b/include/hashpp.h index 1c99a67..a8208a0 100644 --- a/include/hashpp.h +++ b/include/hashpp.h @@ -164,18 +164,38 @@ namespace hashpp { return this->bytesToHexString(); } + std::string getHMAC(std::string key, std::string data) { + return this->HMAC(key, data); + } + protected: // virtual functions to be overridden by each algorithm implementation. virtual std::vector getBytes() = 0; virtual void ctx_init() = 0; virtual void ctx_update(const uint8_t*, size_t) = 0; - virtual void ctx_final() = 0; + virtual void ctx_final() = 0; + + // H as defined in https://www.rfc-editor.org/rfc/rfc2104 for + // Keyed-Hashing for Message Authentication + virtual std::string _H(const std::string&, const std::string&) = 0; + virtual std::string HMAC(const std::string&, const std::string&) = 0; + + // Helper function to convert hex string to bytes and return them in a vector + std::vector fromHex(const std::string& hex) { + std::vector bytes; + for (size_t i = 0; i < hex.length(); i += 2) { + std::string byteString = hex.substr(i, 2); + uint8_t byte = static_cast(strtol(byteString.c_str(), NULL, 16)); + bytes.push_back(byte); + } + return bytes; + } private: std::string bytesToHexString() { const std::vector digest = this->getBytes(); std::string hash; - + for (const auto& d : digest) { hash += this->hexTable[d]; } @@ -194,6 +214,8 @@ namespace hashpp { // private members private: + const uint8_t BLOCK_SIZE = 64, DIGEST_SIZE = 16; + typedef struct { uint64_t size; uint32_t buf[4]; @@ -242,6 +264,30 @@ namespace hashpp { const uint32_t B = 0xefcdab89; const uint32_t C = 0x98badcfe; const uint32_t D = 0x10325476; + + // the byte 0x36 repeated 'B' times where 'B' => block size + std::vector ipad = { + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 + }; + + // the byte 0x5c repeated 'B' times + std::vector opad = { + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c + }; // private class methods private: @@ -251,6 +297,9 @@ namespace hashpp { inline void ctx_update(const uint8_t* data, size_t len) override; inline void ctx_final() override; + inline std::string _H(const std::string& a, const std::string& b) override; + inline std::string HMAC(const std::string& key, const std::string& data) override; + // auxiliary functions defined by the algorithm // as per: https://en.wikipedia.org/wiki/MD5#Algorithm constexpr uint32_t F(const uint32_t B, const uint32_t C, const uint32_t D); @@ -266,6 +315,8 @@ namespace hashpp { // private members private: + const uint8_t BLOCK_SIZE = 64, DIGEST_SIZE = 16; + typedef struct { uint64_t size; uint32_t buf[4]; @@ -311,6 +362,30 @@ namespace hashpp { const uint32_t C = 0x98badcfe; const uint32_t D = 0x10325476; + // the byte 0x36 repeated 'B' times where 'B' => block size + std::vector ipad = { + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 + }; + + // the byte 0x5c repeated 'B' times + std::vector opad = { + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c + }; + // private class methods private: // initialize our context for this hash function @@ -319,6 +394,9 @@ namespace hashpp { inline void ctx_update(const uint8_t* data, size_t len) override; inline void ctx_final() override; + inline std::string _H(const std::string& a, const std::string& b) override; + inline std::string HMAC(const std::string& key, const std::string& data) override; + // auxiliary functions defined by the algorithm // as per: http://practicalcryptography.com/hashes/md4-hash/ constexpr uint32_t F(const uint32_t B, const uint32_t C, const uint32_t D); @@ -338,6 +416,8 @@ namespace hashpp { // private members private: + const uint8_t BLOCK_SIZE = 16, DIGEST_SIZE = 16; + typedef struct { uint8_t buf[16], state[48], checksum[16], digest[16]; uint64_t size; @@ -366,10 +446,25 @@ namespace hashpp { 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14 }; + // the byte 0x36 repeated 'B' times where 'B' => block size + std::vector ipad = { + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 + }; + + // the byte 0x5c repeated 'B' times + std::vector opad = { + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c + }; + inline void ctx_init() override; inline void ctx_transform(const uint8_t* data); inline void ctx_update(const uint8_t* data, size_t len) override; inline void ctx_final() override; + + inline std::string _H(const std::string& a, const std::string& b) override; + inline std::string HMAC(const std::string& key, const std::string& data) override; }; // MD5 @@ -467,6 +562,60 @@ namespace hashpp { this->context.digest[(i * 4) + 3] = static_cast((this->context.buf[i] & 0xFF000000) >> 24); } } + inline std::string MD5::_H(const std::string& a, const std::string& b) { + return this->getHash(a + b); + } + inline std::string MD5::HMAC(const std::string& key, const std::string& data) { + std::array k = { 0 }; std::fill(k.begin(), k.end(), 0x00); + + // (1) append zeros to the end of K to create a B byte string + // (e.g., if K is of length 20 bytes and B = 64, then K will be + // appended with 44 zero bytes 0x00) where B is the block size + if (key.length() > this->BLOCK_SIZE) { + // if K is longer than B bytes, reset K to K=H(K) + // where K can either be composed of entirely bytes of H(K) + // (if H(K) == L [where L => digest]) or the first L bytes of + // H(K) (if H(K) != L) followed by the remaining zeros (if H(K) < L) + std::vector k_ = this->fromHex(this->getHash(key)); + for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) { + k[i] = k_[i]; + } + } + else { + // if K is shorter than B bytes, append zeros to the end of K + // until K is B bytes long + for (uint32_t i = 0; i < key.length(); ++i) { + k[i] = key[i]; + } + } + + // (2) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with ipad + for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) { + this->ipad[i] ^= k[i]; + } + + // (3) append the stream of data 'data' to the B byte string resulting from step (2) + for (uint32_t i = 0; i < data.length(); ++i) { + this->ipad.push_back(data[i]); + } + + // (4) apply H to the stream generated in step (3) + // see step (6) + + // (5) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with opad + for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) { + this->opad[i] ^= k[i]; + } + + // (6) append the H result from step (4) to the B byte string resulting from step (5) + std::vector h_ = this->fromHex(this->getHash(std::string(this->ipad.begin(), this->ipad.end()))); + for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) { + this->opad.push_back(h_[i]); + } + + // (7) apply H to the stream generated in step (6) and output the result + return this->getHash(std::string(this->opad.begin(), this->opad.end())); + } constexpr uint32_t hashpp::MD::MD5::F(const uint32_t B, const uint32_t C, const uint32_t D) { return ((B & C) | (~B & D)); } constexpr uint32_t hashpp::MD::MD5::G(const uint32_t B, const uint32_t C, const uint32_t D) { return ((B & D) | (C & ~D)); } constexpr uint32_t hashpp::MD::MD5::H(const uint32_t B, const uint32_t C, const uint32_t D) { return ((B ^ C ^ D)); } @@ -561,6 +710,60 @@ namespace hashpp { this->context.digest[(i * 4) + 3] = static_cast((this->context.buf[i] & 0xFF000000) >> 24); } } + inline std::string MD4::_H(const std::string& a, const std::string& b) { + return this->getHash(a + b); + } + inline std::string MD4::HMAC(const std::string& key, const std::string& data) { + std::array k = { 0 }; std::fill(k.begin(), k.end(), 0x00); + + // (1) append zeros to the end of K to create a B byte string + // (e.g., if K is of length 20 bytes and B = 64, then K will be + // appended with 44 zero bytes 0x00) where B is the block size + if (key.length() > this->BLOCK_SIZE) { + // if K is longer than B bytes, reset K to K=H(K) + // where K can either be composed of entirely bytes of H(K) + // (if H(K) == L [where L => digest]) or the first L bytes of + // H(K) (if H(K) != L) followed by the remaining zeros (if H(K) < L) + std::vector k_ = this->fromHex(this->getHash(key)); + for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) { + k[i] = k_[i]; + } + } + else { + // if K is shorter than B bytes, append zeros to the end of K + // until K is B bytes long + for (uint32_t i = 0; i < key.length(); ++i) { + k[i] = key[i]; + } + } + + // (2) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with ipad + for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) { + this->ipad[i] ^= k[i]; + } + + // (3) append the stream of data 'data' to the B byte string resulting from step (2) + for (uint32_t i = 0; i < data.length(); ++i) { + this->ipad.push_back(data[i]); + } + + // (4) apply H to the stream generated in step (3) + // see step (6) + + // (5) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with opad + for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) { + this->opad[i] ^= k[i]; + } + + // (6) append the H result from step (4) to the B byte string resulting from step (5) + std::vector h_ = this->fromHex(this->getHash(std::string(this->ipad.begin(), this->ipad.end()))); + for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) { + this->opad.push_back(h_[i]); + } + + // (7) apply H to the stream generated in step (6) and output the result + return this->getHash(std::string(this->opad.begin(), this->opad.end())); + } constexpr uint32_t hashpp::MD::MD4::F(const uint32_t B, const uint32_t C, const uint32_t D) { return ((B & C) | (~B & D)); } constexpr uint32_t hashpp::MD::MD4::G(const uint32_t B, const uint32_t C, const uint32_t D) { return ((B & C) | (B & D) | (C & D)); } constexpr uint32_t hashpp::MD::MD4::H(const uint32_t B, const uint32_t C, const uint32_t D) { return ((B ^ C ^ D)); } @@ -624,6 +827,60 @@ namespace hashpp { ctx_transform(this->context.checksum); memcpy(this->context.digest, this->context.state, 16); } + inline std::string MD2::_H(const std::string& a, const std::string& b) { + return this->getHash(a + b); + } + inline std::string MD2::HMAC(const std::string& key, const std::string& data) { + std::array k = { 0 }; std::fill(k.begin(), k.end(), 0x00); + + // (1) append zeros to the end of K to create a B byte string + // (e.g., if K is of length 20 bytes and B = 64, then K will be + // appended with 44 zero bytes 0x00) where B is the block size + if (key.length() > this->BLOCK_SIZE) { + // if K is longer than B bytes, reset K to K=H(K) + // where K can either be composed of entirely bytes of H(K) + // (if H(K) == L [where L => digest]) or the first L bytes of + // H(K) (if H(K) != L) followed by the remaining zeros (if H(K) < L) + std::vector k_ = this->fromHex(this->getHash(key)); + for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) { + k[i] = k_[i]; + } + } + else { + // if K is shorter than B bytes, append zeros to the end of K + // until K is B bytes long + for (uint32_t i = 0; i < key.length(); ++i) { + k[i] = key[i]; + } + } + + // (2) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with ipad + for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) { + this->ipad[i] ^= k[i]; + } + + // (3) append the stream of data 'data' to the B byte string resulting from step (2) + for (uint32_t i = 0; i < data.length(); ++i) { + this->ipad.push_back(data[i]); + } + + // (4) apply H to the stream generated in step (3) + // see step (6) + + // (5) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with opad + for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) { + this->opad[i] ^= k[i]; + } + + // (6) append the H result from step (4) to the B byte string resulting from step (5) + std::vector h_ = this->fromHex(this->getHash(std::string(this->ipad.begin(), this->ipad.end()))); + for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) { + this->opad.push_back(h_[i]); + } + + // (7) apply H to the stream generated in step (6) and output the result + return this->getHash(std::string(this->opad.begin(), this->opad.end())); + } } // Secure Hash Algorithm (SHA) hash family @@ -651,6 +908,8 @@ namespace hashpp { } private: + const uint8_t BLOCK_SIZE = 64, DIGEST_SIZE = 20; + typedef struct { uint32_t state[5], k[4], size; uint64_t bitsize; @@ -677,11 +936,38 @@ namespace hashpp { 0xca62c1d6 }; + // the byte 0x36 repeated 'B' times where 'B' => block size + std::vector ipad = { + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 + }; + + // the byte 0x5c repeated 'B' times + std::vector opad = { + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c + }; + inline void ctx_init() override; inline void ctx_transform(const uint8_t* data); inline void ctx_update(const uint8_t* data, size_t len) override; inline void ctx_final() override; + inline std::string _H(const std::string& a, const std::string& b) override; + inline std::string HMAC(const std::string& key, const std::string& data) override; + // SHA-1 functions defined by the algorithm constexpr uint32_t A(const uint32_t A, const uint32_t B, const uint32_t C, const uint32_t D); constexpr uint32_t B(const uint32_t A, const uint32_t B, const uint32_t C, const uint32_t D); @@ -699,6 +985,8 @@ namespace hashpp { } private: + const uint8_t BLOCK_SIZE = 64, DIGEST_SIZE = 28; + typedef struct { uint32_t state[8]; uint64_t size, bitsize; @@ -740,11 +1028,38 @@ namespace hashpp { 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 }; + // the byte 0x36 repeated 'B' times where 'B' => block size + std::vector ipad = { + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 + }; + + // the byte 0x5c repeated 'B' times + std::vector opad = { + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c + }; + inline void ctx_init() override; inline void ctx_transform(const uint8_t* data); inline void ctx_update(const uint8_t* data, size_t len) override; inline void ctx_final() override; + inline std::string _H(const std::string& a, const std::string& b) override; + inline std::string HMAC(const std::string& key, const std::string& data) override; + constexpr uint32_t A(const uint32_t A, const uint32_t B, const uint32_t C, const uint32_t D); constexpr uint32_t F(const uint32_t B, const uint32_t C, const uint32_t D); constexpr uint32_t G(const uint32_t B, const uint32_t C, const uint32_t D); @@ -763,6 +1078,8 @@ namespace hashpp { } private: + const uint8_t BLOCK_SIZE = 64, DIGEST_SIZE = 32; + typedef struct { uint32_t state[8], size; uint64_t bitsize; @@ -804,11 +1121,38 @@ namespace hashpp { 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; + // the byte 0x36 repeated 'B' times where 'B' => block size + std::vector ipad = { + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 + }; + + // the byte 0x5c repeated 'B' times + std::vector opad = { + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c + }; + inline void ctx_init() override; inline void ctx_transform(const uint8_t* data); inline void ctx_update(const uint8_t* data, size_t len) override; inline void ctx_final() override; + inline std::string _H(const std::string& a, const std::string& b) override; + inline std::string HMAC(const std::string& key, const std::string& data) override; + constexpr uint32_t A(const uint32_t A, const uint32_t B, const uint32_t C, const uint32_t D); constexpr uint32_t F(const uint32_t B, const uint32_t C, const uint32_t D); constexpr uint32_t G(const uint32_t B, const uint32_t C, const uint32_t D); @@ -827,6 +1171,8 @@ namespace hashpp { } private: + const uint8_t BLOCK_SIZE = 128, DIGEST_SIZE = 48; + typedef struct { uint64_t state[8], count[2]; uint8_t data[128], digest[48]; @@ -871,11 +1217,54 @@ namespace hashpp { 0x4CC5D4BECB3E42B6, 0x597F299CFC657E2A, 0x5FCB6FAB3AD6FAEC, 0x6C44198C4A475817 }; + // the byte 0x36 repeated 'B' times where 'B' => block size + std::vector ipad = { + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 + }; + + // the byte 0x5c repeated 'B' times + std::vector opad = { + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c + }; + inline void ctx_init() override; inline void ctx_transform(const uint8_t* data); inline void ctx_update(const uint8_t* data, size_t len) override; inline void ctx_final() override; + inline std::string _H(const std::string& a, const std::string& b) override; + inline std::string HMAC(const std::string& key, const std::string& data) override; + constexpr uint64_t F(const uint64_t A, const uint64_t B, const uint64_t C); constexpr uint64_t G(const uint64_t A, const uint64_t B, const uint64_t C); @@ -893,6 +1282,8 @@ namespace hashpp { } private: + const uint8_t BLOCK_SIZE = 128, DIGEST_SIZE = 64; + typedef struct { uint64_t state[8], count[2]; uint8_t data[128], digest[64]; @@ -937,11 +1328,54 @@ namespace hashpp { 0x4CC5D4BECB3E42B6, 0x597F299CFC657E2A, 0x5FCB6FAB3AD6FAEC, 0x6C44198C4A475817 }; + // the byte 0x36 repeated 'B' times where 'B' => block size + std::vector ipad = { + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 + }; + + // the byte 0x5c repeated 'B' times + std::vector opad = { + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c + }; + inline void ctx_init() override; inline void ctx_transform(const uint8_t* data); inline void ctx_update(const uint8_t* data, size_t len) override; inline void ctx_final() override; + inline std::string _H(const std::string& a, const std::string& b) override; + inline std::string HMAC(const std::string& key, const std::string& data) override; + constexpr uint64_t F(const uint64_t A, const uint64_t B, const uint64_t C); constexpr uint64_t G(const uint64_t A, const uint64_t B, const uint64_t C); @@ -959,6 +1393,8 @@ namespace hashpp { } private: + const uint8_t BLOCK_SIZE = 128, DIGEST_SIZE = 28; + typedef struct { uint64_t state[8], count[2]; uint8_t data[128], digest[32]; @@ -1003,11 +1439,54 @@ namespace hashpp { 0x4CC5D4BECB3E42B6, 0x597F299CFC657E2A, 0x5FCB6FAB3AD6FAEC, 0x6C44198C4A475817 }; + // the byte 0x36 repeated 'B' times where 'B' => block size + std::vector ipad = { + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 + }; + + // the byte 0x5c repeated 'B' times + std::vector opad = { + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c + }; + inline void ctx_init() override; inline void ctx_transform(const uint8_t* data); inline void ctx_update(const uint8_t* data, size_t len) override; inline void ctx_final() override; + inline std::string _H(const std::string& a, const std::string& b) override; + inline std::string HMAC(const std::string& key, const std::string& data) override; + constexpr uint64_t F(const uint64_t A, const uint64_t B, const uint64_t C); constexpr uint64_t G(const uint64_t A, const uint64_t B, const uint64_t C); @@ -1025,6 +1504,8 @@ namespace hashpp { } private: + const uint8_t BLOCK_SIZE = 128, DIGEST_SIZE = 32; + typedef struct { uint64_t state[8], count[2]; uint8_t data[128], digest[32]; @@ -1069,11 +1550,54 @@ namespace hashpp { 0x4CC5D4BECB3E42B6, 0x597F299CFC657E2A, 0x5FCB6FAB3AD6FAEC, 0x6C44198C4A475817 }; + // the byte 0x36 repeated 'B' times where 'B' => block size + std::vector ipad = { + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 + }; + + // the byte 0x5c repeated 'B' times + std::vector opad = { + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c + }; + inline void ctx_init() override; inline void ctx_transform(const uint8_t* data); inline void ctx_update(const uint8_t* data, size_t len) override; inline void ctx_final() override; + inline std::string _H(const std::string& a, const std::string& b) override; + inline std::string HMAC(const std::string& key, const std::string& data) override; + constexpr uint64_t F(const uint64_t A, const uint64_t B, const uint64_t C); constexpr uint64_t G(const uint64_t A, const uint64_t B, const uint64_t C); @@ -1199,6 +1723,60 @@ namespace hashpp { this->context.digest[L + 16] = (this->context.state[4] >> (24 - L * 8)) & 0x000000ff; } } + inline std::string SHA1::_H(const std::string& a, const std::string& b) { + return this->getHash(a + b); + } + inline std::string SHA1::HMAC(const std::string& key, const std::string& data) { + std::array k = { 0 }; std::fill(k.begin(), k.end(), 0x00); + + // (1) append zeros to the end of K to create a B byte string + // (e.g., if K is of length 20 bytes and B = 64, then K will be + // appended with 44 zero bytes 0x00) where B is the block size + if (key.length() > this->BLOCK_SIZE) { + // if K is longer than B bytes, reset K to K=H(K) + // where K can either be composed of entirely bytes of H(K) + // (if H(K) == L [where L => digest]) or the first L bytes of + // H(K) (if H(K) != L) followed by the remaining zeros (if H(K) < L) + std::vector k_ = this->fromHex(this->getHash(key)); + for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) { + k[i] = k_[i]; + } + } + else { + // if K is shorter than B bytes, append zeros to the end of K + // until K is B bytes long + for (uint32_t i = 0; i < key.length(); ++i) { + k[i] = key[i]; + } + } + + // (2) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with ipad + for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) { + this->ipad[i] ^= k[i]; + } + + // (3) append the stream of data 'data' to the B byte string resulting from step (2) + for (uint32_t i = 0; i < data.length(); ++i) { + this->ipad.push_back(data[i]); + } + + // (4) apply H to the stream generated in step (3) + // see step (6) + + // (5) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with opad + for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) { + this->opad[i] ^= k[i]; + } + + // (6) append the H result from step (4) to the B byte string resulting from step (5) + std::vector h_ = this->fromHex(this->getHash(std::string(this->ipad.begin(), this->ipad.end()))); + for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) { + this->opad.push_back(h_[i]); + } + + // (7) apply H to the stream generated in step (6) and output the result + return this->getHash(std::string(this->opad.begin(), this->opad.end())); + } constexpr uint32_t hashpp::SHA::SHA1::A(const uint32_t A, const uint32_t B, const uint32_t C, const uint32_t D) { return ((A << 24) + (B << 16) + (C << 8) + (D)); } @@ -1308,6 +1886,60 @@ namespace hashpp { this->context.digest[i + 24] = (this->context.state[6] >> (24 - i * 8)) & 0x000000ff; } } + inline std::string SHA2_224::_H(const std::string& a, const std::string& b) { + return this->getHash(a + b); + } + inline std::string SHA2_224::HMAC(const std::string& key, const std::string& data) { + std::array k = { 0 }; std::fill(k.begin(), k.end(), 0x00); + + // (1) append zeros to the end of K to create a B byte string + // (e.g., if K is of length 20 bytes and B = 64, then K will be + // appended with 44 zero bytes 0x00) where B is the block size + if (key.length() > this->BLOCK_SIZE) { + // if K is longer than B bytes, reset K to K=H(K) + // where K can either be composed of entirely bytes of H(K) + // (if H(K) == L [where L => digest]) or the first L bytes of + // H(K) (if H(K) != L) followed by the remaining zeros (if H(K) < L) + std::vector k_ = this->fromHex(this->getHash(key)); + for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) { + k[i] = k_[i]; + } + } + else { + // if K is shorter than B bytes, append zeros to the end of K + // until K is B bytes long + for (uint32_t i = 0; i < key.length(); ++i) { + k[i] = key[i]; + } + } + + // (2) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with ipad + for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) { + this->ipad[i] ^= k[i]; + } + + // (3) append the stream of data 'data' to the B byte string resulting from step (2) + for (uint32_t i = 0; i < data.length(); ++i) { + this->ipad.push_back(data[i]); + } + + // (4) apply H to the stream generated in step (3) + // see step (6) + + // (5) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with opad + for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) { + this->opad[i] ^= k[i]; + } + + // (6) append the H result from step (4) to the B byte string resulting from step (5) + std::vector h_ = this->fromHex(this->getHash(std::string(this->ipad.begin(), this->ipad.end()))); + for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) { + this->opad.push_back(h_[i]); + } + + // (7) apply H to the stream generated in step (6) and output the result + return this->getHash(std::string(this->opad.begin(), this->opad.end())); + } constexpr uint32_t hashpp::SHA::SHA2_224::A(const uint32_t A, const uint32_t B, const uint32_t C, const uint32_t D) { return ((A << 24) + (B << 16) + (C << 8) + (D)); } @@ -1418,6 +2050,60 @@ namespace hashpp { this->context.digest[i + 28] = (this->context.state[7] >> (24 - i * 8)) & 0x000000ff; } } + inline std::string SHA2_256::_H(const std::string& a, const std::string& b) { + return this->getHash(a + b); + } + inline std::string SHA2_256::HMAC(const std::string& key, const std::string& data) { + std::array k = { 0 }; std::fill(k.begin(), k.end(), 0x00); + + // (1) append zeros to the end of K to create a B byte string + // (e.g., if K is of length 20 bytes and B = 64, then K will be + // appended with 44 zero bytes 0x00) where B is the block size + if (key.length() > this->BLOCK_SIZE) { + // if K is longer than B bytes, reset K to K=H(K) + // where K can either be composed of entirely bytes of H(K) + // (if H(K) == L [where L => digest]) or the first L bytes of + // H(K) (if H(K) != L) followed by the remaining zeros (if H(K) < L) + std::vector k_ = this->fromHex(this->getHash(key)); + for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) { + k[i] = k_[i]; + } + } + else { + // if K is shorter than B bytes, append zeros to the end of K + // until K is B bytes long + for (uint32_t i = 0; i < key.length(); ++i) { + k[i] = key[i]; + } + } + + // (2) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with ipad + for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) { + this->ipad[i] ^= k[i]; + } + + // (3) append the stream of data 'data' to the B byte string resulting from step (2) + for (uint32_t i = 0; i < data.length(); ++i) { + this->ipad.push_back(data[i]); + } + + // (4) apply H to the stream generated in step (3) + // see step (6) + + // (5) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with opad + for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) { + this->opad[i] ^= k[i]; + } + + // (6) append the H result from step (4) to the B byte string resulting from step (5) + std::vector h_ = this->fromHex(this->getHash(std::string(this->ipad.begin(), this->ipad.end()))); + for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) { + this->opad.push_back(h_[i]); + } + + // (7) apply H to the stream generated in step (6) and output the result + return this->getHash(std::string(this->opad.begin(), this->opad.end())); + } constexpr uint32_t hashpp::SHA::SHA2_256::A(const uint32_t A, const uint32_t B, const uint32_t C, const uint32_t D) { return ((A << 24) + (B << 16) + (C << 8) + (D)); } @@ -1549,6 +2235,60 @@ namespace hashpp { PU64B(this->context.state[4], this->context.digest, 32); PU64B(this->context.state[5], this->context.digest, 40); } + inline std::string SHA2_384::_H(const std::string& a, const std::string& b) { + return this->getHash(a + b); + } + inline std::string SHA2_384::HMAC(const std::string& key, const std::string& data) { + std::array k = { 0 }; std::fill(k.begin(), k.end(), 0x00); + + // (1) append zeros to the end of K to create a B byte string + // (e.g., if K is of length 20 bytes and B = 64, then K will be + // appended with 44 zero bytes 0x00) where B is the block size + if (key.length() > this->BLOCK_SIZE) { + // if K is longer than B bytes, reset K to K=H(K) + // where K can either be composed of entirely bytes of H(K) + // (if H(K) == L [where L => digest]) or the first L bytes of + // H(K) (if H(K) != L) followed by the remaining zeros (if H(K) < L) + std::vector k_ = this->fromHex(this->getHash(key)); + for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) { + k[i] = k_[i]; + } + } + else { + // if K is shorter than B bytes, append zeros to the end of K + // until K is B bytes long + for (uint32_t i = 0; i < key.length(); ++i) { + k[i] = key[i]; + } + } + + // (2) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with ipad + for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) { + this->ipad[i] ^= k[i]; + } + + // (3) append the stream of data 'data' to the B byte string resulting from step (2) + for (uint32_t i = 0; i < data.length(); ++i) { + this->ipad.push_back(data[i]); + } + + // (4) apply H to the stream generated in step (3) + // see step (6) + + // (5) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with opad + for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) { + this->opad[i] ^= k[i]; + } + + // (6) append the H result from step (4) to the B byte string resulting from step (5) + std::vector h_ = this->fromHex(this->getHash(std::string(this->ipad.begin(), this->ipad.end()))); + for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) { + this->opad.push_back(h_[i]); + } + + // (7) apply H to the stream generated in step (6) and output the result + return this->getHash(std::string(this->opad.begin(), this->opad.end())); + } constexpr uint64_t hashpp::SHA::SHA2_384::F(const uint64_t A, const uint64_t B, const uint64_t C) { return ((A & B) ^ (~A & C)); } constexpr uint64_t hashpp::SHA::SHA2_384::G(const uint64_t A, const uint64_t B, const uint64_t C) { return ((A & B) ^ (A & C) ^ (B & C)); } constexpr uint64_t hashpp::SHA::SHA2_384::SIGMA0(const uint64_t A) { return this->rr64(A, 28) ^ this->rr64(A, 34) ^ this->rr64(A, 39); } @@ -1679,6 +2419,60 @@ namespace hashpp { PU64B(this->context.state[6], this->context.digest, 48); PU64B(this->context.state[7], this->context.digest, 56); } + inline std::string SHA2_512::_H(const std::string& a, const std::string& b) { + return this->getHash(a + b); + } + inline std::string SHA2_512::HMAC(const std::string& key, const std::string& data) { + std::array k = { 0 }; std::fill(k.begin(), k.end(), 0x00); + + // (1) append zeros to the end of K to create a B byte string + // (e.g., if K is of length 20 bytes and B = 64, then K will be + // appended with 44 zero bytes 0x00) where B is the block size + if (key.length() > this->BLOCK_SIZE) { + // if K is longer than B bytes, reset K to K=H(K) + // where K can either be composed of entirely bytes of H(K) + // (if H(K) == L [where L => digest]) or the first L bytes of + // H(K) (if H(K) != L) followed by the remaining zeros (if H(K) < L) + std::vector k_ = this->fromHex(this->getHash(key)); + for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) { + k[i] = k_[i]; + } + } + else { + // if K is shorter than B bytes, append zeros to the end of K + // until K is B bytes long + for (uint32_t i = 0; i < key.length(); ++i) { + k[i] = key[i]; + } + } + + // (2) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with ipad + for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) { + this->ipad[i] ^= k[i]; + } + + // (3) append the stream of data 'data' to the B byte string resulting from step (2) + for (uint32_t i = 0; i < data.length(); ++i) { + this->ipad.push_back(data[i]); + } + + // (4) apply H to the stream generated in step (3) + // see step (6) + + // (5) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with opad + for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) { + this->opad[i] ^= k[i]; + } + + // (6) append the H result from step (4) to the B byte string resulting from step (5) + std::vector h_ = this->fromHex(this->getHash(std::string(this->ipad.begin(), this->ipad.end()))); + for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) { + this->opad.push_back(h_[i]); + } + + // (7) apply H to the stream generated in step (6) and output the result + return this->getHash(std::string(this->opad.begin(), this->opad.end())); + } constexpr uint64_t hashpp::SHA::SHA2_512::F(const uint64_t A, const uint64_t B, const uint64_t C) { return ((A & B) ^ (~A & C)); } constexpr uint64_t hashpp::SHA::SHA2_512::G(const uint64_t A, const uint64_t B, const uint64_t C) { return ((A & B) ^ (A & C) ^ (B & C)); } constexpr uint64_t hashpp::SHA::SHA2_512::SIGMA0(const uint64_t A) { return this->rr64(A, 28) ^ this->rr64(A, 34) ^ this->rr64(A, 39); } @@ -1806,6 +2600,60 @@ namespace hashpp { PU64B(this->context.state[2], this->context.digest, 16); PU64B(this->context.state[3], this->context.digest, 24); } + inline std::string SHA2_512_224::_H(const std::string& a, const std::string& b) { + return this->getHash(a + b); + } + inline std::string SHA2_512_224::HMAC(const std::string& key, const std::string& data) { + std::array k = { 0 }; std::fill(k.begin(), k.end(), 0x00); + + // (1) append zeros to the end of K to create a B byte string + // (e.g., if K is of length 20 bytes and B = 64, then K will be + // appended with 44 zero bytes 0x00) where B is the block size + if (key.length() > this->BLOCK_SIZE) { + // if K is longer than B bytes, reset K to K=H(K) + // where K can either be composed of entirely bytes of H(K) + // (if H(K) == L [where L => digest]) or the first L bytes of + // H(K) (if H(K) != L) followed by the remaining zeros (if H(K) < L) + std::vector k_ = this->fromHex(this->getHash(key)); + for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) { + k[i] = k_[i]; + } + } + else { + // if K is shorter than B bytes, append zeros to the end of K + // until K is B bytes long + for (uint32_t i = 0; i < key.length(); ++i) { + k[i] = key[i]; + } + } + + // (2) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with ipad + for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) { + this->ipad[i] ^= k[i]; + } + + // (3) append the stream of data 'data' to the B byte string resulting from step (2) + for (uint32_t i = 0; i < data.length(); ++i) { + this->ipad.push_back(data[i]); + } + + // (4) apply H to the stream generated in step (3) + // see step (6) + + // (5) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with opad + for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) { + this->opad[i] ^= k[i]; + } + + // (6) append the H result from step (4) to the B byte string resulting from step (5) + std::vector h_ = this->fromHex(this->getHash(std::string(this->ipad.begin(), this->ipad.end()))); + for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) { + this->opad.push_back(h_[i]); + } + + // (7) apply H to the stream generated in step (6) and output the result + return this->getHash(std::string(this->opad.begin(), this->opad.end())); + } constexpr uint64_t hashpp::SHA::SHA2_512_224::F(const uint64_t A, const uint64_t B, const uint64_t C) { return ((A & B) ^ (~A & C)); } constexpr uint64_t hashpp::SHA::SHA2_512_224::G(const uint64_t A, const uint64_t B, const uint64_t C) { return ((A & B) ^ (A & C) ^ (B & C)); } constexpr uint64_t hashpp::SHA::SHA2_512_224::SIGMA0(const uint64_t A) { return this->rr64(A, 28) ^ this->rr64(A, 34) ^ this->rr64(A, 39); } @@ -1932,6 +2780,60 @@ namespace hashpp { PU64B(this->context.state[2], this->context.digest, 16); PU64B(this->context.state[3], this->context.digest, 24); } + inline std::string SHA2_512_256::_H(const std::string& a, const std::string& b) { + return this->getHash(a + b); + } + inline std::string SHA2_512_256::HMAC(const std::string& key, const std::string& data) { + std::array k = { 0 }; std::fill(k.begin(), k.end(), 0x00); + + // (1) append zeros to the end of K to create a B byte string + // (e.g., if K is of length 20 bytes and B = 64, then K will be + // appended with 44 zero bytes 0x00) where B is the block size + if (key.length() > this->BLOCK_SIZE) { + // if K is longer than B bytes, reset K to K=H(K) + // where K can either be composed of entirely bytes of H(K) + // (if H(K) == L [where L => digest]) or the first L bytes of + // H(K) (if H(K) != L) followed by the remaining zeros (if H(K) < L) + std::vector k_ = this->fromHex(this->getHash(key)); + for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) { + k[i] = k_[i]; + } + } + else { + // if K is shorter than B bytes, append zeros to the end of K + // until K is B bytes long + for (uint32_t i = 0; i < key.length(); ++i) { + k[i] = key[i]; + } + } + + // (2) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with ipad + for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) { + this->ipad[i] ^= k[i]; + } + + // (3) append the stream of data 'data' to the B byte string resulting from step (2) + for (uint32_t i = 0; i < data.length(); ++i) { + this->ipad.push_back(data[i]); + } + + // (4) apply H to the stream generated in step (3) + // see step (6) + + // (5) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with opad + for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) { + this->opad[i] ^= k[i]; + } + + // (6) append the H result from step (4) to the B byte string resulting from step (5) + std::vector h_ = this->fromHex(this->getHash(std::string(this->ipad.begin(), this->ipad.end()))); + for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) { + this->opad.push_back(h_[i]); + } + + // (7) apply H to the stream generated in step (6) and output the result + return this->getHash(std::string(this->opad.begin(), this->opad.end())); + } constexpr uint64_t hashpp::SHA::SHA2_512_256::F(const uint64_t A, const uint64_t B, const uint64_t C) { return ((A & B) ^ (~A & C)); } constexpr uint64_t hashpp::SHA::SHA2_512_256::G(const uint64_t A, const uint64_t B, const uint64_t C) { return ((A & B) ^ (A & C) ^ (B & C)); } constexpr uint64_t hashpp::SHA::SHA2_512_256::SIGMA0(const uint64_t A) { return this->rr64(A, 28) ^ this->rr64(A, 34) ^ this->rr64(A, 39); } @@ -1957,12 +2859,12 @@ namespace hashpp { operator std::string() const noexcept { return this->hashStr; } friend std::ostream& operator<<(std::ostream& _Ostr, const hashpp::hash& object) { - _Ostr << object.hashStr; + _Ostr << object.getString(); return _Ostr; } hash& operator=(const hashpp::hash& _rhs) noexcept { - this->hashStr = _rhs.hashStr; + this->hashStr = _rhs.getString(); return *this; } @@ -1971,13 +2873,13 @@ namespace hashpp { return *this; } - bool operator==(const hashpp::hash& _rhs) noexcept { - return _rhs.hashStr == this->hashStr; + bool operator==(const hashpp::hash& _rhs) const noexcept { + return _rhs.getString() == this->getString(); } template , int> = 0> - bool operator==(const _Ty& _rhs) noexcept { - return _rhs == this->hashStr; + bool operator==(const _Ty& _rhs) const noexcept { + return _rhs == this->getString(); } private: @@ -2106,6 +3008,45 @@ namespace hashpp { } } + // function to return a resulting HMAC from selected ALGORITHM and passed key-data pair + static hashpp::hash getHMAC(hashpp::ALGORITHMS algorithm, const std::string& key, const std::string& data) { + switch (algorithm) { + case hashpp::ALGORITHMS::MD5: { + return { hashpp::MD::MD5().getHMAC(key, data) }; + } + case hashpp::ALGORITHMS::MD4: { + return { hashpp::MD::MD4().getHMAC(key, data) }; + } + case hashpp::ALGORITHMS::MD2: { + return { hashpp::MD::MD2().getHMAC(key, data) }; + } + case hashpp::ALGORITHMS::SHA1: { + return { hashpp::SHA::SHA1().getHMAC(key, data) }; + } + case hashpp::ALGORITHMS::SHA2_224: { + return { hashpp::SHA::SHA2_224().getHMAC(key, data) }; + } + case hashpp::ALGORITHMS::SHA2_256: { + return { hashpp::SHA::SHA2_256().getHMAC(key, data) }; + } + case hashpp::ALGORITHMS::SHA2_384: { + return { hashpp::SHA::SHA2_384().getHMAC(key, data) }; + } + case hashpp::ALGORITHMS::SHA2_512: { + return { hashpp::SHA::SHA2_512().getHMAC(key, data) }; + } + case hashpp::ALGORITHMS::SHA2_512_224: { + return { hashpp::SHA::SHA2_512_224().getHMAC(key, data) }; + } + case hashpp::ALGORITHMS::SHA2_512_256: { + return { hashpp::SHA::SHA2_512_256().getHMAC(key, data) }; + } + default: { + return hashpp::hash(); + } + } + } + // function to return a collection of resulting hashes from selected ALGORITHMS and passed data static hashpp::hashCollection getHashes(const std::vector>>& algorithmDataPairs) { std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256; @@ -2171,7 +3112,189 @@ namespace hashpp { } }; } + + // function to return a collection of resulting hashes from selected ALGORITHM and passed data + template ...>, int> = 0> + static hashpp::hashCollection getHashes(hashpp::ALGORITHMS algorithm, const _Ts&... data) { + switch (algorithm) { + case hashpp::ALGORITHMS::MD5: { + std::vector vMD5; + (vMD5.push_back(hashpp::MD::MD5().getHash(static_cast(data))), ...); + return hashCollection {{{ "MD5", vMD5 }}}; + } + case hashpp::ALGORITHMS::MD4: { + std::vector vMD4; + (vMD4.push_back(hashpp::MD::MD4().getHash(static_cast(data))), ...); + return hashCollection {{{ "MD4", vMD4 }}}; + } + case hashpp::ALGORITHMS::MD2: { + std::vector vMD2; + (vMD2.push_back(hashpp::MD::MD2().getHash(static_cast(data))), ...); + return hashCollection {{{ "MD2", vMD2 }}}; + } + case hashpp::ALGORITHMS::SHA1: { + std::vector vSHA1; + (vSHA1.push_back(hashpp::SHA::SHA1().getHash(static_cast(data))), ...); + return hashCollection {{{ "SHA1", vSHA1 }}}; + } + case hashpp::ALGORITHMS::SHA2_224: { + std::vector vSHA2_224; + (vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(static_cast(data))), ...); + return hashCollection {{{ "SHA2-224", vSHA2_224 }}}; + } + case hashpp::ALGORITHMS::SHA2_256: { + std::vector vSHA2_256; + (vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(static_cast(data))), ...); + return hashCollection {{{ "SHA2-256", vSHA2_256 }}}; + } + case hashpp::ALGORITHMS::SHA2_384: { + std::vector vSHA_384; + (vSHA_384.push_back(hashpp::SHA::SHA2_384().getHash(static_cast(data))), ...); + return hashCollection {{{ "SHA2-384", vSHA_384 }}}; + } + case hashpp::ALGORITHMS::SHA2_512: { + std::vector vSHA2_512; + (vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(static_cast(data))), ...); + return hashCollection {{{ "SHA2-512", vSHA2_512 }}}; + } + case hashpp::ALGORITHMS::SHA2_512_224: { + std::vector vSHA2_512_224; + (vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(static_cast(data))), ...); + return hashCollection {{{ "SHA2-512-224", vSHA2_512_224 }}}; + } + case hashpp::ALGORITHMS::SHA2_512_256: { + std::vector vSHA2_512_256; + (vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(static_cast(data))), ...); + return hashCollection {{{ "SHA2-512-256", vSHA2_512_256 }}}; + } + } + } + + // function to return a collection of resulting HMACs from selected ALGORITHMS and passed key-data + static hashpp::hashCollection getHMACs(const std::vector>>>& algorithmKeyDataPairs) { + std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256; + for (const std::pair>>& twin : algorithmKeyDataPairs) { + for (const std::pair& _keyData : twin.second) { + switch (twin.first) { + case hashpp::ALGORITHMS::MD5: { + vMD5.push_back(hashpp::MD::MD5().getHMAC(_keyData.first, _keyData.second)); + break; + } + case hashpp::ALGORITHMS::MD4: { + vMD4.push_back(hashpp::MD::MD4().getHMAC(_keyData.first, _keyData.second)); + break; + } + case hashpp::ALGORITHMS::MD2: { + vMD2.push_back(hashpp::MD::MD2().getHMAC(_keyData.first, _keyData.second)); + break; + } + case hashpp::ALGORITHMS::SHA1: { + vSHA1.push_back(hashpp::SHA::SHA1().getHMAC(_keyData.first, _keyData.second)); + break; + } + case hashpp::ALGORITHMS::SHA2_224: { + vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHMAC(_keyData.first, _keyData.second)); + break; + } + case hashpp::ALGORITHMS::SHA2_256: { + vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHMAC(_keyData.first, _keyData.second)); + break; + } + case hashpp::ALGORITHMS::SHA2_384: { + vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHMAC(_keyData.first, _keyData.second)); + break; + } + case hashpp::ALGORITHMS::SHA2_512: { + vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHMAC(_keyData.first, _keyData.second)); + break; + } + case hashpp::ALGORITHMS::SHA2_512_224: { + vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHMAC(_keyData.first, _keyData.second)); + break; + } + case hashpp::ALGORITHMS::SHA2_512_256: { + vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHMAC(_keyData.first, _keyData.second)); + break; + } + } + } + } + return hashCollection { + { + { "MD5", vMD5 }, + { "MD4", vMD4 }, + { "MD2", vMD2 }, + { "SHA1", vSHA1 }, + { "SHA2-224", vSHA2_224 }, + { "SHA2-256", vSHA2_256 }, + { "SHA2-384", vSHA2_384 }, + { "SHA2-512", vSHA2_512 }, + { "SHA2-512-224", vSHA2_512_224 }, + { "SHA2-512-256", vSHA2_512_256 } + } + }; + } + + // function to return a collection of resulting HMACs from selected ALGORITHM and passed key-data + template ...>, int> = 0> + static hashpp::hashCollection getHMACs(hashpp::ALGORITHMS algorithm, const std::string& key, const _Ts&... data) { + switch (algorithm) { + case hashpp::ALGORITHMS::MD5: { + std::vector vMD5; + (vMD5.push_back(hashpp::MD::MD5().getHMAC(key, data)), ...); + return hashCollection {{{ "MD5", vMD5 }}}; + } + case hashpp::ALGORITHMS::MD4: { + std::vector vMD4; + (vMD4.push_back(hashpp::MD::MD4().getHMAC(key, data)), ...); + return hashCollection {{{ "MD4", vMD4 }}}; + } + case hashpp::ALGORITHMS::MD2: { + std::vector vMD2; + (vMD2.push_back(hashpp::MD::MD2().getHMAC(key, data)), ...); + return hashCollection {{{ "MD2", vMD2 }}}; + } + case hashpp::ALGORITHMS::SHA1: { + std::vector vSHA1; + (vSHA1.push_back(hashpp::SHA::SHA1().getHMAC(key, data)), ...); + return hashCollection {{{ "SHA1", vSHA1 }}}; + } + case hashpp::ALGORITHMS::SHA2_224: { + std::vector vSHA2_224; + (vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHMAC(key, data)), ...); + return hashCollection {{{ "SHA2-224", vSHA2_224 }}}; + } + case hashpp::ALGORITHMS::SHA2_256: { + std::vector vSHA2_256; + (vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHMAC(key, data)), ...); + return hashCollection {{{ "SHA2-256", vSHA2_256 }}}; + } + case hashpp::ALGORITHMS::SHA2_384: { + std::vector vSHA_384; + (vSHA_384.push_back(hashpp::SHA::SHA2_384().getHMAC(key, data)), ...); + return hashCollection {{{ "SHA2-384", vSHA_384 }}}; + } + case hashpp::ALGORITHMS::SHA2_512: { + std::vector vSHA2_512; + (vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHMAC(key, data)), ...); + return hashCollection {{{ "SHA2-512", vSHA2_512 }}}; + } + case hashpp::ALGORITHMS::SHA2_512_224: { + std::vector vSHA2_512_224; + (vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHMAC(key, data)), ...); + return hashCollection {{{ "SHA2-512-224", vSHA2_512_224 }}}; + } + case hashpp::ALGORITHMS::SHA2_512_256: { + std::vector vSHA2_512_256; + (vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHMAC(key, data)), ...); + return hashCollection {{{ "SHA2-512-256", vSHA2_512_256 }}}; + } + } + } + // function to return a resulting hash from selected ALGORITHM and passed file static hashpp::hash getFileHash(hashpp::ALGORITHMS algorithm, const std::string& path) { if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { @@ -2370,6 +3493,18 @@ namespace hashpp { } } + // Function to check each algorithm for HMAC correctness + void checkAlgorithms_HMAC() const { + for (const hashpp::ALGORITHMS& algorithm : this->algorithms) { + if (hashpp::get::getHMAC(algorithm, "k", "d").getString() == this->hmac_comparisons[static_cast(algorithm)].first) { + std::cout << this->hmac_comparisons[static_cast(algorithm)].second << " HMAC pass." << std::endl; + } + else { + std::cout << this->hmac_comparisons[static_cast(algorithm)].second << " HMAC fail." << std::endl; + } + } + } + // Function to measure performance of all hashing algorithms when hashing 10 million // repetitions of argument 'target.' void benchmarkAlgorithms(const std::string& target) { @@ -2389,6 +3524,25 @@ namespace hashpp { } } + // Function to measure performance of all HMAC hashing algorithms when hashing 10 million + // repetitions of argument 'target' with key 'key.' + void benchmarkAlgorithms_HMAC(const std::string& key, const std::string& target) { + std::cout << "Testing 10m HMAC hashing repetitions of '" << target << "' with key '" << key << "'.\n" << std::endl; + for (const hashpp::ALGORITHMS& algorithm : this->algorithms) { + if (algorithm == hashpp::ALGORITHMS::MD2 && !IncludeMD2) { + continue; + } + else { + this->startTimer(); + for (uint32_t i = 0; i < 10000000; i++) { + hashpp::get::getHMAC(algorithm, key, target); + } + this->stopTimer(); + std::cout << this->hmac_comparisons[static_cast(algorithm)].second << ": " << this->getTime().count() << std::endl; + } + } + } + // Function to measure performance of all hashing algorithms when hashing a given file void benchmarkAlgorithms_File(const std::string& path) { std::cout << "Testing algorithm speeds for hashing of file '" << path << "'.\n" << std::endl; @@ -2432,6 +3586,20 @@ namespace hashpp { { "a8c9aa3f45f2ada72e3ae9278407b4ade221490596c69b27af611dae", "SHA2-512/224" }, { "9a895196448c0a9daa9769b48f29db5b41cfe2f6f65943a8ef2b8f446e388f7e", "SHA2-512/256" } }; + + // All correct hashes of data 'd' with key 'k' for HMAC comparison + const std::vector> hmac_comparisons = { + { "7f330edb3a84f317f7ca433d6038ff9a", "MD5" }, + { "de693e9b565099e8fe8129b3833a702d", "MD4" }, + { "a10a9e7a2bcfa4cd38d0a1cab3f25816", "MD2" }, + { "2b90e41e7c0cc8e2f75c02910c3899cc468ba316", "SHA1" }, + { "c9b7d3a28728c8a0b10dd425247af65e00725f6e5d32131b0c9a4ac1", "SHA2-224" }, + { "e7ea21c3bcb63a4da3ad78503168d36bdca0be622382ea60a108fad4e4966679", "SHA2-256" }, + { "48da203588bac88ca21d843f0dd201e15e33fe08a4db11ff4f07d2b62e2e10dee4e55d49612a658a9e5ac2c0a6b8e945", "SHA2-384" }, + { "75e6621bf12000a13d8dae79fed84aadffbbceaefd36ae061493b34aef6a2988f0fb91b8ba4fef293ed0bd09e6bb7578858b8f2f7f70fe3ca7490d37f655fd38", "SHA2-512" }, + { "7882112b43ad00ad1a01bc1a8df3745aad04e27a999ceb60da32bb18", "SHA2-512/224" }, + { "df48fa6a1e87fc2ccdce7a79028b4cd891ce905ebf411898c9aba975f3a2f8ad", "SHA2-512/256" } + }; }; #endif } From 2f9d0e88865fc04449657b34f60ba94006d683c6 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Sun, 4 Dec 2022 08:19:40 -0500 Subject: [PATCH 03/56] Fix copy parameter that I somehow missed. Change copy assignment of string parameters in hashpp::common::getHMAC(...) to lvalue cref to avoid copies. --- include/hashpp.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/hashpp.h b/include/hashpp.h index a8208a0..6bdd0a6 100644 --- a/include/hashpp.h +++ b/include/hashpp.h @@ -164,7 +164,8 @@ namespace hashpp { return this->bytesToHexString(); } - std::string getHMAC(std::string key, std::string data) { + // get hexadecimal HMAC from key-data pair + std::string getHMAC(const std::string& key, const std::string& data) { return this->HMAC(key, data); } From 5363c619e91a708d9d1f4e0012e51d14654b38f5 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 12:59:34 -0500 Subject: [PATCH 04/56] Apply fixes, functional changes, etc. - Fixed various template signatures to constrain properly. - Added an ambiguous base class Container to simplify the function signatures of several getX functions, as well as the process of passing data to them. - Re-factored getFilesHashes function structure. - Added both const std::vector and initializer_list overloads for getXs functions. - Changed hashpp::hash::getString(...) to return a constexpr result. - Fixed const-correctness errors. - Added various type aliases for Container: DataContainer, HMAC_DataContainer, FilePathsContainer. See file for more. --- include/hashpp.h | 829 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 674 insertions(+), 155 deletions(-) diff --git a/include/hashpp.h b/include/hashpp.h index 6bdd0a6..41b19a2 100644 --- a/include/hashpp.h +++ b/include/hashpp.h @@ -67,6 +67,7 @@ #include #include #include +#include #include namespace hashpp { @@ -164,7 +165,7 @@ namespace hashpp { return this->bytesToHexString(); } - // get hexadecimal HMAC from key-data pair + // get hexadecimal HMAC from key-data pair std::string getHMAC(const std::string& key, const std::string& data) { return this->HMAC(key, data); } @@ -2856,7 +2857,7 @@ namespace hashpp { hash(std::string&& hex) noexcept : hashStr(std::move(hex)) {} bool valid() const noexcept { return !this->hashStr.empty(); } - std::string getString() const noexcept { return this->hashStr; }; + constexpr const std::string& getString() const noexcept { return this->hashStr; }; operator std::string() const noexcept { return this->hashStr; } friend std::ostream& operator<<(std::ostream& _Ostr, const hashpp::hash& object) { @@ -2865,12 +2866,16 @@ namespace hashpp { } hash& operator=(const hashpp::hash& _rhs) noexcept { - this->hashStr = _rhs.getString(); + if (this != &_rhs) { + this->hashStr = _rhs.getString(); + } return *this; } hash& operator=(hashpp::hash&& _rhs) noexcept { - this->hashStr = std::move(_rhs.hashStr); + if (this != &_rhs) { + this->hashStr = std::move(_rhs.hashStr); + } return *this; } @@ -2894,16 +2899,12 @@ namespace hashpp { // // for instance, we can get several hashes of several algorithms and print only // selected algorithms like so: - // auto allHashes = hashpp::get::getHashes({ {hashpp::ALGORITHMS::MD4, {"data1", "data2"}}, - // {hashpp::ALGORITHMS::MD5, {"data1", "data2"}} }); + // auto allHashes = hashpp::get::getHashes(ALGORITHMS::MD5, "data1", "data2", "data3", ...); // for (auto hash : allHashes["MD5"]) { // std::cout << hash << std::endl; // } - // for (auto hash : allHashes["MD4"]) { - // std::cout << hash << std::endl; - // } // - // ... et cetera, et cetera ... + // ... et cetera ... class hashCollection { public: @@ -2948,25 +2949,110 @@ namespace hashpp { } }; + // Ambiguous base container class to simplify original function signatures of getHash(...)-related functions + class Container { + public: // constructors + Container() noexcept = default; + Container(const Container& container) noexcept + : algorithm(container.algorithm), key(container.key), data(container.data) {} + Container(Container&& container) noexcept + : algorithm(container.algorithm), key(std::move(container.key)), data(std::move(container.data)) {} + Container( + ALGORITHMS algorithm, + const std::vector& data + ) noexcept : algorithm(algorithm), data(data) {} + Container( + ALGORITHMS algorithm, + const std::vector& data, + const std::string& key + ) noexcept : algorithm(algorithm), data(data), key(key) {} + + template ...>, int> = 0> + Container( + ALGORITHMS algorithm, + const _Ts&... data + ) noexcept : algorithm(algorithm), data({ data... }) {} + + template ..., std::negation>...>, int> = 0> + Container( + ALGORITHMS algorithm, + _Ts&&... data + ) noexcept : algorithm(algorithm), data({ std::forward<_Ts>(data)... }) {} + + public: // member functions + constexpr const ALGORITHMS& getAlgorithm() const noexcept { return this->algorithm; } + constexpr const std::string& getKey() const noexcept { return this->key; } + constexpr const std::vector& getData() const noexcept { return this->data; } + void setAlgorithm(ALGORITHMS algorithm) noexcept { this->algorithm = algorithm; } + void setKey(const std::string& key) noexcept { this->key = key; } + + void setData(const std::vector& data) noexcept { this->data = data; } + void setData(std::vector&& data) noexcept { this->data = std::move(data); } + template void setData(const _Ts&... data) noexcept { this->data = { data... }; } + template >...>, int> = 0> + void setData(_Ts&&... data) noexcept { this->data = { std::forward<_Ts>(data)... }; } + + void appendData(const std::vector& data) noexcept { this->data.insert(this->data.end(), data.begin(), data.end()); } + void appendData(std::vector&& data) noexcept { this->data.insert(this->data.end(), std::make_move_iterator(data.begin()), std::make_move_iterator(data.end())); } + template void appendData(const _Ts&... data) noexcept { (this->data.push_back(data), ...); } + template >...>, int> = 0> + void appendData(_Ts&&... data) noexcept { (this->data.push_back(std::forward<_Ts>(data)), ...); } + + Container& operator=(const Container& _rhs) noexcept { + if (this != &_rhs) { + this->algorithm = _rhs.getAlgorithm(); + this->key = _rhs.getKey(); + this->data = _rhs.getData(); + } + return *this; + } + + Container& operator=(Container&& _rhs) noexcept { + if (this != &_rhs) { + this->algorithm = _rhs.algorithm; + this->key = std::move(_rhs.key); + this->data = std::move(_rhs.data); + } + return *this; + } - // interface class to allow use of static methods to access - // all algorithm classes and use their functions without - // the need of several instantiations of each class in - // the main source code of the user + private: // member variables + ALGORITHMS algorithm; + std::string key; + + // Holds arbitrary data; how this data is defined is determined + // by the functions that the container containing said data is passed to. + // (e.g., a call to getFilesHashes with a container will treat all data + // in it as paths to files to be hashed, and a call to getHashes with + // a container will treat all data as generic data to be hashed) + std::vector data; + }; + using HMAC_DataContainer = Container; + using DataContainer = Container; + using FilePathsContainer = Container; + + // interface class to allow use of static methods to access + // all algorithm classes and use their functions without + // the need of several instantiations of each class in + // the main source code of the user // - // i.e., if a user wants to pass data to one or several - // algorithms and get the hash(es), they can do so via: - // hashpp::get::getHash or hashpp::get::getHashes + // i.e., if a user wants to pass data to one or several + // algorithms and get the hash(es), they can do so via: + // hashpp::get::getHash or hashpp::get::getHashes // - // the retrieval of file hashes is also possible via - // hashpp::get::getFileHash or collectively via - // hashpp::get::getFileHashes + // the retrieval of file hashes is also possible via + // hashpp::get::getFileHash or collectively via + // hashpp::get::getFileHashes // - // all hashpp::get methods return a hashpp::hash or a - // hashpp::hashCollection object. + // all hashpp::get methods return a hashpp::hash or a + // hashpp::hashCollection object. // - // refer to the class definitions of both hashpp::hash and - // hashpp::hashCollection for info on how to use them + // refer to the class definitions of both hashpp::hash and + // hashpp::hashCollection for info on how to use them class get { public: @@ -3048,53 +3134,71 @@ namespace hashpp { } } - // function to return a collection of resulting hashes from selected ALGORITHMS and passed data - static hashpp::hashCollection getHashes(const std::vector>>& algorithmDataPairs) { + // function to return a collection of resulting hashes from passed data containers + static hashpp::hashCollection getHashes(const std::vector& dataSets) { std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256; - for (const std::pair>& twin : algorithmDataPairs) { - for (const std::string& _data : twin.second) { - switch (twin.first) { - case hashpp::ALGORITHMS::MD5: { - vMD5.push_back(hashpp::MD::MD5().getHash(_data)); - break; + for (const DataContainer& dataSet : dataSets) { + switch (dataSet.getAlgorithm()) { + case hashpp::ALGORITHMS::MD5: { + for (const std::string& data : dataSet.getData()) { + vMD5.push_back(hashpp::MD::MD5().getHash(data)); } - case hashpp::ALGORITHMS::MD4: { - vMD4.push_back(hashpp::MD::MD4().getHash(_data)); - break; + break; + } + case hashpp::ALGORITHMS::MD4: { + for (const std::string& data : dataSet.getData()) { + vMD4.push_back(hashpp::MD::MD4().getHash(data)); } - case hashpp::ALGORITHMS::MD2: { - vMD2.push_back(hashpp::MD::MD2().getHash(_data)); - break; + break; + } + case hashpp::ALGORITHMS::MD2: { + for (const std::string& data : dataSet.getData()) { + vMD2.push_back(hashpp::MD::MD2().getHash(data)); } - case hashpp::ALGORITHMS::SHA1: { - vSHA1.push_back(hashpp::SHA::SHA1().getHash(_data)); - break; + break; + } + case hashpp::ALGORITHMS::SHA1: { + for (const std::string& data : dataSet.getData()) { + vSHA1.push_back(hashpp::SHA::SHA1().getHash(data)); } - case hashpp::ALGORITHMS::SHA2_224: { - vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(_data)); - break; + break; + } + case hashpp::ALGORITHMS::SHA2_224: { + for (const std::string& data : dataSet.getData()) { + vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(data)); } - case hashpp::ALGORITHMS::SHA2_256: { - vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(_data)); - break; + break; + } + case hashpp::ALGORITHMS::SHA2_256: { + for (const std::string& data : dataSet.getData()) { + vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(data)); } - case hashpp::ALGORITHMS::SHA2_384: { - vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHash(_data)); - break; + break; + } + case hashpp::ALGORITHMS::SHA2_384: { + for (const std::string& data : dataSet.getData()) { + vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHash(data)); } - case hashpp::ALGORITHMS::SHA2_512: { - vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(_data)); - break; + break; + } + case hashpp::ALGORITHMS::SHA2_512: { + for (const std::string& data : dataSet.getData()) { + vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(data)); } - case hashpp::ALGORITHMS::SHA2_512_224: { - vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(_data)); - break; + break; + } + case hashpp::ALGORITHMS::SHA2_512_224: { + for (const std::string& data : dataSet.getData()) { + vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(data)); } - case hashpp::ALGORITHMS::SHA2_512_256: { - vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(_data)); - break; + break; + } + case hashpp::ALGORITHMS::SHA2_512_256: { + for (const std::string& data : dataSet.getData()) { + vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(data)); } + break; } } } @@ -3114,6 +3218,89 @@ namespace hashpp { }; } + static hashpp::hashCollection getHashes(const std::initializer_list& dataSets) { + std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256; + + for (const DataContainer& dataSet : dataSets) { + switch (dataSet.getAlgorithm()) { + case hashpp::ALGORITHMS::MD5: { + for (const std::string& data : dataSet.getData()) { + vMD5.push_back(hashpp::MD::MD5().getHash(data)); + } + break; + } + case hashpp::ALGORITHMS::MD4: { + for (const std::string& data : dataSet.getData()) { + vMD4.push_back(hashpp::MD::MD4().getHash(data)); + } + break; + } + case hashpp::ALGORITHMS::MD2: { + for (const std::string& data : dataSet.getData()) { + vMD2.push_back(hashpp::MD::MD2().getHash(data)); + } + break; + } + case hashpp::ALGORITHMS::SHA1: { + for (const std::string& data : dataSet.getData()) { + vSHA1.push_back(hashpp::SHA::SHA1().getHash(data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_224: { + for (const std::string& data : dataSet.getData()) { + vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_256: { + for (const std::string& data : dataSet.getData()) { + vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_384: { + for (const std::string& data : dataSet.getData()) { + vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHash(data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_512: { + for (const std::string& data : dataSet.getData()) { + vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_512_224: { + for (const std::string& data : dataSet.getData()) { + vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_512_256: { + for (const std::string& data : dataSet.getData()) { + vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(data)); + } + break; + } + } + } + return hashCollection { + { + { "MD5", vMD5 }, + { "MD4", vMD4 }, + { "MD2", vMD2 }, + { "SHA1", vSHA1 }, + { "SHA2-224", vSHA2_224 }, + { "SHA2-256", vSHA2_256 }, + { "SHA2-384", vSHA2_384 }, + { "SHA2-512", vSHA2_512 }, + { "SHA2-512-224", vSHA2_512_224 }, + { "SHA2-512-256", vSHA2_512_256 } + } + }; + } + // function to return a collection of resulting hashes from selected ALGORITHM and passed data template ...>, int> = 0> @@ -3172,53 +3359,71 @@ namespace hashpp { } } - // function to return a collection of resulting HMACs from selected ALGORITHMS and passed key-data - static hashpp::hashCollection getHMACs(const std::vector>>>& algorithmKeyDataPairs) { + // function to return a collection of resulting HMACs from selected ALGORITHMS and passed key-data containers + static hashpp::hashCollection getHMACs(const std::vector& keyDataSets) { std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256; - for (const std::pair>>& twin : algorithmKeyDataPairs) { - for (const std::pair& _keyData : twin.second) { - switch (twin.first) { - case hashpp::ALGORITHMS::MD5: { - vMD5.push_back(hashpp::MD::MD5().getHMAC(_keyData.first, _keyData.second)); - break; + for (const DataContainer& keyDataSet : keyDataSets) { + switch (keyDataSet.getAlgorithm()) { + case hashpp::ALGORITHMS::MD5: { + for (const std::string& data : keyDataSet.getData()) { + vMD5.push_back(hashpp::MD::MD5().getHMAC(keyDataSet.getKey(), data)); } - case hashpp::ALGORITHMS::MD4: { - vMD4.push_back(hashpp::MD::MD4().getHMAC(_keyData.first, _keyData.second)); - break; + break; + } + case hashpp::ALGORITHMS::MD4: { + for (const std::string& data : keyDataSet.getData()) { + vMD4.push_back(hashpp::MD::MD4().getHMAC(keyDataSet.getKey(), data)); } - case hashpp::ALGORITHMS::MD2: { - vMD2.push_back(hashpp::MD::MD2().getHMAC(_keyData.first, _keyData.second)); - break; + break; + } + case hashpp::ALGORITHMS::MD2: { + for (const std::string& data : keyDataSet.getData()) { + vMD2.push_back(hashpp::MD::MD2().getHMAC(keyDataSet.getKey(), data)); } - case hashpp::ALGORITHMS::SHA1: { - vSHA1.push_back(hashpp::SHA::SHA1().getHMAC(_keyData.first, _keyData.second)); - break; + break; + } + case hashpp::ALGORITHMS::SHA1: { + for (const std::string& data : keyDataSet.getData()) { + vSHA1.push_back(hashpp::SHA::SHA1().getHMAC(keyDataSet.getKey(), data)); } - case hashpp::ALGORITHMS::SHA2_224: { - vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHMAC(_keyData.first, _keyData.second)); - break; + break; + } + case hashpp::ALGORITHMS::SHA2_224: { + for (const std::string& data : keyDataSet.getData()) { + vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHMAC(keyDataSet.getKey(), data)); } - case hashpp::ALGORITHMS::SHA2_256: { - vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHMAC(_keyData.first, _keyData.second)); - break; + break; + } + case hashpp::ALGORITHMS::SHA2_256: { + for (const std::string& data : keyDataSet.getData()) { + vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHMAC(keyDataSet.getKey(), data)); } - case hashpp::ALGORITHMS::SHA2_384: { - vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHMAC(_keyData.first, _keyData.second)); - break; + break; + } + case hashpp::ALGORITHMS::SHA2_384: { + for (const std::string& data : keyDataSet.getData()) { + vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHMAC(keyDataSet.getKey(), data)); } - case hashpp::ALGORITHMS::SHA2_512: { - vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHMAC(_keyData.first, _keyData.second)); - break; + break; + } + case hashpp::ALGORITHMS::SHA2_512: { + for (const std::string& data : keyDataSet.getData()) { + vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHMAC(keyDataSet.getKey(), data)); } - case hashpp::ALGORITHMS::SHA2_512_224: { - vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHMAC(_keyData.first, _keyData.second)); - break; + break; + } + case hashpp::ALGORITHMS::SHA2_512_224: { + for (const std::string& data : keyDataSet.getData()) { + vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHMAC(keyDataSet.getKey(), data)); } - case hashpp::ALGORITHMS::SHA2_512_256: { - vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHMAC(_keyData.first, _keyData.second)); - break; + break; + } + case hashpp::ALGORITHMS::SHA2_512_256: { + for (const std::string& data : keyDataSet.getData()) { + vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHMAC(keyDataSet.getKey(), data)); } + break; } } } @@ -3238,7 +3443,90 @@ namespace hashpp { }; } - // function to return a collection of resulting HMACs from selected ALGORITHM and passed key-data + static hashpp::hashCollection getHMACs(const std::initializer_list& keyDataSets) { + std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256; + + for (const DataContainer& keyDataSet : keyDataSets) { + switch (keyDataSet.getAlgorithm()) { + case hashpp::ALGORITHMS::MD5: { + for (const std::string& data : keyDataSet.getData()) { + vMD5.push_back(hashpp::MD::MD5().getHMAC(keyDataSet.getKey(), data)); + } + break; + } + case hashpp::ALGORITHMS::MD4: { + for (const std::string& data : keyDataSet.getData()) { + vMD4.push_back(hashpp::MD::MD4().getHMAC(keyDataSet.getKey(), data)); + } + break; + } + case hashpp::ALGORITHMS::MD2: { + for (const std::string& data : keyDataSet.getData()) { + vMD2.push_back(hashpp::MD::MD2().getHMAC(keyDataSet.getKey(), data)); + } + break; + } + case hashpp::ALGORITHMS::SHA1: { + for (const std::string& data : keyDataSet.getData()) { + vSHA1.push_back(hashpp::SHA::SHA1().getHMAC(keyDataSet.getKey(), data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_224: { + for (const std::string& data : keyDataSet.getData()) { + vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHMAC(keyDataSet.getKey(), data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_256: { + for (const std::string& data : keyDataSet.getData()) { + vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHMAC(keyDataSet.getKey(), data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_384: { + for (const std::string& data : keyDataSet.getData()) { + vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHMAC(keyDataSet.getKey(), data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_512: { + for (const std::string& data : keyDataSet.getData()) { + vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHMAC(keyDataSet.getKey(), data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_512_224: { + for (const std::string& data : keyDataSet.getData()) { + vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHMAC(keyDataSet.getKey(), data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_512_256: { + for (const std::string& data : keyDataSet.getData()) { + vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHMAC(keyDataSet.getKey(), data)); + } + break; + } + } + } + return hashCollection { + { + { "MD5", vMD5 }, + { "MD4", vMD4 }, + { "MD2", vMD2 }, + { "SHA1", vSHA1 }, + { "SHA2-224", vSHA2_224 }, + { "SHA2-256", vSHA2_256 }, + { "SHA2-384", vSHA2_384 }, + { "SHA2-512", vSHA2_512 }, + { "SHA2-512-224", vSHA2_512_224 }, + { "SHA2-512-256", vSHA2_512_256 } + } + }; + } + + // function to return a collection of resulting HMACs from selected ALGORITHM, key, and data template ...>, int> = 0> static hashpp::hashCollection getHMACs(hashpp::ALGORITHMS algorithm, const std::string& key, const _Ts&... data) { @@ -3341,102 +3629,333 @@ namespace hashpp { } // function to return a collection of resulting hashes from selected ALGORITHMS and passed files (with recursive directory support) - static hashpp::hashCollection getFilesHashes(const std::vector>>& algorithmPathPairs) { + static hashpp::hashCollection getFilesHashes(const std::vector& filePathSets) { std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256; - for (const std::pair>& twin : algorithmPathPairs) { - for (const std::string& _path : twin.second) { - if (std::filesystem::exists(_path) && std::filesystem::is_regular_file(_path)) { - switch (twin.first) { - case hashpp::ALGORITHMS::MD5: { - vMD5.push_back(hashpp::MD::MD5().getHash(std::filesystem::path(_path))); - break; + for (const FilePathsContainer& filePathSet : filePathSets) { + switch (filePathSet.getAlgorithm()) { + case hashpp::ALGORITHMS::MD5: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vMD5.push_back(hashpp::MD::MD5().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { + vMD5.push_back(hashpp::MD::MD5().getHash(item.path())); + } + } + } + } + break; + } + case hashpp::ALGORITHMS::MD4: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vMD4.push_back(hashpp::MD::MD4().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { + vMD4.push_back(hashpp::MD::MD4().getHash(item.path())); + } + } + } + } + break; + } + case hashpp::ALGORITHMS::MD2: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vMD2.push_back(hashpp::MD::MD2().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { + vMD2.push_back(hashpp::MD::MD2().getHash(item.path())); + } + } + } + } + break; + } + case hashpp::ALGORITHMS::SHA1: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vSHA1.push_back(hashpp::SHA::SHA1().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { + vSHA1.push_back(hashpp::SHA::SHA1().getHash(item.path())); + } + } + } + } + break; + } + case hashpp::ALGORITHMS::SHA2_224: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(std::filesystem::path(path))); } - case hashpp::ALGORITHMS::MD4: { - vMD4.push_back(hashpp::MD::MD4().getHash(std::filesystem::path(_path))); - break; + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { + vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(item.path())); + } + } } - case hashpp::ALGORITHMS::MD2: { - vMD2.push_back(hashpp::MD::MD2().getHash(std::filesystem::path(_path))); - break; + } + break; + } + case hashpp::ALGORITHMS::SHA2_256: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(std::filesystem::path(path))); } - case hashpp::ALGORITHMS::SHA1: { - vSHA1.push_back(hashpp::SHA::SHA1().getHash(std::filesystem::path(_path))); - break; + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { + vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(item.path())); + } + } + } + } + break; + } + case hashpp::ALGORITHMS::SHA2_384: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { + vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHash(item.path())); + } + } } - case hashpp::ALGORITHMS::SHA2_224: { - vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(std::filesystem::path(_path))); - break; + } + break; + } + case hashpp::ALGORITHMS::SHA2_512: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(std::filesystem::path(path))); } - case hashpp::ALGORITHMS::SHA2_256: { - vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(std::filesystem::path(_path))); - break; + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { + vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(item.path())); + } + } } - case hashpp::ALGORITHMS::SHA2_384: { - vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHash(std::filesystem::path(_path))); - break; + } + break; + } + case hashpp::ALGORITHMS::SHA2_512_224: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(std::filesystem::path(path))); } - case hashpp::ALGORITHMS::SHA2_512: { - vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(std::filesystem::path(_path))); - break; + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { + vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(item.path())); + } + } } - case hashpp::ALGORITHMS::SHA2_512_224: { - vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(std::filesystem::path(_path))); - break; + } + break; + } + case hashpp::ALGORITHMS::SHA2_512_256: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(std::filesystem::path(path))); } - case hashpp::ALGORITHMS::SHA2_512_256: { - vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(std::filesystem::path(_path))); - break; + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { + vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(item.path())); + } + } } } + break; } - else if (std::filesystem::exists(_path) && std::filesystem::is_directory(_path)) { - for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(_path)) { - if (item.is_regular_file()) { - switch (twin.first) { - case hashpp::ALGORITHMS::MD5: { + } + } + return hashCollection { + { + { "MD5", vMD5 }, + { "MD4", vMD4 }, + { "MD2", vMD2 }, + { "SHA1", vSHA1 }, + { "SHA2-224", vSHA2_224 }, + { "SHA2-256", vSHA2_256 }, + { "SHA2-384", vSHA2_384 }, + { "SHA2-512", vSHA2_512 }, + { "SHA2-512-224", vSHA2_512_224 }, + { "SHA2-512-256", vSHA2_512_256 } + } + }; + } + + static hashpp::hashCollection getFilesHashes(const std::initializer_list& filePathSets) { + std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256; + + for (const FilePathsContainer& filePathSet : filePathSets) { + switch (filePathSet.getAlgorithm()) { + case hashpp::ALGORITHMS::MD5: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vMD5.push_back(hashpp::MD::MD5().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { vMD5.push_back(hashpp::MD::MD5().getHash(item.path())); - break; } - case hashpp::ALGORITHMS::MD4: { + } + } + } + break; + } + case hashpp::ALGORITHMS::MD4: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vMD4.push_back(hashpp::MD::MD4().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { vMD4.push_back(hashpp::MD::MD4().getHash(item.path())); - break; } - case hashpp::ALGORITHMS::MD2: { + } + } + } + break; + } + case hashpp::ALGORITHMS::MD2: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vMD2.push_back(hashpp::MD::MD2().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { vMD2.push_back(hashpp::MD::MD2().getHash(item.path())); - break; } - case hashpp::ALGORITHMS::SHA1: { + } + } + } + break; + } + case hashpp::ALGORITHMS::SHA1: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vSHA1.push_back(hashpp::SHA::SHA1().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { vSHA1.push_back(hashpp::SHA::SHA1().getHash(item.path())); - break; } - case hashpp::ALGORITHMS::SHA2_224: { + } + } + } + break; + } + case hashpp::ALGORITHMS::SHA2_224: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(item.path())); - break; } - case hashpp::ALGORITHMS::SHA2_256: { + } + } + } + break; + } + case hashpp::ALGORITHMS::SHA2_256: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(item.path())); - break; } - case hashpp::ALGORITHMS::SHA2_384: { + } + } + } + break; + } + case hashpp::ALGORITHMS::SHA2_384: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHash(item.path())); - break; } - case hashpp::ALGORITHMS::SHA2_512: { + } + } + } + break; + } + case hashpp::ALGORITHMS::SHA2_512: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(item.path())); - break; } - case hashpp::ALGORITHMS::SHA2_512_224: { + } + } + } + break; + } + case hashpp::ALGORITHMS::SHA2_512_224: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(item.path())); - break; } - case hashpp::ALGORITHMS::SHA2_512_256: { + } + } + } + break; + } + case hashpp::ALGORITHMS::SHA2_512_256: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(item.path())); - break; } } } } + break; } } } @@ -3454,7 +3973,7 @@ namespace hashpp { { "SHA2-512-256", vSHA2_512_256 } } }; - } + } }; #if defined(HASHPP_INCLUDE_METRICS) From 042ef57ea326e953fe91bbe85be39848b10c0872 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 13:06:42 -0500 Subject: [PATCH 05/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 15add65..d6ef0df 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ My original design idea behind Hash++ was for it to be simple. This has r

Below you can find the signatures of the only functions necessary to accomplish retrieving hashes from both single or multiple sets of data, files, and files in nested directories. All functions are located in the hashpp namespace under class get (hashpp::get).

-You can find examples of Hash++ in use in the /examples and /tests directories. +You can find examples of Hash++ in use in the /documentation directory.

getHash(...), getHMAC(...)

Retrieve a single hash from a single piece of data, or retrieve an HMAC from a key-data pair. From 4cefcf56af8ed50a7504034d753607f0827c891f Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 13:11:41 -0500 Subject: [PATCH 06/56] Update function signatures. --- README.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index d6ef0df..aa1a9e0 100644 --- a/README.md +++ b/README.md @@ -112,24 +112,27 @@ static hashpp::hash getHMAC(hashpp::ALGORITHMS algorithm, const std::string& key Retrieve a collection of hashes from multiple pieces of data, or retrieve a collection of HMACs from multiple pieces of data. ```cpp -static hashpp::hashCollection getHashes(const std::vector>>& algorithmDataPairs); -template static hashpp::hashCollection getHashes(hashpp::ALGORITHMS algorithm, const _Ts&... data); -static hashpp::hashCollection getHMACs(const std::vector>>>& algorithmKeyDataPairs); -template static hashpp::hashCollection getHMACs(hashpp::ALGORITHMS algorithm, const std::string& key, const _Ts&... data) +static hashpp::hashCollection getHashes(const std::vector& dataSets); +static hashpp::hashCollection getHashes(const std::initializer_list& dataSets); +template +static hashpp::hashCollection getHashes(hashpp::ALGORITHMS algorithm, const _Ts&... data); +static hashpp::hashCollection getHMACs(const std::vector& keyDataSets); +static hashpp::hashCollection getHMACs(const std::initializer_list& keyDataSets); +template +static hashpp::hashCollection getHMACs(hashpp::ALGORITHMS algorithm, const std::string& key, const _Ts&... data); ```

getFileHash(...)

Retrieve a single hash from a single file. ```cpp -// function to return a resulting hash from selected ALGORITHM and passed file -static hashpp::hash getFileHash(hashpp::ALGORITHMS algorithm, const std::string& path) +static hashpp::hash getFileHash(hashpp::ALGORITHMS algorithm, const std::string& path); ```

getFilesHashes(...)

Retrieve a collection of hashes from multiple files or files in nested directories. ```cpp -// function to return a collection of resulting hashes from selected ALGORITHMS and passed files (with recursive directory support) -static hashpp::hashCollection getFilesHashes(const std::vector>>& algorithmPathPairs) +static hashpp::hashCollection getFilesHashes(const std::vector& filePathSets); +static hashpp::hashCollection getFilesHashes(const std::initializer_list& filePathSets); ``` From 8fdbfe33d5827228394fe4560c9a42495b42588b Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 13:12:39 -0500 Subject: [PATCH 07/56] Delete examples directory --- examples/getHashFromFile.cpp | 20 ------------ examples/getHashesFromFiles.cpp | 44 ------------------------- examples/getSimpleHash.cpp | 26 --------------- examples/getSimpleHashes.cpp | 57 --------------------------------- 4 files changed, 147 deletions(-) delete mode 100644 examples/getHashFromFile.cpp delete mode 100644 examples/getHashesFromFiles.cpp delete mode 100644 examples/getSimpleHash.cpp delete mode 100644 examples/getSimpleHashes.cpp diff --git a/examples/getHashFromFile.cpp b/examples/getHashFromFile.cpp deleted file mode 100644 index 7dcbf5f..0000000 --- a/examples/getHashFromFile.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* - - getHashFromFile - Example to show how to get the hash of a single file. - -*/ - -#include "hashpp.h" - -using namespace hashpp; - -int main() { - // get a hash of item1.txt in relative directory folder1 - hash _a = get::getFileHash(ALGORITHMS::MD5, "./folder1/item1.txt"); - - std::cout << _a << std::endl; - // or _a.getString() - - // output: 4817a091b69d5e89d7d5757e6ce19609 -> ./folder1/item1.txt -} diff --git a/examples/getHashesFromFiles.cpp b/examples/getHashesFromFiles.cpp deleted file mode 100644 index d811a5c..0000000 --- a/examples/getHashesFromFiles.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - - getHashesFromFiles: - Example to show how to get the hashes of multiple files in a directory - or nested directory. - - Assume relative path used has structure: - . - |--> /folder1 - |--> /folder2 - |-- item6.txt - |-- item1.txt - |-- item2.txt - |-- item3.txt - |-- item4.txt - |-- item5.txt - - hashpp::get::getFilesHashes() traverses directories and hashes files - alphabetically. - -*/ - -#include "hashpp.h" - -using namespace hashpp; - -int main() { - // get a collection of hashes from files in relative directory folder1 and subsequent dirs - hashCollection _a = get::getFilesHashes({ {ALGORITHMS::MD5, {"./folder1"}} }); - - // print each MD5 hash collected - for (auto _z : _a["MD5"]) { - std::cout << _z << std::endl; - } - - /* the output is as follows: - 11ddbaf3386aea1f2974eee984542152 -> ./folder1/folder2/item6.txt - 4817a091b69d5e89d7d5757e6ce19609 -> ./folder1/item1.txt - 15cd0e3d368b6a8eb7378dc81ad40dfb -> ./folder1/item2.txt - e09ab0e2ff8e94687f228eac8a627887 -> ./folder1/item3.txt - 2995ff3cd4c7d15b529bf3fa76e5cc71 -> ./folder1/item4.txt - 8188577c8d593f7654c3cc621fdfa009 -> ./folder1/item5.txt - */ -} diff --git a/examples/getSimpleHash.cpp b/examples/getSimpleHash.cpp deleted file mode 100644 index c9a5d62..0000000 --- a/examples/getSimpleHash.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* - - getHash.cpp - Example showing how to get the hash of simple data. - -*/ - -#include "hashpp.h" - -using namespace hashpp; - -int main() { - // string that we want to get the hash of - std::string dataToBeHashed = "sample text"; - - // hashes can be printed directly like normal - // output: bc658c641ef71739fb9995bded59b21150bbff4367f6e4e4c7934b489b9d2c00 - std::cout << get::getHash(ALGORITHMS::SHA2_256, dataToBeHashed) << std::endl; - - // ... or, we can capture the returned hashpp::hash object - hash _hex = get::getHash(ALGORITHMS::SHA2_256, dataToBeHashed); - std::cout << _hex << std::endl; - - // ... or, we can simply capture the std::string object of the hash's hex string - std::string _hexString = get::getHash(ALGORITHMS::SHA2_256, dataToBeHashed).getString(); -} diff --git a/examples/getSimpleHashes.cpp b/examples/getSimpleHashes.cpp deleted file mode 100644 index e7262d4..0000000 --- a/examples/getSimpleHashes.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - - getSimpleHashes.cpp - Example showing how to retrieve and iterate several hashes from several pieces of simple data. - -*/ - -#include "hashpp.h" - -using namespace hashpp; - -int main() { - // get a hash collection containing the MD5 and MD4 hashes for all passed data - std::vector data1 = { "data1", "data2", "data3", "data4", "data5", "data6", "data7", "data8", "data9" }; - std::vector data2 = { "data1", "data2", "data3", "data4", "data5", "data6", "data7", "data8", "data9" }; - hashCollection collection1 = get::getHashes({ {ALGORITHMS::MD4, data1}, {ALGORITHMS::MD5, data2} }); - - // the method above of getting multiple hashes is equivalent to the below - hashCollection collection2 = get::getHashes({ {ALGORITHMS::MD4, {"data1", "data2", "data3", - "data4", "data5", "data6", - "data7", "data8", "data9"} }, - {ALGORITHMS::MD5, {"data1", "data2", "data3", - "data4", "data5", "data6", - "data7", "data8", "data9"} } }); - - // to iterate over hashes from a specific algorithm (in the order they were supplied) - for (auto i : collection2["MD5"]) { - std::cout << i << std::endl; - } - for (auto i : collection2["MD4"]) { - std::cout << i << std::endl; - } - - // the above will iterate through the hashes of "data1"-"data9" for both MD5 and MD4 - /* - First iteration (MD5): - 89d903bc35dede724fd52c51437ff5fd -> data1 - ff9cf2d690d888cb337f6bf4526b6130 -> data2 - 79369f78f7882c1baabbc7d45dc5daa0 -> data3 - 732160808412a20c3f0bfad2b3822d1b -> data4 - cd8e177a28c90b63d548464fa36b2a14 -> data5 - 78c5d69ee9c8aecbf63710a3733501f2 -> data6 - 4a7506e3aa540549299dbf459238f7be -> data7 - c1e739549f7045ca51d24faee4d3f18d -> data8 - fc5f764fd223e02a85787099f2e51431 -> data9 - Second Iteration (MD4): - 6ae4b3d10b07413e1ea4915f6da7cab4 -> data1 - ce730e5c428c5fd0dc951c90508547fe -> data2 - a4673b83fec1b1ae9eeea7f22a71f86f -> data3 - 2985b2773e43dce3033e38eab9956fc5 -> data4 - 6f818b962e62ad9f406e98efbd65feb4 -> data5 - ecd827c94a72c4e23b7fb39b962ed54a -> data6 - 81847db91976839c31292c83eac2683d -> data7 - 496c47c9f969be38672817cac65bb38d -> data8 - 03ce39fe2914fafebd1bcb81acb816ea -> data9 - */ -} From e8a254c0f1fe063995eed6feb694c18eabe3c7f9 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 13:13:17 -0500 Subject: [PATCH 08/56] Delete hashUserSuppliedData.cpp --- tests/hashUserSuppliedData.cpp | 39 ---------------------------------- 1 file changed, 39 deletions(-) delete mode 100644 tests/hashUserSuppliedData.cpp diff --git a/tests/hashUserSuppliedData.cpp b/tests/hashUserSuppliedData.cpp deleted file mode 100644 index a562383..0000000 --- a/tests/hashUserSuppliedData.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - - Simple program to hash command-line supplied data - Example: - ./program.exe data1 data2 data3 - - output: - MD5: "data1": 89d903bc35dede724fd52c51437ff5fd - MD4: "data1": 6ae4b3d10b07413e1ea4915f6da7cab4 - MD2: "data1": 2feff92dc8130b5f4104e430a77269e0 - SHA1: "data1": cbcc2ff6a0894e6e7f9a1a6a6a36b68fb36aa151 - SHA2-224: "data1": 2fa1977e21efb718f7bfa4392e8ff6f9cd07ef2c81e1f0bd5164f8b7 - SHA2-256: "data1": 5b41362bc82b7f3d56edc5a306db22105707d01ff4819e26faef9724a2d406c9 - SHA2-384: "data1": ea77c52d2aab72be97f2864011b11a2d16b07eb67c9dfb9549ac141e2a03369ac59563f5f370a7504f72bccd0ccad31c - SHA2-512: "data1": 9731b541b22c1d7042646ab2ee17685bbb664bced666d8ecf3593f3ef46493deef651b0f31b6cff8c4df8dcb425a1035e86ddb9877a8685647f39847be0d7c01 - SHA2-512/224: "data1": 42161d4488f6f3d03e4f05f85d6354ed8f211ebdd563ba928c388010 - SHA2-512/256: "data1": b4b134e80ec4b27a0d5ab88c7c466ddfca17ce9f4b4369f83b118bfea09516c0 - ... and so on ... - -*/ - -#include "hashpp.h" - -using namespace hashpp; - -int main(int argc, const char* argv[]) { - for (int i = 1; i < argc; i++) { - std::cout << " MD5: \"" << argv[i] << "\": " << get::getHash(ALGORITHMS::MD5, argv[i]) << std::endl; - std::cout << " MD4: \"" << argv[i] << "\": " << get::getHash(ALGORITHMS::MD4, argv[i]) << std::endl; - std::cout << " MD2: \"" << argv[i] << "\": " << get::getHash(ALGORITHMS::MD2, argv[i]) << std::endl; - std::cout << " SHA1: \"" << argv[i] << "\": " << get::getHash(ALGORITHMS::SHA1, argv[i]) << std::endl; - std::cout << " SHA2-224: \"" << argv[i] << "\": " << get::getHash(ALGORITHMS::SHA2_224, argv[i]) << std::endl; - std::cout << " SHA2-256: \"" << argv[i] << "\": " << get::getHash(ALGORITHMS::SHA2_256, argv[i]) << std::endl; - std::cout << " SHA2-384: \"" << argv[i] << "\": " << get::getHash(ALGORITHMS::SHA2_384, argv[i]) << std::endl; - std::cout << " SHA2-512: \"" << argv[i] << "\": " << get::getHash(ALGORITHMS::SHA2_512, argv[i]) << std::endl; - std::cout << "SHA2-512/224: \"" << argv[i] << "\": " << get::getHash(ALGORITHMS::SHA2_512_224, argv[i]) << std::endl; - std::cout << "SHA2-512/256: \"" << argv[i] << "\": " << get::getHash(ALGORITHMS::SHA2_512_256, argv[i]) << std::endl; - } -} From 579bccbf25651a9789a2419aa88088b2ffc851d5 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 13:13:43 -0500 Subject: [PATCH 09/56] Create documentation README. --- documentation/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 documentation/README.md diff --git a/documentation/README.md b/documentation/README.md new file mode 100644 index 0000000..c65637d --- /dev/null +++ b/documentation/README.md @@ -0,0 +1 @@ +Add docs here. From 5e7c61a03cbe77c8bbfe5493d29069ad8446de5f Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 13:15:50 -0500 Subject: [PATCH 10/56] Create documentation/hashing README. --- documentation/hashing/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 documentation/hashing/README.md diff --git a/documentation/hashing/README.md b/documentation/hashing/README.md new file mode 100644 index 0000000..8df3d73 --- /dev/null +++ b/documentation/hashing/README.md @@ -0,0 +1 @@ +Add generic hashing docs + examples here From 33a289b4d5dd10f2f25185d16b34d2aa0b847f3c Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 13:16:20 -0500 Subject: [PATCH 11/56] Create HMAC documentation README. --- documentation/HMACs/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 documentation/HMACs/README.md diff --git a/documentation/HMACs/README.md b/documentation/HMACs/README.md new file mode 100644 index 0000000..c54bdc4 --- /dev/null +++ b/documentation/HMACs/README.md @@ -0,0 +1 @@ +Add HMAC documentation + examples here. From a6c3fcc38402ced7bd1b8b61fde6e1d5506c40f2 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 13:17:39 -0500 Subject: [PATCH 12/56] Create documentation README for file_hashing. --- documentation/file_hashing | 1 + 1 file changed, 1 insertion(+) create mode 100644 documentation/file_hashing diff --git a/documentation/file_hashing b/documentation/file_hashing new file mode 100644 index 0000000..5fd4350 --- /dev/null +++ b/documentation/file_hashing @@ -0,0 +1 @@ +Add file hashing documentation + examples here. From 5502cea17fe4dd57dff2ab091ac8585d4f3314f7 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 13:17:52 -0500 Subject: [PATCH 13/56] Delete file_hashing --- documentation/file_hashing | 1 - 1 file changed, 1 deletion(-) delete mode 100644 documentation/file_hashing diff --git a/documentation/file_hashing b/documentation/file_hashing deleted file mode 100644 index 5fd4350..0000000 --- a/documentation/file_hashing +++ /dev/null @@ -1 +0,0 @@ -Add file hashing documentation + examples here. From c6b8eb5e3989ad220ec2bf3f5160db62660d7086 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 13:18:34 -0500 Subject: [PATCH 14/56] Create file_hashing README documentation (real) --- documentation/file_hashing/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 documentation/file_hashing/README.md diff --git a/documentation/file_hashing/README.md b/documentation/file_hashing/README.md new file mode 100644 index 0000000..5fd4350 --- /dev/null +++ b/documentation/file_hashing/README.md @@ -0,0 +1 @@ +Add file hashing documentation + examples here. From ece1cedae1d17e420b0b750113804b2516e702df Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 17:53:18 -0500 Subject: [PATCH 15/56] Populate base documentation README. --- documentation/README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/documentation/README.md b/documentation/README.md index c65637d..473e5c4 100644 --- a/documentation/README.md +++ b/documentation/README.md @@ -1 +1,11 @@ -Add docs here. +

Documentation

+Hash++ is a modern C++17 header-only library that provides developers simple means of retrieving cryptographic hashes and hased message authentication codes (HMACs) from the algorithm(s) of their choice. The library was developed with the goal of appealing to one particular type of developer--one who does not want to use larger, heavier, or more confusing libraries with unnecessary features to simply hash data. +

+In the directories listed below, you can find explanations of concepts found within the implementations of the library and example usage of features found within Hash++. + +- Hashing Documentation + - Covers basic hashing concepts and how to generate them using the library. +- HMAC Documentation + - Covers basic HMAC concepts and how to generate them using the library. +- File-hashing Documentation + - Covers how to hash files using the library. From cd18f9670a7036778f4d40c458f00bad61cf59c8 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 17:53:53 -0500 Subject: [PATCH 16/56] Fix typo. --- documentation/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/README.md b/documentation/README.md index 473e5c4..cc13ec7 100644 --- a/documentation/README.md +++ b/documentation/README.md @@ -1,5 +1,5 @@

Documentation

-Hash++ is a modern C++17 header-only library that provides developers simple means of retrieving cryptographic hashes and hased message authentication codes (HMACs) from the algorithm(s) of their choice. The library was developed with the goal of appealing to one particular type of developer--one who does not want to use larger, heavier, or more confusing libraries with unnecessary features to simply hash data. +Hash++ is a modern C++17 header-only library that provides developers simple means of retrieving cryptographic hashes and hashed message authentication codes (HMACs) from the algorithm(s) of their choice. The library was developed with the goal of appealing to one particular type of developer--one who does not want to use larger, heavier, or more confusing libraries with unnecessary features to simply hash data.

In the directories listed below, you can find explanations of concepts found within the implementations of the library and example usage of features found within Hash++. From 8680e2e07c0bfde5c3a248c390e9751fdca0da55 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 18:38:01 -0500 Subject: [PATCH 17/56] Update README.md --- documentation/hashing/README.md | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/documentation/hashing/README.md b/documentation/hashing/README.md index 8df3d73..3c2104f 100644 --- a/documentation/hashing/README.md +++ b/documentation/hashing/README.md @@ -1 +1,24 @@ -Add generic hashing docs + examples here +

Hashing

+Hashing, in simple terms, is the cryptographic process of assigning a unique fingerprint to data such that no other data will produce the same fingerprint as another piece of data. +

+In mathematical terms, hashing is the functional process of mapping any arbitrary data X to a fixed-size, unique, and seemingly nonsensical value D. Hashing algorithms are one-way functions such that, given an input x to some hash function H, it is facile to compute the output hash digest D; however, given only some hash function H and an associated output digest D, it is infeasible to compute the original input data x. +

+Simply, a one-way function H(x) = D is one such function that satisfies all constraints such that... + +- D is easily computed given x. +- H's output range is known. +- Given only output D and function H, x is infeasibly computed such that H(x) = D. + +Given this inherent infeasibility of recovering initial input data to a given hash function, they are useful for a number of security purposes such as: + +- Message and file integrity verification. +- Password verification. +- Signature/identifier generation and verification. +- Key Derivation Functions (KDFs). +- Proof-of-Work. +- Blockchain Technology. +- Public-Key Cryptography. +- CSPRNGs. + +

Using Hash++

+Hash++ offers a simple set of methods to take advantage of the cryptographic-magic described above. From ea6309a1dd4a185c0dedf8491bbc1fb2db0ea3e9 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 18:40:23 -0500 Subject: [PATCH 18/56] Update README.md --- README.md | 43 +------------------------------------------ 1 file changed, 1 insertion(+), 42 deletions(-) diff --git a/README.md b/README.md index aa1a9e0..06a58b1 100644 --- a/README.md +++ b/README.md @@ -94,45 +94,4 @@ No, it doesn't. ```

Using Hash++

-My original design idea behind Hash++ was for it to be simple. This has remained unchanged. -

-Below you can find the signatures of the only functions necessary to accomplish retrieving hashes from both single or multiple sets of data, files, and files in nested directories. All functions are located in the hashpp namespace under class get (hashpp::get). -

-You can find examples of Hash++ in use in the /documentation directory. -
-

getHash(...), getHMAC(...)

-Retrieve a single hash from a single piece of data, or retrieve an HMAC from a key-data pair. - -```cpp -static hashpp::hash getHash(hashpp::ALGORITHMS algorithm, const std::string& data); -static hashpp::hash getHMAC(hashpp::ALGORITHMS algorithm, const std::string& key, const std::string& data) -``` - -

getHashes(...), getHMACs(...)

-Retrieve a collection of hashes from multiple pieces of data, or retrieve a collection of HMACs from multiple pieces of data. - -```cpp -static hashpp::hashCollection getHashes(const std::vector& dataSets); -static hashpp::hashCollection getHashes(const std::initializer_list& dataSets); -template -static hashpp::hashCollection getHashes(hashpp::ALGORITHMS algorithm, const _Ts&... data); -static hashpp::hashCollection getHMACs(const std::vector& keyDataSets); -static hashpp::hashCollection getHMACs(const std::initializer_list& keyDataSets); -template -static hashpp::hashCollection getHMACs(hashpp::ALGORITHMS algorithm, const std::string& key, const _Ts&... data); -``` - -

getFileHash(...)

-Retrieve a single hash from a single file. - -```cpp -static hashpp::hash getFileHash(hashpp::ALGORITHMS algorithm, const std::string& path); -``` - -

getFilesHashes(...)

-Retrieve a collection of hashes from multiple files or files in nested directories. - -```cpp -static hashpp::hashCollection getFilesHashes(const std::vector& filePathSets); -static hashpp::hashCollection getFilesHashes(const std::initializer_list& filePathSets); -``` +You can find detailed documentation in the /documentation directory. From c58cade8410164505cb8419d808ddf4dca136311 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 18:52:05 -0500 Subject: [PATCH 19/56] Create container.cpp --- documentation/hashing/container.cpp | 81 +++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 documentation/hashing/container.cpp diff --git a/documentation/hashing/container.cpp b/documentation/hashing/container.cpp new file mode 100644 index 0000000..72be7f8 --- /dev/null +++ b/documentation/hashing/container.cpp @@ -0,0 +1,81 @@ + class Container { + public: // constructors + Container() noexcept = default; + Container(const Container& container) noexcept + : algorithm(container.algorithm), key(container.key), data(container.data) {} + Container(Container&& container) noexcept + : algorithm(container.algorithm), key(std::move(container.key)), data(std::move(container.data)) {} + Container( + ALGORITHMS algorithm, + const std::vector& data + ) noexcept : algorithm(algorithm), data(data) {} + Container( + ALGORITHMS algorithm, + const std::vector& data, + const std::string& key + ) noexcept : algorithm(algorithm), data(data), key(key) {} + + template ...>, int> = 0> + Container( + ALGORITHMS algorithm, + const _Ts&... data + ) noexcept : algorithm(algorithm), data({ data... }) {} + + template ..., std::negation>...>, int> = 0> + Container( + ALGORITHMS algorithm, + _Ts&&... data + ) noexcept : algorithm(algorithm), data({ std::forward<_Ts>(data)... }) {} + + public: // member functions + constexpr const ALGORITHMS& getAlgorithm() const noexcept { return this->algorithm; } + constexpr const std::string& getKey() const noexcept { return this->key; } + constexpr const std::vector& getData() const noexcept { return this->data; } + void setAlgorithm(ALGORITHMS algorithm) noexcept { this->algorithm = algorithm; } + void setKey(const std::string& key) noexcept { this->key = key; } + + void setData(const std::vector& data) noexcept { this->data = data; } + void setData(std::vector&& data) noexcept { this->data = std::move(data); } + template void setData(const _Ts&... data) noexcept { this->data = { data... }; } + template >...>, int> = 0> + void setData(_Ts&&... data) noexcept { this->data = { std::forward<_Ts>(data)... }; } + + void appendData(const std::vector& data) noexcept { this->data.insert(this->data.end(), data.begin(), data.end()); } + void appendData(std::vector&& data) noexcept { this->data.insert(this->data.end(), std::make_move_iterator(data.begin()), std::make_move_iterator(data.end())); } + template void appendData(const _Ts&... data) noexcept { (this->data.push_back(data), ...); } + template >...>, int> = 0> + void appendData(_Ts&&... data) noexcept { (this->data.push_back(std::forward<_Ts>(data)), ...); } + + Container& operator=(const Container& _rhs) noexcept { + if (this != &_rhs) { + this->algorithm = _rhs.getAlgorithm(); + this->key = _rhs.getKey(); + this->data = _rhs.getData(); + } + return *this; + } + + Container& operator=(Container&& _rhs) noexcept { + if (this != &_rhs) { + this->algorithm = _rhs.algorithm; + this->key = std::move(_rhs.key); + this->data = std::move(_rhs.data); + } + return *this; + } + + private: // member variables + ALGORITHMS algorithm; + std::string key; + + // Holds arbitrary data; how this data is defined is determined + // by the functions that the container containing said data is passed to. + // (e.g., a call to getFilesHashes with a container will treat all data + // in it as paths to files to be hashed, and a call to getHashes with + // a container will treat all data as generic data to be hashed) + std::vector data; + }; From ff79840060de728177390b2f54716cc4e8d1db30 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 18:53:13 -0500 Subject: [PATCH 20/56] Update container.cpp --- documentation/hashing/container.cpp | 142 ++++++++++++++-------------- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/documentation/hashing/container.cpp b/documentation/hashing/container.cpp index 72be7f8..dca99a3 100644 --- a/documentation/hashing/container.cpp +++ b/documentation/hashing/container.cpp @@ -1,81 +1,81 @@ - class Container { - public: // constructors - Container() noexcept = default; - Container(const Container& container) noexcept - : algorithm(container.algorithm), key(container.key), data(container.data) {} - Container(Container&& container) noexcept - : algorithm(container.algorithm), key(std::move(container.key)), data(std::move(container.data)) {} - Container( - ALGORITHMS algorithm, - const std::vector& data - ) noexcept : algorithm(algorithm), data(data) {} - Container( - ALGORITHMS algorithm, - const std::vector& data, - const std::string& key - ) noexcept : algorithm(algorithm), data(data), key(key) {} - - template ...>, int> = 0> - Container( - ALGORITHMS algorithm, - const _Ts&... data - ) noexcept : algorithm(algorithm), data({ data... }) {} +class Container { + public: // constructors + Container() noexcept = default; + Container(const Container& container) noexcept + : algorithm(container.algorithm), key(container.key), data(container.data) {} + Container(Container&& container) noexcept + : algorithm(container.algorithm), key(std::move(container.key)), data(std::move(container.data)) {} + Container( + ALGORITHMS algorithm, + const std::vector& data + ) noexcept : algorithm(algorithm), data(data) {} + Container( + ALGORITHMS algorithm, + const std::vector& data, + const std::string& key + ) noexcept : algorithm(algorithm), data(data), key(key) {} + + template ...>, int> = 0> + Container( + ALGORITHMS algorithm, + const _Ts&... data + ) noexcept : algorithm(algorithm), data({ data... }) {} - template ..., std::negation>...>, int> = 0> - Container( - ALGORITHMS algorithm, - _Ts&&... data - ) noexcept : algorithm(algorithm), data({ std::forward<_Ts>(data)... }) {} + template ..., std::negation>...>, int> = 0> + Container( + ALGORITHMS algorithm, + _Ts&&... data + ) noexcept : algorithm(algorithm), data({ std::forward<_Ts>(data)... }) {} - public: // member functions - constexpr const ALGORITHMS& getAlgorithm() const noexcept { return this->algorithm; } - constexpr const std::string& getKey() const noexcept { return this->key; } - constexpr const std::vector& getData() const noexcept { return this->data; } - void setAlgorithm(ALGORITHMS algorithm) noexcept { this->algorithm = algorithm; } - void setKey(const std::string& key) noexcept { this->key = key; } + public: // member functions + constexpr const ALGORITHMS& getAlgorithm() const noexcept { return this->algorithm; } + constexpr const std::string& getKey() const noexcept { return this->key; } + constexpr const std::vector& getData() const noexcept { return this->data; } + void setAlgorithm(ALGORITHMS algorithm) noexcept { this->algorithm = algorithm; } + void setKey(const std::string& key) noexcept { this->key = key; } - void setData(const std::vector& data) noexcept { this->data = data; } - void setData(std::vector&& data) noexcept { this->data = std::move(data); } - template void setData(const _Ts&... data) noexcept { this->data = { data... }; } - template >...>, int> = 0> - void setData(_Ts&&... data) noexcept { this->data = { std::forward<_Ts>(data)... }; } + void setData(const std::vector& data) noexcept { this->data = data; } + void setData(std::vector&& data) noexcept { this->data = std::move(data); } + template void setData(const _Ts&... data) noexcept { this->data = { data... }; } + template >...>, int> = 0> + void setData(_Ts&&... data) noexcept { this->data = { std::forward<_Ts>(data)... }; } - void appendData(const std::vector& data) noexcept { this->data.insert(this->data.end(), data.begin(), data.end()); } - void appendData(std::vector&& data) noexcept { this->data.insert(this->data.end(), std::make_move_iterator(data.begin()), std::make_move_iterator(data.end())); } - template void appendData(const _Ts&... data) noexcept { (this->data.push_back(data), ...); } - template >...>, int> = 0> - void appendData(_Ts&&... data) noexcept { (this->data.push_back(std::forward<_Ts>(data)), ...); } + void appendData(const std::vector& data) noexcept { this->data.insert(this->data.end(), data.begin(), data.end()); } + void appendData(std::vector&& data) noexcept { this->data.insert(this->data.end(), std::make_move_iterator(data.begin()), std::make_move_iterator(data.end())); } + template void appendData(const _Ts&... data) noexcept { (this->data.push_back(data), ...); } + template >...>, int> = 0> + void appendData(_Ts&&... data) noexcept { (this->data.push_back(std::forward<_Ts>(data)), ...); } - Container& operator=(const Container& _rhs) noexcept { - if (this != &_rhs) { - this->algorithm = _rhs.getAlgorithm(); - this->key = _rhs.getKey(); - this->data = _rhs.getData(); - } - return *this; + Container& operator=(const Container& _rhs) noexcept { + if (this != &_rhs) { + this->algorithm = _rhs.getAlgorithm(); + this->key = _rhs.getKey(); + this->data = _rhs.getData(); } + return *this; + } - Container& operator=(Container&& _rhs) noexcept { - if (this != &_rhs) { - this->algorithm = _rhs.algorithm; - this->key = std::move(_rhs.key); - this->data = std::move(_rhs.data); - } - return *this; + Container& operator=(Container&& _rhs) noexcept { + if (this != &_rhs) { + this->algorithm = _rhs.algorithm; + this->key = std::move(_rhs.key); + this->data = std::move(_rhs.data); } + return *this; + } - private: // member variables - ALGORITHMS algorithm; - std::string key; + private: // member variables + ALGORITHMS algorithm; + std::string key; - // Holds arbitrary data; how this data is defined is determined - // by the functions that the container containing said data is passed to. - // (e.g., a call to getFilesHashes with a container will treat all data - // in it as paths to files to be hashed, and a call to getHashes with - // a container will treat all data as generic data to be hashed) - std::vector data; - }; + // Holds arbitrary data; how this data is defined is determined + // by the functions that the container containing said data is passed to. + // (e.g., a call to getFilesHashes with a container will treat all data + // in it as paths to files to be hashed, and a call to getHashes with + // a container will treat all data as generic data to be hashed) + std::vector data; +}; From 2c8e4280291cef5472f41bb2cc00c21e9001fac2 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 19:10:48 -0500 Subject: [PATCH 21/56] Create container_use.cpp --- documentation/hashing/container_use.cpp | 37 +++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 documentation/hashing/container_use.cpp diff --git a/documentation/hashing/container_use.cpp b/documentation/hashing/container_use.cpp new file mode 100644 index 0000000..81c2074 --- /dev/null +++ b/documentation/hashing/container_use.cpp @@ -0,0 +1,37 @@ +/* + + Basic usage and examples of Hash++ container class Container. + This container can be used to store paths to files to be hashed, + data to be hashed, keys to use in generating HMACs of contained data, + the algorithm to use to hash the contained data, etc. + + This container and its aliases are used in several function overloads + where a developer may want to pass several sets of data and use a + different hashing algorithm for each set of data. + +*/ + +#include "hashpp.h" + +using namespace hashpp; + +int main() { + // instantiation, assignment via member functions + DataContainer cont1; + cont1.setData("dataToHash1", "dataToHash2"); + cont1.appendData("moreDataToHash1", "moreDataToHash2"); + cont1.setAlgorithm(ALGORITHMS::SHA2_224); + + // instantiation, assignment via variadic data constructor + DataContainer cont2(ALGORITHMS::SHA2_256, "dataToHash1", "dataToHash2", "moreDataToHash1", "moreDataToHash2"); + + // instantiation, assignment via vector constructor + std::vector data = { "dataToHash1", "dataToHash2", "moreDataToHash1", "moreDataToHash2" }; + DataContainer cont3(ALGORITHMS::SHA2_384, data); + + // these containers can then be passed to their respective library function overloads + // as an initializer list or vector + std::vector containers = { cont1, cont2, cont3 }; + auto _hashes1 = get::getHashes(containers); + auto _hashes2 = get::getHashes({ cont1, cont2, cont3 }); +} From 1feff88e7ff8d039c077525a7fe87a6646673c48 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 19:19:40 -0500 Subject: [PATCH 22/56] Add more moves cons. for Container --- include/hashpp.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/include/hashpp.h b/include/hashpp.h index 41b19a2..706ee2a 100644 --- a/include/hashpp.h +++ b/include/hashpp.h @@ -2961,11 +2961,30 @@ namespace hashpp { ALGORITHMS algorithm, const std::vector& data ) noexcept : algorithm(algorithm), data(data) {} + Container( + ALGORITHMS algorithm, + std::vector&& data + ) noexcept : algorithm(algorithm), data(std::move(data)) {} Container( ALGORITHMS algorithm, const std::vector& data, const std::string& key ) noexcept : algorithm(algorithm), data(data), key(key) {} + Container( + ALGORITHMS algorithm, + std::vector&& data, + const std::string& key + ) noexcept : algorithm(algorithm), data(std::move(data)), key(key) {} + Container( + ALGORITHMS algorithm, + const std::vector& data, + std::string&& key + ) noexcept : algorithm(algorithm), data(data), key(std::move(key)) {} + Container( + ALGORITHMS algorithm, + std::vector&& data, + std::string&& key + ) noexcept : algorithm(algorithm), data(std::move(data)), key(std::move(key)) {} template ...>, int> = 0> From 913b164188fdb9efaf543aea1abebf3e9dcf083a Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 19:22:27 -0500 Subject: [PATCH 23/56] Update README.md --- documentation/hashing/README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/documentation/hashing/README.md b/documentation/hashing/README.md index 3c2104f..4f480cf 100644 --- a/documentation/hashing/README.md +++ b/documentation/hashing/README.md @@ -21,4 +21,18 @@ Given this inherent infeasibility of recovering initial input data to a given ha - CSPRNGs.

Using Hash++

-Hash++ offers a simple set of methods to take advantage of the cryptographic-magic described above. +Hash++ offers a simple set of methods to take advantage of the cryptographic-magic described above. You can generate simple hashes using the functions described below. + +``` +static hashpp::hash getHash(hashpp::ALGORITHMS algorithm, const std::string& data); +static hashpp::hashCollection getHashes(const std::vector& dataSets); +static hashpp::hashCollection getHashes(const std::initializer_list& dataSets); +template static hashpp::hashCollection getHashes(hashpp::ALGORITHMS algorithm, const _Ts&... data); +``` +
+Some function overloads found in Hash++ make use of a container class Container with aliases DataContainer, HMAC_DataContainer, and FilePathsContainer. This class allows developers to contain all data associated with a particular hash algorithm in one name, making it easier to pass several of them, if desired, and, in turn, several sets of data to hash. You can find the detailed implementation of the class below. +https://github.com/D7EAD/HashPlusPlus/blob/ff79840060de728177390b2f54716cc4e8d1db30/documentation/hashing/container.cpp#L1-L81 + +
+While the class may seem daunting at first, below you can find examples of its use and instantiation, as well as how it can be passed to certain function overloads. +https://github.com/D7EAD/HashPlusPlus/blob/2c8e4280291cef5472f41bb2cc00c21e9001fac2/documentation/hashing/container_use.cpp#L14-L37 From b7ef585198e52e05a2e2b9f9c29d052de98e9110 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 19:33:17 -0500 Subject: [PATCH 24/56] Update container.cpp --- documentation/hashing/container.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/documentation/hashing/container.cpp b/documentation/hashing/container.cpp index dca99a3..beba1de 100644 --- a/documentation/hashing/container.cpp +++ b/documentation/hashing/container.cpp @@ -9,12 +9,31 @@ class Container { ALGORITHMS algorithm, const std::vector& data ) noexcept : algorithm(algorithm), data(data) {} + Container( + ALGORITHMS algorithm, + std::vector&& data + ) noexcept : algorithm(algorithm), data(std::move(data)) {} Container( ALGORITHMS algorithm, const std::vector& data, const std::string& key ) noexcept : algorithm(algorithm), data(data), key(key) {} - + Container( + ALGORITHMS algorithm, + std::vector&& data, + const std::string& key + ) noexcept : algorithm(algorithm), data(std::move(data)), key(key) {} + Container( + ALGORITHMS algorithm, + const std::vector& data, + std::string&& key + ) noexcept : algorithm(algorithm), data(data), key(std::move(key)) {} + Container( + ALGORITHMS algorithm, + std::vector&& data, + std::string&& key + ) noexcept : algorithm(algorithm), data(std::move(data)), key(std::move(key)) {} + template ...>, int> = 0> Container( From 8a22574b0e71709ddbb0b6d3525f20a807a6e056 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 19:34:38 -0500 Subject: [PATCH 25/56] Update README.md --- documentation/hashing/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/hashing/README.md b/documentation/hashing/README.md index 4f480cf..4f2f88a 100644 --- a/documentation/hashing/README.md +++ b/documentation/hashing/README.md @@ -31,7 +31,7 @@ template static hashpp::hashCollection getHashes(hashpp::ALG ```
Some function overloads found in Hash++ make use of a container class Container with aliases DataContainer, HMAC_DataContainer, and FilePathsContainer. This class allows developers to contain all data associated with a particular hash algorithm in one name, making it easier to pass several of them, if desired, and, in turn, several sets of data to hash. You can find the detailed implementation of the class below. -https://github.com/D7EAD/HashPlusPlus/blob/ff79840060de728177390b2f54716cc4e8d1db30/documentation/hashing/container.cpp#L1-L81 +https://github.com/D7EAD/HashPlusPlus/blob/b7ef585198e52e05a2e2b9f9c29d052de98e9110/documentation/hashing/container.cpp#L1-L100
While the class may seem daunting at first, below you can find examples of its use and instantiation, as well as how it can be passed to certain function overloads. From 305aba5958789eb309889c3abba571b186afd5b5 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Tue, 6 Dec 2022 23:17:37 -0500 Subject: [PATCH 26/56] Update container.cpp --- documentation/hashing/container.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/hashing/container.cpp b/documentation/hashing/container.cpp index beba1de..5472d23 100644 --- a/documentation/hashing/container.cpp +++ b/documentation/hashing/container.cpp @@ -93,7 +93,7 @@ class Container { // Holds arbitrary data; how this data is defined is determined // by the functions that the container containing said data is passed to. - // (e.g., a call to getFilesHashes with a container will treat all data + // (e.g., a call to getFilesHashes with a container will treat all data // in it as paths to files to be hashed, and a call to getHashes with // a container will treat all data as generic data to be hashed) std::vector data; From 405c33001003a9ece1e30613eba5f48d37835831 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Wed, 7 Dec 2022 15:43:15 -0500 Subject: [PATCH 27/56] Rename documentation/hashing/container.cpp to documentation/hashing/container/container.cpp --- documentation/hashing/{ => container}/container.cpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename documentation/hashing/{ => container}/container.cpp (100%) diff --git a/documentation/hashing/container.cpp b/documentation/hashing/container/container.cpp similarity index 100% rename from documentation/hashing/container.cpp rename to documentation/hashing/container/container.cpp From 8bf4d2971f5fab4ad0df75ea6f71a012841c504e Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Wed, 7 Dec 2022 15:43:30 -0500 Subject: [PATCH 28/56] Rename documentation/hashing/container_use.cpp to documentation/hashing/container/container_use.cpp --- documentation/hashing/{ => container}/container_use.cpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename documentation/hashing/{ => container}/container_use.cpp (100%) diff --git a/documentation/hashing/container_use.cpp b/documentation/hashing/container/container_use.cpp similarity index 100% rename from documentation/hashing/container_use.cpp rename to documentation/hashing/container/container_use.cpp From dbb9f22a25e19f344061eae8941cb5bd3d13da37 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Wed, 7 Dec 2022 15:44:53 -0500 Subject: [PATCH 29/56] Update README.md --- documentation/hashing/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/hashing/README.md b/documentation/hashing/README.md index 4f2f88a..0875c3a 100644 --- a/documentation/hashing/README.md +++ b/documentation/hashing/README.md @@ -31,8 +31,8 @@ template static hashpp::hashCollection getHashes(hashpp::ALG ```
Some function overloads found in Hash++ make use of a container class Container with aliases DataContainer, HMAC_DataContainer, and FilePathsContainer. This class allows developers to contain all data associated with a particular hash algorithm in one name, making it easier to pass several of them, if desired, and, in turn, several sets of data to hash. You can find the detailed implementation of the class below. -https://github.com/D7EAD/HashPlusPlus/blob/b7ef585198e52e05a2e2b9f9c29d052de98e9110/documentation/hashing/container.cpp#L1-L100 +https://github.com/D7EAD/HashPlusPlus/blob/8bf4d2971f5fab4ad0df75ea6f71a012841c504e/documentation/hashing/container/container.cpp#L1-L100
While the class may seem daunting at first, below you can find examples of its use and instantiation, as well as how it can be passed to certain function overloads. -https://github.com/D7EAD/HashPlusPlus/blob/2c8e4280291cef5472f41bb2cc00c21e9001fac2/documentation/hashing/container_use.cpp#L14-L37 +https://github.com/D7EAD/HashPlusPlus/blob/8bf4d2971f5fab4ad0df75ea6f71a012841c504e/documentation/hashing/container/container_use.cpp#L14-L37 From b7fbc10fc627ab21c39a51698882641e1073c78e Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 12:41:46 -0500 Subject: [PATCH 30/56] Create getHashes_usage.cpp --- .../hashing/getHashes/getHashes_usage.cpp | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 documentation/hashing/getHashes/getHashes_usage.cpp diff --git a/documentation/hashing/getHashes/getHashes_usage.cpp b/documentation/hashing/getHashes/getHashes_usage.cpp new file mode 100644 index 0000000..9616545 --- /dev/null +++ b/documentation/hashing/getHashes/getHashes_usage.cpp @@ -0,0 +1,29 @@ +/* + + Basic usage of Hash++ getHashes method. + This file shows basic usage of the above described method + and its overloads, as well as how data can be extracted + from its returned object. + +*/ + +#include "hashpp.h" + +using namespace hashpp; + +int main() { + // a container holding data to be hashed and algorithm to use + DataContainer cont1; + cont1.setAlgorithm(ALGORITHMS::SHA2_256); + cont1.setData("dataToHash1", "dataToHash2", "dataToHash3"); + + // acquiring the hashes of the data contained in the above + // container using its set algorithm (SHA2-256). + hashCollection hashes = get::getHashes(cont1); + + // printing the resulting hashes via hashCollection::operator[] + // with specific algorithm name + for (auto& hash : hashes["SHA2-256"]) { + std::cout << hash << std::endl; + } +} From 97eac3f461a144361041c6a111a4b84a7496f27e Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 12:43:22 -0500 Subject: [PATCH 31/56] Update README.md --- documentation/hashing/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/documentation/hashing/README.md b/documentation/hashing/README.md index 0875c3a..9541ee8 100644 --- a/documentation/hashing/README.md +++ b/documentation/hashing/README.md @@ -36,3 +36,7 @@ https://github.com/D7EAD/HashPlusPlus/blob/8bf4d2971f5fab4ad0df75ea6f71a012841c5
While the class may seem daunting at first, below you can find examples of its use and instantiation, as well as how it can be passed to certain function overloads. https://github.com/D7EAD/HashPlusPlus/blob/8bf4d2971f5fab4ad0df75ea6f71a012841c504e/documentation/hashing/container/container_use.cpp#L14-L37 + +
+As you can see above, when given a properly created Container, the library function getHashes(...) can easily calculate and retrieve the hash digests of the passed data contained in the container(s). The function getHashes(...) itself, though, returns a hashCollection object. This object can be parsed quite easily: +https://github.com/D7EAD/HashPlusPlus/blob/b7fbc10fc627ab21c39a51698882641e1073c78e/documentation/hashing/getHashes/getHashes_usage.cpp#L10-L29 From 4186529653b276a51b20074b7145c9574e3ec4e4 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 13:00:32 -0500 Subject: [PATCH 32/56] Add singular Container overloads for getXs(...) --- include/hashpp.h | 341 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 338 insertions(+), 3 deletions(-) diff --git a/include/hashpp.h b/include/hashpp.h index 706ee2a..5b3c66c 100644 --- a/include/hashpp.h +++ b/include/hashpp.h @@ -3153,7 +3153,88 @@ namespace hashpp { } } - // function to return a collection of resulting hashes from passed data containers + // function to return a collection of resulting hashes from passed data container(s) + static hashpp::hashCollection getHashes(const DataContainer& dataSet) { + std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256; + + switch (dataSet.getAlgorithm()) { + case hashpp::ALGORITHMS::MD5: { + for (const std::string& data : dataSet.getData()) { + vMD5.push_back(hashpp::MD::MD5().getHash(data)); + } + break; + } + case hashpp::ALGORITHMS::MD4: { + for (const std::string& data : dataSet.getData()) { + vMD4.push_back(hashpp::MD::MD4().getHash(data)); + } + break; + } + case hashpp::ALGORITHMS::MD2: { + for (const std::string& data : dataSet.getData()) { + vMD2.push_back(hashpp::MD::MD2().getHash(data)); + } + break; + } + case hashpp::ALGORITHMS::SHA1: { + for (const std::string& data : dataSet.getData()) { + vSHA1.push_back(hashpp::SHA::SHA1().getHash(data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_224: { + for (const std::string& data : dataSet.getData()) { + vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_256: { + for (const std::string& data : dataSet.getData()) { + vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_384: { + for (const std::string& data : dataSet.getData()) { + vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHash(data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_512: { + for (const std::string& data : dataSet.getData()) { + vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_512_224: { + for (const std::string& data : dataSet.getData()) { + vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_512_256: { + for (const std::string& data : dataSet.getData()) { + vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(data)); + } + break; + } + } + return hashCollection { + { + { "MD5", vMD5 }, + { "MD4", vMD4 }, + { "MD2", vMD2 }, + { "SHA1", vSHA1 }, + { "SHA2-224", vSHA2_224 }, + { "SHA2-256", vSHA2_256 }, + { "SHA2-384", vSHA2_384 }, + { "SHA2-512", vSHA2_512 }, + { "SHA2-512-224", vSHA2_512_224 }, + { "SHA2-512-256", vSHA2_512_256 } + } + }; + } + static hashpp::hashCollection getHashes(const std::vector& dataSets) { std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256; @@ -3378,7 +3459,88 @@ namespace hashpp { } } - // function to return a collection of resulting HMACs from selected ALGORITHMS and passed key-data containers + // function to return a collection of resulting HMACs from selected ALGORITHMS and passed key-data container(s) + static hashpp::hashCollection getHMACs(const HMAC_DataContainer& keyDataSet) { + std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256; + + switch (keyDataSet.getAlgorithm()) { + case hashpp::ALGORITHMS::MD5: { + for (const std::string& data : keyDataSet.getData()) { + vMD5.push_back(hashpp::MD::MD5().getHMAC(keyDataSet.getKey(), data)); + } + break; + } + case hashpp::ALGORITHMS::MD4: { + for (const std::string& data : keyDataSet.getData()) { + vMD4.push_back(hashpp::MD::MD4().getHMAC(keyDataSet.getKey(), data)); + } + break; + } + case hashpp::ALGORITHMS::MD2: { + for (const std::string& data : keyDataSet.getData()) { + vMD2.push_back(hashpp::MD::MD2().getHMAC(keyDataSet.getKey(), data)); + } + break; + } + case hashpp::ALGORITHMS::SHA1: { + for (const std::string& data : keyDataSet.getData()) { + vSHA1.push_back(hashpp::SHA::SHA1().getHMAC(keyDataSet.getKey(), data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_224: { + for (const std::string& data : keyDataSet.getData()) { + vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHMAC(keyDataSet.getKey(), data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_256: { + for (const std::string& data : keyDataSet.getData()) { + vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHMAC(keyDataSet.getKey(), data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_384: { + for (const std::string& data : keyDataSet.getData()) { + vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHMAC(keyDataSet.getKey(), data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_512: { + for (const std::string& data : keyDataSet.getData()) { + vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHMAC(keyDataSet.getKey(), data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_512_224: { + for (const std::string& data : keyDataSet.getData()) { + vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHMAC(keyDataSet.getKey(), data)); + } + break; + } + case hashpp::ALGORITHMS::SHA2_512_256: { + for (const std::string& data : keyDataSet.getData()) { + vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHMAC(keyDataSet.getKey(), data)); + } + break; + } + } + return hashCollection { + { + { "MD5", vMD5 }, + { "MD4", vMD4 }, + { "MD2", vMD2 }, + { "SHA1", vSHA1 }, + { "SHA2-224", vSHA2_224 }, + { "SHA2-256", vSHA2_256 }, + { "SHA2-384", vSHA2_384 }, + { "SHA2-512", vSHA2_512 }, + { "SHA2-512-224", vSHA2_512_224 }, + { "SHA2-512-256", vSHA2_512_256 } + } + }; + } + static hashpp::hashCollection getHMACs(const std::vector& keyDataSets) { std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256; @@ -3647,7 +3809,179 @@ namespace hashpp { } } - // function to return a collection of resulting hashes from selected ALGORITHMS and passed files (with recursive directory support) + // function to return a collection of resulting hashes from selected ALGORITHMS and passed file path container(s) (with recursive directory support) + static hashpp::hashCollection getFilesHashes(const FilePathsContainer& filePathSet) { + std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256; + + switch (filePathSet.getAlgorithm()) { + case hashpp::ALGORITHMS::MD5: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vMD5.push_back(hashpp::MD::MD5().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { + vMD5.push_back(hashpp::MD::MD5().getHash(item.path())); + } + } + } + } + break; + } + case hashpp::ALGORITHMS::MD4: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vMD4.push_back(hashpp::MD::MD4().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { + vMD4.push_back(hashpp::MD::MD4().getHash(item.path())); + } + } + } + } + break; + } + case hashpp::ALGORITHMS::MD2: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vMD2.push_back(hashpp::MD::MD2().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { + vMD2.push_back(hashpp::MD::MD2().getHash(item.path())); + } + } + } + } + break; + } + case hashpp::ALGORITHMS::SHA1: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vSHA1.push_back(hashpp::SHA::SHA1().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { + vSHA1.push_back(hashpp::SHA::SHA1().getHash(item.path())); + } + } + } + } + break; + } + case hashpp::ALGORITHMS::SHA2_224: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { + vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(item.path())); + } + } + } + } + break; + } + case hashpp::ALGORITHMS::SHA2_256: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { + vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(item.path())); + } + } + } + } + break; + } + case hashpp::ALGORITHMS::SHA2_384: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { + vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHash(item.path())); + } + } + } + } + break; + } + case hashpp::ALGORITHMS::SHA2_512: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { + vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(item.path())); + } + } + } + } + break; + } + case hashpp::ALGORITHMS::SHA2_512_224: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { + vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(item.path())); + } + } + } + } + break; + } + case hashpp::ALGORITHMS::SHA2_512_256: { + for (const std::string& path : filePathSet.getData()) { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) { + vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(std::filesystem::path(path))); + } + else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) { + if (item.is_regular_file()) { + vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(item.path())); + } + } + } + } + break; + } + } + return hashCollection { + { + { "MD5", vMD5 }, + { "MD4", vMD4 }, + { "MD2", vMD2 }, + { "SHA1", vSHA1 }, + { "SHA2-224", vSHA2_224 }, + { "SHA2-256", vSHA2_256 }, + { "SHA2-384", vSHA2_384 }, + { "SHA2-512", vSHA2_512 }, + { "SHA2-512-224", vSHA2_512_224 }, + { "SHA2-512-256", vSHA2_512_256 } + } + }; + } + + // function to return a collection of resulting hashes from selected ALGORITHMS and passed file path container(s) (with recursive directory support) static hashpp::hashCollection getFilesHashes(const std::vector& filePathSets) { std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256; @@ -3821,6 +4155,7 @@ namespace hashpp { }; } + // function to return a collection of resulting hashes from selected ALGORITHMS and passed file path container(s) (with recursive directory support) static hashpp::hashCollection getFilesHashes(const std::initializer_list& filePathSets) { std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256; From 2815c7a0d1a9c18a92136681ca716a63217993d2 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 13:15:06 -0500 Subject: [PATCH 33/56] Update comments. --- include/hashpp.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/hashpp.h b/include/hashpp.h index 5b3c66c..ffdff08 100644 --- a/include/hashpp.h +++ b/include/hashpp.h @@ -3235,6 +3235,7 @@ namespace hashpp { }; } + // function to return a collection of resulting hashes from passed data container(s) static hashpp::hashCollection getHashes(const std::vector& dataSets) { std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256; @@ -3317,7 +3318,8 @@ namespace hashpp { } }; } - + + // function to return a collection of resulting hashes from passed data container(s) static hashpp::hashCollection getHashes(const std::initializer_list& dataSets) { std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256; @@ -3541,6 +3543,7 @@ namespace hashpp { }; } + // function to return a collection of resulting HMACs from selected ALGORITHMS and passed key-data container(s) static hashpp::hashCollection getHMACs(const std::vector& keyDataSets) { std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256; @@ -3624,6 +3627,7 @@ namespace hashpp { }; } + // function to return a collection of resulting HMACs from selected ALGORITHMS and passed key-data container(s) static hashpp::hashCollection getHMACs(const std::initializer_list& keyDataSets) { std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256; From 289b7e09b7a941f502d8a8452baaecbf58e1791f Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 13:16:18 -0500 Subject: [PATCH 34/56] Update README.md --- documentation/hashing/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/documentation/hashing/README.md b/documentation/hashing/README.md index 9541ee8..67f3648 100644 --- a/documentation/hashing/README.md +++ b/documentation/hashing/README.md @@ -25,6 +25,7 @@ Hash++ offers a simple set of methods to take advantage of the cryptographic-mag ``` static hashpp::hash getHash(hashpp::ALGORITHMS algorithm, const std::string& data); +static hashpp::hashCollection getHashes(const DataContainer& dataSet) static hashpp::hashCollection getHashes(const std::vector& dataSets); static hashpp::hashCollection getHashes(const std::initializer_list& dataSets); template static hashpp::hashCollection getHashes(hashpp::ALGORITHMS algorithm, const _Ts&... data); From ffca4d776939f950dbce37d3477bd3e164cc7ba9 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 13:24:54 -0500 Subject: [PATCH 35/56] Create getHash_usage.cpp --- .../hashing/getHash/getHash_usage.cpp | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 documentation/hashing/getHash/getHash_usage.cpp diff --git a/documentation/hashing/getHash/getHash_usage.cpp b/documentation/hashing/getHash/getHash_usage.cpp new file mode 100644 index 0000000..021e03f --- /dev/null +++ b/documentation/hashing/getHash/getHash_usage.cpp @@ -0,0 +1,26 @@ +/* + + Basic usage of Hash++ getHash method. + This file shows basic usage of the above described method + and its overloads, as well as how data can be extracted + from its returned object. + +*/ + +#include "hashpp.h" + +using namespace hashpp; + +int main() { + // the data we want to hash + std::string data = "dataToHash"; + + // store the resulting hash object of 'data' using SHA-256 + auto hash = get::getHash(ALGORITHMS::SHA2_256, data); + + // print the hash digest + std::cout << hash << std::endl; + + // or we can be more specific... + std::cout << hash.getString() << std::endl; +} From f6eb05e6823ce2d0360587ab4597b6d949905a91 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 13:27:35 -0500 Subject: [PATCH 36/56] Update README.md --- documentation/hashing/README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/documentation/hashing/README.md b/documentation/hashing/README.md index 67f3648..d2b5cb6 100644 --- a/documentation/hashing/README.md +++ b/documentation/hashing/README.md @@ -40,4 +40,8 @@ https://github.com/D7EAD/HashPlusPlus/blob/8bf4d2971f5fab4ad0df75ea6f71a012841c5
As you can see above, when given a properly created Container, the library function getHashes(...) can easily calculate and retrieve the hash digests of the passed data contained in the container(s). The function getHashes(...) itself, though, returns a hashCollection object. This object can be parsed quite easily: -https://github.com/D7EAD/HashPlusPlus/blob/b7fbc10fc627ab21c39a51698882641e1073c78e/documentation/hashing/getHashes/getHashes_usage.cpp#L10-L29 +https://github.com/D7EAD/HashPlusPlus/blob/b7fbc10fc627ab21c39a51698882641e1073c78e/documentation/hashing/getHashes/getHashes_usage.cpp#L14-L29 + +
+Parsing hashCollection objects is great and all when you want to get the hashes of several pieces of data. However, what if you want to get the hash of a single piece of data? To do this, we make use of the library function getHash which returns a hash object. +https://github.com/D7EAD/HashPlusPlus/blob/ffca4d776939f950dbce37d3477bd3e164cc7ba9/documentation/hashing/getHash/getHash_usage.cpp#L14-L26 From 195bc9a2253ba115d931c1f0c2e29683a48613e8 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 16:53:48 -0500 Subject: [PATCH 37/56] Create getFileHash_usage.cpp --- .../file_hashing/getFileHash_usage.cpp | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 documentation/file_hashing/getFileHash_usage.cpp diff --git a/documentation/file_hashing/getFileHash_usage.cpp b/documentation/file_hashing/getFileHash_usage.cpp new file mode 100644 index 0000000..664204e --- /dev/null +++ b/documentation/file_hashing/getFileHash_usage.cpp @@ -0,0 +1,29 @@ +/* + + Basic usage of Hash++ getFileHash method. + This file shows basic usage of the above described method + and its overloads, as well as how data can be extracted + from its returned object. + +*/ + +#include "hashpp.h" + +using namespace hashpp; + +int main() { + // path to file we want to hash (test.txt) + std::string pathToFile = "N:/source/test.txt"; + + // store the resulting hash object of the file using SHA-256 + auto hash = get::getFileHash(ALGORITHMS::SHA2_256, pathToFile); + + // print the hash digest + std::cout << hash << std::endl; + + // or we can be more specific... + std::cout << hash.getString() << std::endl; + + // output: + // 4de0d727216e14760010efdb0cccf577853d7da4e122a507b422148940f4aa34 +} From ba418167da59826cda2a18990a90cf332d75308e Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 16:54:03 -0500 Subject: [PATCH 38/56] Rename documentation/file_hashing/getFileHash_usage.cpp to documentation/file_hashing/getFileHash/getFileHash_usage.cpp --- .../file_hashing/{ => getFileHash}/getFileHash_usage.cpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename documentation/file_hashing/{ => getFileHash}/getFileHash_usage.cpp (100%) diff --git a/documentation/file_hashing/getFileHash_usage.cpp b/documentation/file_hashing/getFileHash/getFileHash_usage.cpp similarity index 100% rename from documentation/file_hashing/getFileHash_usage.cpp rename to documentation/file_hashing/getFileHash/getFileHash_usage.cpp From 8c59ed7fed7dec9fc9eded36912b16228a95df67 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 16:59:58 -0500 Subject: [PATCH 39/56] Add files via upload --- documentation/file_hashing/getFilesHashes/test.txt | 1 + documentation/file_hashing/getFilesHashes/test2.txt | 1 + documentation/file_hashing/getFilesHashes/test3.txt | 1 + 3 files changed, 3 insertions(+) create mode 100644 documentation/file_hashing/getFilesHashes/test.txt create mode 100644 documentation/file_hashing/getFilesHashes/test2.txt create mode 100644 documentation/file_hashing/getFilesHashes/test3.txt diff --git a/documentation/file_hashing/getFilesHashes/test.txt b/documentation/file_hashing/getFilesHashes/test.txt new file mode 100644 index 0000000..0efa7e5 --- /dev/null +++ b/documentation/file_hashing/getFilesHashes/test.txt @@ -0,0 +1 @@ +A hash a day keeps the doctor away. \ No newline at end of file diff --git a/documentation/file_hashing/getFilesHashes/test2.txt b/documentation/file_hashing/getFilesHashes/test2.txt new file mode 100644 index 0000000..4f77000 --- /dev/null +++ b/documentation/file_hashing/getFilesHashes/test2.txt @@ -0,0 +1 @@ +Too many hashes may lead to gastrointestinal issues. \ No newline at end of file diff --git a/documentation/file_hashing/getFilesHashes/test3.txt b/documentation/file_hashing/getFilesHashes/test3.txt new file mode 100644 index 0000000..afb6ee7 --- /dev/null +++ b/documentation/file_hashing/getFilesHashes/test3.txt @@ -0,0 +1 @@ +Passwords should not be stored in plaintext. \ No newline at end of file From 28e0fdbc071ca36bd5385b8ab4e5aa1601dec8ec Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 17:00:16 -0500 Subject: [PATCH 40/56] Add files via upload --- documentation/file_hashing/getFileHash/test.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 documentation/file_hashing/getFileHash/test.txt diff --git a/documentation/file_hashing/getFileHash/test.txt b/documentation/file_hashing/getFileHash/test.txt new file mode 100644 index 0000000..0efa7e5 --- /dev/null +++ b/documentation/file_hashing/getFileHash/test.txt @@ -0,0 +1 @@ +A hash a day keeps the doctor away. \ No newline at end of file From c007af7d81bdf054a389314ad1d7bbb6d0757262 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 17:03:55 -0500 Subject: [PATCH 41/56] Create getFilesHashes_usage.cpp --- .../getFilesHashes/getFilesHashes_usage.cpp | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 documentation/file_hashing/getFilesHashes/getFilesHashes_usage.cpp diff --git a/documentation/file_hashing/getFilesHashes/getFilesHashes_usage.cpp b/documentation/file_hashing/getFilesHashes/getFilesHashes_usage.cpp new file mode 100644 index 0000000..b38992a --- /dev/null +++ b/documentation/file_hashing/getFilesHashes/getFilesHashes_usage.cpp @@ -0,0 +1,35 @@ +/* + + Basic usage of Hash++ getFileHashes method. + This file shows basic usage of the above described method + and its overloads, as well as how data can be extracted + from its returned object. + +*/ + +#include "hashpp.h" + +using namespace hashpp; + +int main() { + // create a FilePathsContainer object + FilePathsContainer path_cont1; + + // set its algorithm and some paths + path_cont1.setAlgorithm(ALGORITHMS::SHA2_256); + path_cont1.setData("N:/source/test.txt", "N:/source/test2.txt", "N:/source/test3.txt"); + + // get the hashes of each file via get::getFilesHashes + // and store them in a hashCollection object + hashCollection hashes = get::getFilesHashes(path_cont1); + + // parse and print the hashes + for (auto& hash : hashes["SHA2-256"]) { + std::cout << hash << std::endl; + } + + // output: + // 4de0d727216e14760010efdb0cccf577853d7da4e122a507b422148940f4aa34 + // 7c88d6bc28e9bd6660b96cfa3b69cdbaaaf0187047267106842841357ac03bd8 + // 44d25e664ce6d6e82beb7a14fe312d7c09c5dc107668a6d40449bc24938e5c73 +} From 12cbcabb4b93662531ac609fca88b275838ea4bc Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 17:05:34 -0500 Subject: [PATCH 42/56] Update README.md --- documentation/file_hashing/README.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/documentation/file_hashing/README.md b/documentation/file_hashing/README.md index 5fd4350..a58a039 100644 --- a/documentation/file_hashing/README.md +++ b/documentation/file_hashing/README.md @@ -1 +1,17 @@ -Add file hashing documentation + examples here. +

Using Hash++ to Generate File Hashes

+Much like how hashes can be generated using generic data, Hash++ provides functions for developers to find hashes for files. The signatures for the methods can be found below. + +``` +static hashpp::hash getFileHash(hashpp::ALGORITHMS algorithm, const std::string& path); +static hashpp::hashCollection getFilesHashes(const FilePathsContainer& filePathSet); +static hashpp::hashCollection getFilesHashes(const std::vector& filePathSets); +static hashpp::hashCollection getFilesHashes(const std::initializer_list& filePathSets); +``` + +
+Some file hashing functions, much like some other components of the library, make use of their own Container alias FilePathsContainer (if you have not read about the Container class used by Hash++, please see the documentation for Hashing). You can find an example of a single file being hashed below. +https://github.com/D7EAD/HashPlusPlus/blob/ba418167da59826cda2a18990a90cf332d75308e/documentation/file_hashing/getFileHash/getFileHash_usage.cpp#L10-L29 + +
+If you're in the business of hashing multiple files at once, you can find an example of such a use below. +https://github.com/D7EAD/HashPlusPlus/blob/c007af7d81bdf054a389314ad1d7bbb6d0757262/documentation/file_hashing/getFilesHashes/getFilesHashes_usage.cpp#L14-L35 From 6d9142026c7527a032fc043f8ea205730700c6b7 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 17:39:18 -0500 Subject: [PATCH 43/56] Update README.md --- documentation/HMACs/README.md | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/documentation/HMACs/README.md b/documentation/HMACs/README.md index c54bdc4..b49ad18 100644 --- a/documentation/HMACs/README.md +++ b/documentation/HMACs/README.md @@ -1 +1,31 @@ -Add HMAC documentation + examples here. +

Keyed-Hash Message Authentication Codes (HMACs)

+

While they may sound considerably more complicated, HMACs aren't too different from cryptographic hashes at the end of the day. HMACs are keyed hashes of data meaning, simply, that an HMAC is used to generate a unique hash digest of data when that data is paired with another specific piece of data--a key.

+ +

Take, for instance, the simple example hash function of H(x) = y where H is our hash function, x is our input data, and y is our output hash digest. The output digest depends on two things:

+ +- The hash function in use. +- The input supplied to said function. + +

Now, take, for instance, the following naive keyed hash algorithm *H(x + k) = y where H is our hash function, x is our input data, k is our key data, and y is our output hash digest. The output digest now depends on three things:

+ +- The hash function in use. +- The input supplied to said function. +- The key data. + +

Hash functions provide collision-resistance whereas an HMAC provides both collision-resistance and unforgeability. Due to this provided element of unforgeability, HMACs are used in combination with hash algorithms to prove not only that data is unmodified, but that whoeever calculated the hash for said data did so with the correct key--otherwise the incorrect HMAC would result.

+ +

Simply put, a hash allows for verification of the authenticity of data whereas an HMAC allows for verification of both the authenticity of data and the originator of said data.

+ +

*Keep in mind that HMACs do not simply operate as a hash function H applied on the key k appended to data x. How HMACs are calculated is a bit more nuanced. You can read more about the RFC specification here.

+ +
+

Using Hash++

+Hash++ offers a simple set of methods to generate one or multiple HMACs given data and an associated key. You can find the signatures for the functions below. + +``` +static hashpp::hashCollection getHMACs(const HMAC_DataContainer& keyDataSet); +static hashpp::hashCollection getHMACs(const std::vector& keyDataSets); +static hashpp::hashCollection getHMACs(const std::initializer_list& keyDataSets) +static hashpp::hashCollection getHashes(const std::initializer_list& dataSets); +template static hashpp::hashCollection getHMACs(hashpp::ALGORITHMS algorithm, const std::string& key, const _Ts&... data); +``` From 2596ee6f069f71289d59f439260215e7e5b0e3cd Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 17:40:58 -0500 Subject: [PATCH 44/56] Update README.md --- documentation/HMACs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/HMACs/README.md b/documentation/HMACs/README.md index b49ad18..ac5f105 100644 --- a/documentation/HMACs/README.md +++ b/documentation/HMACs/README.md @@ -12,7 +12,7 @@ - The input supplied to said function. - The key data. -

Hash functions provide collision-resistance whereas an HMAC provides both collision-resistance and unforgeability. Due to this provided element of unforgeability, HMACs are used in combination with hash algorithms to prove not only that data is unmodified, but that whoeever calculated the hash for said data did so with the correct key--otherwise the incorrect HMAC would result.

+

Hash functions provide collision-resistance whereas an HMAC provides both collision-resistance and unforgeability. Due to this provided element of unforgeability, HMACs are used in combination with hash algorithms to prove not only that data is unmodified, but that whoever calculated the hash for said data did so with the correct key--otherwise the incorrect HMAC would result.

Simply put, a hash allows for verification of the authenticity of data whereas an HMAC allows for verification of both the authenticity of data and the originator of said data.

From e123335dd7616a7169acd913df87257deaae1f74 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 17:43:37 -0500 Subject: [PATCH 45/56] Update README.md --- documentation/HMACs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/HMACs/README.md b/documentation/HMACs/README.md index ac5f105..798238c 100644 --- a/documentation/HMACs/README.md +++ b/documentation/HMACs/README.md @@ -16,7 +16,7 @@

Simply put, a hash allows for verification of the authenticity of data whereas an HMAC allows for verification of both the authenticity of data and the originator of said data.

-

*Keep in mind that HMACs do not simply operate as a hash function H applied on the key k appended to data x. How HMACs are calculated is a bit more nuanced. You can read more about the RFC specification here.

+

*Keep in mind that HMACs do not simply operate as a hash function H applied on a key k appended to data x. Hash algorithms are not HMACs and vice-versa--the HMAC mechanism works atop existing hash algorithms. How HMACs are calculated is a bit more nuanced. You can read more about the RFC specification here.


Using Hash++

From f4da991ebaa37dacb07569de1e33df6bcb4310d5 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 17:44:32 -0500 Subject: [PATCH 46/56] Update README.md --- documentation/HMACs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/HMACs/README.md b/documentation/HMACs/README.md index 798238c..06e1b1c 100644 --- a/documentation/HMACs/README.md +++ b/documentation/HMACs/README.md @@ -16,7 +16,7 @@

Simply put, a hash allows for verification of the authenticity of data whereas an HMAC allows for verification of both the authenticity of data and the originator of said data.

-

*Keep in mind that HMACs do not simply operate as a hash function H applied on a key k appended to data x. Hash algorithms are not HMACs and vice-versa--the HMAC mechanism works atop existing hash algorithms. How HMACs are calculated is a bit more nuanced. You can read more about the RFC specification here.

+

*Keep in mind that HMACs do not simply operate as a hash function H applied on a key k appended to data x. How HMACs are calculated is a bit more nuanced. Hash algorithms are not HMACs and vice-versa--the HMAC mechanism works atop existing hash algorithms. You can read more about the RFC specification here.


Using Hash++

From 079213166f4b3db2f67dfdf605c7d53b39b304ec Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 17:48:24 -0500 Subject: [PATCH 47/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 06a58b1..b66e95c 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ No, it doesn't. |------------------|---------------------------------------------| | 64-bit test: | | | | | [MD5] | 7846 ms | 7.846 s | 1,274,535 hashes/s | -| [MD4] | 7846 ms | 7.846 s | 1,274,535 hashes/s | +| [MD4] | 5783 ms | 5.783 s | 1,729,206 hashes/s | | [MD2] | 181315 ms | 181.315 s | 55,153 hashes/s | | [SHA1] | 8676 ms | 8.676 s | 1,152,605 hashes/s | | [SHA2-224] | 12370 ms | 12.370 s | 808,407 hashes/s | From 2410a221e5d72af74b392e41af2c4f07eb428b1f Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 17:50:18 -0500 Subject: [PATCH 48/56] Update README.md --- documentation/HMACs/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/documentation/HMACs/README.md b/documentation/HMACs/README.md index 06e1b1c..48abc05 100644 --- a/documentation/HMACs/README.md +++ b/documentation/HMACs/README.md @@ -25,7 +25,6 @@ Hash++ offers a simple set of methods to generate one or multiple HMACs given da ``` static hashpp::hashCollection getHMACs(const HMAC_DataContainer& keyDataSet); static hashpp::hashCollection getHMACs(const std::vector& keyDataSets); -static hashpp::hashCollection getHMACs(const std::initializer_list& keyDataSets) -static hashpp::hashCollection getHashes(const std::initializer_list& dataSets); +static hashpp::hashCollection getHMACs(const std::initializer_list& keyDataSets); template static hashpp::hashCollection getHMACs(hashpp::ALGORITHMS algorithm, const std::string& key, const _Ts&... data); ``` From aa6a45053860a4e7872bc58b4152d46cfca88d75 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 17:50:56 -0500 Subject: [PATCH 49/56] Update README.md --- documentation/HMACs/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/documentation/HMACs/README.md b/documentation/HMACs/README.md index 48abc05..79a5d8e 100644 --- a/documentation/HMACs/README.md +++ b/documentation/HMACs/README.md @@ -23,6 +23,7 @@ Hash++ offers a simple set of methods to generate one or multiple HMACs given data and an associated key. You can find the signatures for the functions below. ``` +static hashpp::hash getHMAC(hashpp::ALGORITHMS algorithm, const std::string& key, const std::string& data; static hashpp::hashCollection getHMACs(const HMAC_DataContainer& keyDataSet); static hashpp::hashCollection getHMACs(const std::vector& keyDataSets); static hashpp::hashCollection getHMACs(const std::initializer_list& keyDataSets); From 0ac434933e4d54b584b810d863a9f1a4a4f5f7b4 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 17:55:16 -0500 Subject: [PATCH 50/56] Create getHMAC_usage.cpp --- documentation/HMACs/getHMAC/getHMAC_usage.cpp | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 documentation/HMACs/getHMAC/getHMAC_usage.cpp diff --git a/documentation/HMACs/getHMAC/getHMAC_usage.cpp b/documentation/HMACs/getHMAC/getHMAC_usage.cpp new file mode 100644 index 0000000..5e9d7e5 --- /dev/null +++ b/documentation/HMACs/getHMAC/getHMAC_usage.cpp @@ -0,0 +1,29 @@ +/* + + Basic usage of Hash++ getHMAC method. + This file shows basic usage of the above described method + and its overloads, as well as how data can be extracted + from its returned object. + +*/ + +#include "hashpp.h" + +using namespace hashpp; + +int main() { + // data we want to get HMAC of + std::string dataToHash = "Hello World!"; + + // key to use for HMAC + std::string key = "secret"; + + // get HMAC of dataToHash using SHA-256 + auto hmac = get::getHMAC(ALGORITHMS::SHA2_256, key, dataToHash); + + // print out the hash + std::cout << "HMAC: " << hmac << std::endl; + + // output: + // 6fa7b4dea28ee348df10f9bb595ad985ff150a4adfd6131cca677d9acee07dc6 +} From fc5edb76cd829794a3fb34c416df7431653044e0 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 18:02:24 -0500 Subject: [PATCH 51/56] Create getHMACs_usage.cpp --- .../HMACs/getHMACs/getHMACs_usage.cpp | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 documentation/HMACs/getHMACs/getHMACs_usage.cpp diff --git a/documentation/HMACs/getHMACs/getHMACs_usage.cpp b/documentation/HMACs/getHMACs/getHMACs_usage.cpp new file mode 100644 index 0000000..e556253 --- /dev/null +++ b/documentation/HMACs/getHMACs/getHMACs_usage.cpp @@ -0,0 +1,42 @@ +/* + + Basic usage of Hash++ getHMACs method. + This file shows basic usage of the above described method + and its overloads, as well as how data can be extracted + from its returned object. + +*/ + +#include "hashpp.h" + +using namespace hashpp; + +int main() { + // create HMAC_DataContainer object + // to store algorithm to use, key, + // and data to HMAC + HMAC_DataContainer hmac_container; + + // set algorithm to use + hmac_container.setAlgorithm(ALGORITHMS::SHA2_256); + + // set key to use + hmac_container.setKey("secretKey"); + + // set data to HMAC + hmac_container.setData("dataToHMAC1", "dataToHMAC2", "dataToHMAC3"); + + // calculate the HMACs for all data in container + // using key and algorithm specified + hashCollection hmacs = get::getHMACs(hmac_container); + + // parse and print each HMAC + for (auto& hmac : hmacs["SHA2-256"]) { + std::cout << hmac << std::endl; + } + + // output: + // f0dfad2b51176704f8fff07e2c6063417b1d361465b4f9eaacf9b756037bb815 + // bf912338f4c9d21eff351d085a26b9723eb0da6582039d18a003046c3ae3fbef + // abba2bd3400c1b03322fac45539462241ca6ae14a81d58e1db017a9bcb3947b2 +} From 245e1e8462f12b038f2215f486215e3181fc3a5f Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 18:03:10 -0500 Subject: [PATCH 52/56] Update README.md --- documentation/HMACs/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/documentation/HMACs/README.md b/documentation/HMACs/README.md index 79a5d8e..7d116eb 100644 --- a/documentation/HMACs/README.md +++ b/documentation/HMACs/README.md @@ -29,3 +29,11 @@ static hashpp::hashCollection getHMACs(const std::vector& ke static hashpp::hashCollection getHMACs(const std::initializer_list& keyDataSets); template static hashpp::hashCollection getHMACs(hashpp::ALGORITHMS algorithm, const std::string& key, const _Ts&... data); ``` + +
+You can easily generate an HMAC for a single piece of data using Hash++. See below for an example. +https://github.com/D7EAD/HashPlusPlus/blob/0ac434933e4d54b584b810d863a9f1a4a4f5f7b4/documentation/HMACs/getHMAC/getHMAC_usage.cpp#L10-L29 + +
+In order to generate several HMACs for several pieces of data, we can use a Container alias HMAC_DataContainer (if you have not read about the Container class used by Hash++, please see the documentation for Hashing). See below for an example. +https://github.com/D7EAD/HashPlusPlus/blob/fc5edb76cd829794a3fb34c416df7431653044e0/documentation/HMACs/getHMACs/getHMACs_usage.cpp#L14-L42 From 6dd1468eaad0a7ea184b349b5901402cd61b63dd Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 18:04:25 -0500 Subject: [PATCH 53/56] Update README.md --- documentation/HMACs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/HMACs/README.md b/documentation/HMACs/README.md index 7d116eb..2fadd44 100644 --- a/documentation/HMACs/README.md +++ b/documentation/HMACs/README.md @@ -35,5 +35,5 @@ You can easily generate an HMAC for a single piece of data using Hash++. See bel https://github.com/D7EAD/HashPlusPlus/blob/0ac434933e4d54b584b810d863a9f1a4a4f5f7b4/documentation/HMACs/getHMAC/getHMAC_usage.cpp#L10-L29
-In order to generate several HMACs for several pieces of data, we can use a Container alias HMAC_DataContainer (if you have not read about the Container class used by Hash++, please see the documentation for Hashing). See below for an example. +In order to generate several HMACs for several pieces of data, we can use a Container alias HMAC_DataContainer (if you have not read about the Container class used by Hash++, please see the documentation for Hashing). See below for an example. https://github.com/D7EAD/HashPlusPlus/blob/fc5edb76cd829794a3fb34c416df7431653044e0/documentation/HMACs/getHMACs/getHMACs_usage.cpp#L14-L42 From b1e3dd37de40ff1e3168cba45ef5bb17707ab29f Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 18:15:13 -0500 Subject: [PATCH 54/56] Update hashpp.h --- include/hashpp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/hashpp.h b/include/hashpp.h index ffdff08..cfbc9e4 100644 --- a/include/hashpp.h +++ b/include/hashpp.h @@ -3045,7 +3045,7 @@ namespace hashpp { // Holds arbitrary data; how this data is defined is determined // by the functions that the container containing said data is passed to. - // (e.g., a call to getFilesHashes with a container will treat all data + // (e.g., a call to getFilesHashes with a container will treat all data // in it as paths to files to be hashed, and a call to getHashes with // a container will treat all data as generic data to be hashed) std::vector data; From ec363e2e0a68fbd28ea134ffb45d5ad939145883 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 18:16:26 -0500 Subject: [PATCH 55/56] Update README.md --- documentation/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/README.md b/documentation/README.md index cc13ec7..96f2ef9 100644 --- a/documentation/README.md +++ b/documentation/README.md @@ -1,5 +1,5 @@

Documentation

-Hash++ is a modern C++17 header-only library that provides developers simple means of retrieving cryptographic hashes and hashed message authentication codes (HMACs) from the algorithm(s) of their choice. The library was developed with the goal of appealing to one particular type of developer--one who does not want to use larger, heavier, or more confusing libraries with unnecessary features to simply hash data. +Hash++ is a modern C++17 header-only library that provides developers simple means of retrieving cryptographic hashes and keyed-hashed message authentication codes (HMACs) from the algorithm(s) of their choice. The library was developed with the goal of appealing to one particular type of developer--one who does not want to use larger, heavier, or more confusing libraries with unnecessary features to simply hash data.

In the directories listed below, you can find explanations of concepts found within the implementations of the library and example usage of features found within Hash++. From c3b4525001bedf34730af2fff3ea9d42a9309bc1 Mon Sep 17 00:00:00 2001 From: Dread <42398281+D7EAD@users.noreply.github.com> Date: Thu, 8 Dec 2022 18:17:12 -0500 Subject: [PATCH 56/56] Update README.md --- documentation/file_hashing/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/file_hashing/README.md b/documentation/file_hashing/README.md index a58a039..de52f51 100644 --- a/documentation/file_hashing/README.md +++ b/documentation/file_hashing/README.md @@ -1,5 +1,5 @@

Using Hash++ to Generate File Hashes

-Much like how hashes can be generated using generic data, Hash++ provides functions for developers to find hashes for files. The signatures for the methods can be found below. +Much like how hashes can be generated using generic data, Hash++ provides functions for developers to find hashes for files and files in nested directories. The signatures for the methods can be found below. ``` static hashpp::hash getFileHash(hashpp::ALGORITHMS algorithm, const std::string& path);