Simple C++ implementation of the [SHA-256 Hashing Algorithm] (https://en.wikipedia.org/wiki/SHA-2)
More...
#include <array>
#include <cassert>
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <utility>
#include <vector>
Go to the source code of this file.
|
namespace | hashing |
| Used for assert.
|
|
namespace | SHA |
| Functions for the SHA-1 algorithm implementation.
|
|
Simple C++ implementation of the [SHA-256 Hashing Algorithm] (https://en.wikipedia.org/wiki/SHA-2)
- Author
- Md. Anisul Haque
SHA-2 is a set of cryptographic hash functions that was designed by the NSA and first published in 2001. SHA-256 is a part of the SHA-2 family. SHA-256 is widely used for authenticating software packages and secure password hashing.
Definition in file sha256.cpp.
◆ compute_padded_size()
std::size_t hashing::sha256::compute_padded_size |
( |
const std::size_t | input_size | ) |
|
Computes size of the padded input.
- Parameters
-
- Returns
- size_t Size of the padded input
Definition at line 143 of file sha256.cpp.
143 {
144 if (input_size % 64 < 56) {
145 return input_size + 64 - (input_size % 64);
146 }
147 return input_size + 128 - (input_size % 64);
148}
◆ create_message_schedule_array()
std::array< uint32_t, 64 > hashing::sha256::create_message_schedule_array |
( |
const std::string & | input, |
|
|
const size_t | byte_num ) |
Creates the message schedule array.
- Parameters
-
input | Input string |
byte_num | Position of the first byte of the chunk |
- Returns
- std::array<uint32_t, 64> Message schedule array
Definition at line 195 of file sha256.cpp.
196 {
197 std::array<uint32_t, 64> blocks{};
198
199
200 for (size_t block_num = 0; block_num < 16; ++block_num) {
201 blocks[block_num] =
202 (
static_cast<uint8_t
>(
get_char(input, byte_num + block_num * 4))
203 << 24) |
204 (
static_cast<uint8_t
>(
get_char(input, byte_num + block_num * 4 + 1))
205 << 16) |
206 (
static_cast<uint8_t
>(
get_char(input, byte_num + block_num * 4 + 2))
207 << 8) |
208 static_cast<uint8_t
>(
get_char(input, byte_num + block_num * 4 + 3));
209 }
210
211
212
213 for (size_t block_num = 16; block_num < 64; ++block_num) {
214 const auto s0 =
right_rotate(blocks[block_num - 15], 7) ^
216 (blocks[block_num - 15] >> 3);
217 const auto s1 =
right_rotate(blocks[block_num - 2], 17) ^
219 (blocks[block_num - 2] >> 10);
220 blocks[block_num] =
221 blocks[block_num - 16] + s0 + blocks[block_num - 7] + s1;
222 }
223
224 return blocks;
225}
char get_char(const std::string &input, std::size_t pos)
Returns the character at pos after the input is padded.
uint32_t right_rotate(uint32_t n, size_t rotate)
Rotates the bits of a 32-bit unsigned integer.
◆ extract_byte()
template<typename T >
uint8_t hashing::sha256::extract_byte |
( |
const T | in_value, |
|
|
const std::size_t | byte_num ) |
Returns the byte at position byte_num in in_value.
- Parameters
-
in_value | Input value |
byte_num | Position of byte to be returned |
- Returns
- uint8_t Byte at position byte_num
Definition at line 157 of file sha256.cpp.
157 {
158 if (sizeof(in_value) <= byte_num) {
159 throw std::out_of_range("Byte at index byte_num does not exist");
160 }
161 return (in_value >> (byte_num * 8)) & 0xFF;
162}
◆ get_char()
char hashing::sha256::get_char |
( |
const std::string & | input, |
|
|
std::size_t | pos ) |
Returns the character at pos after the input is padded.
- Parameters
-
input | Input string |
pos | Position of character to be returned |
- Returns
- char Character at the index pos in the padded string
Definition at line 170 of file sha256.cpp.
170 {
171 const auto input_size = input.length();
172 if (pos < input_size) {
173 return input[pos];
174 }
175 if (pos == input_size) {
176 return '\x80';
177 }
179 if (pos < padded_input_size - 8) {
180 return '\x00';
181 }
182 if (padded_input_size <= pos) {
183 throw std::out_of_range("pos is out of range");
184 }
185 return static_cast<char>(
186 extract_byte<size_t>(input_size * 8, padded_input_size - pos - 1));
187}
std::size_t compute_padded_size(const std::size_t input_size)
Computes size of the padded input.
◆ main()
Main function.
- Returns
- 0 on exit
Definition at line 326 of file sha256.cpp.
◆ right_rotate()
uint32_t hashing::sha256::right_rotate |
( |
uint32_t | n, |
|
|
size_t | rotate ) |
Rotates the bits of a 32-bit unsigned integer.
- Parameters
-
n | Integer to rotate |
rotate | Number of bits to rotate |
- Returns
- uint32_t The rotated integer
Definition at line 58 of file sha256.cpp.
58 {
59 return (n >> rotate) | (n << (32 - rotate));
60}
◆ sha256()
std::string hashing::sha256::sha256 |
( |
const std::string & | input | ) |
|
Computes the final hash value.
- Parameters
-
- Returns
- std::string The final hash value
Definition at line 232 of file sha256.cpp.
232 {
234
236 byte_num += 64) {
238 }
239 return h.to_string();
240}
std::array< uint32_t, 64 > create_message_schedule_array(const std::string &input, const size_t byte_num)
Creates the message schedule array.
◆ test()
Definition at line 312 of file sha256.cpp.
312 {
314 test_extract_byte();
315 test_get_char();
316 test_right_rotate();
317 test_sha256();
318
319 std::cout << "All tests have successfully passed!\n";
320}
static void test_compute_padded_size()
Self-test implementations.
◆ test_compute_padded_size()
static void test_compute_padded_size |
( |
| ) |
|
|
static |
Self-test implementations.
- Returns
- void
Definition at line 248 of file sha256.cpp.
248 {
249 assert(hashing::sha256::compute_padded_size(55) == 64);
250 assert(hashing::sha256::compute_padded_size(56) == 128);
251 assert(hashing::sha256::compute_padded_size(130) == 192);
252}
◆ test_extract_byte()
static void test_extract_byte |
( |
| ) |
|
|
static |
Definition at line 254 of file sha256.cpp.
254 {
255 assert(hashing::sha256::extract_byte<uint32_t>(512, 0) == 0);
256 assert(hashing::sha256::extract_byte<uint32_t>(512, 1) == 2);
257 bool exception = false;
258 try {
259 hashing::sha256::extract_byte<uint32_t>(512, 5);
260 } catch (const std::out_of_range &) {
261 exception = true;
262 }
263 assert(exception);
264}
◆ test_get_char()
static void test_get_char |
( |
| ) |
|
|
static |
Definition at line 266 of file sha256.cpp.
266 {
267 assert(hashing::sha256::get_char("test", 3) == 't');
268 assert(hashing::sha256::get_char("test", 4) == '\x80');
269 assert(hashing::sha256::get_char("test", 5) == '\x00');
270 assert(hashing::sha256::get_char("test", 63) == 32);
271 bool exception = false;
272 try {
274 } catch (const std::out_of_range &) {
275 exception = true;
276 }
277 assert(exception);
278}
◆ test_right_rotate()
static void test_right_rotate |
( |
| ) |
|
|
static |
Definition at line 280 of file sha256.cpp.
280 {
281 assert(hashing::sha256::right_rotate(128, 3) == 16);
282 assert(hashing::sha256::right_rotate(1, 30) == 4);
283 assert(hashing::sha256::right_rotate(6, 30) == 24);
284}
◆ test_sha256()
static void test_sha256 |
( |
| ) |
|
|
static |
Definition at line 286 of file sha256.cpp.
286 {
288 const std::string input;
289 const std::string expected_hash;
290 TestCase(std::string input, std::string expected_hash)
291 : input(std::move(input)),
292 expected_hash(std::move(expected_hash)) {}
293 };
294 const std::vector<TestCase> test_cases{
296 "",
297 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"),
299 "test",
300 "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"),
302 "Hello World",
303 "a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e"),
305 "7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9"
306 "069")};
307 for (const auto &tc : test_cases) {
308 assert(hashing::sha256::sha256(tc.input) == tc.expected_hash);
309 }
310}
represents single example inputs and expected output of the function longest_common_string_length