25
25
26
26
#include < cassert> // / For assert
27
27
#include < cstdint> // / For data types such as std::int32_t, std::uint32_t, etc
28
- #include < iomanip> // / For functions like setw, setfill
28
+ #include < iomanip> // / For functions like std:: setw, std:: setfill
29
29
#include < iostream> // / For managing io
30
30
#include < sstream> // / For bytes to hex string
31
31
#include < string> // / For string data
@@ -45,70 +45,10 @@ namespace hashing {
45
45
class RIPEMD160 {
46
46
private:
47
47
/* *
48
- * @brief converts string data to vector of uint32_t (4 byte words)
49
- * @details converts the string to 4 byte words in little endian format
50
- * after adding padding and message length as specified in the algorithm
51
- * @param data data to be converted
52
- * @return vector of 4 byte words in little endian format
53
- */
54
- std::vector<uint32_t > string_to_word_data (std::string &data) {
55
- std::vector<uint32_t > word_data;
56
-
57
- // convert string data to 4 byte words in little endian format
58
- for (uint64_t i = 0 ; i < (data.size () / 4 ) * 4 ; i += 4 ) {
59
- word_data.push_back (static_cast <uint32_t >(data[i]) |
60
- (static_cast <uint32_t >(data[i + 1 ]) << 8 ) |
61
- (static_cast <uint32_t >(data[i + 2 ]) << 16 ) |
62
- (static_cast <uint32_t >(data[i + 3 ]) << 24 ));
63
- }
64
-
65
- // add padding to data
66
- int extra = data.size () % 4 ;
67
-
68
- switch (extra) {
69
- case 0 :
70
- word_data.push_back (0x00000080 );
71
- break ;
72
-
73
- case 1 :
74
- word_data.push_back (
75
- static_cast <uint32_t >(data[data.size () - 1 ]) | 0x00008000 );
76
- break ;
77
-
78
- case 2 :
79
- word_data.push_back (
80
- static_cast <uint32_t >(data[data.size () - 2 ]) |
81
- (static_cast <uint32_t >(data[data.size () - 1 ]) << 8 ) |
82
- 0x00800000 );
83
- break ;
84
-
85
- case 3 :
86
- word_data.push_back (
87
- static_cast <uint32_t >(data[data.size () - 3 ]) |
88
- (static_cast <uint32_t >(data[data.size () - 2 ]) << 8 ) |
89
- (static_cast <uint32_t >(data[data.size () - 1 ]) << 16 ) |
90
- 0x80000000 );
91
- break ;
92
- }
93
-
94
- while (word_data.size () % 16 != 14 ) {
95
- word_data.push_back (0x00000000 );
96
- }
97
-
98
- // add message length
99
- word_data.push_back ((static_cast <uint64_t >(data.size ()) << 3 ) &
100
- 0xffffffff );
101
- word_data.push_back ((static_cast <uint64_t >(data.size ()) >> 29 ) &
102
- 0xffffffff );
103
-
104
- return word_data;
105
- }
106
-
107
- /* *
108
- * @brief implements f(j,x,y,z)
109
- * @param j round number j / 16
110
- * @param B,C,D the state values
111
- * @return returns the function value
48
+ * @brief Implements f(j,x,y,z)
49
+ * @param j Round number j / 16
50
+ * @param B,C,D The state values
51
+ * @return Returns the function value
112
52
*/
113
53
uint32_t f (int j, uint32_t B, uint32_t C, uint32_t D) {
114
54
switch (j) {
@@ -126,9 +66,9 @@ class RIPEMD160 {
126
66
}
127
67
128
68
/* *
129
- * @brief implements K value for a given j
130
- * @param j round number j / 16
131
- * @return appropriate K value
69
+ * @brief Implements K value for a given j
70
+ * @param j Round number j / 16
71
+ * @return Appropriate K value
132
72
*/
133
73
uint32_t K (int j) {
134
74
switch (j) {
@@ -146,9 +86,9 @@ class RIPEMD160 {
146
86
}
147
87
148
88
/* *
149
- * @brief implements K' value for a given j
150
- * @param j round number j / 16
151
- * @return appropriate K' value
89
+ * @brief Implements K' value for a given j
90
+ * @param j Round number j / 16
91
+ * @return Appropriate K' value
152
92
*/
153
93
uint32_t K_dash (int j) {
154
94
switch (j) {
@@ -165,34 +105,128 @@ class RIPEMD160 {
165
105
}
166
106
}
167
107
108
+ /* *
109
+ * @brief Specifies r value for a given j.
110
+ *
111
+ * @details Specifies the order in which 4-byte words of the current
112
+ * 512-bits block are accessed and processed in each step of the compression
113
+ * function. Introduces non-linearity to the code. It is used by one of the
114
+ * parallel path.
115
+ */
168
116
static constexpr int r[80 ] = {
169
117
0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ,
170
118
7 , 4 , 13 , 1 , 10 , 6 , 15 , 3 , 12 , 0 , 9 , 5 , 2 , 14 , 11 , 8 ,
171
119
3 , 10 , 14 , 4 , 9 , 15 , 8 , 1 , 2 , 7 , 0 , 6 , 13 , 11 , 5 , 12 ,
172
120
1 , 9 , 11 , 10 , 0 , 8 , 12 , 4 , 13 , 3 , 7 , 15 , 14 , 5 , 6 , 2 ,
173
121
4 , 0 , 5 , 9 , 7 , 12 , 2 , 10 , 14 , 1 , 3 , 8 , 11 , 6 , 15 , 13 };
174
122
123
+ /* *
124
+ * @brief Specifies the r' value a given j.
125
+ *
126
+ * @details Specifies the order in which 4-byte words of the current
127
+ * 512-bits block are accessed and processed in each step of the compression
128
+ * function. Introduces non-linearity to the code. It is used in the other
129
+ * parallel path.
130
+ */
175
131
static constexpr int r_dash[80 ] = {
176
132
5 , 14 , 7 , 0 , 9 , 2 , 11 , 4 , 13 , 6 , 15 , 8 , 1 , 10 , 3 , 12 ,
177
133
6 , 11 , 3 , 7 , 0 , 13 , 5 , 10 , 14 , 15 , 8 , 12 , 4 , 9 , 1 , 2 ,
178
134
15 , 5 , 1 , 3 , 7 , 14 , 6 , 9 , 11 , 8 , 12 , 2 , 10 , 0 , 4 , 13 ,
179
135
8 , 6 , 4 , 1 , 3 , 11 , 15 , 0 , 5 , 12 , 2 , 13 , 9 , 7 , 10 , 14 ,
180
136
12 , 15 , 10 , 4 , 1 , 5 , 8 , 7 , 6 , 2 , 13 , 14 , 0 , 3 , 9 , 11 };
181
137
138
+ /* *
139
+ * @brief Specifies the s value for a given j.
140
+ *
141
+ * @details Determines the number of bits to cyclically shift (left rotate)
142
+ * the result of each step. The different shift values prevent patterns from
143
+ * emerging in the output, which is crucial for achieving properties like
144
+ * the avalanche effect (where a small change in the input results in a
145
+ * large change in the output). It is used by one of the parallel path.
146
+ */
182
147
static constexpr int s[80 ] = {
183
148
11 , 14 , 15 , 12 , 5 , 8 , 7 , 9 , 11 , 13 , 14 , 15 , 6 , 7 , 9 , 8 ,
184
149
7 , 6 , 8 , 13 , 11 , 9 , 7 , 15 , 7 , 12 , 15 , 9 , 11 , 7 , 13 , 12 ,
185
150
11 , 13 , 6 , 7 , 14 , 9 , 13 , 15 , 14 , 8 , 13 , 6 , 5 , 12 , 7 , 5 ,
186
151
11 , 12 , 14 , 15 , 14 , 15 , 9 , 8 , 9 , 14 , 5 , 6 , 8 , 6 , 5 , 12 ,
187
152
9 , 15 , 5 , 11 , 6 , 8 , 13 , 12 , 5 , 12 , 13 , 14 , 11 , 8 , 5 , 6 };
188
153
154
+ /* *
155
+ * @brief Specifies the s' value for a given j.
156
+ *
157
+ * @details Determines the number of bits to cyclically shift (left rotate)
158
+ * the result of each step. The different shift values prevent patterns from
159
+ * emerging in the output, which is crucial for achieving properties like
160
+ * the avalanche effect (where a small change in the input results in a
161
+ * large change in the output). It is used in the other parallel path.
162
+ */
189
163
static constexpr int s_dash[80 ] = {
190
164
8 , 9 , 9 , 11 , 13 , 15 , 15 , 5 , 7 , 7 , 8 , 11 , 14 , 14 , 12 , 6 ,
191
165
9 , 13 , 15 , 7 , 12 , 8 , 9 , 11 , 7 , 7 , 12 , 7 , 6 , 15 , 13 , 11 ,
192
166
9 , 7 , 15 , 11 , 8 , 6 , 6 , 14 , 12 , 13 , 5 , 14 , 13 , 13 , 7 , 5 ,
193
167
15 , 5 , 8 , 11 , 14 , 14 , 6 , 14 , 6 , 9 , 12 , 9 , 12 , 5 , 15 , 8 ,
194
168
8 , 5 , 12 , 9 , 12 , 5 , 14 , 6 , 8 , 13 , 6 , 5 , 15 , 13 , 11 , 11 };
195
169
170
+ /* *
171
+ * @brief converts string data to vector of uint32_t (4 byte words)
172
+ * @details converts the string to 4 byte words in little endian format
173
+ * after adding padding and message length as specified in the algorithm
174
+ * @param data data to be converted
175
+ * @return vector of 4 byte words in little endian format
176
+ */
177
+ std::vector<uint32_t > string_to_word_data (std::string &data) {
178
+ std::vector<uint32_t > word_data;
179
+
180
+ // convert string data to 4 byte words in little endian format
181
+ for (uint64_t i = 0 ; i < (data.size () / 4 ) * 4 ; i += 4 ) {
182
+ word_data.push_back (static_cast <uint32_t >(data[i]) |
183
+ (static_cast <uint32_t >(data[i + 1 ]) << 8 ) |
184
+ (static_cast <uint32_t >(data[i + 2 ]) << 16 ) |
185
+ (static_cast <uint32_t >(data[i + 3 ]) << 24 ));
186
+ }
187
+
188
+ // add padding to data
189
+ int extra = data.size () % 4 ;
190
+
191
+ switch (extra) {
192
+ case 0 :
193
+ word_data.push_back (0x00000080 );
194
+ break ;
195
+
196
+ case 1 :
197
+ word_data.push_back (
198
+ static_cast <uint32_t >(data[data.size () - 1 ]) | 0x00008000 );
199
+ break ;
200
+
201
+ case 2 :
202
+ word_data.push_back (
203
+ static_cast <uint32_t >(data[data.size () - 2 ]) |
204
+ (static_cast <uint32_t >(data[data.size () - 1 ]) << 8 ) |
205
+ 0x00800000 );
206
+ break ;
207
+
208
+ case 3 :
209
+ word_data.push_back (
210
+ static_cast <uint32_t >(data[data.size () - 3 ]) |
211
+ (static_cast <uint32_t >(data[data.size () - 2 ]) << 8 ) |
212
+ (static_cast <uint32_t >(data[data.size () - 1 ]) << 16 ) |
213
+ 0x80000000 );
214
+ break ;
215
+ }
216
+
217
+ while (word_data.size () % 16 != 14 ) {
218
+ word_data.push_back (0x00000000 );
219
+ }
220
+
221
+ // add message length
222
+ word_data.push_back ((static_cast <uint64_t >(data.size ()) << 3 ) &
223
+ 0xffffffff );
224
+ word_data.push_back ((static_cast <uint64_t >(data.size ()) >> 29 ) &
225
+ 0xffffffff );
226
+
227
+ return word_data;
228
+ }
229
+
196
230
/* *
197
231
* @brief cyclic left shift of uint32_t
198
232
* @param value value to be shifted
@@ -395,6 +429,6 @@ static void test() {
395
429
* @return 0 on exit
396
430
*/
397
431
int main () {
398
- test (); // run self test implementation
432
+ test (); // run self test implementation
399
433
return 0 ;
400
434
}
0 commit comments