2525
2626#include < cassert> // / For assert
2727#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
2929#include < iostream> // / For managing io
3030#include < sstream> // / For bytes to hex string
3131#include < string> // / For string data
@@ -45,70 +45,10 @@ namespace hashing {
4545class RIPEMD160 {
4646 private:
4747 /* *
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
11252 */
11353 uint32_t f (int j, uint32_t B, uint32_t C, uint32_t D) {
11454 switch (j) {
@@ -126,9 +66,9 @@ class RIPEMD160 {
12666 }
12767
12868 /* *
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
13272 */
13373 uint32_t K (int j) {
13474 switch (j) {
@@ -146,9 +86,9 @@ class RIPEMD160 {
14686 }
14787
14888 /* *
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
15292 */
15393 uint32_t K_dash (int j) {
15494 switch (j) {
@@ -165,34 +105,128 @@ class RIPEMD160 {
165105 }
166106 }
167107
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+ */
168116 static constexpr int r[80 ] = {
169117 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ,
170118 7 , 4 , 13 , 1 , 10 , 6 , 15 , 3 , 12 , 0 , 9 , 5 , 2 , 14 , 11 , 8 ,
171119 3 , 10 , 14 , 4 , 9 , 15 , 8 , 1 , 2 , 7 , 0 , 6 , 13 , 11 , 5 , 12 ,
172120 1 , 9 , 11 , 10 , 0 , 8 , 12 , 4 , 13 , 3 , 7 , 15 , 14 , 5 , 6 , 2 ,
173121 4 , 0 , 5 , 9 , 7 , 12 , 2 , 10 , 14 , 1 , 3 , 8 , 11 , 6 , 15 , 13 };
174122
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+ */
175131 static constexpr int r_dash[80 ] = {
176132 5 , 14 , 7 , 0 , 9 , 2 , 11 , 4 , 13 , 6 , 15 , 8 , 1 , 10 , 3 , 12 ,
177133 6 , 11 , 3 , 7 , 0 , 13 , 5 , 10 , 14 , 15 , 8 , 12 , 4 , 9 , 1 , 2 ,
178134 15 , 5 , 1 , 3 , 7 , 14 , 6 , 9 , 11 , 8 , 12 , 2 , 10 , 0 , 4 , 13 ,
179135 8 , 6 , 4 , 1 , 3 , 11 , 15 , 0 , 5 , 12 , 2 , 13 , 9 , 7 , 10 , 14 ,
180136 12 , 15 , 10 , 4 , 1 , 5 , 8 , 7 , 6 , 2 , 13 , 14 , 0 , 3 , 9 , 11 };
181137
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+ */
182147 static constexpr int s[80 ] = {
183148 11 , 14 , 15 , 12 , 5 , 8 , 7 , 9 , 11 , 13 , 14 , 15 , 6 , 7 , 9 , 8 ,
184149 7 , 6 , 8 , 13 , 11 , 9 , 7 , 15 , 7 , 12 , 15 , 9 , 11 , 7 , 13 , 12 ,
185150 11 , 13 , 6 , 7 , 14 , 9 , 13 , 15 , 14 , 8 , 13 , 6 , 5 , 12 , 7 , 5 ,
186151 11 , 12 , 14 , 15 , 14 , 15 , 9 , 8 , 9 , 14 , 5 , 6 , 8 , 6 , 5 , 12 ,
187152 9 , 15 , 5 , 11 , 6 , 8 , 13 , 12 , 5 , 12 , 13 , 14 , 11 , 8 , 5 , 6 };
188153
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+ */
189163 static constexpr int s_dash[80 ] = {
190164 8 , 9 , 9 , 11 , 13 , 15 , 15 , 5 , 7 , 7 , 8 , 11 , 14 , 14 , 12 , 6 ,
191165 9 , 13 , 15 , 7 , 12 , 8 , 9 , 11 , 7 , 7 , 12 , 7 , 6 , 15 , 13 , 11 ,
192166 9 , 7 , 15 , 11 , 8 , 6 , 6 , 14 , 12 , 13 , 5 , 14 , 13 , 13 , 7 , 5 ,
193167 15 , 5 , 8 , 11 , 14 , 14 , 6 , 14 , 6 , 9 , 12 , 9 , 12 , 5 , 15 , 8 ,
194168 8 , 5 , 12 , 9 , 12 , 5 , 14 , 6 , 8 , 13 , 6 , 5 , 15 , 13 , 11 , 11 };
195169
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+
196230 /* *
197231 * @brief cyclic left shift of uint32_t
198232 * @param value value to be shifted
@@ -395,6 +429,6 @@ static void test() {
395429 * @return 0 on exit
396430 */
397431int main () {
398- test (); // run self test implementation
432+ test (); // run self test implementation
399433 return 0 ;
400434}
0 commit comments