libxcks  0.1.0.1
rmd160.cpp
Go to the documentation of this file.
1 /*
2  * libxcks
3  * Copyright (C) 2022 Julien Couot
4  *
5  * This program is free software: you can redistribute it and/or modify it
6  * under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or (at your
8  * option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
13  * License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  */
18 
24 //---------------------------------------------------------------------------
25 #include <cstring>
26 
27 #include "rmd160.hpp"
28 //---------------------------------------------------------------------------
29 
31 using namespace std;
32 //---------------------------------------------------------------------------
33 
34 
35 namespace libxcks
36 {
37 // For doxygen
106 //---------------------------------------------------------------------------
107 
108 
109 /*
110  * Default constructor.
111  */
112 RIPEMD160::RIPEMD160()
113 {
114  reset();
115 }
116 //---------------------------------------------------------------------------
117 
118 
119 /*
120  * Resets the RIPE-MD160 hash to initial value.
121  */
122 void RIPEMD160::reset()
123 {
124  h0 = 0x67452301;
125  h1 = 0xEFCDAB89;
126  h2 = 0x98BADCFE;
127  h3 = 0x10325476;
128  h4 = 0xC3D2E1F0;
129  nblocks = 0;
130  count = 0;
131 }
132 //---------------------------------------------------------------------------
133 
134 
135 /*
136  * Process the remaining bytes in the internal buffer and the usual
137  * prolog according to the standard.
138  */
139 void RIPEMD160::finish()
140 {
141  uint32_t t, msb, lsb;
142  uint8_t *p;
143 
144  update(nullptr, 0); // flush
145 
146  t = nblocks;
147  // multiply by 64 to make a byte count
148  lsb = t << 6;
149  msb = t >> 26;
150  // add the count
151  t = lsb;
152  if ((lsb += count) < t)
153  msb++;
154  // multiply by 8 to make a bit count
155  t = lsb;
156  lsb <<= 3;
157  msb <<= 3;
158  msb |= t >> 29;
159 
160  if (count < 56) // enough room
161  {
162  ibuffer[count++] = 0x80; // pad
163  while (count < 56)
164  ibuffer[count++] = 0; // pad
165  }
166  else // need one extra block
167  {
168  ibuffer[count++] = 0x80; // pad character
169  while(count < 64)
170  ibuffer[count++] = 0;
171  update(nullptr, 0); // flush
172  memset(ibuffer, 0, 56); // fill next block with zeroes
173  }
174  // append the 64 bit count
175  ibuffer[56] = lsb ;
176  ibuffer[57] = lsb >> 8;
177  ibuffer[58] = lsb >> 16;
178  ibuffer[59] = lsb >> 24;
179  ibuffer[60] = msb ;
180  ibuffer[61] = msb >> 8;
181  ibuffer[62] = msb >> 16;
182  ibuffer[63] = msb >> 24;
183  transform(ibuffer);
184  //_gcry_burn_stack (108+5*sizeof(void*));
185 
186  p = ibuffer;
187  #if (LIBXCKS_BYTE_ORDER == LIBXCKS_BIG_ENDIAN)
188  #define X(a) do { *p++ = h##a ; *p++ = h##a >> 8; \
189  *p++ = h##a >> 16; *p++ = h##a >> 24; } while(0)
190  #else // little endian
191  #define X(a) do { *(uint32_t*)p = h##a ; p += 4; } while(0)
192  #endif
193  X(0);
194  X(1);
195  X(2);
196  X(3);
197  X(4);
198  #undef X
199 }
200 //---------------------------------------------------------------------------
201 
202 
203 /*
204  * Updates the RIPE-MD160 hash with specified array of bytes.
205  */
206 void RIPEMD160::update(const uint8_t* buf, size_t len)
207 {
208  if (count == 64) // flush the buffer
209  {
210  transform(ibuffer);
211  // _gcry_burn_stack (108+5*sizeof(void*));
212  count = 0;
213  nblocks++;
214  }
215  if (buf == nullptr)
216  return;
217 
218  if (count != 0)
219  {
220  for (; len && count < 64; len--)
221  ibuffer[count++] = *buf++;
222  update(nullptr, 0);
223  if (len == 0)
224  return;
225  }
226 
227  while (len >= 64)
228  {
229  uint8_t tmpBuf[sizeof(uint32_t) * 16];
230  memcpy(tmpBuf, buf, sizeof(uint32_t) * 16);
231  transform(tmpBuf);
232  count = 0;
233  nblocks++;
234  len -= 64;
235  buf += 64;
236  }
237  //_gcry_burn_stack (108+5*sizeof(void*));
238  for(; len && count < 64; len--)
239  ibuffer[count++] = *buf++;
240 }
241 //---------------------------------------------------------------------------
242 
243 
244 /*
245  * Transform the message X which consists of 16 32-bit-words.
246  */
247 void RIPEMD160::transform(uint8_t* data)
248 {
249  uint32_t a,b,c,d,e;
250  uint32_t aa,bb,cc,dd,ee,t;
251  uint32_t x[16];
252 
253  #if (LIBXCKS_BYTE_ORDER == LIBXCKS_BIG_ENDIAN)
254  {
255  int i;
256  uint8_t *p2, *p1;
257  for (i = 0, p1 = data, p2 = (uint8_t*)x; i < 16; i++, p2 += 4)
258  {
259  p2[3] = *p1++;
260  p2[2] = *p1++;
261  p2[1] = *p1++;
262  p2[0] = *p1++;
263  }
264  }
265  #else
266  /* This version is better because it is always aligned;
267  * The performance penalty on a 586-100 is about 6% which
268  * is acceptable - because the data is more local it might
269  * also be possible that this is faster on some machines.
270  * This function (when compiled with -02 on gcc 2.7.2)
271  * executes on a 586-100 (39.73 bogomips) at about 1900kb/sec;
272  * [measured with a 4MB data and "gpgm --print-md rmd160"] */
273  memcpy(x, data, 64);
274  #endif
275 
276 
277  #define K0 0x00000000
278  #define K1 0x5A827999
279  #define K2 0x6ED9EBA1
280  #define K3 0x8F1BBCDC
281  #define K4 0xA953FD4E
282  #define KK0 0x50A28BE6
283  #define KK1 0x5C4DD124
284  #define KK2 0x6D703EF3
285  #define KK3 0x7A6D76E9
286  #define KK4 0x00000000
287  #define F0(x,y,z) ( (x) ^ (y) ^ (z) )
288  #define F1(x,y,z) ( ((x) & (y)) | (~(x) & (z)) )
289  #define F2(x,y,z) ( ((x) | ~(y)) ^ (z) )
290  #define F3(x,y,z) ( ((x) & (z)) | ((y) & ~(z)) )
291  #define F4(x,y,z) ( (x) ^ ((y) | ~(z)) )
292  #define R(a,b,c,d,e,f,k,r,s) do { t = a + f(b,c,d) + k + x[r]; \
293  a = rol(t,s) + e; \
294  c = rol(c,10); \
295  } while(0)
296 
297  // left lane
298  a = h0;
299  b = h1;
300  c = h2;
301  d = h3;
302  e = h4;
303  R(a, b, c, d, e, F0, K0, 0, 11);
304  R(e, a, b, c, d, F0, K0, 1, 14);
305  R(d, e, a, b, c, F0, K0, 2, 15);
306  R(c, d, e, a, b, F0, K0, 3, 12);
307  R(b, c, d, e, a, F0, K0, 4, 5);
308  R(a, b, c, d, e, F0, K0, 5, 8);
309  R(e, a, b, c, d, F0, K0, 6, 7);
310  R(d, e, a, b, c, F0, K0, 7, 9);
311  R(c, d, e, a, b, F0, K0, 8, 11);
312  R(b, c, d, e, a, F0, K0, 9, 13);
313  R(a, b, c, d, e, F0, K0, 10, 14);
314  R(e, a, b, c, d, F0, K0, 11, 15);
315  R(d, e, a, b, c, F0, K0, 12, 6);
316  R(c, d, e, a, b, F0, K0, 13, 7);
317  R(b, c, d, e, a, F0, K0, 14, 9);
318  R(a, b, c, d, e, F0, K0, 15, 8);
319  R(e, a, b, c, d, F1, K1, 7, 7);
320  R(d, e, a, b, c, F1, K1, 4, 6);
321  R(c, d, e, a, b, F1, K1, 13, 8);
322  R(b, c, d, e, a, F1, K1, 1, 13);
323  R(a, b, c, d, e, F1, K1, 10, 11);
324  R(e, a, b, c, d, F1, K1, 6, 9);
325  R(d, e, a, b, c, F1, K1, 15, 7);
326  R(c, d, e, a, b, F1, K1, 3, 15);
327  R(b, c, d, e, a, F1, K1, 12, 7);
328  R(a, b, c, d, e, F1, K1, 0, 12);
329  R(e, a, b, c, d, F1, K1, 9, 15);
330  R(d, e, a, b, c, F1, K1, 5, 9);
331  R(c, d, e, a, b, F1, K1, 2, 11);
332  R(b, c, d, e, a, F1, K1, 14, 7);
333  R(a, b, c, d, e, F1, K1, 11, 13);
334  R(e, a, b, c, d, F1, K1, 8, 12);
335  R(d, e, a, b, c, F2, K2, 3, 11);
336  R(c, d, e, a, b, F2, K2, 10, 13);
337  R(b, c, d, e, a, F2, K2, 14, 6);
338  R(a, b, c, d, e, F2, K2, 4, 7);
339  R(e, a, b, c, d, F2, K2, 9, 14);
340  R(d, e, a, b, c, F2, K2, 15, 9);
341  R(c, d, e, a, b, F2, K2, 8, 13);
342  R(b, c, d, e, a, F2, K2, 1, 15);
343  R(a, b, c, d, e, F2, K2, 2, 14);
344  R(e, a, b, c, d, F2, K2, 7, 8);
345  R(d, e, a, b, c, F2, K2, 0, 13);
346  R(c, d, e, a, b, F2, K2, 6, 6);
347  R(b, c, d, e, a, F2, K2, 13, 5);
348  R(a, b, c, d, e, F2, K2, 11, 12);
349  R(e, a, b, c, d, F2, K2, 5, 7);
350  R(d, e, a, b, c, F2, K2, 12, 5);
351  R(c, d, e, a, b, F3, K3, 1, 11);
352  R(b, c, d, e, a, F3, K3, 9, 12);
353  R(a, b, c, d, e, F3, K3, 11, 14);
354  R(e, a, b, c, d, F3, K3, 10, 15);
355  R(d, e, a, b, c, F3, K3, 0, 14);
356  R(c, d, e, a, b, F3, K3, 8, 15);
357  R(b, c, d, e, a, F3, K3, 12, 9);
358  R(a, b, c, d, e, F3, K3, 4, 8);
359  R(e, a, b, c, d, F3, K3, 13, 9);
360  R(d, e, a, b, c, F3, K3, 3, 14);
361  R(c, d, e, a, b, F3, K3, 7, 5);
362  R(b, c, d, e, a, F3, K3, 15, 6);
363  R(a, b, c, d, e, F3, K3, 14, 8);
364  R(e, a, b, c, d, F3, K3, 5, 6);
365  R(d, e, a, b, c, F3, K3, 6, 5);
366  R(c, d, e, a, b, F3, K3, 2, 12);
367  R(b, c, d, e, a, F4, K4, 4, 9);
368  R(a, b, c, d, e, F4, K4, 0, 15);
369  R(e, a, b, c, d, F4, K4, 5, 5);
370  R(d, e, a, b, c, F4, K4, 9, 11);
371  R(c, d, e, a, b, F4, K4, 7, 6);
372  R(b, c, d, e, a, F4, K4, 12, 8);
373  R(a, b, c, d, e, F4, K4, 2, 13);
374  R(e, a, b, c, d, F4, K4, 10, 12);
375  R(d, e, a, b, c, F4, K4, 14, 5);
376  R(c, d, e, a, b, F4, K4, 1, 12);
377  R(b, c, d, e, a, F4, K4, 3, 13);
378  R(a, b, c, d, e, F4, K4, 8, 14);
379  R(e, a, b, c, d, F4, K4, 11, 11);
380  R(d, e, a, b, c, F4, K4, 6, 8);
381  R(c, d, e, a, b, F4, K4, 15, 5);
382  R(b, c, d, e, a, F4, K4, 13, 6);
383 
384  aa = a; bb = b; cc = c; dd = d; ee = e;
385 
386  /* right lane */
387  a = h0;
388  b = h1;
389  c = h2;
390  d = h3;
391  e = h4;
392  R(a, b, c, d, e, F4, KK0, 5, 8);
393  R(e, a, b, c, d, F4, KK0, 14, 9);
394  R(d, e, a, b, c, F4, KK0, 7, 9);
395  R(c, d, e, a, b, F4, KK0, 0, 11);
396  R(b, c, d, e, a, F4, KK0, 9, 13);
397  R(a, b, c, d, e, F4, KK0, 2, 15);
398  R(e, a, b, c, d, F4, KK0, 11, 15);
399  R(d, e, a, b, c, F4, KK0, 4, 5);
400  R(c, d, e, a, b, F4, KK0, 13, 7);
401  R(b, c, d, e, a, F4, KK0, 6, 7);
402  R(a, b, c, d, e, F4, KK0, 15, 8);
403  R(e, a, b, c, d, F4, KK0, 8, 11);
404  R(d, e, a, b, c, F4, KK0, 1, 14);
405  R(c, d, e, a, b, F4, KK0, 10, 14);
406  R(b, c, d, e, a, F4, KK0, 3, 12);
407  R(a, b, c, d, e, F4, KK0, 12, 6);
408  R(e, a, b, c, d, F3, KK1, 6, 9);
409  R(d, e, a, b, c, F3, KK1, 11, 13);
410  R(c, d, e, a, b, F3, KK1, 3, 15);
411  R(b, c, d, e, a, F3, KK1, 7, 7);
412  R(a, b, c, d, e, F3, KK1, 0, 12);
413  R(e, a, b, c, d, F3, KK1, 13, 8);
414  R(d, e, a, b, c, F3, KK1, 5, 9);
415  R(c, d, e, a, b, F3, KK1, 10, 11);
416  R(b, c, d, e, a, F3, KK1, 14, 7);
417  R(a, b, c, d, e, F3, KK1, 15, 7);
418  R(e, a, b, c, d, F3, KK1, 8, 12);
419  R(d, e, a, b, c, F3, KK1, 12, 7);
420  R(c, d, e, a, b, F3, KK1, 4, 6);
421  R(b, c, d, e, a, F3, KK1, 9, 15);
422  R(a, b, c, d, e, F3, KK1, 1, 13);
423  R(e, a, b, c, d, F3, KK1, 2, 11);
424  R(d, e, a, b, c, F2, KK2, 15, 9);
425  R(c, d, e, a, b, F2, KK2, 5, 7);
426  R(b, c, d, e, a, F2, KK2, 1, 15);
427  R(a, b, c, d, e, F2, KK2, 3, 11);
428  R(e, a, b, c, d, F2, KK2, 7, 8);
429  R(d, e, a, b, c, F2, KK2, 14, 6);
430  R(c, d, e, a, b, F2, KK2, 6, 6);
431  R(b, c, d, e, a, F2, KK2, 9, 14);
432  R(a, b, c, d, e, F2, KK2, 11, 12);
433  R(e, a, b, c, d, F2, KK2, 8, 13);
434  R(d, e, a, b, c, F2, KK2, 12, 5);
435  R(c, d, e, a, b, F2, KK2, 2, 14);
436  R(b, c, d, e, a, F2, KK2, 10, 13);
437  R(a, b, c, d, e, F2, KK2, 0, 13);
438  R(e, a, b, c, d, F2, KK2, 4, 7);
439  R(d, e, a, b, c, F2, KK2, 13, 5);
440  R(c, d, e, a, b, F1, KK3, 8, 15);
441  R(b, c, d, e, a, F1, KK3, 6, 5);
442  R(a, b, c, d, e, F1, KK3, 4, 8);
443  R(e, a, b, c, d, F1, KK3, 1, 11);
444  R(d, e, a, b, c, F1, KK3, 3, 14);
445  R(c, d, e, a, b, F1, KK3, 11, 14);
446  R(b, c, d, e, a, F1, KK3, 15, 6);
447  R(a, b, c, d, e, F1, KK3, 0, 14);
448  R(e, a, b, c, d, F1, KK3, 5, 6);
449  R(d, e, a, b, c, F1, KK3, 12, 9);
450  R(c, d, e, a, b, F1, KK3, 2, 12);
451  R(b, c, d, e, a, F1, KK3, 13, 9);
452  R(a, b, c, d, e, F1, KK3, 9, 12);
453  R(e, a, b, c, d, F1, KK3, 7, 5);
454  R(d, e, a, b, c, F1, KK3, 10, 15);
455  R(c, d, e, a, b, F1, KK3, 14, 8);
456  R(b, c, d, e, a, F0, KK4, 12, 8);
457  R(a, b, c, d, e, F0, KK4, 15, 5);
458  R(e, a, b, c, d, F0, KK4, 10, 12);
459  R(d, e, a, b, c, F0, KK4, 4, 9);
460  R(c, d, e, a, b, F0, KK4, 1, 12);
461  R(b, c, d, e, a, F0, KK4, 5, 5);
462  R(a, b, c, d, e, F0, KK4, 8, 14);
463  R(e, a, b, c, d, F0, KK4, 7, 6);
464  R(d, e, a, b, c, F0, KK4, 6, 8);
465  R(c, d, e, a, b, F0, KK4, 2, 13);
466  R(b, c, d, e, a, F0, KK4, 13, 6);
467  R(a, b, c, d, e, F0, KK4, 14, 5);
468  R(e, a, b, c, d, F0, KK4, 0, 15);
469  R(d, e, a, b, c, F0, KK4, 3, 13);
470  R(c, d, e, a, b, F0, KK4, 9, 11);
471  R(b, c, d, e, a, F0, KK4, 11, 11);
472 
473  t = h1 + d + cc;
474  h1 = h2 + e + dd;
475  h2 = h3 + a + ee;
476  h3 = h4 + b + aa;
477  h4 = h0 + c + bb;
478  h0 = t;
479 }
480 //---------------------------------------------------------------------------
481 
482 
483 /*
484  * Returns the RIPE-MD160 hash value in the first 20 bytes of the given address.
485  */
486 uint8_t* RIPEMD160::getValue(uint8_t* buffer) const
487 {
488  RIPEMD160 rmd160(*this);
489  rmd160.finish();
490 
491  memcpy(buffer, rmd160.ibuffer, getSize());
492 
493  return buffer;
494 }
495 //---------------------------------------------------------------------------
496 
497 
498 /*
499  * Returns the alternative names of the RIPE-MD160 hash algorithm.
500  */
501 ArrayString RIPEMD160::getAlternativeNames()
502 {
503  return ArrayString{ "RIPEMD-160" };
504 }
505 //---------------------------------------------------------------------------
506 } // namespace libxcks
507 //---------------------------------------------------------------------------
Computes the RIPE-MD160 hash from a byte stream.
Definition: rmd160.hpp:57
uint8_t ibuffer[64]
Input buffer.
Definition: rmd160.hpp:68
void finish()
Process the remaining bytes in the internal buffer and the usual prolog according to the standard.
Definition: rmd160.cpp:139
#define K0
Helper value for RIPE-MD160's computing.
#define F1(x, y, z)
Helper value for RIPE-MD160's computing.
#define KK2
Helper value for RIPE-MD160's computing.
#define R(a, b, c, d, e, f, k, r, s)
Helper value for RIPE-MD160's computing.
#define KK1
Helper value for RIPE-MD160's computing.
#define F4(x, y, z)
Helper value for RIPE-MD160's computing.
#define KK4
Helper value for RIPE-MD160's computing.
#define F3(x, y, z)
Helper value for RIPE-MD160's computing.
#define K3
Helper value for RIPE-MD160's computing.
#define K1
Helper value for RIPE-MD160's computing.
#define KK0
Helper value for RIPE-MD160's computing.
#define F0(x, y, z)
Helper value for RIPE-MD160's computing.
#define K4
Helper value for RIPE-MD160's computing.
#define KK3
Helper value for RIPE-MD160's computing.
#define K2
Helper value for RIPE-MD160's computing.
#define X(a)
Helper value for RIPE-MD160's computing.
#define F2(x, y, z)
Helper value for RIPE-MD160's computing.
Compute ripe-md160 hash.
std::vector< std::string > ArrayString
Array of strings.
Definition: types.hpp:44