Annotation of embedaddon/php/ext/hash/hash_ripemd.c, revision 1.1
1.1 ! misho 1: /*
! 2: +----------------------------------------------------------------------+
! 3: | PHP Version 5 |
! 4: +----------------------------------------------------------------------+
! 5: | Copyright (c) 1997-2012 The PHP Group |
! 6: +----------------------------------------------------------------------+
! 7: | This source file is subject to version 3.01 of the PHP license, |
! 8: | that is bundled with this package in the file LICENSE, and is |
! 9: | available through the world-wide-web at the following url: |
! 10: | http://www.php.net/license/3_01.txt |
! 11: | If you did not receive a copy of the PHP license and are unable to |
! 12: | obtain it through the world-wide-web, please send a note to |
! 13: | license@php.net so we can mail you a copy immediately. |
! 14: +----------------------------------------------------------------------+
! 15: | Author: Sara Golemon <pollita@php.net> |
! 16: +----------------------------------------------------------------------+
! 17: */
! 18:
! 19: /* $Id: hash_ripemd.c 321634 2012-01-01 13:15:04Z felipe $ */
! 20:
! 21: /* Heavily borrowed from md5.c & sha1.c of PHP archival fame
! 22: Note that ripemd laughs in the face of logic and uses
! 23: little endian byte ordering */
! 24:
! 25: #include "php_hash.h"
! 26: #include "php_hash_ripemd.h"
! 27:
! 28: const php_hash_ops php_hash_ripemd128_ops = {
! 29: (php_hash_init_func_t) PHP_RIPEMD128Init,
! 30: (php_hash_update_func_t) PHP_RIPEMD128Update,
! 31: (php_hash_final_func_t) PHP_RIPEMD128Final,
! 32: (php_hash_copy_func_t) php_hash_copy,
! 33: 16,
! 34: 64,
! 35: sizeof(PHP_RIPEMD128_CTX)
! 36: };
! 37:
! 38: const php_hash_ops php_hash_ripemd160_ops = {
! 39: (php_hash_init_func_t) PHP_RIPEMD160Init,
! 40: (php_hash_update_func_t) PHP_RIPEMD160Update,
! 41: (php_hash_final_func_t) PHP_RIPEMD160Final,
! 42: (php_hash_copy_func_t) php_hash_copy,
! 43: 20,
! 44: 64,
! 45: sizeof(PHP_RIPEMD160_CTX)
! 46: };
! 47:
! 48: const php_hash_ops php_hash_ripemd256_ops = {
! 49: (php_hash_init_func_t) PHP_RIPEMD256Init,
! 50: (php_hash_update_func_t) PHP_RIPEMD256Update,
! 51: (php_hash_final_func_t) PHP_RIPEMD256Final,
! 52: (php_hash_copy_func_t) php_hash_copy,
! 53: 32,
! 54: 64,
! 55: sizeof(PHP_RIPEMD256_CTX)
! 56: };
! 57:
! 58: const php_hash_ops php_hash_ripemd320_ops = {
! 59: (php_hash_init_func_t) PHP_RIPEMD320Init,
! 60: (php_hash_update_func_t) PHP_RIPEMD320Update,
! 61: (php_hash_final_func_t) PHP_RIPEMD320Final,
! 62: (php_hash_copy_func_t) php_hash_copy,
! 63: 40,
! 64: 64,
! 65: sizeof(PHP_RIPEMD320_CTX)
! 66: };
! 67:
! 68: /* {{{ PHP_RIPEMD128Init
! 69: * ripemd128 initialization. Begins a ripemd128 operation, writing a new context.
! 70: */
! 71: PHP_HASH_API void PHP_RIPEMD128Init(PHP_RIPEMD128_CTX * context)
! 72: {
! 73: context->count[0] = context->count[1] = 0;
! 74: /* Load magic initialization constants.
! 75: */
! 76: context->state[0] = 0x67452301;
! 77: context->state[1] = 0xEFCDAB89;
! 78: context->state[2] = 0x98BADCFE;
! 79: context->state[3] = 0x10325476;
! 80: }
! 81: /* }}} */
! 82:
! 83: /* {{{ PHP_RIPEMD256Init
! 84: * ripemd256 initialization. Begins a ripemd256 operation, writing a new context.
! 85: */
! 86: PHP_HASH_API void PHP_RIPEMD256Init(PHP_RIPEMD256_CTX * context)
! 87: {
! 88: context->count[0] = context->count[1] = 0;
! 89: /* Load magic initialization constants.
! 90: */
! 91: context->state[0] = 0x67452301;
! 92: context->state[1] = 0xEFCDAB89;
! 93: context->state[2] = 0x98BADCFE;
! 94: context->state[3] = 0x10325476;
! 95: context->state[4] = 0x76543210;
! 96: context->state[5] = 0xFEDCBA98;
! 97: context->state[6] = 0x89ABCDEF;
! 98: context->state[7] = 0x01234567;
! 99: }
! 100: /* }}} */
! 101:
! 102: /* {{{ PHP_RIPEMD160Init
! 103: * ripemd160 initialization. Begins a ripemd160 operation, writing a new context.
! 104: */
! 105: PHP_HASH_API void PHP_RIPEMD160Init(PHP_RIPEMD160_CTX * context)
! 106: {
! 107: context->count[0] = context->count[1] = 0;
! 108: /* Load magic initialization constants.
! 109: */
! 110: context->state[0] = 0x67452301;
! 111: context->state[1] = 0xEFCDAB89;
! 112: context->state[2] = 0x98BADCFE;
! 113: context->state[3] = 0x10325476;
! 114: context->state[4] = 0xC3D2E1F0;
! 115: }
! 116: /* }}} */
! 117:
! 118: /* {{{ PHP_RIPEMD320Init
! 119: * ripemd320 initialization. Begins a ripemd320 operation, writing a new context.
! 120: */
! 121: PHP_HASH_API void PHP_RIPEMD320Init(PHP_RIPEMD320_CTX * context)
! 122: {
! 123: context->count[0] = context->count[1] = 0;
! 124: /* Load magic initialization constants.
! 125: */
! 126: context->state[0] = 0x67452301;
! 127: context->state[1] = 0xEFCDAB89;
! 128: context->state[2] = 0x98BADCFE;
! 129: context->state[3] = 0x10325476;
! 130: context->state[4] = 0xC3D2E1F0;
! 131: context->state[5] = 0x76543210;
! 132: context->state[6] = 0xFEDCBA98;
! 133: context->state[7] = 0x89ABCDEF;
! 134: context->state[8] = 0x01234567;
! 135: context->state[9] = 0x3C2D1E0F;
! 136: }
! 137: /* }}} */
! 138:
! 139: /* Basic ripemd function */
! 140: #define F0(x,y,z) ((x) ^ (y) ^ (z))
! 141: #define F1(x,y,z) (((x) & (y)) | ((~(x)) & (z)))
! 142: #define F2(x,y,z) (((x) | (~(y))) ^ (z))
! 143: #define F3(x,y,z) (((x) & (z)) | ((y) & (~(z))))
! 144: #define F4(x,y,z) ((x) ^ ((y) | (~(z))))
! 145:
! 146: static const php_hash_uint32 K_values[5] = { 0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E }; /* 128, 256, 160, 320 */
! 147: static const php_hash_uint32 KK_values[4] = { 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x00000000 }; /* 128 & 256 */
! 148: static const php_hash_uint32 KK160_values[5] = { 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000 }; /* 160 & 320 */
! 149:
! 150: #define K(n) K_values[ (n) >> 4]
! 151: #define KK(n) KK_values[(n) >> 4]
! 152: #define KK160(n) KK160_values[(n) >> 4]
! 153:
! 154: static const unsigned char R[80] = {
! 155: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
! 156: 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
! 157: 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
! 158: 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
! 159: 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 };
! 160:
! 161: static const unsigned char RR[80] = {
! 162: 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
! 163: 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
! 164: 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
! 165: 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
! 166: 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 };
! 167:
! 168: static const unsigned char S[80] = {
! 169: 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
! 170: 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
! 171: 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
! 172: 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
! 173: 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 };
! 174:
! 175: static const unsigned char SS[80] = {
! 176: 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
! 177: 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
! 178: 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
! 179: 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
! 180: 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 };
! 181:
! 182: #define ROLS(j, x) (((x) << S[j]) | ((x) >> (32 - S[j])))
! 183: #define ROLSS(j, x) (((x) << SS[j]) | ((x) >> (32 - SS[j])))
! 184: #define ROL(n, x) (((x) << n) | ((x) >> (32 - n)))
! 185:
! 186: /* {{{ RIPEMDDecode
! 187: Decodes input (unsigned char) into output (php_hash_uint32). Assumes len is
! 188: a multiple of 4.
! 189: */
! 190: static void RIPEMDDecode(php_hash_uint32 *output, const unsigned char *input, unsigned int len)
! 191: {
! 192: unsigned int i, j;
! 193:
! 194: for (i = 0, j = 0; j < len; i++, j += 4)
! 195: output[i] = ((php_hash_uint32) input[j + 0]) | (((php_hash_uint32) input[j + 1]) << 8) |
! 196: (((php_hash_uint32) input[j + 2]) << 16) | (((php_hash_uint32) input[j + 3]) << 24);
! 197: }
! 198: /* }}} */
! 199:
! 200: /* {{{ RIPEMD128Transform
! 201: * ripemd128 basic transformation. Transforms state based on block.
! 202: */
! 203: static void RIPEMD128Transform(php_hash_uint32 state[4], const unsigned char block[64])
! 204: {
! 205: php_hash_uint32 a = state[0], b = state[1], c = state[2], d = state[3];
! 206: php_hash_uint32 aa = state[0], bb = state[1], cc = state[2], dd = state[3];
! 207: php_hash_uint32 tmp, x[16];
! 208: int j;
! 209:
! 210: RIPEMDDecode(x, block, 64);
! 211:
! 212: for(j = 0; j < 16; j++) {
! 213: tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j));
! 214: a = d; d = c; c = b; b = tmp;
! 215: tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK(j));
! 216: aa = dd; dd = cc; cc = bb; bb = tmp;
! 217: }
! 218:
! 219: for(j = 16; j < 32; j++) {
! 220: tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j));
! 221: a = d; d = c; c = b; b = tmp;
! 222: tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK(j));
! 223: aa = dd; dd = cc; cc = bb; bb = tmp;
! 224: }
! 225:
! 226: for(j = 32; j < 48; j++) {
! 227: tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j));
! 228: a = d; d = c; c = b; b = tmp;
! 229: tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK(j));
! 230: aa = dd; dd = cc; cc = bb; bb = tmp;
! 231: }
! 232:
! 233: for(j = 48; j < 64; j++) {
! 234: tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j));
! 235: a = d; d = c; c = b; b = tmp;
! 236: tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK(j));
! 237: aa = dd; dd = cc; cc = bb; bb = tmp;
! 238: }
! 239:
! 240: tmp = state[1] + c + dd;
! 241: state[1] = state[2] + d + aa;
! 242: state[2] = state[3] + a + bb;
! 243: state[3] = state[0] + b + cc;
! 244: state[0] = tmp;
! 245:
! 246: tmp = 0;
! 247: memset(x, 0, sizeof(x));
! 248: }
! 249: /* }}} */
! 250:
! 251: /* {{{ PHP_RIPEMD128Update
! 252: ripemd128 block update operation. Continues a ripemd128 message-digest
! 253: operation, processing another message block, and updating the
! 254: context.
! 255: */
! 256: PHP_HASH_API void PHP_RIPEMD128Update(PHP_RIPEMD128_CTX * context, const unsigned char *input, unsigned int inputLen)
! 257: {
! 258: unsigned int i, index, partLen;
! 259:
! 260: /* Compute number of bytes mod 64 */
! 261: index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
! 262:
! 263: /* Update number of bits */
! 264: if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
! 265: context->count[1]++;
! 266: }
! 267: context->count[1] += ((php_hash_uint32) inputLen >> 29);
! 268:
! 269: partLen = 64 - index;
! 270:
! 271: /* Transform as many times as possible.
! 272: */
! 273: if (inputLen >= partLen) {
! 274: memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
! 275: RIPEMD128Transform(context->state, context->buffer);
! 276:
! 277: for (i = partLen; i + 63 < inputLen; i += 64) {
! 278: RIPEMD128Transform(context->state, &input[i]);
! 279: }
! 280:
! 281: index = 0;
! 282: } else {
! 283: i = 0;
! 284: }
! 285:
! 286: /* Buffer remaining input */
! 287: memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
! 288: }
! 289: /* }}} */
! 290:
! 291: /* {{{ RIPEMD256Transform
! 292: * ripemd256 basic transformation. Transforms state based on block.
! 293: */
! 294: static void RIPEMD256Transform(php_hash_uint32 state[8], const unsigned char block[64])
! 295: {
! 296: php_hash_uint32 a = state[0], b = state[1], c = state[2], d = state[3];
! 297: php_hash_uint32 aa = state[4], bb = state[5], cc = state[6], dd = state[7];
! 298: php_hash_uint32 tmp, x[16];
! 299: int j;
! 300:
! 301: RIPEMDDecode(x, block, 64);
! 302:
! 303: for(j = 0; j < 16; j++) {
! 304: tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j));
! 305: a = d; d = c; c = b; b = tmp;
! 306: tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK(j));
! 307: aa = dd; dd = cc; cc = bb; bb = tmp;
! 308: }
! 309: tmp = a; a = aa; aa = tmp;
! 310:
! 311: for(j = 16; j < 32; j++) {
! 312: tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j));
! 313: a = d; d = c; c = b; b = tmp;
! 314: tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK(j));
! 315: aa = dd; dd = cc; cc = bb; bb = tmp;
! 316: }
! 317: tmp = b; b = bb; bb = tmp;
! 318:
! 319: for(j = 32; j < 48; j++) {
! 320: tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j));
! 321: a = d; d = c; c = b; b = tmp;
! 322: tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK(j));
! 323: aa = dd; dd = cc; cc = bb; bb = tmp;
! 324: }
! 325: tmp = c; c = cc; cc = tmp;
! 326:
! 327: for(j = 48; j < 64; j++) {
! 328: tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j));
! 329: a = d; d = c; c = b; b = tmp;
! 330: tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK(j));
! 331: aa = dd; dd = cc; cc = bb; bb = tmp;
! 332: }
! 333: tmp = d; d = dd; dd = tmp;
! 334:
! 335: state[0] += a;
! 336: state[1] += b;
! 337: state[2] += c;
! 338: state[3] += d;
! 339: state[4] += aa;
! 340: state[5] += bb;
! 341: state[6] += cc;
! 342: state[7] += dd;
! 343:
! 344: tmp = 0;
! 345: memset(x, 0, sizeof(x));
! 346: }
! 347: /* }}} */
! 348:
! 349: /* {{{ PHP_RIPEMD256Update
! 350: ripemd256 block update operation. Continues a ripemd256 message-digest
! 351: operation, processing another message block, and updating the
! 352: context.
! 353: */
! 354: PHP_HASH_API void PHP_RIPEMD256Update(PHP_RIPEMD256_CTX * context, const unsigned char *input, unsigned int inputLen)
! 355: {
! 356: unsigned int i, index, partLen;
! 357:
! 358: /* Compute number of bytes mod 64 */
! 359: index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
! 360:
! 361: /* Update number of bits */
! 362: if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
! 363: context->count[1]++;
! 364: }
! 365: context->count[1] += ((php_hash_uint32) inputLen >> 29);
! 366:
! 367: partLen = 64 - index;
! 368:
! 369: /* Transform as many times as possible.
! 370: */
! 371: if (inputLen >= partLen) {
! 372: memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
! 373: RIPEMD256Transform(context->state, context->buffer);
! 374:
! 375: for (i = partLen; i + 63 < inputLen; i += 64) {
! 376: RIPEMD256Transform(context->state, &input[i]);
! 377: }
! 378:
! 379: index = 0;
! 380: } else {
! 381: i = 0;
! 382: }
! 383:
! 384: /* Buffer remaining input */
! 385: memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
! 386: }
! 387: /* }}} */
! 388:
! 389: /* {{{ RIPEMD160Transform
! 390: * ripemd160 basic transformation. Transforms state based on block.
! 391: */
! 392: static void RIPEMD160Transform(php_hash_uint32 state[5], const unsigned char block[64])
! 393: {
! 394: php_hash_uint32 a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
! 395: php_hash_uint32 aa = state[0], bb = state[1], cc = state[2], dd = state[3], ee = state[4];
! 396: php_hash_uint32 tmp, x[16];
! 397: int j;
! 398:
! 399: RIPEMDDecode(x, block, 64);
! 400:
! 401: for(j = 0; j < 16; j++) {
! 402: tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j)) + e;
! 403: a = e; e = d; d = ROL(10, c); c = b; b = tmp;
! 404: tmp = ROLSS(j, aa + F4(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
! 405: aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
! 406: }
! 407:
! 408: for(j = 16; j < 32; j++) {
! 409: tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j)) + e;
! 410: a = e; e = d; d = ROL(10, c); c = b; b = tmp;
! 411: tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
! 412: aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
! 413: }
! 414:
! 415: for(j = 32; j < 48; j++) {
! 416: tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j)) + e;
! 417: a = e; e = d; d = ROL(10, c); c = b; b = tmp;
! 418: tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
! 419: aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
! 420: }
! 421:
! 422: for(j = 48; j < 64; j++) {
! 423: tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j)) + e;
! 424: a = e; e = d; d = ROL(10, c); c = b; b = tmp;
! 425: tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
! 426: aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
! 427: }
! 428:
! 429: for(j = 64; j < 80; j++) {
! 430: tmp = ROLS( j, a + F4(b, c, d) + x[R[j]] + K(j)) + e;
! 431: a = e; e = d; d = ROL(10, c); c = b; b = tmp;
! 432: tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
! 433: aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
! 434: }
! 435:
! 436: tmp = state[1] + c + dd;
! 437: state[1] = state[2] + d + ee;
! 438: state[2] = state[3] + e + aa;
! 439: state[3] = state[4] + a + bb;
! 440: state[4] = state[0] + b + cc;
! 441: state[0] = tmp;
! 442:
! 443: tmp = 0;
! 444: memset(x, 0, sizeof(x));
! 445: }
! 446: /* }}} */
! 447:
! 448: /* {{{ PHP_RIPEMD160Update
! 449: ripemd160 block update operation. Continues a ripemd160 message-digest
! 450: operation, processing another message block, and updating the
! 451: context.
! 452: */
! 453: PHP_HASH_API void PHP_RIPEMD160Update(PHP_RIPEMD160_CTX * context, const unsigned char *input, unsigned int inputLen)
! 454: {
! 455: unsigned int i, index, partLen;
! 456:
! 457: /* Compute number of bytes mod 64 */
! 458: index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
! 459:
! 460: /* Update number of bits */
! 461: if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
! 462: context->count[1]++;
! 463: }
! 464: context->count[1] += ((php_hash_uint32) inputLen >> 29);
! 465:
! 466: partLen = 64 - index;
! 467:
! 468: /* Transform as many times as possible.
! 469: */
! 470: if (inputLen >= partLen) {
! 471: memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
! 472: RIPEMD160Transform(context->state, context->buffer);
! 473:
! 474: for (i = partLen; i + 63 < inputLen; i += 64) {
! 475: RIPEMD160Transform(context->state, &input[i]);
! 476: }
! 477:
! 478: index = 0;
! 479: } else {
! 480: i = 0;
! 481: }
! 482:
! 483: /* Buffer remaining input */
! 484: memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
! 485: }
! 486: /* }}} */
! 487:
! 488: /* {{{ RIPEMD320Transform
! 489: * ripemd320 basic transformation. Transforms state based on block.
! 490: */
! 491: static void RIPEMD320Transform(php_hash_uint32 state[10], const unsigned char block[64])
! 492: {
! 493: php_hash_uint32 a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
! 494: php_hash_uint32 aa = state[5], bb = state[6], cc = state[7], dd = state[8], ee = state[9];
! 495: php_hash_uint32 tmp, x[16];
! 496: int j;
! 497:
! 498: RIPEMDDecode(x, block, 64);
! 499:
! 500: for(j = 0; j < 16; j++) {
! 501: tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j)) + e;
! 502: a = e; e = d; d = ROL(10, c); c = b; b = tmp;
! 503: tmp = ROLSS(j, aa + F4(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
! 504: aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
! 505: }
! 506: tmp = b; b = bb; bb = tmp;
! 507:
! 508: for(j = 16; j < 32; j++) {
! 509: tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j)) + e;
! 510: a = e; e = d; d = ROL(10, c); c = b; b = tmp;
! 511: tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
! 512: aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
! 513: }
! 514: tmp = d; d = dd; dd = tmp;
! 515:
! 516: for(j = 32; j < 48; j++) {
! 517: tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j)) + e;
! 518: a = e; e = d; d = ROL(10, c); c = b; b = tmp;
! 519: tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
! 520: aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
! 521: }
! 522: tmp = a; a = aa; aa = tmp;
! 523:
! 524: for(j = 48; j < 64; j++) {
! 525: tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j)) + e;
! 526: a = e; e = d; d = ROL(10, c); c = b; b = tmp;
! 527: tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
! 528: aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
! 529: }
! 530: tmp = c; c = cc; cc = tmp;
! 531:
! 532: for(j = 64; j < 80; j++) {
! 533: tmp = ROLS( j, a + F4(b, c, d) + x[R[j]] + K(j)) + e;
! 534: a = e; e = d; d = ROL(10, c); c = b; b = tmp;
! 535: tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
! 536: aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
! 537: }
! 538: tmp = e; e = ee; ee = tmp;
! 539:
! 540: state[0] += a;
! 541: state[1] += b;
! 542: state[2] += c;
! 543: state[3] += d;
! 544: state[4] += e;
! 545: state[5] += aa;
! 546: state[6] += bb;
! 547: state[7] += cc;
! 548: state[8] += dd;
! 549: state[9] += ee;
! 550:
! 551: tmp = 0;
! 552: memset(x, 0, sizeof(x));
! 553: }
! 554: /* }}} */
! 555:
! 556: /* {{{ PHP_RIPEMD320Update
! 557: ripemd320 block update operation. Continues a ripemd320 message-digest
! 558: operation, processing another message block, and updating the
! 559: context.
! 560: */
! 561: PHP_HASH_API void PHP_RIPEMD320Update(PHP_RIPEMD320_CTX * context, const unsigned char *input, unsigned int inputLen)
! 562: {
! 563: unsigned int i, index, partLen;
! 564:
! 565: /* Compute number of bytes mod 64 */
! 566: index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
! 567:
! 568: /* Update number of bits */
! 569: if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
! 570: context->count[1]++;
! 571: }
! 572: context->count[1] += ((php_hash_uint32) inputLen >> 29);
! 573:
! 574: partLen = 64 - index;
! 575:
! 576: /* Transform as many times as possible.
! 577: */
! 578: if (inputLen >= partLen) {
! 579: memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
! 580: RIPEMD320Transform(context->state, context->buffer);
! 581:
! 582: for (i = partLen; i + 63 < inputLen; i += 64) {
! 583: RIPEMD320Transform(context->state, &input[i]);
! 584: }
! 585:
! 586: index = 0;
! 587: } else {
! 588: i = 0;
! 589: }
! 590:
! 591: /* Buffer remaining input */
! 592: memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
! 593: }
! 594: /* }}} */
! 595:
! 596: static const unsigned char PADDING[64] =
! 597: {
! 598: 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
! 599: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
! 600: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
! 601: };
! 602:
! 603: /* {{{ RIPEMDEncode
! 604: Encodes input (php_hash_uint32) into output (unsigned char). Assumes len is
! 605: a multiple of 4.
! 606: */
! 607: static void RIPEMDEncode(unsigned char *output, php_hash_uint32 *input, unsigned int len)
! 608: {
! 609: unsigned int i, j;
! 610:
! 611: for (i = 0, j = 0; j < len; i++, j += 4) {
! 612: output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
! 613: output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
! 614: output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
! 615: output[j + 0] = (unsigned char) (input[i] & 0xff);
! 616: }
! 617: }
! 618: /* }}} */
! 619:
! 620: /* {{{ PHP_RIPEMD128Final
! 621: ripemd128 finalization. Ends a ripemd128 message-digest operation, writing the
! 622: the message digest and zeroizing the context.
! 623: */
! 624: PHP_HASH_API void PHP_RIPEMD128Final(unsigned char digest[16], PHP_RIPEMD128_CTX * context)
! 625: {
! 626: unsigned char bits[8];
! 627: unsigned int index, padLen;
! 628:
! 629: /* Save number of bits */
! 630: bits[0] = (unsigned char) (context->count[0] & 0xFF);
! 631: bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
! 632: bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
! 633: bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
! 634: bits[4] = (unsigned char) (context->count[1] & 0xFF);
! 635: bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
! 636: bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
! 637: bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
! 638:
! 639: /* Pad out to 56 mod 64.
! 640: */
! 641: index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
! 642: padLen = (index < 56) ? (56 - index) : (120 - index);
! 643: PHP_RIPEMD128Update(context, PADDING, padLen);
! 644:
! 645: /* Append length (before padding) */
! 646: PHP_RIPEMD128Update(context, bits, 8);
! 647:
! 648: /* Store state in digest */
! 649: RIPEMDEncode(digest, context->state, 16);
! 650:
! 651: /* Zeroize sensitive information.
! 652: */
! 653: memset((unsigned char*) context, 0, sizeof(*context));
! 654: }
! 655: /* }}} */
! 656:
! 657: /* {{{ PHP_RIPEMD256Final
! 658: ripemd256 finalization. Ends a ripemd256 message-digest operation, writing the
! 659: the message digest and zeroizing the context.
! 660: */
! 661: PHP_HASH_API void PHP_RIPEMD256Final(unsigned char digest[32], PHP_RIPEMD256_CTX * context)
! 662: {
! 663: unsigned char bits[8];
! 664: unsigned int index, padLen;
! 665:
! 666: /* Save number of bits */
! 667: bits[0] = (unsigned char) (context->count[0] & 0xFF);
! 668: bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
! 669: bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
! 670: bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
! 671: bits[4] = (unsigned char) (context->count[1] & 0xFF);
! 672: bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
! 673: bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
! 674: bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
! 675:
! 676: /* Pad out to 56 mod 64.
! 677: */
! 678: index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
! 679: padLen = (index < 56) ? (56 - index) : (120 - index);
! 680: PHP_RIPEMD256Update(context, PADDING, padLen);
! 681:
! 682: /* Append length (before padding) */
! 683: PHP_RIPEMD256Update(context, bits, 8);
! 684:
! 685: /* Store state in digest */
! 686: RIPEMDEncode(digest, context->state, 32);
! 687:
! 688: /* Zeroize sensitive information.
! 689: */
! 690: memset((unsigned char*) context, 0, sizeof(*context));
! 691: }
! 692: /* }}} */
! 693:
! 694: /* {{{ PHP_RIPEMD160Final
! 695: ripemd160 finalization. Ends a ripemd160 message-digest operation, writing the
! 696: the message digest and zeroizing the context.
! 697: */
! 698: PHP_HASH_API void PHP_RIPEMD160Final(unsigned char digest[20], PHP_RIPEMD160_CTX * context)
! 699: {
! 700: unsigned char bits[8];
! 701: unsigned int index, padLen;
! 702:
! 703: /* Save number of bits */
! 704: bits[0] = (unsigned char) (context->count[0] & 0xFF);
! 705: bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
! 706: bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
! 707: bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
! 708: bits[4] = (unsigned char) (context->count[1] & 0xFF);
! 709: bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
! 710: bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
! 711: bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
! 712:
! 713: /* Pad out to 56 mod 64.
! 714: */
! 715: index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
! 716: padLen = (index < 56) ? (56 - index) : (120 - index);
! 717: PHP_RIPEMD160Update(context, PADDING, padLen);
! 718:
! 719: /* Append length (before padding) */
! 720: PHP_RIPEMD160Update(context, bits, 8);
! 721:
! 722: /* Store state in digest */
! 723: RIPEMDEncode(digest, context->state, 20);
! 724:
! 725: /* Zeroize sensitive information.
! 726: */
! 727: memset((unsigned char*) context, 0, sizeof(*context));
! 728: }
! 729: /* }}} */
! 730:
! 731: /* {{{ PHP_RIPEMD320Final
! 732: ripemd320 finalization. Ends a ripemd320 message-digest operation, writing the
! 733: the message digest and zeroizing the context.
! 734: */
! 735: PHP_HASH_API void PHP_RIPEMD320Final(unsigned char digest[40], PHP_RIPEMD320_CTX * context)
! 736: {
! 737: unsigned char bits[8];
! 738: unsigned int index, padLen;
! 739:
! 740: /* Save number of bits */
! 741: bits[0] = (unsigned char) (context->count[0] & 0xFF);
! 742: bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
! 743: bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
! 744: bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
! 745: bits[4] = (unsigned char) (context->count[1] & 0xFF);
! 746: bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
! 747: bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
! 748: bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
! 749:
! 750: /* Pad out to 56 mod 64.
! 751: */
! 752: index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
! 753: padLen = (index < 56) ? (56 - index) : (120 - index);
! 754: PHP_RIPEMD320Update(context, PADDING, padLen);
! 755:
! 756: /* Append length (before padding) */
! 757: PHP_RIPEMD320Update(context, bits, 8);
! 758:
! 759: /* Store state in digest */
! 760: RIPEMDEncode(digest, context->state, 40);
! 761:
! 762: /* Zeroize sensitive information.
! 763: */
! 764: memset((unsigned char*) context, 0, sizeof(*context));
! 765: }
! 766: /* }}} */
! 767:
! 768: /*
! 769: * Local variables:
! 770: * tab-width: 4
! 771: * c-basic-offset: 4
! 772: * End:
! 773: * vim600: sw=4 ts=4 fdm=marker
! 774: * vim<600: sw=4 ts=4
! 775: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>