@@ -32,27 +32,26 @@ namespace hashing {
32
32
*/
33
33
namespace sha256 {
34
34
/* *
35
- * @brief Pads the input string to be a multiple of 512-bits
35
+ * @brief Returns the character at pos after the input is padded
36
36
* @param input Input string
37
- * @return std::string The padded input string
37
+ * @param pos Position of character to be returned
38
+ * @param padded_input_size Size of the padded input
39
+ * @return char Character at the index pos in the padded string
38
40
*/
39
- std::string prepare_input (const std::string &input) {
40
- // Pre-processing
41
- std::string padded_input = input;
42
- uint64_t input_size = input.length () * 8 ; // Message length in bits
43
-
44
- // Append a single '1' bit
45
- padded_input += ' \x80 ' ;
46
-
47
- // Pad with zeros
48
- while ((padded_input.length () * 8 ) % 512 != 448 ) padded_input += ' \x00 ' ;
49
-
50
- // Append length of the original input string as a 64-bit big-endian integer
51
- for (uint32_t i = 64 ; i != 0 ; i -= 8 ) {
52
- padded_input += static_cast <char >((input_size >> (i - 8 )) & 0xFF );
53
- }
54
-
55
- return padded_input;
41
+ char get_char (const std::string input, std::size_t pos,
42
+ size_t padded_input_size) {
43
+ size_t input_size = input.length ();
44
+ char ch;
45
+ if (pos < input_size)
46
+ ch = input[pos];
47
+ else if (pos == input_size)
48
+ ch = ' \x80 ' ;
49
+ else if (pos < padded_input_size - 8 )
50
+ ch = ' \x00 ' ;
51
+ else
52
+ ch =
53
+ static_cast <char >((input_size * 8 >> (56 - (pos % 56 ) * 8 )) & 0xFF );
54
+ return ch;
56
55
}
57
56
58
57
/* *
@@ -70,7 +69,7 @@ uint32_t right_rotate(uint32_t n, size_t rotate) {
70
69
* @param padded_input Padded input string
71
70
* @return std::array<uint32_t, 8> The final hash array
72
71
*/
73
- std::array<uint32_t , 8 > compute_hash (const std::string &padded_input ) {
72
+ std::array<uint32_t , 8 > compute_hash (const std::string &input ) {
74
73
// Initialize array of hash values with first 32 bits of the fractional
75
74
// parts of the square roots of the first 8 primes 2..19
76
75
std::array<uint32_t , 8 > hash = {0x6A09E667 , 0xBB67AE85 , 0x3C6EF372 ,
@@ -92,17 +91,33 @@ std::array<uint32_t, 8> compute_hash(const std::string &padded_input) {
92
91
0x5B9CCA4F , 0x682E6FF3 , 0x748F82EE , 0x78A5636F , 0x84C87814 , 0x8CC70208 ,
93
92
0x90BEFFFA , 0xA4506CEB , 0xBEF9A3F7 , 0xC67178F2 };
94
93
94
+ size_t input_size = input.length (); // Input size in bytes
95
+
96
+ // Calculate size of the padded input in bytes
97
+ size_t padded_input_size = 0 ;
98
+ if (input_size % 64 < 56 ) {
99
+ padded_input_size = input_size + 64 - (input_size % 64 );
100
+ } else {
101
+ padded_input_size = input_size + 128 - (input_size % 64 );
102
+ }
103
+
95
104
// Process message in successive 512-bit (64-byte) chunks
96
- for (size_t i = 0 ; i < padded_input. length () ; i += 64 ) {
105
+ for (size_t i = 0 ; i < padded_input_size ; i += 64 ) {
97
106
std::array<uint32_t , 64 > blocks{};
98
107
99
108
// Copy chunk into first 16 words of the message schedule array
100
109
for (size_t j = 0 ; j < 16 ; ++j) {
101
- blocks[j] =
102
- (static_cast <uint8_t >(padded_input[i + j * 4 ]) << 24 ) |
103
- (static_cast <uint8_t >(padded_input[i + j * 4 + 1 ]) << 16 ) |
104
- (static_cast <uint8_t >(padded_input[i + j * 4 + 2 ]) << 8 ) |
105
- static_cast <uint8_t >(padded_input[i + j * 4 + 3 ]);
110
+ blocks[j] = (static_cast <uint8_t >(
111
+ get_char (input, i + j * 4 , padded_input_size))
112
+ << 24 ) |
113
+ (static_cast <uint8_t >(
114
+ get_char (input, i + j * 4 + 1 , padded_input_size))
115
+ << 16 ) |
116
+ (static_cast <uint8_t >(
117
+ get_char (input, i + j * 4 + 2 , padded_input_size))
118
+ << 8 ) |
119
+ static_cast <uint8_t >(
120
+ get_char (input, i + j * 4 + 3 , padded_input_size));
106
121
}
107
122
108
123
for (size_t j = 16 ; j < 64 ; ++j) {
@@ -185,9 +200,7 @@ std::string hash_to_string(const std::array<uint32_t, 8> &hash) {
185
200
* @return std::string The final hash value
186
201
*/
187
202
std::string sha256 (const std::string &input) {
188
- const std::string padded_input = prepare_input (input);
189
-
190
- std::array<uint32_t , 8 > hash = compute_hash (padded_input);
203
+ std::array<uint32_t , 8 > hash = compute_hash (input);
191
204
192
205
std::string result = hash_to_string (hash);
193
206
0 commit comments