1
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
3
* LibTomCrypt is a library that provides various cryptographic
4
* algorithms in a highly modular and flexible manner.
6
* The library is free for all purposes without any express
9
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com
20
const struct ltc_hash_descriptor rmd320_desc =
38
/* the five basic functions F(), G() and H() */
39
#define F(x, y, z) ((x) ^ (y) ^ (z))
40
#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
41
#define H(x, y, z) (((x) | ~(y)) ^ (z))
42
#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
43
#define J(x, y, z) ((x) ^ ((y) | ~(z)))
45
/* the ten basic operations FF() through III() */
46
#define FF(a, b, c, d, e, x, s) \
47
(a) += F((b), (c), (d)) + (x);\
48
(a) = ROLc((a), (s)) + (e);\
51
#define GG(a, b, c, d, e, x, s) \
52
(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
53
(a) = ROLc((a), (s)) + (e);\
56
#define HH(a, b, c, d, e, x, s) \
57
(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
58
(a) = ROLc((a), (s)) + (e);\
61
#define II(a, b, c, d, e, x, s) \
62
(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
63
(a) = ROLc((a), (s)) + (e);\
66
#define JJ(a, b, c, d, e, x, s) \
67
(a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
68
(a) = ROLc((a), (s)) + (e);\
71
#define FFF(a, b, c, d, e, x, s) \
72
(a) += F((b), (c), (d)) + (x);\
73
(a) = ROLc((a), (s)) + (e);\
76
#define GGG(a, b, c, d, e, x, s) \
77
(a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
78
(a) = ROLc((a), (s)) + (e);\
81
#define HHH(a, b, c, d, e, x, s) \
82
(a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
83
(a) = ROLc((a), (s)) + (e);\
86
#define III(a, b, c, d, e, x, s) \
87
(a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
88
(a) = ROLc((a), (s)) + (e);\
91
#define JJJ(a, b, c, d, e, x, s) \
92
(a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
93
(a) = ROLc((a), (s)) + (e);\
97
#ifdef LTC_CLEAN_STACK
98
static int _rmd320_compress(hash_state *md, unsigned char *buf)
100
static int rmd320_compress(hash_state *md, unsigned char *buf)
103
ulong32 aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,tmp,X[16];
107
for (i = 0; i < 16; i++){
108
LOAD32L(X[i], buf + (4 * i));
112
aa = md->rmd320.state[0];
113
bb = md->rmd320.state[1];
114
cc = md->rmd320.state[2];
115
dd = md->rmd320.state[3];
116
ee = md->rmd320.state[4];
117
aaa = md->rmd320.state[5];
118
bbb = md->rmd320.state[6];
119
ccc = md->rmd320.state[7];
120
ddd = md->rmd320.state[8];
121
eee = md->rmd320.state[9];
124
FF(aa, bb, cc, dd, ee, X[ 0], 11);
125
FF(ee, aa, bb, cc, dd, X[ 1], 14);
126
FF(dd, ee, aa, bb, cc, X[ 2], 15);
127
FF(cc, dd, ee, aa, bb, X[ 3], 12);
128
FF(bb, cc, dd, ee, aa, X[ 4], 5);
129
FF(aa, bb, cc, dd, ee, X[ 5], 8);
130
FF(ee, aa, bb, cc, dd, X[ 6], 7);
131
FF(dd, ee, aa, bb, cc, X[ 7], 9);
132
FF(cc, dd, ee, aa, bb, X[ 8], 11);
133
FF(bb, cc, dd, ee, aa, X[ 9], 13);
134
FF(aa, bb, cc, dd, ee, X[10], 14);
135
FF(ee, aa, bb, cc, dd, X[11], 15);
136
FF(dd, ee, aa, bb, cc, X[12], 6);
137
FF(cc, dd, ee, aa, bb, X[13], 7);
138
FF(bb, cc, dd, ee, aa, X[14], 9);
139
FF(aa, bb, cc, dd, ee, X[15], 8);
141
/* parallel round 1 */
142
JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
143
JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
144
JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
145
JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
146
JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
147
JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
148
JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
149
JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
150
JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
151
JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
152
JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
153
JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
154
JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
155
JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
156
JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
157
JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
159
tmp = aa; aa = aaa; aaa = tmp;
162
GG(ee, aa, bb, cc, dd, X[ 7], 7);
163
GG(dd, ee, aa, bb, cc, X[ 4], 6);
164
GG(cc, dd, ee, aa, bb, X[13], 8);
165
GG(bb, cc, dd, ee, aa, X[ 1], 13);
166
GG(aa, bb, cc, dd, ee, X[10], 11);
167
GG(ee, aa, bb, cc, dd, X[ 6], 9);
168
GG(dd, ee, aa, bb, cc, X[15], 7);
169
GG(cc, dd, ee, aa, bb, X[ 3], 15);
170
GG(bb, cc, dd, ee, aa, X[12], 7);
171
GG(aa, bb, cc, dd, ee, X[ 0], 12);
172
GG(ee, aa, bb, cc, dd, X[ 9], 15);
173
GG(dd, ee, aa, bb, cc, X[ 5], 9);
174
GG(cc, dd, ee, aa, bb, X[ 2], 11);
175
GG(bb, cc, dd, ee, aa, X[14], 7);
176
GG(aa, bb, cc, dd, ee, X[11], 13);
177
GG(ee, aa, bb, cc, dd, X[ 8], 12);
179
/* parallel round 2 */
180
III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
181
III(ddd, eee, aaa, bbb, ccc, X[11], 13);
182
III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
183
III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
184
III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
185
III(eee, aaa, bbb, ccc, ddd, X[13], 8);
186
III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
187
III(ccc, ddd, eee, aaa, bbb, X[10], 11);
188
III(bbb, ccc, ddd, eee, aaa, X[14], 7);
189
III(aaa, bbb, ccc, ddd, eee, X[15], 7);
190
III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
191
III(ddd, eee, aaa, bbb, ccc, X[12], 7);
192
III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
193
III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
194
III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
195
III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
197
tmp = bb; bb = bbb; bbb = tmp;
200
HH(dd, ee, aa, bb, cc, X[ 3], 11);
201
HH(cc, dd, ee, aa, bb, X[10], 13);
202
HH(bb, cc, dd, ee, aa, X[14], 6);
203
HH(aa, bb, cc, dd, ee, X[ 4], 7);
204
HH(ee, aa, bb, cc, dd, X[ 9], 14);
205
HH(dd, ee, aa, bb, cc, X[15], 9);
206
HH(cc, dd, ee, aa, bb, X[ 8], 13);
207
HH(bb, cc, dd, ee, aa, X[ 1], 15);
208
HH(aa, bb, cc, dd, ee, X[ 2], 14);
209
HH(ee, aa, bb, cc, dd, X[ 7], 8);
210
HH(dd, ee, aa, bb, cc, X[ 0], 13);
211
HH(cc, dd, ee, aa, bb, X[ 6], 6);
212
HH(bb, cc, dd, ee, aa, X[13], 5);
213
HH(aa, bb, cc, dd, ee, X[11], 12);
214
HH(ee, aa, bb, cc, dd, X[ 5], 7);
215
HH(dd, ee, aa, bb, cc, X[12], 5);
217
/* parallel round 3 */
218
HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
219
HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
220
HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
221
HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
222
HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
223
HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
224
HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
225
HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
226
HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
227
HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
228
HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
229
HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
230
HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
231
HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
232
HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
233
HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
235
tmp = cc; cc = ccc; ccc = tmp;
238
II(cc, dd, ee, aa, bb, X[ 1], 11);
239
II(bb, cc, dd, ee, aa, X[ 9], 12);
240
II(aa, bb, cc, dd, ee, X[11], 14);
241
II(ee, aa, bb, cc, dd, X[10], 15);
242
II(dd, ee, aa, bb, cc, X[ 0], 14);
243
II(cc, dd, ee, aa, bb, X[ 8], 15);
244
II(bb, cc, dd, ee, aa, X[12], 9);
245
II(aa, bb, cc, dd, ee, X[ 4], 8);
246
II(ee, aa, bb, cc, dd, X[13], 9);
247
II(dd, ee, aa, bb, cc, X[ 3], 14);
248
II(cc, dd, ee, aa, bb, X[ 7], 5);
249
II(bb, cc, dd, ee, aa, X[15], 6);
250
II(aa, bb, cc, dd, ee, X[14], 8);
251
II(ee, aa, bb, cc, dd, X[ 5], 6);
252
II(dd, ee, aa, bb, cc, X[ 6], 5);
253
II(cc, dd, ee, aa, bb, X[ 2], 12);
255
/* parallel round 4 */
256
GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
257
GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
258
GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
259
GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
260
GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
261
GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
262
GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
263
GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
264
GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
265
GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
266
GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
267
GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
268
GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
269
GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
270
GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
271
GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
273
tmp = dd; dd = ddd; ddd = tmp;
276
JJ(bb, cc, dd, ee, aa, X[ 4], 9);
277
JJ(aa, bb, cc, dd, ee, X[ 0], 15);
278
JJ(ee, aa, bb, cc, dd, X[ 5], 5);
279
JJ(dd, ee, aa, bb, cc, X[ 9], 11);
280
JJ(cc, dd, ee, aa, bb, X[ 7], 6);
281
JJ(bb, cc, dd, ee, aa, X[12], 8);
282
JJ(aa, bb, cc, dd, ee, X[ 2], 13);
283
JJ(ee, aa, bb, cc, dd, X[10], 12);
284
JJ(dd, ee, aa, bb, cc, X[14], 5);
285
JJ(cc, dd, ee, aa, bb, X[ 1], 12);
286
JJ(bb, cc, dd, ee, aa, X[ 3], 13);
287
JJ(aa, bb, cc, dd, ee, X[ 8], 14);
288
JJ(ee, aa, bb, cc, dd, X[11], 11);
289
JJ(dd, ee, aa, bb, cc, X[ 6], 8);
290
JJ(cc, dd, ee, aa, bb, X[15], 5);
291
JJ(bb, cc, dd, ee, aa, X[13], 6);
293
/* parallel round 5 */
294
FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
295
FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
296
FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
297
FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
298
FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
299
FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
300
FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
301
FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
302
FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
303
FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
304
FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
305
FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
306
FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
307
FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
308
FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
309
FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
311
tmp = ee; ee = eee; eee = tmp;
313
/* combine results */
314
md->rmd320.state[0] += aa;
315
md->rmd320.state[1] += bb;
316
md->rmd320.state[2] += cc;
317
md->rmd320.state[3] += dd;
318
md->rmd320.state[4] += ee;
319
md->rmd320.state[5] += aaa;
320
md->rmd320.state[6] += bbb;
321
md->rmd320.state[7] += ccc;
322
md->rmd320.state[8] += ddd;
323
md->rmd320.state[9] += eee;
328
#ifdef LTC_CLEAN_STACK
329
static int rmd320_compress(hash_state *md, unsigned char *buf)
332
err = _rmd320_compress(md, buf);
333
burn_stack(sizeof(ulong32) * 27 + sizeof(int));
339
Initialize the hash state
340
@param md The hash state you wish to initialize
341
@return CRYPT_OK if successful
343
int rmd320_init(hash_state * md)
345
LTC_ARGCHK(md != NULL);
346
md->rmd320.state[0] = 0x67452301UL;
347
md->rmd320.state[1] = 0xefcdab89UL;
348
md->rmd320.state[2] = 0x98badcfeUL;
349
md->rmd320.state[3] = 0x10325476UL;
350
md->rmd320.state[4] = 0xc3d2e1f0UL;
351
md->rmd320.state[5] = 0x76543210UL;
352
md->rmd320.state[6] = 0xfedcba98UL;
353
md->rmd320.state[7] = 0x89abcdefUL;
354
md->rmd320.state[8] = 0x01234567UL;
355
md->rmd320.state[9] = 0x3c2d1e0fUL;
356
md->rmd320.curlen = 0;
357
md->rmd320.length = 0;
362
Process a block of memory though the hash
363
@param md The hash state
364
@param in The data to hash
365
@param inlen The length of the data (octets)
366
@return CRYPT_OK if successful
368
HASH_PROCESS(rmd320_process, rmd320_compress, rmd320, 64)
371
Terminate the hash to get the digest
372
@param md The hash state
373
@param out [out] The destination of the hash (20 bytes)
374
@return CRYPT_OK if successful
376
int rmd320_done(hash_state * md, unsigned char *out)
380
LTC_ARGCHK(md != NULL);
381
LTC_ARGCHK(out != NULL);
383
if (md->rmd320.curlen >= sizeof(md->rmd320.buf)) {
384
return CRYPT_INVALID_ARG;
388
/* increase the length of the message */
389
md->rmd320.length += md->rmd320.curlen * 8;
391
/* append the '1' bit */
392
md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0x80;
394
/* if the length is currently above 56 bytes we append zeros
395
* then compress. Then we can fall back to padding zeros and length
396
* encoding like normal.
398
if (md->rmd320.curlen > 56) {
399
while (md->rmd320.curlen < 64) {
400
md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0;
402
rmd320_compress(md, md->rmd320.buf);
403
md->rmd320.curlen = 0;
406
/* pad upto 56 bytes of zeroes */
407
while (md->rmd320.curlen < 56) {
408
md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0;
412
STORE64L(md->rmd320.length, md->rmd320.buf+56);
413
rmd320_compress(md, md->rmd320.buf);
416
for (i = 0; i < 10; i++) {
417
STORE32L(md->rmd320.state[i], out+(4*i));
419
#ifdef LTC_CLEAN_STACK
420
zeromem(md, sizeof(hash_state));
427
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
429
int rmd320_test(void)
434
static const struct {
436
unsigned char md[40];
439
{ 0x22, 0xd6, 0x5d, 0x56, 0x61, 0x53, 0x6c, 0xdc, 0x75, 0xc1,
440
0xfd, 0xf5, 0xc6, 0xde, 0x7b, 0x41, 0xb9, 0xf2, 0x73, 0x25,
441
0xeb, 0xc6, 0x1e, 0x85, 0x57, 0x17, 0x7d, 0x70, 0x5a, 0x0e,
442
0xc8, 0x80, 0x15, 0x1c, 0x3a, 0x32, 0xa0, 0x08, 0x99, 0xb8 }
445
{ 0xce, 0x78, 0x85, 0x06, 0x38, 0xf9, 0x26, 0x58, 0xa5, 0xa5,
446
0x85, 0x09, 0x75, 0x79, 0x92, 0x6d, 0xda, 0x66, 0x7a, 0x57,
447
0x16, 0x56, 0x2c, 0xfc, 0xf6, 0xfb, 0xe7, 0x7f, 0x63, 0x54,
448
0x2f, 0x99, 0xb0, 0x47, 0x05, 0xd6, 0x97, 0x0d, 0xff, 0x5d }
451
{ 0xde, 0x4c, 0x01, 0xb3, 0x05, 0x4f, 0x89, 0x30, 0xa7, 0x9d,
452
0x09, 0xae, 0x73, 0x8e, 0x92, 0x30, 0x1e, 0x5a, 0x17, 0x08,
453
0x5b, 0xef, 0xfd, 0xc1, 0xb8, 0xd1, 0x16, 0x71, 0x3e, 0x74,
454
0xf8, 0x2f, 0xa9, 0x42, 0xd6, 0x4c, 0xdb, 0xc4, 0x68, 0x2d }
457
{ 0x3a, 0x8e, 0x28, 0x50, 0x2e, 0xd4, 0x5d, 0x42, 0x2f, 0x68,
458
0x84, 0x4f, 0x9d, 0xd3, 0x16, 0xe7, 0xb9, 0x85, 0x33, 0xfa,
459
0x3f, 0x2a, 0x91, 0xd2, 0x9f, 0x84, 0xd4, 0x25, 0xc8, 0x8d,
460
0x6b, 0x4e, 0xff, 0x72, 0x7d, 0xf6, 0x6a, 0x7c, 0x01, 0x97 }
462
{ "abcdefghijklmnopqrstuvwxyz",
463
{ 0xca, 0xbd, 0xb1, 0x81, 0x0b, 0x92, 0x47, 0x0a, 0x20, 0x93,
464
0xaa, 0x6b, 0xce, 0x05, 0x95, 0x2c, 0x28, 0x34, 0x8c, 0xf4,
465
0x3f, 0xf6, 0x08, 0x41, 0x97, 0x51, 0x66, 0xbb, 0x40, 0xed,
466
0x23, 0x40, 0x04, 0xb8, 0x82, 0x44, 0x63, 0xe6, 0xb0, 0x09 }
468
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
469
{ 0xd0, 0x34, 0xa7, 0x95, 0x0c, 0xf7, 0x22, 0x02, 0x1b, 0xa4,
470
0xb8, 0x4d, 0xf7, 0x69, 0xa5, 0xde, 0x20, 0x60, 0xe2, 0x59,
471
0xdf, 0x4c, 0x9b, 0xb4, 0xa4, 0x26, 0x8c, 0x0e, 0x93, 0x5b,
472
0xbc, 0x74, 0x70, 0xa9, 0x69, 0xc9, 0xd0, 0x72, 0xa1, 0xac }
476
unsigned char buf[40];
479
for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
481
rmd320_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg));
482
rmd320_done(&md, buf);
483
if (XMEMCMP(buf, tests[x].md, 40) != 0) {
485
printf("Failed test %d\n", x);
487
return CRYPT_FAIL_TESTVECTOR;