TheAlgorithms/C++ 1.0.0
All the 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:

Go to the source code of this file.

Classes

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

Namespaces

namespace  hashing
 Used for assert.
 
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.

Definition in file sha256.cpp.

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

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
inputInput string
byte_numPosition 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 // 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

◆ 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

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
inputInput string
posPosition 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 }
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

◆ main()

int main ( void )

Main function.

Returns
0 on exit

Definition at line 326 of file sha256.cpp.

326 {
327 test(); // Run self-test implementations
328 return 0;
329}
void test()

◆ 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

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
inputInput string
Returns
std::string The final hash value

Definition at line 232 of file sha256.cpp.

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)
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

◆ test()

static void test ( )
static

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.
Definition sha256.cpp:248

◆ 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 {
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

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 {
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}
represents single example inputs and expected output of the function longest_common_string_length