Back to index

php5  5.3.10
hash_ripemd.c
Go to the documentation of this file.
00001 /*
00002   +----------------------------------------------------------------------+
00003   | PHP Version 5                                                        |
00004   +----------------------------------------------------------------------+
00005   | Copyright (c) 1997-2012 The PHP Group                                |
00006   +----------------------------------------------------------------------+
00007   | This source file is subject to version 3.01 of the PHP license,      |
00008   | that is bundled with this package in the file LICENSE, and is        |
00009   | available through the world-wide-web at the following url:           |
00010   | http://www.php.net/license/3_01.txt                                  |
00011   | If you did not receive a copy of the PHP license and are unable to   |
00012   | obtain it through the world-wide-web, please send a note to          |
00013   | license@php.net so we can mail you a copy immediately.               |
00014   +----------------------------------------------------------------------+
00015   | Author: Sara Golemon <pollita@php.net>                               |
00016   +----------------------------------------------------------------------+
00017 */
00018 
00019 /* $Id: hash_ripemd.c 321634 2012-01-01 13:15:04Z felipe $ */
00020 
00021 /* Heavily borrowed from md5.c & sha1.c of PHP archival fame
00022    Note that ripemd laughs in the face of logic and uses
00023    little endian byte ordering */
00024 
00025 #include "php_hash.h"
00026 #include "php_hash_ripemd.h"
00027 
00028 const php_hash_ops php_hash_ripemd128_ops = {
00029        (php_hash_init_func_t) PHP_RIPEMD128Init,
00030        (php_hash_update_func_t) PHP_RIPEMD128Update,
00031        (php_hash_final_func_t) PHP_RIPEMD128Final,
00032        (php_hash_copy_func_t) php_hash_copy,
00033        16,
00034        64,
00035        sizeof(PHP_RIPEMD128_CTX)
00036 };
00037 
00038 const php_hash_ops php_hash_ripemd160_ops = {
00039        (php_hash_init_func_t) PHP_RIPEMD160Init,
00040        (php_hash_update_func_t) PHP_RIPEMD160Update,
00041        (php_hash_final_func_t) PHP_RIPEMD160Final,
00042        (php_hash_copy_func_t) php_hash_copy,
00043        20,
00044        64,
00045        sizeof(PHP_RIPEMD160_CTX)
00046 };
00047 
00048 const php_hash_ops php_hash_ripemd256_ops = {
00049        (php_hash_init_func_t) PHP_RIPEMD256Init,
00050        (php_hash_update_func_t) PHP_RIPEMD256Update,
00051        (php_hash_final_func_t) PHP_RIPEMD256Final,
00052        (php_hash_copy_func_t) php_hash_copy,
00053        32,
00054        64,
00055        sizeof(PHP_RIPEMD256_CTX)
00056 };
00057 
00058 const php_hash_ops php_hash_ripemd320_ops = {
00059        (php_hash_init_func_t) PHP_RIPEMD320Init,
00060        (php_hash_update_func_t) PHP_RIPEMD320Update,
00061        (php_hash_final_func_t) PHP_RIPEMD320Final,
00062        (php_hash_copy_func_t) php_hash_copy,
00063        40,
00064        64,
00065        sizeof(PHP_RIPEMD320_CTX)
00066 };
00067 
00068 /* {{{ PHP_RIPEMD128Init
00069  * ripemd128 initialization. Begins a ripemd128 operation, writing a new context.
00070  */
00071 PHP_HASH_API void PHP_RIPEMD128Init(PHP_RIPEMD128_CTX * context)
00072 {
00073        context->count[0] = context->count[1] = 0;
00074        /* Load magic initialization constants.
00075         */
00076        context->state[0] = 0x67452301;
00077        context->state[1] = 0xEFCDAB89;
00078        context->state[2] = 0x98BADCFE;
00079        context->state[3] = 0x10325476; 
00080 }
00081 /* }}} */
00082 
00083 /* {{{ PHP_RIPEMD256Init
00084  * ripemd256 initialization. Begins a ripemd256 operation, writing a new context.
00085  */
00086 PHP_HASH_API void PHP_RIPEMD256Init(PHP_RIPEMD256_CTX * context)
00087 {
00088        context->count[0] = context->count[1] = 0;
00089        /* Load magic initialization constants.
00090         */
00091        context->state[0] = 0x67452301;
00092        context->state[1] = 0xEFCDAB89;
00093        context->state[2] = 0x98BADCFE;
00094        context->state[3] = 0x10325476; 
00095        context->state[4] = 0x76543210;
00096        context->state[5] = 0xFEDCBA98;
00097        context->state[6] = 0x89ABCDEF;
00098        context->state[7] = 0x01234567;
00099 }
00100 /* }}} */
00101 
00102 /* {{{ PHP_RIPEMD160Init
00103  * ripemd160 initialization. Begins a ripemd160 operation, writing a new context.
00104  */
00105 PHP_HASH_API void PHP_RIPEMD160Init(PHP_RIPEMD160_CTX * context)
00106 {
00107        context->count[0] = context->count[1] = 0;
00108        /* Load magic initialization constants.
00109         */
00110        context->state[0] = 0x67452301;
00111        context->state[1] = 0xEFCDAB89;
00112        context->state[2] = 0x98BADCFE;
00113        context->state[3] = 0x10325476; 
00114        context->state[4] = 0xC3D2E1F0;
00115 }
00116 /* }}} */
00117 
00118 /* {{{ PHP_RIPEMD320Init
00119  * ripemd320 initialization. Begins a ripemd320 operation, writing a new context.
00120  */
00121 PHP_HASH_API void PHP_RIPEMD320Init(PHP_RIPEMD320_CTX * context)
00122 {
00123        context->count[0] = context->count[1] = 0;
00124        /* Load magic initialization constants.
00125         */
00126        context->state[0] = 0x67452301;
00127        context->state[1] = 0xEFCDAB89;
00128        context->state[2] = 0x98BADCFE;
00129        context->state[3] = 0x10325476; 
00130        context->state[4] = 0xC3D2E1F0;
00131        context->state[5] = 0x76543210;
00132        context->state[6] = 0xFEDCBA98;
00133        context->state[7] = 0x89ABCDEF;
00134        context->state[8] = 0x01234567;
00135        context->state[9] = 0x3C2D1E0F;
00136 }
00137 /* }}} */
00138 
00139 /* Basic ripemd function */
00140 #define F0(x,y,z)           ((x) ^ (y) ^ (z))
00141 #define F1(x,y,z)           (((x) & (y)) | ((~(x)) & (z)))
00142 #define F2(x,y,z)           (((x) | (~(y))) ^ (z))
00143 #define F3(x,y,z)           (((x) & (z)) | ((y) & (~(z))))
00144 #define F4(x,y,z)           ((x) ^ ((y) | (~(z))))
00145 
00146 static const php_hash_uint32 K_values[5]  = { 0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E };    /* 128, 256, 160, 320 */
00147 static const php_hash_uint32 KK_values[4] = { 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x00000000 };                /* 128 & 256 */
00148 static const php_hash_uint32 KK160_values[5] = { 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000 }; /* 160 & 320 */
00149 
00150 #define K(n)  K_values[ (n) >> 4]
00151 #define KK(n) KK_values[(n) >> 4]
00152 #define KK160(n) KK160_values[(n) >> 4]
00153 
00154 static const unsigned char R[80] = {
00155         0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
00156         7,  4, 13,  1, 10,  6, 15,  3, 12,  0,  9,  5,  2, 14, 11,  8,
00157         3, 10, 14,  4,  9, 15,  8,  1,  2,  7,  0,  6, 13, 11,  5, 12,
00158         1,  9, 11, 10,  0,  8, 12,  4, 13,  3,  7, 15, 14,  5,  6,  2,
00159         4,  0,  5,  9,  7, 12,  2, 10, 14,  1,  3,  8, 11,  6, 15, 13 };
00160 
00161 static const unsigned char RR[80] = {
00162         5, 14,  7,  0,  9,  2, 11,  4, 13,  6, 15,  8,  1, 10,  3, 12,
00163         6, 11,  3,  7,  0, 13,  5, 10, 14, 15,  8, 12,  4,  9,  1,  2,
00164        15,  5,  1,  3,  7, 14,  6,  9, 11,  8, 12,  2, 10,  0,  4, 13,
00165         8,  6,  4,  1,  3, 11, 15,  0,  5, 12,  2, 13,  9,  7, 10, 14,
00166        12, 15, 10,  4,  1,  5,  8,  7,  6,  2, 13, 14,  0,  3,  9, 11 };
00167 
00168 static const unsigned char S[80] = {
00169        11, 14, 15, 12,  5,  8,  7,  9, 11, 13, 14, 15,  6,  7,  9,  8,
00170         7,  6,  8, 13, 11,  9,  7, 15,  7, 12, 15,  9, 11,  7, 13, 12,
00171        11, 13,  6,  7, 14,  9, 13, 15, 14,  8, 13,  6,  5, 12,  7,  5,
00172        11, 12, 14, 15, 14, 15,  9,  8,  9, 14,  5,  6,  8,  6,  5, 12,
00173         9, 15,  5, 11,  6,  8, 13, 12,  5, 12, 13, 14, 11,  8,  5,  6 };
00174 
00175 static const unsigned char SS[80] = {
00176         8,  9,  9, 11, 13, 15, 15,  5,  7,  7,  8, 11, 14, 14, 12,  6,
00177         9, 13, 15,  7, 12,  8,  9, 11,  7,  7, 12,  7,  6, 15, 13, 11,
00178         9,  7, 15, 11,  8,  6,  6, 14, 12, 13,  5, 14, 13, 13,  7,  5,
00179        15,  5,  8, 11, 14, 14,  6, 14,  6,  9, 12,  9, 12,  5, 15,  8,
00180         8,  5, 12,  9, 12,  5, 14,  6,  8, 13,  6,  5, 15, 13, 11, 11 };
00181 
00182 #define ROLS(j, x)   (((x) << S[j])  | ((x) >> (32 - S[j])))
00183 #define ROLSS(j, x)  (((x) << SS[j]) | ((x) >> (32 - SS[j])))
00184 #define ROL(n, x)    (((x) << n) | ((x) >> (32 - n)))
00185 
00186 /* {{{ RIPEMDDecode
00187    Decodes input (unsigned char) into output (php_hash_uint32). Assumes len is
00188    a multiple of 4.
00189  */
00190 static void RIPEMDDecode(php_hash_uint32 *output, const unsigned char *input, unsigned int len)
00191 {
00192        unsigned int i, j;
00193 
00194        for (i = 0, j = 0; j < len; i++, j += 4)
00195               output[i] = ((php_hash_uint32) input[j + 0]) | (((php_hash_uint32) input[j + 1]) << 8) |
00196                      (((php_hash_uint32) input[j + 2]) << 16) | (((php_hash_uint32) input[j + 3]) << 24);
00197 }
00198 /* }}} */
00199 
00200 /* {{{ RIPEMD128Transform
00201  * ripemd128 basic transformation. Transforms state based on block.
00202  */
00203 static void RIPEMD128Transform(php_hash_uint32 state[4], const unsigned char block[64])
00204 {
00205        php_hash_uint32 a  = state[0], b  = state[1], c  = state[2], d  = state[3];
00206        php_hash_uint32 aa = state[0], bb = state[1], cc = state[2], dd = state[3];
00207        php_hash_uint32 tmp, x[16];
00208        int j;
00209 
00210        RIPEMDDecode(x, block, 64);
00211 
00212        for(j = 0; j < 16; j++) {
00213               tmp = ROLS( j, a  + F0(b,  c,  d)  + x[R[j]]  + K(j));
00214               a = d; d = c; c = b; b = tmp;
00215               tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK(j));
00216               aa = dd; dd = cc; cc = bb; bb = tmp;
00217        }
00218 
00219        for(j = 16; j < 32; j++) {
00220               tmp = ROLS( j, a  + F1(b,  c,  d)  + x[R[j]]  + K(j));
00221               a = d; d = c; c = b; b = tmp;
00222               tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK(j));
00223               aa = dd; dd = cc; cc = bb; bb = tmp;
00224        }
00225 
00226        for(j = 32; j < 48; j++) {
00227               tmp = ROLS( j, a  + F2(b,  c,  d)  + x[R[j]]  + K(j));
00228               a = d; d = c; c = b; b = tmp;
00229               tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK(j));
00230               aa = dd; dd = cc; cc = bb; bb = tmp;
00231        }
00232 
00233        for(j = 48; j < 64; j++) {
00234               tmp = ROLS( j, a  + F3(b,  c,  d)  + x[R[j]]  + K(j));
00235               a = d; d = c; c = b; b = tmp;
00236               tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK(j));
00237               aa = dd; dd = cc; cc = bb; bb = tmp;
00238        }
00239 
00240        tmp = state[1] + c + dd;
00241        state[1] = state[2] + d + aa;
00242        state[2] = state[3] + a + bb;
00243        state[3] = state[0] + b + cc;
00244        state[0] = tmp;
00245 
00246        tmp = 0;
00247        memset(x, 0, sizeof(x));
00248 }
00249 /* }}} */
00250 
00251 /* {{{ PHP_RIPEMD128Update
00252    ripemd128 block update operation. Continues a ripemd128 message-digest
00253    operation, processing another message block, and updating the
00254    context.
00255  */
00256 PHP_HASH_API void PHP_RIPEMD128Update(PHP_RIPEMD128_CTX * context, const unsigned char *input, unsigned int inputLen)
00257 {
00258        unsigned int i, index, partLen;
00259 
00260        /* Compute number of bytes mod 64 */
00261        index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
00262 
00263        /* Update number of bits */
00264        if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
00265               context->count[1]++;
00266        }
00267        context->count[1] += ((php_hash_uint32) inputLen >> 29);
00268 
00269        partLen = 64 - index;
00270 
00271        /* Transform as many times as possible.
00272         */
00273        if (inputLen >= partLen) {
00274               memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
00275               RIPEMD128Transform(context->state, context->buffer);
00276 
00277               for (i = partLen; i + 63 < inputLen; i += 64) {
00278                      RIPEMD128Transform(context->state, &input[i]);
00279               }
00280 
00281               index = 0;
00282        } else {
00283               i = 0;
00284        }
00285 
00286        /* Buffer remaining input */
00287        memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
00288 }
00289 /* }}} */
00290 
00291 /* {{{ RIPEMD256Transform
00292  * ripemd256 basic transformation. Transforms state based on block.
00293  */
00294 static void RIPEMD256Transform(php_hash_uint32 state[8], const unsigned char block[64])
00295 {
00296        php_hash_uint32 a  = state[0], b  = state[1], c  = state[2], d  = state[3];
00297        php_hash_uint32 aa = state[4], bb = state[5], cc = state[6], dd = state[7];
00298        php_hash_uint32 tmp, x[16];
00299        int j;
00300 
00301        RIPEMDDecode(x, block, 64);
00302 
00303        for(j = 0; j < 16; j++) {
00304               tmp = ROLS( j, a  + F0(b,  c,  d)  + x[R[j]]  + K(j));
00305               a = d; d = c; c = b; b = tmp;
00306               tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK(j));
00307               aa = dd; dd = cc; cc = bb; bb = tmp;
00308        }
00309        tmp = a; a = aa; aa = tmp;
00310 
00311        for(j = 16; j < 32; j++) {
00312               tmp = ROLS( j, a  + F1(b,  c,  d)  + x[R[j]]  + K(j));
00313               a = d; d = c; c = b; b = tmp;
00314               tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK(j));
00315               aa = dd; dd = cc; cc = bb; bb = tmp;
00316        }
00317        tmp = b; b = bb; bb = tmp;
00318 
00319        for(j = 32; j < 48; j++) {
00320               tmp = ROLS( j, a  + F2(b,  c,  d)  + x[R[j]]  + K(j));
00321               a = d; d = c; c = b; b = tmp;
00322               tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK(j));
00323               aa = dd; dd = cc; cc = bb; bb = tmp;
00324        }
00325        tmp = c; c = cc; cc = tmp;
00326 
00327        for(j = 48; j < 64; j++) {
00328               tmp = ROLS( j, a  + F3(b,  c,  d)  + x[R[j]]  + K(j));
00329               a = d; d = c; c = b; b = tmp;
00330               tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK(j));
00331               aa = dd; dd = cc; cc = bb; bb = tmp;
00332        }
00333        tmp = d; d = dd; dd = tmp;
00334 
00335        state[0] += a;
00336        state[1] += b;
00337        state[2] += c;
00338        state[3] += d;
00339        state[4] += aa;
00340        state[5] += bb;
00341        state[6] += cc;
00342        state[7] += dd;
00343 
00344        tmp = 0;
00345        memset(x, 0, sizeof(x));
00346 }
00347 /* }}} */
00348 
00349 /* {{{ PHP_RIPEMD256Update
00350    ripemd256 block update operation. Continues a ripemd256 message-digest
00351    operation, processing another message block, and updating the
00352    context.
00353  */
00354 PHP_HASH_API void PHP_RIPEMD256Update(PHP_RIPEMD256_CTX * context, const unsigned char *input, unsigned int inputLen)
00355 {
00356        unsigned int i, index, partLen;
00357 
00358        /* Compute number of bytes mod 64 */
00359        index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
00360 
00361        /* Update number of bits */
00362        if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
00363               context->count[1]++;
00364        }
00365        context->count[1] += ((php_hash_uint32) inputLen >> 29);
00366 
00367        partLen = 64 - index;
00368 
00369        /* Transform as many times as possible.
00370         */
00371        if (inputLen >= partLen) {
00372               memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
00373               RIPEMD256Transform(context->state, context->buffer);
00374 
00375               for (i = partLen; i + 63 < inputLen; i += 64) {
00376                      RIPEMD256Transform(context->state, &input[i]);
00377               }
00378 
00379               index = 0;
00380        } else {
00381               i = 0;
00382        }
00383 
00384        /* Buffer remaining input */
00385        memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
00386 }
00387 /* }}} */
00388 
00389 /* {{{ RIPEMD160Transform
00390  * ripemd160 basic transformation. Transforms state based on block.
00391  */
00392 static void RIPEMD160Transform(php_hash_uint32 state[5], const unsigned char block[64])
00393 {
00394        php_hash_uint32 a  = state[0], b  = state[1], c  = state[2], d  = state[3], e  = state[4];
00395        php_hash_uint32 aa = state[0], bb = state[1], cc = state[2], dd = state[3], ee = state[4];
00396        php_hash_uint32 tmp, x[16];
00397        int j;
00398 
00399        RIPEMDDecode(x, block, 64);
00400 
00401        for(j = 0; j < 16; j++) {
00402               tmp = ROLS( j, a  + F0(b,  c,  d)  + x[R[j]]  + K(j)) + e;
00403               a = e; e = d; d = ROL(10, c); c = b; b = tmp;
00404               tmp = ROLSS(j, aa + F4(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
00405               aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
00406        }
00407 
00408        for(j = 16; j < 32; j++) {
00409               tmp = ROLS( j, a  + F1(b,  c,  d)  + x[R[j]]  + K(j)) + e;
00410               a = e; e = d; d = ROL(10, c); c = b; b = tmp;
00411               tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
00412               aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
00413        }
00414 
00415        for(j = 32; j < 48; j++) {
00416               tmp = ROLS( j, a  + F2(b,  c,  d)  + x[R[j]]  + K(j)) + e;
00417               a = e; e = d; d = ROL(10, c); c = b; b = tmp;
00418               tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
00419               aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
00420        }
00421 
00422        for(j = 48; j < 64; j++) {
00423               tmp = ROLS( j, a  + F3(b,  c,  d)  + x[R[j]]  + K(j)) + e;
00424               a = e; e = d; d = ROL(10, c); c = b; b = tmp;
00425               tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
00426               aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
00427        }
00428 
00429        for(j = 64; j < 80; j++) {
00430               tmp = ROLS( j, a  + F4(b,  c,  d)  + x[R[j]]  + K(j)) + e;
00431               a = e; e = d; d = ROL(10, c); c = b; b = tmp;
00432               tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
00433               aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
00434        }
00435 
00436        tmp = state[1] + c + dd;
00437        state[1] = state[2] + d + ee;
00438        state[2] = state[3] + e + aa;
00439        state[3] = state[4] + a + bb;
00440        state[4] = state[0] + b + cc;
00441        state[0] = tmp;
00442 
00443        tmp = 0;
00444        memset(x, 0, sizeof(x));
00445 }
00446 /* }}} */
00447 
00448 /* {{{ PHP_RIPEMD160Update
00449    ripemd160 block update operation. Continues a ripemd160 message-digest
00450    operation, processing another message block, and updating the
00451    context.
00452  */
00453 PHP_HASH_API void PHP_RIPEMD160Update(PHP_RIPEMD160_CTX * context, const unsigned char *input, unsigned int inputLen)
00454 {
00455        unsigned int i, index, partLen;
00456 
00457        /* Compute number of bytes mod 64 */
00458        index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
00459 
00460        /* Update number of bits */
00461        if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
00462               context->count[1]++;
00463        }
00464        context->count[1] += ((php_hash_uint32) inputLen >> 29);
00465 
00466        partLen = 64 - index;
00467 
00468        /* Transform as many times as possible.
00469         */
00470        if (inputLen >= partLen) {
00471               memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
00472               RIPEMD160Transform(context->state, context->buffer);
00473 
00474               for (i = partLen; i + 63 < inputLen; i += 64) {
00475                      RIPEMD160Transform(context->state, &input[i]);
00476               }
00477 
00478               index = 0;
00479        } else {
00480               i = 0;
00481        }
00482 
00483        /* Buffer remaining input */
00484        memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
00485 }
00486 /* }}} */
00487 
00488 /* {{{ RIPEMD320Transform
00489  * ripemd320 basic transformation. Transforms state based on block.
00490  */
00491 static void RIPEMD320Transform(php_hash_uint32 state[10], const unsigned char block[64])
00492 {
00493        php_hash_uint32 a  = state[0], b  = state[1], c  = state[2], d  = state[3], e  = state[4];
00494        php_hash_uint32 aa = state[5], bb = state[6], cc = state[7], dd = state[8], ee = state[9];
00495        php_hash_uint32 tmp, x[16];
00496        int j;
00497 
00498        RIPEMDDecode(x, block, 64);
00499 
00500        for(j = 0; j < 16; j++) {
00501               tmp = ROLS( j, a  + F0(b,  c,  d)  + x[R[j]]  + K(j)) + e;
00502               a = e; e = d; d = ROL(10, c); c = b; b = tmp;
00503               tmp = ROLSS(j, aa + F4(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
00504               aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
00505        }
00506        tmp = b; b = bb; bb = tmp;
00507 
00508        for(j = 16; j < 32; j++) {
00509               tmp = ROLS( j, a  + F1(b,  c,  d)  + x[R[j]]  + K(j)) + e;
00510               a = e; e = d; d = ROL(10, c); c = b; b = tmp;
00511               tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
00512               aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
00513        }
00514        tmp = d; d = dd; dd = tmp;
00515 
00516        for(j = 32; j < 48; j++) {
00517               tmp = ROLS( j, a  + F2(b,  c,  d)  + x[R[j]]  + K(j)) + e;
00518               a = e; e = d; d = ROL(10, c); c = b; b = tmp;
00519               tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
00520               aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
00521        }
00522        tmp = a; a = aa; aa = tmp;
00523 
00524        for(j = 48; j < 64; j++) {
00525               tmp = ROLS( j, a  + F3(b,  c,  d)  + x[R[j]]  + K(j)) + e;
00526               a = e; e = d; d = ROL(10, c); c = b; b = tmp;
00527               tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
00528               aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
00529        }
00530        tmp = c; c = cc; cc = tmp;
00531 
00532        for(j = 64; j < 80; j++) {
00533               tmp = ROLS( j, a  + F4(b,  c,  d)  + x[R[j]]  + K(j)) + e;
00534               a = e; e = d; d = ROL(10, c); c = b; b = tmp;
00535               tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
00536               aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
00537        }
00538        tmp = e; e = ee; ee = tmp;
00539 
00540        state[0] += a;
00541        state[1] += b;
00542        state[2] += c;
00543        state[3] += d;
00544        state[4] += e;
00545        state[5] += aa;
00546        state[6] += bb;
00547        state[7] += cc;
00548        state[8] += dd;
00549        state[9] += ee;
00550 
00551        tmp = 0;
00552        memset(x, 0, sizeof(x));
00553 }
00554 /* }}} */
00555 
00556 /* {{{ PHP_RIPEMD320Update
00557    ripemd320 block update operation. Continues a ripemd320 message-digest
00558    operation, processing another message block, and updating the
00559    context.
00560  */
00561 PHP_HASH_API void PHP_RIPEMD320Update(PHP_RIPEMD320_CTX * context, const unsigned char *input, unsigned int inputLen)
00562 {
00563        unsigned int i, index, partLen;
00564 
00565        /* Compute number of bytes mod 64 */
00566        index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
00567 
00568        /* Update number of bits */
00569        if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
00570               context->count[1]++;
00571        }
00572        context->count[1] += ((php_hash_uint32) inputLen >> 29);
00573 
00574        partLen = 64 - index;
00575 
00576        /* Transform as many times as possible.
00577         */
00578        if (inputLen >= partLen) {
00579               memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
00580               RIPEMD320Transform(context->state, context->buffer);
00581 
00582               for (i = partLen; i + 63 < inputLen; i += 64) {
00583                      RIPEMD320Transform(context->state, &input[i]);
00584               }
00585 
00586               index = 0;
00587        } else {
00588               i = 0;
00589        }
00590 
00591        /* Buffer remaining input */
00592        memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
00593 }
00594 /* }}} */
00595 
00596 static const unsigned char PADDING[64] =
00597 {
00598        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00599        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00600        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00601 };
00602 
00603 /* {{{ RIPEMDEncode
00604    Encodes input (php_hash_uint32) into output (unsigned char). Assumes len is
00605    a multiple of 4.
00606  */
00607 static void RIPEMDEncode(unsigned char *output, php_hash_uint32 *input, unsigned int len)
00608 {
00609        unsigned int i, j;
00610 
00611        for (i = 0, j = 0; j < len; i++, j += 4) {
00612               output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
00613               output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
00614               output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
00615               output[j + 0] = (unsigned char) (input[i] & 0xff);
00616        }
00617 }
00618 /* }}} */
00619 
00620 /* {{{ PHP_RIPEMD128Final
00621    ripemd128 finalization. Ends a ripemd128 message-digest operation, writing the
00622    the message digest and zeroizing the context.
00623  */
00624 PHP_HASH_API void PHP_RIPEMD128Final(unsigned char digest[16], PHP_RIPEMD128_CTX * context)
00625 {
00626        unsigned char bits[8];
00627        unsigned int index, padLen;
00628 
00629        /* Save number of bits */
00630        bits[0] = (unsigned char) (context->count[0] & 0xFF);
00631        bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
00632        bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
00633        bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
00634        bits[4] = (unsigned char) (context->count[1] & 0xFF);
00635        bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
00636        bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
00637        bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
00638        
00639        /* Pad out to 56 mod 64.
00640         */
00641        index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
00642        padLen = (index < 56) ? (56 - index) : (120 - index);
00643        PHP_RIPEMD128Update(context, PADDING, padLen);
00644 
00645        /* Append length (before padding) */
00646        PHP_RIPEMD128Update(context, bits, 8);
00647 
00648        /* Store state in digest */
00649        RIPEMDEncode(digest, context->state, 16);
00650 
00651        /* Zeroize sensitive information.
00652         */
00653        memset((unsigned char*) context, 0, sizeof(*context));
00654 }
00655 /* }}} */
00656 
00657 /* {{{ PHP_RIPEMD256Final
00658    ripemd256 finalization. Ends a ripemd256 message-digest operation, writing the
00659    the message digest and zeroizing the context.
00660  */
00661 PHP_HASH_API void PHP_RIPEMD256Final(unsigned char digest[32], PHP_RIPEMD256_CTX * context)
00662 {
00663        unsigned char bits[8];
00664        unsigned int index, padLen;
00665 
00666        /* Save number of bits */
00667        bits[0] = (unsigned char) (context->count[0] & 0xFF);
00668        bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
00669        bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
00670        bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
00671        bits[4] = (unsigned char) (context->count[1] & 0xFF);
00672        bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
00673        bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
00674        bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
00675        
00676        /* Pad out to 56 mod 64.
00677         */
00678        index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
00679        padLen = (index < 56) ? (56 - index) : (120 - index);
00680        PHP_RIPEMD256Update(context, PADDING, padLen);
00681 
00682        /* Append length (before padding) */
00683        PHP_RIPEMD256Update(context, bits, 8);
00684 
00685        /* Store state in digest */
00686        RIPEMDEncode(digest, context->state, 32);
00687 
00688        /* Zeroize sensitive information.
00689         */
00690        memset((unsigned char*) context, 0, sizeof(*context));
00691 }
00692 /* }}} */
00693 
00694 /* {{{ PHP_RIPEMD160Final
00695    ripemd160 finalization. Ends a ripemd160 message-digest operation, writing the
00696    the message digest and zeroizing the context.
00697  */
00698 PHP_HASH_API void PHP_RIPEMD160Final(unsigned char digest[20], PHP_RIPEMD160_CTX * context)
00699 {
00700        unsigned char bits[8];
00701        unsigned int index, padLen;
00702 
00703        /* Save number of bits */
00704        bits[0] = (unsigned char) (context->count[0] & 0xFF);
00705        bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
00706        bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
00707        bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
00708        bits[4] = (unsigned char) (context->count[1] & 0xFF);
00709        bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
00710        bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
00711        bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
00712        
00713        /* Pad out to 56 mod 64.
00714         */
00715        index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
00716        padLen = (index < 56) ? (56 - index) : (120 - index);
00717        PHP_RIPEMD160Update(context, PADDING, padLen);
00718 
00719        /* Append length (before padding) */
00720        PHP_RIPEMD160Update(context, bits, 8);
00721 
00722        /* Store state in digest */
00723        RIPEMDEncode(digest, context->state, 20);
00724 
00725        /* Zeroize sensitive information.
00726         */
00727        memset((unsigned char*) context, 0, sizeof(*context));
00728 }
00729 /* }}} */
00730 
00731 /* {{{ PHP_RIPEMD320Final
00732    ripemd320 finalization. Ends a ripemd320 message-digest operation, writing the
00733    the message digest and zeroizing the context.
00734  */
00735 PHP_HASH_API void PHP_RIPEMD320Final(unsigned char digest[40], PHP_RIPEMD320_CTX * context)
00736 {
00737        unsigned char bits[8];
00738        unsigned int index, padLen;
00739 
00740        /* Save number of bits */
00741        bits[0] = (unsigned char) (context->count[0] & 0xFF);
00742        bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
00743        bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
00744        bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
00745        bits[4] = (unsigned char) (context->count[1] & 0xFF);
00746        bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
00747        bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
00748        bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
00749        
00750        /* Pad out to 56 mod 64.
00751         */
00752        index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
00753        padLen = (index < 56) ? (56 - index) : (120 - index);
00754        PHP_RIPEMD320Update(context, PADDING, padLen);
00755 
00756        /* Append length (before padding) */
00757        PHP_RIPEMD320Update(context, bits, 8);
00758 
00759        /* Store state in digest */
00760        RIPEMDEncode(digest, context->state, 40);
00761 
00762        /* Zeroize sensitive information.
00763         */
00764        memset((unsigned char*) context, 0, sizeof(*context));
00765 }
00766 /* }}} */
00767 
00768 /*
00769  * Local variables:
00770  * tab-width: 4
00771  * c-basic-offset: 4
00772  * End:
00773  * vim600: sw=4 ts=4 fdm=marker
00774  * vim<600: sw=4 ts=4
00775  */