1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis 2 * 3 * LibTomCrypt is a library that provides various cryptographic 4 * algorithms in a highly modular and flexible manner. 5 * 6 * The library is free for all purposes without any express 7 * guarantee it works. 8 * 9 * Tom St Denis, tomstdenis (at) gmail.com, http://libtomcrypt.com 10 */ 11 #include "tomcrypt.h" 12 13 /** 14 @param rmd128.c 15 RMD128 Hash function 16 */ 17 18 /* Implementation of RIPEMD-128 based on the source by Antoon Bosselaers, ESAT-COSIC 19 * 20 * This source has been radically overhauled to be portable and work within 21 * the LibTomCrypt API by Tom St Denis 22 */ 23 24 #ifdef RIPEMD128 25 26 const struct ltc_hash_descriptor rmd128_desc = 27 { 28 "rmd128", 29 8, 30 16, 31 64, 32 33 /* OID */ 34 { 1, 0, 10118, 3, 0, 50 }, 35 6, 36 37 &rmd128_init, 38 &rmd128_process, 39 &rmd128_done, 40 &rmd128_test, 41 NULL 42 }; 43 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))) 49 50 /* the eight basic operations FF() through III() */ 51 #define FF(a, b, c, d, x, s) \ 52 (a) += F((b), (c), (d)) + (x);\ 53 (a) = ROLc((a), (s)); 54 55 #define GG(a, b, c, d, x, s) \ 56 (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ 57 (a) = ROLc((a), (s)); 58 59 #define HH(a, b, c, d, x, s) \ 60 (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ 61 (a) = ROLc((a), (s)); 62 63 #define II(a, b, c, d, x, s) \ 64 (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ 65 (a) = ROLc((a), (s)); 66 67 #define FFF(a, b, c, d, x, s) \ 68 (a) += F((b), (c), (d)) + (x);\ 69 (a) = ROLc((a), (s)); 70 71 #define GGG(a, b, c, d, x, s) \ 72 (a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\ 73 (a) = ROLc((a), (s)); 74 75 #define HHH(a, b, c, d, x, s) \ 76 (a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\ 77 (a) = ROLc((a), (s)); 78 79 #define III(a, b, c, d, x, s) \ 80 (a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\ 81 (a) = ROLc((a), (s)); 82 83 #ifdef LTC_CLEAN_STACK 84 static int _rmd128_compress(hash_state *md, unsigned char *buf) 85 #else 86 static int rmd128_compress(hash_state *md, unsigned char *buf) 87 #endif 88 { 89 ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,X[16]; 90 int i; 91 92 /* load words X */ 93 for (i = 0; i < 16; i++){ 94 LOAD32L(X[i], buf + (4 * i)); 95 } 96 97 /* load state */ 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]; 102 103 /* round 1 */ 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); 120 121 /* round 2 */ 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); 138 139 /* round 3 */ 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); 156 157 /* round 4 */ 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); 174 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); 192 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); 210 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); 228 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); 246 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; 253 254 return CRYPT_OK; 255 } 256 257 #ifdef LTC_CLEAN_STACK 258 static int rmd128_compress(hash_state *md, unsigned char *buf) 259 { 260 int err; 261 err = _rmd128_compress(md, buf); 262 burn_stack(sizeof(ulong32) * 24 + sizeof(int)); 263 return err; 264 } 265 #endif 266 267 /** 268 Initialize the hash state 269 @param md The hash state you wish to initialize 270 @return CRYPT_OK if successful 271 */ 272 int rmd128_init(hash_state * md) 273 { 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; 281 return CRYPT_OK; 282 } 283 284 /** 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 290 */ 291 HASH_PROCESS(rmd128_process, rmd128_compress, rmd128, 64) 292 293 /** 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 298 */ 299 int rmd128_done(hash_state * md, unsigned char *out) 300 { 301 int i; 302 303 LTC_ARGCHK(md != NULL); 304 LTC_ARGCHK(out != NULL); 305 306 if (md->rmd128.curlen >= sizeof(md->rmd128.buf)) { 307 return CRYPT_INVALID_ARG; 308 } 309 310 311 /* increase the length of the message */ 312 md->rmd128.length += md->rmd128.curlen * 8; 313 314 /* append the '1' bit */ 315 md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0x80; 316 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. 320 */ 321 if (md->rmd128.curlen > 56) { 322 while (md->rmd128.curlen < 64) { 323 md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0; 324 } 325 rmd128_compress(md, md->rmd128.buf); 326 md->rmd128.curlen = 0; 327 } 328 329 /* pad upto 56 bytes of zeroes */ 330 while (md->rmd128.curlen < 56) { 331 md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0; 332 } 333 334 /* store length */ 335 STORE64L(md->rmd128.length, md->rmd128.buf+56); 336 rmd128_compress(md, md->rmd128.buf); 337 338 /* copy output */ 339 for (i = 0; i < 4; i++) { 340 STORE32L(md->rmd128.state[i], out+(4*i)); 341 } 342 #ifdef LTC_CLEAN_STACK 343 zeromem(md, sizeof(hash_state)); 344 #endif 345 return CRYPT_OK; 346 } 347 348 /** 349 Self-test the hash 350 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled 351 */ 352 int rmd128_test(void) 353 { 354 #ifndef LTC_TEST 355 return CRYPT_NOP; 356 #else 357 static const struct { 358 char *msg; 359 unsigned char md[16]; 360 } tests[] = { 361 { "", 362 { 0xcd, 0xf2, 0x62, 0x13, 0xa1, 0x50, 0xdc, 0x3e, 363 0xcb, 0x61, 0x0f, 0x18, 0xf6, 0xb3, 0x8b, 0x46 } 364 }, 365 { "a", 366 { 0x86, 0xbe, 0x7a, 0xfa, 0x33, 0x9d, 0x0f, 0xc7, 367 0xcf, 0xc7, 0x85, 0xe7, 0x2f, 0x57, 0x8d, 0x33 } 368 }, 369 { "abc", 370 { 0xc1, 0x4a, 0x12, 0x19, 0x9c, 0x66, 0xe4, 0xba, 371 0x84, 0x63, 0x6b, 0x0f, 0x69, 0x14, 0x4c, 0x77 } 372 }, 373 { "message digest", 374 { 0x9e, 0x32, 0x7b, 0x3d, 0x6e, 0x52, 0x30, 0x62, 375 0xaf, 0xc1, 0x13, 0x2d, 0x7d, 0xf9, 0xd1, 0xb8 } 376 }, 377 { "abcdefghijklmnopqrstuvwxyz", 378 { 0xfd, 0x2a, 0xa6, 0x07, 0xf7, 0x1d, 0xc8, 0xf5, 379 0x10, 0x71, 0x49, 0x22, 0xb3, 0x71, 0x83, 0x4e } 380 }, 381 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 382 { 0xd1, 0xe9, 0x59, 0xeb, 0x17, 0x9c, 0x91, 0x1f, 383 0xae, 0xa4, 0x62, 0x4c, 0x60, 0xc5, 0xc7, 0x02 } 384 } 385 }; 386 int x; 387 unsigned char buf[16]; 388 hash_state md; 389 390 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { 391 rmd128_init(&md); 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) { 395 #if 0 396 printf("Failed test %d\n", x); 397 #endif 398 return CRYPT_FAIL_TESTVECTOR; 399 } 400 } 401 return CRYPT_OK; 402 #endif 403 } 404 405 #endif 406 407 408 /* $Source: /cvs/libtom/libtomcrypt/src/hashes/rmd128.c,v $ */ 409 /* $Revision: 1.9 $ */ 410 /* $Date: 2006/11/01 09:28:17 $ */ 411