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
18 /* Implementation of RIPEMD-128 based on the source by Antoon Bosselaers, ESAT-COSIC
20 * This source has been radically overhauled to be portable and work within
21 * the LibTomCrypt API by Tom St Denis
26 const struct ltc_hash_descriptor rmd128_desc
=
34 { 1, 0, 10118, 3, 0, 50 },
44 /* the four basic functions F(), G() and H() */
45 #define F(x, y, z) ((x) ^ (y) ^ (z))
46 #define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
47 #define H(x, y, z) (((x) | ~(y)) ^ (z))
48 #define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
50 /* the eight basic operations FF() through III() */
51 #define FF(a, b, c, d, x, s) \
52 (a) += F((b), (c), (d)) + (x);\
55 #define GG(a, b, c, d, x, s) \
56 (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
59 #define HH(a, b, c, d, x, s) \
60 (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
63 #define II(a, b, c, d, x, s) \
64 (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
67 #define FFF(a, b, c, d, x, s) \
68 (a) += F((b), (c), (d)) + (x);\
71 #define GGG(a, b, c, d, x, s) \
72 (a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\
75 #define HHH(a, b, c, d, x, s) \
76 (a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\
79 #define III(a, b, c, d, x, s) \
80 (a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\
83 #ifdef LTC_CLEAN_STACK
84 static int _rmd128_compress(hash_state
*md
, unsigned char *buf
)
86 static int rmd128_compress(hash_state
*md
, unsigned char *buf
)
89 ulong32 aa
,bb
,cc
,dd
,aaa
,bbb
,ccc
,ddd
,X
[16];
93 for (i
= 0; i
< 16; i
++){
94 LOAD32L(X
[i
], buf
+ (4 * i
));
98 aa
= aaa
= md
->rmd128
.state
[0];
99 bb
= bbb
= md
->rmd128
.state
[1];
100 cc
= ccc
= md
->rmd128
.state
[2];
101 dd
= ddd
= md
->rmd128
.state
[3];
104 FF(aa
, bb
, cc
, dd
, X
[ 0], 11);
105 FF(dd
, aa
, bb
, cc
, X
[ 1], 14);
106 FF(cc
, dd
, aa
, bb
, X
[ 2], 15);
107 FF(bb
, cc
, dd
, aa
, X
[ 3], 12);
108 FF(aa
, bb
, cc
, dd
, X
[ 4], 5);
109 FF(dd
, aa
, bb
, cc
, X
[ 5], 8);
110 FF(cc
, dd
, aa
, bb
, X
[ 6], 7);
111 FF(bb
, cc
, dd
, aa
, X
[ 7], 9);
112 FF(aa
, bb
, cc
, dd
, X
[ 8], 11);
113 FF(dd
, aa
, bb
, cc
, X
[ 9], 13);
114 FF(cc
, dd
, aa
, bb
, X
[10], 14);
115 FF(bb
, cc
, dd
, aa
, X
[11], 15);
116 FF(aa
, bb
, cc
, dd
, X
[12], 6);
117 FF(dd
, aa
, bb
, cc
, X
[13], 7);
118 FF(cc
, dd
, aa
, bb
, X
[14], 9);
119 FF(bb
, cc
, dd
, aa
, X
[15], 8);
122 GG(aa
, bb
, cc
, dd
, X
[ 7], 7);
123 GG(dd
, aa
, bb
, cc
, X
[ 4], 6);
124 GG(cc
, dd
, aa
, bb
, X
[13], 8);
125 GG(bb
, cc
, dd
, aa
, X
[ 1], 13);
126 GG(aa
, bb
, cc
, dd
, X
[10], 11);
127 GG(dd
, aa
, bb
, cc
, X
[ 6], 9);
128 GG(cc
, dd
, aa
, bb
, X
[15], 7);
129 GG(bb
, cc
, dd
, aa
, X
[ 3], 15);
130 GG(aa
, bb
, cc
, dd
, X
[12], 7);
131 GG(dd
, aa
, bb
, cc
, X
[ 0], 12);
132 GG(cc
, dd
, aa
, bb
, X
[ 9], 15);
133 GG(bb
, cc
, dd
, aa
, X
[ 5], 9);
134 GG(aa
, bb
, cc
, dd
, X
[ 2], 11);
135 GG(dd
, aa
, bb
, cc
, X
[14], 7);
136 GG(cc
, dd
, aa
, bb
, X
[11], 13);
137 GG(bb
, cc
, dd
, aa
, X
[ 8], 12);
140 HH(aa
, bb
, cc
, dd
, X
[ 3], 11);
141 HH(dd
, aa
, bb
, cc
, X
[10], 13);
142 HH(cc
, dd
, aa
, bb
, X
[14], 6);
143 HH(bb
, cc
, dd
, aa
, X
[ 4], 7);
144 HH(aa
, bb
, cc
, dd
, X
[ 9], 14);
145 HH(dd
, aa
, bb
, cc
, X
[15], 9);
146 HH(cc
, dd
, aa
, bb
, X
[ 8], 13);
147 HH(bb
, cc
, dd
, aa
, X
[ 1], 15);
148 HH(aa
, bb
, cc
, dd
, X
[ 2], 14);
149 HH(dd
, aa
, bb
, cc
, X
[ 7], 8);
150 HH(cc
, dd
, aa
, bb
, X
[ 0], 13);
151 HH(bb
, cc
, dd
, aa
, X
[ 6], 6);
152 HH(aa
, bb
, cc
, dd
, X
[13], 5);
153 HH(dd
, aa
, bb
, cc
, X
[11], 12);
154 HH(cc
, dd
, aa
, bb
, X
[ 5], 7);
155 HH(bb
, cc
, dd
, aa
, X
[12], 5);
158 II(aa
, bb
, cc
, dd
, X
[ 1], 11);
159 II(dd
, aa
, bb
, cc
, X
[ 9], 12);
160 II(cc
, dd
, aa
, bb
, X
[11], 14);
161 II(bb
, cc
, dd
, aa
, X
[10], 15);
162 II(aa
, bb
, cc
, dd
, X
[ 0], 14);
163 II(dd
, aa
, bb
, cc
, X
[ 8], 15);
164 II(cc
, dd
, aa
, bb
, X
[12], 9);
165 II(bb
, cc
, dd
, aa
, X
[ 4], 8);
166 II(aa
, bb
, cc
, dd
, X
[13], 9);
167 II(dd
, aa
, bb
, cc
, X
[ 3], 14);
168 II(cc
, dd
, aa
, bb
, X
[ 7], 5);
169 II(bb
, cc
, dd
, aa
, X
[15], 6);
170 II(aa
, bb
, cc
, dd
, X
[14], 8);
171 II(dd
, aa
, bb
, cc
, X
[ 5], 6);
172 II(cc
, dd
, aa
, bb
, X
[ 6], 5);
173 II(bb
, cc
, dd
, aa
, X
[ 2], 12);
175 /* parallel round 1 */
176 III(aaa
, bbb
, ccc
, ddd
, X
[ 5], 8);
177 III(ddd
, aaa
, bbb
, ccc
, X
[14], 9);
178 III(ccc
, ddd
, aaa
, bbb
, X
[ 7], 9);
179 III(bbb
, ccc
, ddd
, aaa
, X
[ 0], 11);
180 III(aaa
, bbb
, ccc
, ddd
, X
[ 9], 13);
181 III(ddd
, aaa
, bbb
, ccc
, X
[ 2], 15);
182 III(ccc
, ddd
, aaa
, bbb
, X
[11], 15);
183 III(bbb
, ccc
, ddd
, aaa
, X
[ 4], 5);
184 III(aaa
, bbb
, ccc
, ddd
, X
[13], 7);
185 III(ddd
, aaa
, bbb
, ccc
, X
[ 6], 7);
186 III(ccc
, ddd
, aaa
, bbb
, X
[15], 8);
187 III(bbb
, ccc
, ddd
, aaa
, X
[ 8], 11);
188 III(aaa
, bbb
, ccc
, ddd
, X
[ 1], 14);
189 III(ddd
, aaa
, bbb
, ccc
, X
[10], 14);
190 III(ccc
, ddd
, aaa
, bbb
, X
[ 3], 12);
191 III(bbb
, ccc
, ddd
, aaa
, X
[12], 6);
193 /* parallel round 2 */
194 HHH(aaa
, bbb
, ccc
, ddd
, X
[ 6], 9);
195 HHH(ddd
, aaa
, bbb
, ccc
, X
[11], 13);
196 HHH(ccc
, ddd
, aaa
, bbb
, X
[ 3], 15);
197 HHH(bbb
, ccc
, ddd
, aaa
, X
[ 7], 7);
198 HHH(aaa
, bbb
, ccc
, ddd
, X
[ 0], 12);
199 HHH(ddd
, aaa
, bbb
, ccc
, X
[13], 8);
200 HHH(ccc
, ddd
, aaa
, bbb
, X
[ 5], 9);
201 HHH(bbb
, ccc
, ddd
, aaa
, X
[10], 11);
202 HHH(aaa
, bbb
, ccc
, ddd
, X
[14], 7);
203 HHH(ddd
, aaa
, bbb
, ccc
, X
[15], 7);
204 HHH(ccc
, ddd
, aaa
, bbb
, X
[ 8], 12);
205 HHH(bbb
, ccc
, ddd
, aaa
, X
[12], 7);
206 HHH(aaa
, bbb
, ccc
, ddd
, X
[ 4], 6);
207 HHH(ddd
, aaa
, bbb
, ccc
, X
[ 9], 15);
208 HHH(ccc
, ddd
, aaa
, bbb
, X
[ 1], 13);
209 HHH(bbb
, ccc
, ddd
, aaa
, X
[ 2], 11);
211 /* parallel round 3 */
212 GGG(aaa
, bbb
, ccc
, ddd
, X
[15], 9);
213 GGG(ddd
, aaa
, bbb
, ccc
, X
[ 5], 7);
214 GGG(ccc
, ddd
, aaa
, bbb
, X
[ 1], 15);
215 GGG(bbb
, ccc
, ddd
, aaa
, X
[ 3], 11);
216 GGG(aaa
, bbb
, ccc
, ddd
, X
[ 7], 8);
217 GGG(ddd
, aaa
, bbb
, ccc
, X
[14], 6);
218 GGG(ccc
, ddd
, aaa
, bbb
, X
[ 6], 6);
219 GGG(bbb
, ccc
, ddd
, aaa
, X
[ 9], 14);
220 GGG(aaa
, bbb
, ccc
, ddd
, X
[11], 12);
221 GGG(ddd
, aaa
, bbb
, ccc
, X
[ 8], 13);
222 GGG(ccc
, ddd
, aaa
, bbb
, X
[12], 5);
223 GGG(bbb
, ccc
, ddd
, aaa
, X
[ 2], 14);
224 GGG(aaa
, bbb
, ccc
, ddd
, X
[10], 13);
225 GGG(ddd
, aaa
, bbb
, ccc
, X
[ 0], 13);
226 GGG(ccc
, ddd
, aaa
, bbb
, X
[ 4], 7);
227 GGG(bbb
, ccc
, ddd
, aaa
, X
[13], 5);
229 /* parallel round 4 */
230 FFF(aaa
, bbb
, ccc
, ddd
, X
[ 8], 15);
231 FFF(ddd
, aaa
, bbb
, ccc
, X
[ 6], 5);
232 FFF(ccc
, ddd
, aaa
, bbb
, X
[ 4], 8);
233 FFF(bbb
, ccc
, ddd
, aaa
, X
[ 1], 11);
234 FFF(aaa
, bbb
, ccc
, ddd
, X
[ 3], 14);
235 FFF(ddd
, aaa
, bbb
, ccc
, X
[11], 14);
236 FFF(ccc
, ddd
, aaa
, bbb
, X
[15], 6);
237 FFF(bbb
, ccc
, ddd
, aaa
, X
[ 0], 14);
238 FFF(aaa
, bbb
, ccc
, ddd
, X
[ 5], 6);
239 FFF(ddd
, aaa
, bbb
, ccc
, X
[12], 9);
240 FFF(ccc
, ddd
, aaa
, bbb
, X
[ 2], 12);
241 FFF(bbb
, ccc
, ddd
, aaa
, X
[13], 9);
242 FFF(aaa
, bbb
, ccc
, ddd
, X
[ 9], 12);
243 FFF(ddd
, aaa
, bbb
, ccc
, X
[ 7], 5);
244 FFF(ccc
, ddd
, aaa
, bbb
, X
[10], 15);
245 FFF(bbb
, ccc
, ddd
, aaa
, X
[14], 8);
247 /* combine results */
248 ddd
+= cc
+ md
->rmd128
.state
[1]; /* final result for MDbuf[0] */
249 md
->rmd128
.state
[1] = md
->rmd128
.state
[2] + dd
+ aaa
;
250 md
->rmd128
.state
[2] = md
->rmd128
.state
[3] + aa
+ bbb
;
251 md
->rmd128
.state
[3] = md
->rmd128
.state
[0] + bb
+ ccc
;
252 md
->rmd128
.state
[0] = ddd
;
257 #ifdef LTC_CLEAN_STACK
258 static int rmd128_compress(hash_state
*md
, unsigned char *buf
)
261 err
= _rmd128_compress(md
, buf
);
262 burn_stack(sizeof(ulong32
) * 24 + sizeof(int));
268 Initialize the hash state
269 @param md The hash state you wish to initialize
270 @return CRYPT_OK if successful
272 int rmd128_init(hash_state
* md
)
274 LTC_ARGCHK(md
!= NULL
);
275 md
->rmd128
.state
[0] = 0x67452301UL
;
276 md
->rmd128
.state
[1] = 0xefcdab89UL
;
277 md
->rmd128
.state
[2] = 0x98badcfeUL
;
278 md
->rmd128
.state
[3] = 0x10325476UL
;
279 md
->rmd128
.curlen
= 0;
280 md
->rmd128
.length
= 0;
285 Process a block of memory though the hash
286 @param md The hash state
287 @param in The data to hash
288 @param inlen The length of the data (octets)
289 @return CRYPT_OK if successful
291 HASH_PROCESS(rmd128_process
, rmd128_compress
, rmd128
, 64)
294 Terminate the hash to get the digest
295 @param md The hash state
296 @param out [out] The destination of the hash (16 bytes)
297 @return CRYPT_OK if successful
299 int rmd128_done(hash_state
* md
, unsigned char *out
)
303 LTC_ARGCHK(md
!= NULL
);
304 LTC_ARGCHK(out
!= NULL
);
306 if (md
->rmd128
.curlen
>= sizeof(md
->rmd128
.buf
)) {
307 return CRYPT_INVALID_ARG
;
311 /* increase the length of the message */
312 md
->rmd128
.length
+= md
->rmd128
.curlen
* 8;
314 /* append the '1' bit */
315 md
->rmd128
.buf
[md
->rmd128
.curlen
++] = (unsigned char)0x80;
317 /* if the length is currently above 56 bytes we append zeros
318 * then compress. Then we can fall back to padding zeros and length
319 * encoding like normal.
321 if (md
->rmd128
.curlen
> 56) {
322 while (md
->rmd128
.curlen
< 64) {
323 md
->rmd128
.buf
[md
->rmd128
.curlen
++] = (unsigned char)0;
325 rmd128_compress(md
, md
->rmd128
.buf
);
326 md
->rmd128
.curlen
= 0;
329 /* pad upto 56 bytes of zeroes */
330 while (md
->rmd128
.curlen
< 56) {
331 md
->rmd128
.buf
[md
->rmd128
.curlen
++] = (unsigned char)0;
335 STORE64L(md
->rmd128
.length
, md
->rmd128
.buf
+56);
336 rmd128_compress(md
, md
->rmd128
.buf
);
339 for (i
= 0; i
< 4; i
++) {
340 STORE32L(md
->rmd128
.state
[i
], out
+(4*i
));
342 #ifdef LTC_CLEAN_STACK
343 zeromem(md
, sizeof(hash_state
));
350 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
352 int rmd128_test(void)
357 static const struct {
359 unsigned char md
[16];
362 { 0xcd, 0xf2, 0x62, 0x13, 0xa1, 0x50, 0xdc, 0x3e,
363 0xcb, 0x61, 0x0f, 0x18, 0xf6, 0xb3, 0x8b, 0x46 }
366 { 0x86, 0xbe, 0x7a, 0xfa, 0x33, 0x9d, 0x0f, 0xc7,
367 0xcf, 0xc7, 0x85, 0xe7, 0x2f, 0x57, 0x8d, 0x33 }
370 { 0xc1, 0x4a, 0x12, 0x19, 0x9c, 0x66, 0xe4, 0xba,
371 0x84, 0x63, 0x6b, 0x0f, 0x69, 0x14, 0x4c, 0x77 }
374 { 0x9e, 0x32, 0x7b, 0x3d, 0x6e, 0x52, 0x30, 0x62,
375 0xaf, 0xc1, 0x13, 0x2d, 0x7d, 0xf9, 0xd1, 0xb8 }
377 { "abcdefghijklmnopqrstuvwxyz",
378 { 0xfd, 0x2a, 0xa6, 0x07, 0xf7, 0x1d, 0xc8, 0xf5,
379 0x10, 0x71, 0x49, 0x22, 0xb3, 0x71, 0x83, 0x4e }
381 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
382 { 0xd1, 0xe9, 0x59, 0xeb, 0x17, 0x9c, 0x91, 0x1f,
383 0xae, 0xa4, 0x62, 0x4c, 0x60, 0xc5, 0xc7, 0x02 }
387 unsigned char buf
[16];
390 for (x
= 0; x
< (int)(sizeof(tests
)/sizeof(tests
[0])); x
++) {
392 rmd128_process(&md
, (unsigned char *)tests
[x
].msg
, strlen(tests
[x
].msg
));
393 rmd128_done(&md
, buf
);
394 if (XMEMCMP(buf
, tests
[x
].md
, 16) != 0) {
396 printf("Failed test %d\n", x
);
398 return CRYPT_FAIL_TESTVECTOR
;
408 /* $Source: /cvs/libtom/libtomcrypt/src/hashes/rmd128.c,v $ */
409 /* $Revision: 1.9 $ */
410 /* $Date: 2006/11/01 09:28:17 $ */