├── .gitignore ├── hash_file.c ├── LICENSE ├── README.md ├── sha256.h ├── sha256_tests.c └── sha256.c /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | -------------------------------------------------------------------------------- /hash_file.c: -------------------------------------------------------------------------------- 1 | /* 2 | This is an example C program using LekKit' SHA256 library 3 | (https://github.com/LekKit/sha256) 4 | 5 | Produces a hash for a given file, much like sha256sum CLI utility 6 | */ 7 | 8 | #include "sha256.h" 9 | #include 10 | 11 | int main(int argc, char** argv){ 12 | if (argc < 2){ 13 | printf("Usage: %s [file]\n", argv[0]); 14 | return 0; 15 | } 16 | FILE* file = fopen(argv[1], "rb"); 17 | if (!file){ 18 | printf("Cannot open file\n"); 19 | return 0; 20 | } 21 | char buffer[1024]; 22 | size_t size; 23 | struct sha256_buff buff; 24 | sha256_init(&buff); 25 | while (!feof(file)){ 26 | /* Hash file by 1kb chunks, instead of loading into RAM at once */ 27 | size = fread(buffer, 1, 1024, file); 28 | sha256_update(&buff, buffer, size); 29 | } 30 | char hash[65] = {0}; /* hash[64] is null-byte */ 31 | sha256_finalize(&buff); 32 | sha256_read_hex(&buff, hash); 33 | printf("%s\n", hash); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 LekKit 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 | # sha256 3 | SHA-256 algorithm implementation (С/С++) 4 | 5 | - Pure C with no platform or architecture dependencies 6 | - Easy to use - just include sha256.h and add sha256.c to your project source files 7 | - Can be used in C++, extends API appropriately 8 | - Two types of API: easy - for hashing strings, etc in a single call; extended - for hashing files, streams, etc 9 | - Based on the pseudocode algorithm from [Wikipedia](https://en.wikipedia.org/wiki/SHA-2#Pseudocode) 10 | - Pretty fast, comparable to sha256sum in speed 11 | # Usage 12 | ## Easy API - String hashing example 13 | ```c 14 | const char* str = "test"; 15 | char hash[65] = {0}; // Notice the additional null-byte 16 | sha256_easy_hash_hex(str, strlen(str), hash); 17 | printf("%s\n", hash); 18 | ``` 19 | ## Extended API - File hashing example 20 | ```c 21 | FILE* file = fopen("test", "rb"); 22 | char buffer[1024]; 23 | size_t size; 24 | struct sha256_buff buff; 25 | sha256_init(&buff); 26 | while (!feof(file)) { 27 | // Hash file by 1kb chunks, instead of loading into RAM at once 28 | size = fread(buffer, 1, 1024, file); 29 | sha256_update(&buff, buffer, size); 30 | } 31 | char hash[65] = {0}; 32 | sha256_finalize(&buff); 33 | sha256_read_hex(&buff, hash); 34 | printf("%s\n", hash); 35 | ``` 36 | ## C++ 37 | ```c 38 | std::cout << SHA256::hashString("test") << std::endl; 39 | 40 | SHA256 buff; 41 | buff.update("test", 4); 42 | std::cout << buff.hash() << std::endl; 43 | ``` 44 | -------------------------------------------------------------------------------- /sha256.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2020 LekKit https://github.com/LekKit 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef SHA256_H 26 | #define SHA256_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #include 33 | #include 34 | #include 35 | 36 | struct sha256_buff { 37 | uint64_t data_size; 38 | uint32_t h[8]; 39 | uint8_t last_chunk[64]; 40 | uint8_t chunk_size; 41 | }; 42 | 43 | /* Initialization, must be called before any further use */ 44 | void sha256_init(struct sha256_buff* buff); 45 | 46 | /* Process block of data of arbitary length, can be used on data streams (files, etc) */ 47 | void sha256_update(struct sha256_buff* buff, const void* data, size_t size); 48 | 49 | /* Produces final hash values (digest) to be read 50 | If the buffer is reused later, init must be called again */ 51 | void sha256_finalize(struct sha256_buff* buff); 52 | 53 | /* Read digest into 32-byte binary array */ 54 | void sha256_read(const struct sha256_buff* buff, uint8_t* hash); 55 | 56 | /* Read digest into 64-char string as hex (without null-byte) */ 57 | void sha256_read_hex(const struct sha256_buff* buff, char* hex); 58 | 59 | /* Hashes single contiguous block of data and reads digest into 32-byte binary array */ 60 | void sha256_easy_hash(const void* data, size_t size, uint8_t* hash); 61 | 62 | /* Hashes single contiguous block of data and reads digest into 64-char string (without null-byte) */ 63 | void sha256_easy_hash_hex(const void* data, size_t size, char* hex); 64 | 65 | #ifdef __cplusplus 66 | } 67 | 68 | #include 69 | 70 | class SHA256 { 71 | private: 72 | struct sha256_buff buff; 73 | public: 74 | SHA256() { 75 | sha256_init(&buff); 76 | } 77 | 78 | void update(const void* data, std::size_t size) { 79 | sha256_update(&buff, data, size); 80 | } 81 | 82 | std::string hash() { 83 | char hash[64]; 84 | sha256_finalize(&buff); 85 | sha256_read_hex(&buff, hash); 86 | sha256_init(&buff); 87 | return std::string(hash, 64); 88 | } 89 | 90 | static std::string hashString(const std::string& str) { 91 | char hash[64]; 92 | sha256_easy_hash_hex(str.c_str(), str.length(), hash); 93 | return std::string(hash, 64); 94 | } 95 | }; 96 | 97 | #endif 98 | 99 | #endif 100 | -------------------------------------------------------------------------------- /sha256_tests.c: -------------------------------------------------------------------------------- 1 | /* 2 | This is a test vector suite for LekKit' SHA256 library 3 | (https://github.com/LekKit/sha256) 4 | 5 | Used sources: 6 | https://www.di-mgt.com.au/sha_testvectors.html 7 | https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA2_Additional.pdf 8 | */ 9 | 10 | #include "sha256.h" 11 | #include 12 | #include 13 | 14 | void test_str(const char* in, const char* out) { 15 | static int test_count = 0; 16 | 17 | char buffer[65] = {0}; 18 | sha256_easy_hash_hex(in, strlen(in), buffer); 19 | if (strcmp(out, buffer) != 0) { 20 | printf("String test #%i failed!!!\nsha256(\"%s\") = \"%s\"\nExpected value: \"%s\"\n\n", test_count, in, buffer, out); 21 | printf("Please report this issue to https://github.com/LekKit/sha256\n"); 22 | exit(0); 23 | } else { 24 | printf("String test #%i passed\nsha256(\"%s\") = \"%s\"\n\n", test_count, in, buffer); 25 | } 26 | 27 | test_count++; 28 | } 29 | 30 | void test_bytes(char byte, size_t size, const char* out) { 31 | static int test_count = 0; 32 | 33 | char buffer[1024]; 34 | struct sha256_buff buff; 35 | size_t tmp_size = size; 36 | memset(buffer, byte, 1024); 37 | sha256_init(&buff); 38 | 39 | while (tmp_size >= 1024) { 40 | sha256_update(&buff, buffer, 1024); 41 | tmp_size -= 1024; 42 | } 43 | sha256_update(&buff, buffer, size % 1024); 44 | sha256_finalize(&buff); 45 | 46 | sha256_read_hex(&buff, buffer); 47 | buffer[64] = 0; 48 | 49 | if (strcmp(out, buffer) != 0) { 50 | printf("Byte test #%i failed!!!\nsha256(0x%X * %zu) = \"%s\"\nExpected value: \"%s\"\n\n", test_count, byte, size, buffer, out); 51 | printf("Please report this issue to https://github.com/LekKit/sha256\n"); 52 | exit(0); 53 | } else { 54 | printf("Byte test #%i passed\nsha256(0x%X * %zu) = \"%s\"\n\n", test_count, byte, size, buffer); 55 | } 56 | 57 | test_count++; 58 | } 59 | 60 | int main() { 61 | test_str("", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); 62 | test_str("abc", "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); 63 | test_str("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"); 64 | test_str("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1"); 65 | test_str("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno", "2ff100b36c386c65a1afc462ad53e25479bec9498ed00aa5a04de584bc25301b"); 66 | test_str("LekKit", "500f94082c97ab2c1188e53d9f467a9e73bfb366e7309adbfac098f0a46d7711"); 67 | test_str("\xBD", "68325720aabd7c82f30f554b313d0570c95accbb7dc4b5aae11204c08ffe732b"); 68 | test_str("\xC9\x8C\x8E\x55", "7abc22c0ae5af26ce93dbb94433a0e0b2e119d014f8e7f65bd56c61ccccd9504"); 69 | 70 | test_bytes(0x00, 55, "02779466cdec163811d078815c633f21901413081449002f24aa3e80f0b88ef7"); 71 | test_bytes(0x00, 56, "d4817aa5497628e7c77e6b606107042bbba3130888c5f47a375e6179be789fbb"); 72 | test_bytes(0x00, 57, "65a16cb7861335d5ace3c60718b5052e44660726da4cd13bb745381b235a1785"); 73 | test_bytes(0x00, 64, "f5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b"); 74 | test_bytes(0x00, 1000, "541b3e9daa09b20bf85fa273e5cbd3e80185aa4ec298e765db87742b70138a53"); 75 | test_bytes(0x41, 1000, "c2e686823489ced2017f6059b8b239318b6364f6dcd835d0a519105a1eadd6e4"); 76 | test_bytes(0x55, 1005, "f4d62ddec0f3dd90ea1380fa16a5ff8dc4c54b21740650f24afc4120903552b0"); 77 | test_bytes(0x00, 1000000, "d29751f2649b32ff572b5e0a9f541ea660a50f94ff0beedfb0b692b924cc8025"); 78 | test_bytes(0x61, 1000000, "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"); 79 | test_bytes(0x5A, 536870912, "15a1868c12cc53951e182344277447cd0979536badcc512ad24c67e9b2d4f3dd"); 80 | test_bytes(0x00, 1090519040, "461c19a93bd4344f9215f5ec64357090342bc66b15a148317d276e31cbc20b53"); 81 | test_bytes(0x42, 1610612798, "c23ce8a7895f4b21ec0daf37920ac0a262a220045a03eb2dfed48ef9b05aabea"); 82 | 83 | printf("All tests passed! Fine then ;)\n"); 84 | 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /sha256.c: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2020 LekKit https://github.com/LekKit 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | /* Details of the implementation, etc can be found here: https://en.wikipedia.org/wiki/SHA-2 26 | See sha256.h for short documentation on library usage */ 27 | 28 | #include "sha256.h" 29 | 30 | void sha256_init(struct sha256_buff* buff) { 31 | buff->h[0] = 0x6a09e667; 32 | buff->h[1] = 0xbb67ae85; 33 | buff->h[2] = 0x3c6ef372; 34 | buff->h[3] = 0xa54ff53a; 35 | buff->h[4] = 0x510e527f; 36 | buff->h[5] = 0x9b05688c; 37 | buff->h[6] = 0x1f83d9ab; 38 | buff->h[7] = 0x5be0cd19; 39 | buff->data_size = 0; 40 | buff->chunk_size = 0; 41 | } 42 | 43 | static const uint32_t k[64] = { 44 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 45 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 46 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 47 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 48 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 49 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 50 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 51 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 52 | }; 53 | 54 | #define rotate_r(val, bits) (val >> bits | val << (32 - bits)) 55 | 56 | static void sha256_calc_chunk(struct sha256_buff* buff, const uint8_t* chunk) { 57 | uint32_t w[64]; 58 | uint32_t tv[8]; 59 | uint32_t i; 60 | 61 | for (i=0; i<16; ++i){ 62 | w[i] = (uint32_t) chunk[0] << 24 | (uint32_t) chunk[1] << 16 | (uint32_t) chunk[2] << 8 | (uint32_t) chunk[3]; 63 | chunk += 4; 64 | } 65 | 66 | for (i=16; i<64; ++i){ 67 | uint32_t s0 = rotate_r(w[i-15], 7) ^ rotate_r(w[i-15], 18) ^ (w[i-15] >> 3); 68 | uint32_t s1 = rotate_r(w[i-2], 17) ^ rotate_r(w[i-2], 19) ^ (w[i-2] >> 10); 69 | w[i] = w[i-16] + s0 + w[i-7] + s1; 70 | } 71 | 72 | for (i = 0; i < 8; ++i) 73 | tv[i] = buff->h[i]; 74 | 75 | for (i=0; i<64; ++i){ 76 | uint32_t S1 = rotate_r(tv[4], 6) ^ rotate_r(tv[4], 11) ^ rotate_r(tv[4], 25); 77 | uint32_t ch = (tv[4] & tv[5]) ^ (~tv[4] & tv[6]); 78 | uint32_t temp1 = tv[7] + S1 + ch + k[i] + w[i]; 79 | uint32_t S0 = rotate_r(tv[0], 2) ^ rotate_r(tv[0], 13) ^ rotate_r(tv[0], 22); 80 | uint32_t maj = (tv[0] & tv[1]) ^ (tv[0] & tv[2]) ^ (tv[1] & tv[2]); 81 | uint32_t temp2 = S0 + maj; 82 | 83 | tv[7] = tv[6]; 84 | tv[6] = tv[5]; 85 | tv[5] = tv[4]; 86 | tv[4] = tv[3] + temp1; 87 | tv[3] = tv[2]; 88 | tv[2] = tv[1]; 89 | tv[1] = tv[0]; 90 | tv[0] = temp1 + temp2; 91 | } 92 | 93 | for (i = 0; i < 8; ++i) 94 | buff->h[i] += tv[i]; 95 | } 96 | 97 | void sha256_update(struct sha256_buff* buff, const void* data, size_t size) { 98 | const uint8_t* ptr = (const uint8_t*)data; 99 | buff->data_size += size; 100 | /* If there is data left in buff, concatenate it to process as new chunk */ 101 | if (size + buff->chunk_size >= 64) { 102 | uint8_t tmp_chunk[64]; 103 | memcpy(tmp_chunk, buff->last_chunk, buff->chunk_size); 104 | memcpy(tmp_chunk + buff->chunk_size, ptr, 64 - buff->chunk_size); 105 | ptr += (64 - buff->chunk_size); 106 | size -= (64 - buff->chunk_size); 107 | buff->chunk_size = 0; 108 | sha256_calc_chunk(buff, tmp_chunk); 109 | } 110 | /* Run over data chunks */ 111 | while (size >= 64) { 112 | sha256_calc_chunk(buff, ptr); 113 | ptr += 64; 114 | size -= 64; 115 | } 116 | 117 | /* Save remaining data in buff, will be reused on next call or finalize */ 118 | memcpy(buff->last_chunk + buff->chunk_size, ptr, size); 119 | buff->chunk_size += size; 120 | } 121 | 122 | void sha256_finalize(struct sha256_buff* buff) { 123 | buff->last_chunk[buff->chunk_size] = 0x80; 124 | buff->chunk_size++; 125 | memset(buff->last_chunk + buff->chunk_size, 0, 64 - buff->chunk_size); 126 | 127 | /* If there isn't enough space to fit int64, pad chunk with zeroes and prepare next chunk */ 128 | if (buff->chunk_size > 56) { 129 | sha256_calc_chunk(buff, buff->last_chunk); 130 | memset(buff->last_chunk, 0, 64); 131 | } 132 | 133 | /* Add total size as big-endian int64 x8 */ 134 | uint64_t size = buff->data_size * 8; 135 | int i; 136 | for (i = 8; i > 0; --i) { 137 | buff->last_chunk[55+i] = size & 255; 138 | size >>= 8; 139 | } 140 | 141 | sha256_calc_chunk(buff, buff->last_chunk); 142 | } 143 | 144 | void sha256_read(const struct sha256_buff* buff, uint8_t* hash) { 145 | uint32_t i; 146 | for (i = 0; i < 8; i++) { 147 | hash[i*4] = (buff->h[i] >> 24) & 255; 148 | hash[i*4 + 1] = (buff->h[i] >> 16) & 255; 149 | hash[i*4 + 2] = (buff->h[i] >> 8) & 255; 150 | hash[i*4 + 3] = buff->h[i] & 255; 151 | } 152 | } 153 | 154 | static void bin_to_hex(const void* data, uint32_t len, char* out) { 155 | static const char* const lut = "0123456789abcdef"; 156 | uint32_t i; 157 | for (i = 0; i < len; ++i){ 158 | uint8_t c = ((const uint8_t*)data)[i]; 159 | out[i*2] = lut[c >> 4]; 160 | out[i*2 + 1] = lut[c & 15]; 161 | } 162 | } 163 | 164 | void sha256_read_hex(const struct sha256_buff* buff, char* hex) { 165 | uint8_t hash[32]; 166 | sha256_read(buff, hash); 167 | bin_to_hex(hash, 32, hex); 168 | } 169 | 170 | void sha256_easy_hash(const void* data, size_t size, uint8_t* hash) { 171 | struct sha256_buff buff; 172 | sha256_init(&buff); 173 | sha256_update(&buff, data, size); 174 | sha256_finalize(&buff); 175 | sha256_read(&buff, hash); 176 | } 177 | 178 | void sha256_easy_hash_hex(const void* data, size_t size, char* hex) { 179 | uint8_t hash[32]; 180 | sha256_easy_hash(data, size, hash); 181 | bin_to_hex(hash, 32, hex); 182 | } 183 | --------------------------------------------------------------------------------