├── LICENSE ├── README.md ├── benchmarks ├── amd │ └── 5900HX │ │ └── README.md └── intel │ ├── 12400 │ └── README.md │ ├── 10300H │ └── README.md │ └── 12900K │ └── README.md ├── documentation ├── HMACs │ ├── README.md │ ├── getHMAC │ │ └── getHMAC_usage.cpp │ └── getHMACs │ │ └── getHMACs_usage.cpp ├── README.md ├── file_hashing │ ├── README.md │ ├── getFileHash │ │ ├── getFileHash_usage.cpp │ │ └── test.txt │ └── getFilesHashes │ │ ├── getFilesHashes_usage.cpp │ │ ├── test.txt │ │ ├── test2.txt │ │ └── test3.txt └── hashing │ ├── README.md │ ├── container │ ├── container.cpp │ └── container_use.cpp │ ├── getHash │ └── getHash_usage.cpp │ └── getHashes │ └── getHashes_usage.cpp ├── images └── hpp.png └── include └── hashpp.h /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Dread 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 |
5 |

Purpose

6 | 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. 7 |
8 |

Supported Algorithms

9 | 10 | | Algorithm | HMAC Support? | 11 | | :-------------: | :-----------------: | 12 | | MD5 | :heavy_check_mark: | 13 | | MD4 | :heavy_check_mark: | 14 | | MD2 | :heavy_check_mark: | 15 | | SHA1 | :heavy_check_mark: | 16 | | SHA2-224 | :heavy_check_mark: | 17 | | SHA2-256 | :heavy_check_mark: | 18 | | SHA2-384 | :heavy_check_mark: | 19 | | SHA2-512 | :heavy_check_mark: | 20 | | SHA2-512/224 | :heavy_check_mark: | 21 | | SHA2-512/256 | :heavy_check_mark: | 22 | | SHA-3 | In Progress | 23 | 24 | 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? 25 | 26 | No, it doesn't. 27 |
28 | 29 |

Quick Example

30 | Below you can find a minimal example of how to calculate the SHA2-256 hash of the data Hello World! using Hash++. 31 |

32 | 33 | ```cpp 34 | #include "hashpp.h" 35 | 36 | using namespace hashpp; 37 | 38 | int main() { 39 | std::cout << get::getHash(ALGORITHMS::SHA2_256, "Hello World!") << std::endl; 40 | 41 | // output: 42 | // 7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069 43 | } 44 | ``` 45 | 46 | You can find further detailed documentation in the /documentation directory. 47 | 48 |

Algorithm Metrics

49 | Below you can view benchmarks of Hash++ computing 10 million hashes for each algorithm. Each benchmark is based on the hashing of four concatenations of the lower and uppercase alphabet, plus base ten digits. 50 | 51 | - Intel Benchmarks 52 | - Ryzen 9 5900HX Benchmark 53 | -------------------------------------------------------------------------------- /benchmarks/amd/5900HX/README.md: -------------------------------------------------------------------------------- 1 |

Benchmark: AMD Ryzen 9 5900HX

2 | Below you can find the benchmarks for a stock Ryzen 9 5900HX computing 10 million hashes using Hash++. Each hash is the result of four concatenations of the lower and uppercase alphabet plus base ten digits. 3 |

4 | 5 |
 6 | +----------------------------------------------------------------+
 7 | |    Algorithms    |            Computational Metrics            |
 8 | |------------------|---------------------------------------------|
 9 | | 64-bit test:     |           |           |                     |
10 | |   [MD5]          | 10140  ms | 10.140  s | 986,193    hashes/s |
11 | |   [MD4]          | 8922   ms | 8.922   s | 1,120,825  hashes/s |
12 | |   [MD2]          | 253154 ms | 253.154 s | 39,502     hashes/s | 
13 | |   [SHA1]         | 12641  ms | 12.641  s | 791,077    hashes/s |
14 | |   [SHA2-224]     | 16908  ms | 16.908  s | 591,436    hashes/s |
15 | |   [SHA2-256]     | 17143  ms | 17.143  s | 583,328    hashes/s |
16 | |   [SHA2-384]     | 12931  ms | 12.931  s | 773,335    hashes/s |
17 | |   [SHA2-512]     | 14814  ms | 14.814  s | 675,037    hashes/s |
18 | |   [SHA2-512/224] | 11806  ms | 11.806  s | 847,027    hashes/s |
19 | |   [SHA2-512/256] | 11829  ms | 11.829  s | 845,380    hashes/s |
20 | |------------------|-----------|-----------|---------------------|
21 | | 32-bit test:     |           |           |                     |
22 | |   [MD5]          | 15288  ms | 15.288  s | 654,108    hashes/s |
23 | |   [MD4]          | 11704  ms | 11.704  s | 854,409    hashes/s |
24 | |   [MD2]          | 319056 ms | 319.056 s | 31,342     hashes/s |
25 | |   [SHA1]         | 18317  ms | 18.317  s | 545,941    hashes/s |
26 | |   [SHA2-224]     | 23672  ms | 23.672  s | 422,440    hashes/s |
27 | |   [SHA2-256]     | 23643  ms | 23.643  s | 422,958    hashes/s |
28 | |   [SHA2-384]     | 46221  ms | 46.221  s | 216,352    hashes/s |
29 | |   [SHA2-512]     | 47700  ms | 47.700  s | 209,644    hashes/s |
30 | |   [SHA2-512/224] | 44673  ms | 44.673  s | 223,849    hashes/s |
31 | |   [SHA2-512/256] | 45009  ms | 45.009  s | 222,178    hashes/s |
32 | +----------------------------------------------------------------+
33 | *Updated as of 12/09/2022
34 | 
35 | 36 | **Below you can find single-threaded speed metrics of each algorithm when calculating a hash for a 3GB binary file. 37 | 38 |
39 | +------------------------------------------+
40 | |    Algorithms    | Computational Metrics |          
41 | |------------------|-----------------------|
42 | | 64-bit test:     |           |           |
43 | |   [MD5]          | 27547  ms | 27.547  s |
44 | |   [MD4]          | 18792  ms | 18.792  s |
45 | |  *[MD2]          | N/A    ms | N/A     s | 
46 | |   [SHA1]         | 29517  ms | 29.517  s |
47 | |   [SHA2-224]     | 38259  ms | 38.259  s |
48 | |   [SHA2-256]     | 39529  ms | 39.529  s |
49 | |   [SHA2-384]     | 19100  ms | 19.100  s |
50 | |   [SHA2-512]     | 18950  ms | 18.950  s |
51 | |   [SHA2-512/224] | 18914  ms | 18.914  s |
52 | |   [SHA2-512/256] | 19101  ms | 19.101  s |
53 | |------------------|-----------|-----------|
54 | | 32-bit test:     |           |           |
55 | |   [MD5]          | 27889  ms | 27.889  s |
56 | |   [MD4]          | 17807  ms | 17.807  s |
57 | |  *[MD2]          | N/A    ms | N/A     s | 
58 | |   [SHA1]         | 37695  ms | 37.695  s |
59 | |   [SHA2-224]     | 49349  ms | 49.349  s |
60 | |   [SHA2-256]     | 48687  ms | 48.687  s |
61 | |   [SHA2-384]     | 85244  ms | 85.244  s |
62 | |   [SHA2-512]     | 84989  ms | 84.989  s |
63 | |   [SHA2-512/224] | 84926  ms | 84.926  s |
64 | |   [SHA2-512/256] | 84966  ms | 84.966  s |
65 | +------------------------------------------+
66 | *Excluded due to impractically long computational times.
67 | **Updated as of 12/09/2022
68 | 
69 | -------------------------------------------------------------------------------- /benchmarks/intel/10300H/README.md: -------------------------------------------------------------------------------- 1 |

Benchmark: Intel i5 10300H

2 | Below you can find the benchmarks for a stock i5 10300H computing 10 million hashes using Hash++. Each hash is the result of four concatenations of the lower and uppercase alphabet plus base ten digits. 3 |

4 | 5 |
 6 | +----------------------------------------------------------------+
 7 | |    Algorithms    |            Computational Metrics            |
 8 | |------------------|---------------------------------------------|
 9 | | 64-bit test:     |           |           |                     |
10 | |   [MD5]          | 14269  ms | 14.269  s | 700,820    hashes/s |
11 | |   [MD4]          | 10490  ms | 10.490  s | 953,289    hashes/s |
12 | |   [MD2]          | 231283 ms | 231.283 s | 43,237     hashes/s | 
13 | |   [SHA1]         | 17990  ms | 17.990  s | 555,864    hashes/s |
14 | |   [SHA2-224]     | 23757  ms | 23.757  s | 420,929    hashes/s |
15 | |   [SHA2-256]     | 24231  ms | 24.231  s | 412,694    hashes/s |
16 | |   [SHA2-384]     | 17918  ms | 17.918  s | 515,756    hashes/s |
17 | |   [SHA2-512]     | 19389  ms | 19.389  s | 716,743    hashes/s |
18 | |   [SHA2-512/224] | 16915  ms | 16.915  s | 591,191    hashes/s |
19 | |   [SHA2-512/256] | 16622  ms | 16.622  s | 601,612    hashes/s |
20 | |------------------|-----------|-----------|---------------------|
21 | | 32-bit test:     |           |           |                     |
22 | |   [MD5]          | 26660  ms | 26.660  s | 375,094    hashes/s |
23 | |   [MD4]          | 19281  ms | 19.281  s | 518,645    hashes/s |
24 | |   [MD2]          | 318013 ms | 318.013 s | 31,445     hashes/s |
25 | |   [SHA1]         | 21684  ms | 21.684  s | 461,169    hashes/s |
26 | |   [SHA2-224]     | 31088  ms | 31.088  s | 321,668    hashes/s |
27 | |   [SHA2-256]     | 31870  ms | 31.870  s | 313,775    hashes/s |
28 | |   [SHA2-384]     | 54682  ms | 54.682  s | 182,876    hashes/s |
29 | |   [SHA2-512]     | 51913  ms | 51.913  s | 192,630    hashes/s |
30 | |   [SHA2-512/224] | 47457  ms | 47.457  s | 210,717    hashes/s |
31 | |   [SHA2-512/256] | 47545  ms | 47.545  s | 210,327    hashes/s |
32 | +----------------------------------------------------------------+
33 | *Updated as of 12/11/2022
34 | 
Benchmark: Intel i5 12400 2 | Below you can find the benchmarks for a stock i5 12400 computing 10 million hashes using Hash++. Each hash is the result of four concatenations of the lower and uppercase alphabet plus base ten digits. 3 |

4 | 5 |
 6 | +----------------------------------------------------------------+
 7 | |    Algorithms    |            Computational Metrics            |
 8 | |------------------|---------------------------------------------|
 9 | | 64-bit test:     |           |           |                     |
10 | |   [MD5]          | 10490  ms | 10.490  s | 953,289    hashes/s |
11 | |   [MD4]          | 8745   ms | 8.745   s | 1,143,511  hashes/s |
12 | |   [MD2]          | 240131 ms | 240.131 s | 41,644     hashes/s | 
13 | |   [SHA1]         | 12181  ms | 12.181  s | 820,951    hashes/s |
14 | |   [SHA2-224]     | 20734  ms | 20.734  s | 482,300    hashes/s |
15 | |   [SHA2-256]     | 17749  ms | 17.749  s | 563,412    hashes/s |
16 | |   [SHA2-384]     | 13294  ms | 13.294  s | 752,219    hashes/s |
17 | |   [SHA2-512]     | 13952  ms | 13.952  s | 716,743    hashes/s |
18 | |   [SHA2-512/224] | 11874  ms | 11.874  s | 842,176    hashes/s |
19 | |   [SHA2-512/256] | 11945  ms | 11.945  s | 837,170    hashes/s |
20 | |------------------|-----------|-----------|---------------------|
21 | | 32-bit test:     |           |           |                     |
22 | |   [MD5]          | 13730  ms | 13.730  s | 728,332    hashes/s |
23 | |   [MD4]          | 9918   ms | 9.918   s | 1,008,268  hashes/s |
24 | |   [MD2]          | 312529 ms | 312.529 s | 31,997     hashes/s |
25 | |   [SHA1]         | 14600  ms | 14.600  s | 684,932    hashes/s |
26 | |   [SHA2-224]     | 22767  ms | 22.767  s | 439,232    hashes/s |
27 | |   [SHA2-256]     | 21531  ms | 21.531  s | 464,447    hashes/s |
28 | |   [SHA2-384]     | 35484  ms | 35.484  s | 281,817    hashes/s |
29 | |   [SHA2-512]     | 35863  ms | 35.863  s | 278,839    hashes/s |
30 | |   [SHA2-512/224] | 32160  ms | 32.160  s | 310,945    hashes/s |
31 | |   [SHA2-512/256] | 32286  ms | 32.286  s | 309,732    hashes/s |
32 | +----------------------------------------------------------------+
33 | *Updated as of 12/10/2022
34 | 
Benchmark: Intel i9 12900K 2 | Below you can find the benchmarks for a stock i9 12900K computing 10 million hashes using Hash++. Each hash is the result of four concatenations of the lower and uppercase alphabet plus base ten digits. 3 |

4 | 5 |
 6 | +----------------------------------------------------------------+
 7 | |    Algorithms    |            Computational Metrics            |
 8 | |------------------|---------------------------------------------|
 9 | | 64-bit test:     |           |           |                     |
10 | |   [MD5]          | 7846   ms | 7.846   s | 1,274,535  hashes/s |
11 | |   [MD4]          | 5783   ms | 5.783   s | 1,729,206  hashes/s |
12 | |   [MD2]          | 181315 ms | 181.315 s | 55,153     hashes/s | 
13 | |   [SHA1]         | 8676   ms | 8.676   s | 1,152,605  hashes/s |
14 | |   [SHA2-224]     | 12370  ms | 12.370  s | 808,407    hashes/s |
15 | |   [SHA2-256]     | 12943  ms | 12.943  s | 772,618    hashes/s |
16 | |   [SHA2-384]     | 9303   ms | 9.303   s | 1,074,922  hashes/s |
17 | |   [SHA2-512]     | 10096  ms | 10.096  s | 990,491    hashes/s |
18 | |   [SHA2-512/224] | 8439   ms | 8.439   s | 1,184,975  hashes/s |
19 | |   [SHA2-512/256] | 8601   ms | 8.601   s | 1,162,656  hashes/s |
20 | |------------------|-----------|-----------|---------------------|
21 | | 32-bit test:     |           |           |                     |
22 | |   [MD5]          | 10070  ms | 10.070  s | 993,049    hashes/s |
23 | |   [MD4]          | 5998   ms | 5.998   s | 1,667,222  hashes/s |
24 | |   [MD2]          | 234746 ms | 234.746 s | 42,599     hashes/s |
25 | |   [SHA1]         | 10075  ms | 10.075  s | 992,556    hashes/s |
26 | |   [SHA2-224]     | 15981  ms | 15.981  s | 625,743    hashes/s |
27 | |   [SHA2-256]     | 14805  ms | 14.805  s | 675,447    hashes/s |
28 | |   [SHA2-384]     | 23972  ms | 23.972  s | 417,153    hashes/s |
29 | |   [SHA2-512]     | 24785  ms | 24.785  s | 403,470    hashes/s |
30 | |   [SHA2-512/224] | 22772  ms | 22.772  s | 439,136    hashes/s |
31 | |   [SHA2-512/256] | 23192  ms | 23.192  s | 431,183    hashes/s |
32 | +----------------------------------------------------------------+
33 | *Updated as of 11/03/2022
34 | 
35 | 36 | **Below you can find single-threaded speed metrics of each algorithm when calculating a hash for a 3GB binary file. 37 | 38 |
39 | +------------------------------------------+
40 | |    Algorithms    | Computational Metrics |          
41 | |------------------|-----------------------|
42 | | 64-bit test:     |           |           |
43 | |   [MD5]          | 7143   ms | 7.143   s |
44 | |   [MD4]          | 5041   ms | 5.041   s |
45 | |  *[MD2]          | N/A    ms | N/A     s | 
46 | |   [SHA1]         | 8092   ms | 8.092   s |
47 | |   [SHA2-224]     | 11245  ms | 11.245  s |
48 | |   [SHA2-256]     | 11194  ms | 11.194  s |
49 | |   [SHA2-384]     | 5865   ms | 5.865   s |
50 | |   [SHA2-512]     | 5937   ms | 5.937   s |
51 | |   [SHA2-512/224] | 5903   ms | 5.903   s |
52 | |   [SHA2-512/256] | 5953   ms | 5.953   s |
53 | |------------------|-----------|-----------|
54 | | 32-bit test:     |           |           |
55 | |   [MD5]          | 9519   ms | 9.519   s |
56 | |   [MD4]          | 5138   ms | 5.138   s |
57 | |  *[MD2]          | N/A    ms | N/A     s | 
58 | |   [SHA1]         | 9239   ms | 9.239   s |
59 | |   [SHA2-224]     | 15441  ms | 15.441  s |
60 | |   [SHA2-256]     | 13332  ms | 13.332  s |
61 | |   [SHA2-384]     | 18297  ms | 18.297  s |
62 | |   [SHA2-512]     | 17741  ms | 17.741  s |
63 | |   [SHA2-512/224] | 17910  ms | 17.910  s |
64 | |   [SHA2-512/256] | 18550  ms | 18.550  s |
65 | +------------------------------------------+
66 | *Excluded due to impractically long computational times.
67 | **Updated as of 11/03/2022
68 | 
69 | -------------------------------------------------------------------------------- /documentation/HMACs/README.md: -------------------------------------------------------------------------------- 1 |

Keyed-Hash Message Authentication Codes (HMACs)

2 |

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.

3 | 4 |

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:

5 | 6 | - The hash function in use. 7 | - The input supplied to said function. 8 | 9 |

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:

10 | 11 | - The hash function in use. 12 | - The input supplied to said function. 13 | - The key data. 14 | 15 |

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.

16 | 17 |

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.

18 | 19 |

*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.

20 | 21 |
22 |

Using Hash++

23 | 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. 24 | 25 | ```cpp 26 | static hashpp::hash getHMAC(hashpp::ALGORITHMS algorithm, const std::string& key, const std::string& data); 27 | static hashpp::hashCollection getHMACs(const HMAC_DataContainer& keyDataSet); 28 | static hashpp::hashCollection getHMACs(const std::vector& keyDataSets); 29 | static hashpp::hashCollection getHMACs(const std::initializer_list& keyDataSets); 30 | template static hashpp::hashCollection getHMACs(hashpp::ALGORITHMS algorithm, const std::string& key, const _Ts&... data); 31 | ``` 32 | 33 |
34 | You can easily generate an HMAC for a single piece of data using Hash++. See below for an example. 35 | https://github.com/D7EAD/HashPlusPlus/blob/0ac434933e4d54b584b810d863a9f1a4a4f5f7b4/documentation/HMACs/getHMAC/getHMAC_usage.cpp#L10-L29 36 | 37 |
38 | 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. 39 | https://github.com/D7EAD/HashPlusPlus/blob/fc5edb76cd829794a3fb34c416df7431653044e0/documentation/HMACs/getHMACs/getHMACs_usage.cpp#L14-L42 40 | -------------------------------------------------------------------------------- /documentation/HMACs/getHMAC/getHMAC_usage.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Basic usage of Hash++ getHMAC method. 4 | This file shows basic usage of the above described method 5 | and its overloads, as well as how data can be extracted 6 | from its returned object. 7 | 8 | */ 9 | 10 | #include "hashpp.h" 11 | 12 | using namespace hashpp; 13 | 14 | int main() { 15 | // data we want to get HMAC of 16 | std::string dataToHash = "Hello World!"; 17 | 18 | // key to use for HMAC 19 | std::string key = "secret"; 20 | 21 | // get HMAC of dataToHash using SHA-256 22 | auto hmac = get::getHMAC(ALGORITHMS::SHA2_256, key, dataToHash); 23 | 24 | // print out the hash 25 | std::cout << "HMAC: " << hmac << std::endl; 26 | 27 | // output: 28 | // 6fa7b4dea28ee348df10f9bb595ad985ff150a4adfd6131cca677d9acee07dc6 29 | } 30 | -------------------------------------------------------------------------------- /documentation/HMACs/getHMACs/getHMACs_usage.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Basic usage of Hash++ getHMACs method. 4 | This file shows basic usage of the above described method 5 | and its overloads, as well as how data can be extracted 6 | from its returned object. 7 | 8 | */ 9 | 10 | #include "hashpp.h" 11 | 12 | using namespace hashpp; 13 | 14 | int main() { 15 | // create HMAC_DataContainer object 16 | // to store algorithm to use, key, 17 | // and data to HMAC 18 | HMAC_DataContainer hmac_container; 19 | 20 | // set algorithm to use 21 | hmac_container.setAlgorithm(ALGORITHMS::SHA2_256); 22 | 23 | // set key to use 24 | hmac_container.setKey("secretKey"); 25 | 26 | // set data to HMAC 27 | hmac_container.setData("dataToHMAC1", "dataToHMAC2", "dataToHMAC3"); 28 | 29 | // calculate the HMACs for all data in container 30 | // using key and algorithm specified 31 | hashCollection hmacs = get::getHMACs(hmac_container); 32 | 33 | // parse and print each HMAC 34 | for (auto& hmac : hmacs["SHA2-256"]) { 35 | std::cout << hmac << std::endl; 36 | } 37 | 38 | // output: 39 | // f0dfad2b51176704f8fff07e2c6063417b1d361465b4f9eaacf9b756037bb815 40 | // bf912338f4c9d21eff351d085a26b9723eb0da6582039d18a003046c3ae3fbef 41 | // abba2bd3400c1b03322fac45539462241ca6ae14a81d58e1db017a9bcb3947b2 42 | } 43 | -------------------------------------------------------------------------------- /documentation/README.md: -------------------------------------------------------------------------------- 1 |

Documentation

2 | Hash++ is a modern C++17 header-only library that provides developers simple means of retrieving cryptographic hashes and keyed-hash 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. 3 |

4 | 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++. 5 | 6 | - Hashing Documentation 7 | - Covers basic hashing concepts and how to generate them using the library. 8 | - HMAC Documentation 9 | - Covers basic HMAC concepts and how to generate them using the library. 10 | - File-hashing Documentation 11 | - Covers how to hash files using the library. 12 | -------------------------------------------------------------------------------- /documentation/file_hashing/README.md: -------------------------------------------------------------------------------- 1 |

Using Hash++ to Generate File Hashes

2 | 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. 3 | 4 | ```cpp 5 | static hashpp::hash getFileHash(hashpp::ALGORITHMS algorithm, const std::string& path); 6 | static hashpp::hashCollection getFilesHashes(const FilePathsContainer& filePathSet); 7 | static hashpp::hashCollection getFilesHashes(const std::vector& filePathSets); 8 | static hashpp::hashCollection getFilesHashes(const std::initializer_list& filePathSets); 9 | ``` 10 | 11 |
12 | 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. 13 | https://github.com/D7EAD/HashPlusPlus/blob/ba418167da59826cda2a18990a90cf332d75308e/documentation/file_hashing/getFileHash/getFileHash_usage.cpp#L10-L29 14 | 15 |
16 | If you're in the business of hashing multiple files at once, you can find an example of such a use below. 17 | https://github.com/D7EAD/HashPlusPlus/blob/c007af7d81bdf054a389314ad1d7bbb6d0757262/documentation/file_hashing/getFilesHashes/getFilesHashes_usage.cpp#L14-L35 18 | -------------------------------------------------------------------------------- /documentation/file_hashing/getFileHash/getFileHash_usage.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Basic usage of Hash++ getFileHash method. 4 | This file shows basic usage of the above described method 5 | and its overloads, as well as how data can be extracted 6 | from its returned object. 7 | 8 | */ 9 | 10 | #include "hashpp.h" 11 | 12 | using namespace hashpp; 13 | 14 | int main() { 15 | // path to file we want to hash (test.txt) 16 | std::string pathToFile = "N:/source/test.txt"; 17 | 18 | // store the resulting hash object of the file using SHA-256 19 | auto hash = get::getFileHash(ALGORITHMS::SHA2_256, pathToFile); 20 | 21 | // print the hash digest 22 | std::cout << hash << std::endl; 23 | 24 | // or we can be more specific... 25 | std::cout << hash.getString() << std::endl; 26 | 27 | // output: 28 | // 4de0d727216e14760010efdb0cccf577853d7da4e122a507b422148940f4aa34 29 | } 30 | -------------------------------------------------------------------------------- /documentation/file_hashing/getFileHash/test.txt: -------------------------------------------------------------------------------- 1 | A hash a day keeps the doctor away. -------------------------------------------------------------------------------- /documentation/file_hashing/getFilesHashes/getFilesHashes_usage.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Basic usage of Hash++ getFileHashes method. 4 | This file shows basic usage of the above described method 5 | and its overloads, as well as how data can be extracted 6 | from its returned object. 7 | 8 | */ 9 | 10 | #include "hashpp.h" 11 | 12 | using namespace hashpp; 13 | 14 | int main() { 15 | // create a FilePathsContainer object 16 | FilePathsContainer path_cont1; 17 | 18 | // set its algorithm and some paths 19 | path_cont1.setAlgorithm(ALGORITHMS::SHA2_256); 20 | path_cont1.setData("N:/source/test.txt", "N:/source/test2.txt", "N:/source/test3.txt"); 21 | 22 | // get the hashes of each file via get::getFilesHashes 23 | // and store them in a hashCollection object 24 | hashCollection hashes = get::getFilesHashes(path_cont1); 25 | 26 | // parse and print the hashes 27 | for (auto& hash : hashes["SHA2-256"]) { 28 | std::cout << hash << std::endl; 29 | } 30 | 31 | // output: 32 | // 4de0d727216e14760010efdb0cccf577853d7da4e122a507b422148940f4aa34 33 | // 7c88d6bc28e9bd6660b96cfa3b69cdbaaaf0187047267106842841357ac03bd8 34 | // 44d25e664ce6d6e82beb7a14fe312d7c09c5dc107668a6d40449bc24938e5c73 35 | } 36 | -------------------------------------------------------------------------------- /documentation/file_hashing/getFilesHashes/test.txt: -------------------------------------------------------------------------------- 1 | A hash a day keeps the doctor away. -------------------------------------------------------------------------------- /documentation/file_hashing/getFilesHashes/test2.txt: -------------------------------------------------------------------------------- 1 | Too many hashes may lead to gastrointestinal issues. -------------------------------------------------------------------------------- /documentation/file_hashing/getFilesHashes/test3.txt: -------------------------------------------------------------------------------- 1 | Passwords should not be stored in plaintext. -------------------------------------------------------------------------------- /documentation/hashing/README.md: -------------------------------------------------------------------------------- 1 |

Hashing

2 | 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. 3 |

4 | 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. 5 |

6 | Simply, a one-way function H(x) = D is one such function that satisfies all constraints such that... 7 | 8 | - D is easily computed given x. 9 | - H's output range is known. 10 | - Given only output D and function H, x is infeasibly computed such that H(x) = D. 11 | 12 | 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: 13 | 14 | - Message and file integrity verification. 15 | - Password verification. 16 | - Signature/identifier generation and verification. 17 | - Key Derivation Functions (KDFs). 18 | - Proof-of-Work. 19 | - Blockchain Technology. 20 | - Public-Key Cryptography. 21 | - CSPRNGs. 22 | 23 |

Using Hash++

24 | 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. 25 | 26 | ```cpp 27 | static hashpp::hash getHash(hashpp::ALGORITHMS algorithm, const std::string& data); 28 | static hashpp::hashCollection getHashes(const DataContainer& dataSet); 29 | static hashpp::hashCollection getHashes(const std::vector& dataSets); 30 | static hashpp::hashCollection getHashes(const std::initializer_list& dataSets); 31 | template static hashpp::hashCollection getHashes(hashpp::ALGORITHMS algorithm, const _Ts&... data); 32 | ``` 33 |
34 | 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. 35 | https://github.com/D7EAD/HashPlusPlus/blob/8bf4d2971f5fab4ad0df75ea6f71a012841c504e/documentation/hashing/container/container.cpp#L1-L100 36 | 37 |
38 | 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. 39 | https://github.com/D7EAD/HashPlusPlus/blob/8bf4d2971f5fab4ad0df75ea6f71a012841c504e/documentation/hashing/container/container_use.cpp#L14-L37 40 | 41 |
42 | 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: 43 | https://github.com/D7EAD/HashPlusPlus/blob/b7fbc10fc627ab21c39a51698882641e1073c78e/documentation/hashing/getHashes/getHashes_usage.cpp#L14-L29 44 | 45 |
46 | 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. 47 | https://github.com/D7EAD/HashPlusPlus/blob/ffca4d776939f950dbce37d3477bd3e164cc7ba9/documentation/hashing/getHash/getHash_usage.cpp#L14-L26 48 | -------------------------------------------------------------------------------- /documentation/hashing/container/container.cpp: -------------------------------------------------------------------------------- 1 | class Container { 2 | public: // constructors 3 | Container() noexcept = default; 4 | Container(const Container& container) noexcept 5 | : algorithm(container.algorithm), key(container.key), data(container.data) {} 6 | Container(Container&& container) noexcept 7 | : algorithm(container.algorithm), key(std::move(container.key)), data(std::move(container.data)) {} 8 | Container( 9 | ALGORITHMS algorithm, 10 | const std::vector& data 11 | ) noexcept : algorithm(algorithm), data(data) {} 12 | Container( 13 | ALGORITHMS algorithm, 14 | std::vector&& data 15 | ) noexcept : algorithm(algorithm), data(std::move(data)) {} 16 | Container( 17 | ALGORITHMS algorithm, 18 | const std::vector& data, 19 | const std::string& key 20 | ) noexcept : algorithm(algorithm), data(data), key(key) {} 21 | Container( 22 | ALGORITHMS algorithm, 23 | std::vector&& data, 24 | const std::string& key 25 | ) noexcept : algorithm(algorithm), data(std::move(data)), key(key) {} 26 | Container( 27 | ALGORITHMS algorithm, 28 | const std::vector& data, 29 | std::string&& key 30 | ) noexcept : algorithm(algorithm), data(data), key(std::move(key)) {} 31 | Container( 32 | ALGORITHMS algorithm, 33 | std::vector&& data, 34 | std::string&& key 35 | ) noexcept : algorithm(algorithm), data(std::move(data)), key(std::move(key)) {} 36 | 37 | template ...>, int> = 0> 39 | Container( 40 | ALGORITHMS algorithm, 41 | const _Ts&... data 42 | ) noexcept : algorithm(algorithm), data({ data... }) {} 43 | 44 | template ..., std::negation>...>, int> = 0> 46 | Container( 47 | ALGORITHMS algorithm, 48 | _Ts&&... data 49 | ) noexcept : algorithm(algorithm), data({ std::forward<_Ts>(data)... }) {} 50 | 51 | public: // member functions 52 | constexpr const ALGORITHMS& getAlgorithm() const noexcept { return this->algorithm; } 53 | constexpr const std::string& getKey() const noexcept { return this->key; } 54 | constexpr const std::vector& getData() const noexcept { return this->data; } 55 | void setAlgorithm(ALGORITHMS algorithm) noexcept { this->algorithm = algorithm; } 56 | void setKey(const std::string& key) noexcept { this->key = key; } 57 | 58 | void setData(const std::vector& data) noexcept { this->data = data; } 59 | void setData(std::vector&& data) noexcept { this->data = std::move(data); } 60 | template void setData(const _Ts&... data) noexcept { this->data = { data... }; } 61 | template >...>, int> = 0> 63 | void setData(_Ts&&... data) noexcept { this->data = { std::forward<_Ts>(data)... }; } 64 | 65 | void appendData(const std::vector& data) noexcept { this->data.insert(this->data.end(), data.begin(), data.end()); } 66 | void appendData(std::vector&& data) noexcept { this->data.insert(this->data.end(), std::make_move_iterator(data.begin()), std::make_move_iterator(data.end())); } 67 | template void appendData(const _Ts&... data) noexcept { (this->data.push_back(data), ...); } 68 | template >...>, int> = 0> 70 | void appendData(_Ts&&... data) noexcept { (this->data.push_back(std::forward<_Ts>(data)), ...); } 71 | 72 | Container& operator=(const Container& _rhs) noexcept { 73 | if (this != &_rhs) { 74 | this->algorithm = _rhs.getAlgorithm(); 75 | this->key = _rhs.getKey(); 76 | this->data = _rhs.getData(); 77 | } 78 | return *this; 79 | } 80 | 81 | Container& operator=(Container&& _rhs) noexcept { 82 | if (this != &_rhs) { 83 | this->algorithm = _rhs.algorithm; 84 | this->key = std::move(_rhs.key); 85 | this->data = std::move(_rhs.data); 86 | } 87 | return *this; 88 | } 89 | 90 | private: // member variables 91 | ALGORITHMS algorithm; 92 | std::string key; 93 | 94 | // Holds arbitrary data; how this data is defined is determined 95 | // by the functions that the container containing said data is passed to. 96 | // (e.g., a call to getFilesHashes with a container will treat all data 97 | // in it as paths to files to be hashed, and a call to getHashes with 98 | // a container will treat all data as generic data to be hashed) 99 | std::vector data; 100 | }; 101 | -------------------------------------------------------------------------------- /documentation/hashing/container/container_use.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Basic usage and examples of Hash++ container class Container. 4 | This container can be used to store paths to files to be hashed, 5 | data to be hashed, keys to use in generating HMACs of contained data, 6 | the algorithm to use to hash the contained data, etc. 7 | 8 | This container and its aliases are used in several function overloads 9 | where a developer may want to pass several sets of data and use a 10 | different hashing algorithm for each set of data. 11 | 12 | */ 13 | 14 | #include "hashpp.h" 15 | 16 | using namespace hashpp; 17 | 18 | int main() { 19 | // instantiation, assignment via member functions 20 | DataContainer cont1; 21 | cont1.setData("dataToHash1", "dataToHash2"); 22 | cont1.appendData("moreDataToHash1", "moreDataToHash2"); 23 | cont1.setAlgorithm(ALGORITHMS::SHA2_224); 24 | 25 | // instantiation, assignment via variadic data constructor 26 | DataContainer cont2(ALGORITHMS::SHA2_256, "dataToHash1", "dataToHash2", "moreDataToHash1", "moreDataToHash2"); 27 | 28 | // instantiation, assignment via vector constructor 29 | std::vector data = { "dataToHash1", "dataToHash2", "moreDataToHash1", "moreDataToHash2" }; 30 | DataContainer cont3(ALGORITHMS::SHA2_384, data); 31 | 32 | // these containers can then be passed to their respective library function overloads 33 | // as an initializer list or vector 34 | std::vector containers = { cont1, cont2, cont3 }; 35 | auto _hashes1 = get::getHashes(containers); 36 | auto _hashes2 = get::getHashes({ cont1, cont2, cont3 }); 37 | } 38 | -------------------------------------------------------------------------------- /documentation/hashing/getHash/getHash_usage.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Basic usage of Hash++ getHash method. 4 | This file shows basic usage of the above described method 5 | and its overloads, as well as how data can be extracted 6 | from its returned object. 7 | 8 | */ 9 | 10 | #include "hashpp.h" 11 | 12 | using namespace hashpp; 13 | 14 | int main() { 15 | // the data we want to hash 16 | std::string data = "dataToHash"; 17 | 18 | // store the resulting hash object of 'data' using SHA-256 19 | auto hash = get::getHash(ALGORITHMS::SHA2_256, data); 20 | 21 | // print the hash digest 22 | std::cout << hash << std::endl; 23 | 24 | // or we can be more specific... 25 | std::cout << hash.getString() << std::endl; 26 | } 27 | -------------------------------------------------------------------------------- /documentation/hashing/getHashes/getHashes_usage.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Basic usage of Hash++ getHashes method. 4 | This file shows basic usage of the above described method 5 | and its overloads, as well as how data can be extracted 6 | from its returned object. 7 | 8 | */ 9 | 10 | #include "hashpp.h" 11 | 12 | using namespace hashpp; 13 | 14 | int main() { 15 | // a container holding data to be hashed and algorithm to use 16 | DataContainer cont1; 17 | cont1.setAlgorithm(ALGORITHMS::SHA2_256); 18 | cont1.setData("dataToHash1", "dataToHash2", "dataToHash3"); 19 | 20 | // acquiring the hashes of the data contained in the above 21 | // container using its set algorithm (SHA2-256). 22 | hashCollection hashes = get::getHashes(cont1); 23 | 24 | // printing the resulting hashes via hashCollection::operator[] 25 | // with specific algorithm name 26 | for (auto& hash : hashes["SHA2-256"]) { 27 | std::cout << hash << std::endl; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /images/hpp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D7EAD/HashPlusPlus/3805b30589d0e50b00b2896a7cb94bc85200e563/images/hpp.png --------------------------------------------------------------------------------