Algorithms_in_C++ 1.0.0
Set of algorithms implemented in C++.
Loading...
Searching...
No Matches
sha256.cpp File Reference

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>
Include dependency graph for sha256.cpp:

Classes

class  hashing::sha256::Hash
 Contains hash array and functions to update it and convert it to a hexadecimal string. More...
 

Namespaces

namespace  hashing
 Hashing algorithms.
 
namespace  SHA
 Functions for the SHA-1 algorithm implementation.
 

Functions

uint32_t hashing::sha256::right_rotate (uint32_t n, size_t rotate)
 Rotates the bits of a 32-bit unsigned integer.
 
std::size_t hashing::sha256::compute_padded_size (const std::size_t input_size)
 Computes size of the padded input.
 
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.
 
char hashing::sha256::get_char (const std::string &input, std::size_t pos)
 Returns the character at pos after the input is padded.
 
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.
 
std::string hashing::sha256::sha256 (const std::string &input)
 Computes the final hash value.
 
static void test_compute_padded_size ()
 Self-test implementations.
 
static void test_extract_byte ()
 
static void test_get_char ()
 
static void test_right_rotate ()
 
static void test_sha256 ()
 
static void test ()
 
int main ()
 Main function.
 

Detailed Description

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.

Function Documentation

◆ compute_padded_size()

std::size_t hashing::sha256::compute_padded_size ( const std::size_t input_size)

Computes size of the padded input.

Parameters
inputInput string
Returns
size_t Size of the padded input
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}
Here is the call graph for this function:

◆ 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
inputInput string
byte_numPosition of the first byte of the chunk
Returns
std::array<uint32_t, 64> Message schedule array
196 {
198
199 // Copy chunk into first 16 words of the message schedule array
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 // Extend the first 16 words into remaining 48 words of the message schedule
212 // array
213 for (size_t block_num = 16; block_num < 64; ++block_num) {
214 const auto s0 = right_rotate(blocks[block_num - 15], 7) ^
215 right_rotate(blocks[block_num - 15], 18) ^
216 (blocks[block_num - 15] >> 3);
217 const auto s1 = right_rotate(blocks[block_num - 2], 17) ^
218 right_rotate(blocks[block_num - 2], 19) ^
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.
Definition sha256.cpp:170
uint32_t right_rotate(uint32_t n, size_t rotate)
Rotates the bits of a 32-bit unsigned integer.
Definition sha256.cpp:58
Here is the call graph for this function:

◆ 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_valueInput value
byte_numPosition of byte to be returned
Returns
uint8_t Byte at position byte_num
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}
Here is the call graph for this function:

◆ 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
inputInput string
posPosition of character to be returned
Returns
char Character at the index pos in the padded string
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 }
178 const auto padded_input_size = compute_padded_size(input_size);
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.
Definition sha256.cpp:143
T length(T... args)
Here is the call graph for this function:

◆ main()

int main ( void )

Main function.

Returns
0 on exit
326 {
327 test(); // Run self-test implementations
328 return 0;
329}
void test()
Definition caesar_cipher.cpp:100
Here is the call graph for this function:

◆ right_rotate()

uint32_t hashing::sha256::right_rotate ( uint32_t n,
size_t rotate )

Rotates the bits of a 32-bit unsigned integer.

Parameters
nInteger to rotate
rotateNumber of bits to rotate
Returns
uint32_t The rotated integer
58 {
59 return (n >> rotate) | (n << (32 - rotate));
60}
T rotate(T... args)
Here is the call graph for this function:

◆ sha256()

std::string hashing::sha256::sha256 ( const std::string & input)

Computes the final hash value.

Parameters
inputInput string
Returns
std::string The final hash value
232 {
233 Hash h;
234 // Process message in successive 512-bit (64-byte) chunks
235 for (size_t byte_num = 0; byte_num < compute_padded_size(input.length());
236 byte_num += 64) {
237 h.update(create_message_schedule_array(input, byte_num));
238 }
239 return h.to_string();
240}
int h(int key)
Definition hash_search.cpp:45
std::array< uint32_t, 64 > create_message_schedule_array(const std::string &input, const size_t byte_num)
Creates the message schedule array.
Definition sha256.cpp:195
Here is the call graph for this function:

◆ test()

static void test ( )
static
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.
Definition sha256.cpp:248

◆ test_compute_padded_size()

static void test_compute_padded_size ( )
static

Self-test implementations.

Returns
void
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
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
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 {
273 hashing::sha256::get_char("test", 64);
274 } catch (const std::out_of_range &) {
275 exception = true;
276 }
277 assert(exception);
278}

◆ test_right_rotate()

static void test_right_rotate ( )
static
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
286 {
287 struct TestCase {
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{
295 TestCase(
296 "",
297 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"),
298 TestCase(
299 "test",
300 "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"),
301 TestCase(
302 "Hello World",
303 "a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e"),
304 TestCase("Hello World!",
305 "7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9"
306 "069")};
307 for (const auto &tc : test_cases) {
308 assert(hashing::sha256::sha256(tc.input) == tc.expected_hash);
309 }
310}
T move(T... args)
STL namespace.
represents single example inputs and expected output of the function longest_common_string_length
Definition longest_common_string.cpp:54