Annotation of embedaddon/php/ext/hash/hash_tiger.c, revision 1.1.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:   | Authors: Michael Wallner <mike@php.net>                              |
                     16:   |          Sara Golemon <pollita@php.net>                              |
                     17:   +----------------------------------------------------------------------+
                     18: */
                     19: 
                     20: /* $Id: hash_tiger.c 321634 2012-01-01 13:15:04Z felipe $ */
                     21: 
                     22: #include "php_hash.h"
                     23: #include "php_hash_tiger.h"
                     24: #include "php_hash_tiger_tables.h"
                     25: 
                     26: #if (defined(__APPLE__) || defined(__APPLE_CC__)) && (defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__))
                     27: # if defined(__LITTLE_ENDIAN__)
                     28: #  undef WORDS_BIGENDIAN
                     29: # else 
                     30: #  if defined(__BIG_ENDIAN__)
                     31: #   define WORDS_BIGENDIAN
                     32: #  endif
                     33: # endif
                     34: #endif
                     35: 
                     36: /* {{{ */
                     37: #define save_abc \
                     38:        aa = a; \
                     39:        bb = b; \
                     40:        cc = c;
                     41: 
                     42: #define round(a,b,c,x,mul) \
                     43:        c ^= x; \
                     44:        a -= t1[(unsigned char)(c)] ^ \
                     45:                t2[(unsigned char)(((php_hash_uint32)(c))>>(2*8))] ^ \
                     46:                t3[(unsigned char)((c)>>(4*8))] ^ \
                     47:                t4[(unsigned char)(((php_hash_uint32)((c)>>(4*8)))>>(2*8))] ; \
                     48:        b += t4[(unsigned char)(((php_hash_uint32)(c))>>(1*8))] ^ \
                     49:                t3[(unsigned char)(((php_hash_uint32)(c))>>(3*8))] ^ \
                     50:                t2[(unsigned char)(((php_hash_uint32)((c)>>(4*8)))>>(1*8))] ^ \
                     51:                t1[(unsigned char)(((php_hash_uint32)((c)>>(4*8)))>>(3*8))]; \
                     52:        b *= mul;
                     53: 
                     54: #define pass(a,b,c,mul) \
                     55:        round(a,b,c,x0,mul) \
                     56:        round(b,c,a,x1,mul) \
                     57:        round(c,a,b,x2,mul) \
                     58:        round(a,b,c,x3,mul) \
                     59:        round(b,c,a,x4,mul) \
                     60:        round(c,a,b,x5,mul) \
                     61:        round(a,b,c,x6,mul) \
                     62:        round(b,c,a,x7,mul)
                     63: 
                     64: #define key_schedule \
                     65:        x0 -= x7 ^ L64(0xA5A5A5A5A5A5A5A5); \
                     66:        x1 ^= x0; \
                     67:        x2 += x1; \
                     68:        x3 -= x2 ^ ((~x1)<<19); \
                     69:        x4 ^= x3; \
                     70:        x5 += x4; \
                     71:        x6 -= x5 ^ ((~x4)>>23); \
                     72:        x7 ^= x6; \
                     73:        x0 += x7; \
                     74:        x1 -= x0 ^ ((~x7)<<19); \
                     75:        x2 ^= x1; \
                     76:        x3 += x2; \
                     77:        x4 -= x3 ^ ((~x2)>>23); \
                     78:        x5 ^= x4; \
                     79:        x6 += x5; \
                     80:        x7 -= x6 ^ L64(0x0123456789ABCDEF);
                     81: 
                     82: #define feedforward \
                     83:        a ^= aa; \
                     84:        b -= bb; \
                     85:        c += cc;
                     86: 
                     87: #define compress(passes) \
                     88:        save_abc \
                     89:        pass(a,b,c,5) \
                     90:        key_schedule \
                     91:        pass(c,a,b,7) \
                     92:        key_schedule \
                     93:        pass(b,c,a,9) \
                     94:        for(pass_no=0; pass_no<passes; pass_no++) { \
                     95:                key_schedule \
                     96:                pass(a,b,c,9) \
                     97:                tmpa=a; a=c; c=b; b=tmpa; \
                     98:        } \
                     99:        feedforward
                    100: 
                    101: #define split_ex(str) \
                    102:        x0=str[0]; x1=str[1]; x2=str[2]; x3=str[3]; \
                    103:        x4=str[4]; x5=str[5]; x6=str[6]; x7=str[7];
                    104: #ifdef WORDS_BIGENDIAN
                    105: #      define split(str) \
                    106:        { \
                    107:                int i; \
                    108:                php_hash_uint64 tmp[8]; \
                    109:                 \
                    110:                for (i = 0; i < 64; ++i) { \
                    111:                        ((unsigned char *) tmp)[i^7] = ((unsigned char *) str)[i]; \
                    112:                } \
                    113:                split_ex(tmp); \
                    114:        }
                    115: #else
                    116: #      define split split_ex
                    117: #endif
                    118: 
                    119: #define tiger_compress(passes, str, state) \
                    120: { \
                    121:        register php_hash_uint64 a, b, c, tmpa, x0, x1, x2, x3, x4, x5, x6, x7; \
                    122:        php_hash_uint64 aa, bb, cc; \
                    123:        int pass_no; \
                    124:        \
                    125:        a = state[0]; \
                    126:        b = state[1]; \
                    127:        c = state[2]; \
                    128:        \
                    129:        split(str); \
                    130:        \
                    131:        compress(passes); \
                    132:        \
                    133:        state[0] = a; \
                    134:        state[1] = b; \
                    135:        state[2] = c; \
                    136: }
                    137: /* }}} */
                    138: 
                    139: static inline void TigerFinalize(PHP_TIGER_CTX *context)
                    140: {
                    141:        context->passed += (php_hash_uint64) context->length << 3;
                    142:        
                    143:        context->buffer[context->length++] = 0x1;
                    144:        if (context->length % 8) {
                    145:                memset(&context->buffer[context->length], 0, 8-context->length%8);
                    146:                context->length += 8-context->length%8;
                    147:        }
                    148:        
                    149:        if (context->length > 56) {
                    150:                memset(&context->buffer[context->length], 0, 64 - context->length);
                    151:                tiger_compress(context->passes, ((php_hash_uint64 *) context->buffer), context->state);
                    152:                memset(context->buffer, 0, 56);
                    153:        } else {
                    154:                memset(&context->buffer[context->length], 0, 56 - context->length);
                    155:        }
                    156: 
                    157: #ifndef WORDS_BIGENDIAN        
                    158:        memcpy(&context->buffer[56], &context->passed, sizeof(php_hash_uint64));
                    159: #else
                    160:        context->buffer[56] = (unsigned char) (context->passed & 0xff);
                    161:        context->buffer[57] = (unsigned char) ((context->passed >> 8) & 0xff);
                    162:        context->buffer[58] = (unsigned char) ((context->passed >> 16) & 0xff);
                    163:        context->buffer[59] = (unsigned char) ((context->passed >> 24) & 0xff);
                    164:        context->buffer[60] = (unsigned char) ((context->passed >> 32) & 0xff);
                    165:        context->buffer[61] = (unsigned char) ((context->passed >> 40) & 0xff);
                    166:        context->buffer[62] = (unsigned char) ((context->passed >> 48) & 0xff);
                    167:        context->buffer[63] = (unsigned char) ((context->passed >> 56) & 0xff);
                    168: #endif
                    169:        tiger_compress(context->passes, ((php_hash_uint64 *) context->buffer), context->state);
                    170: }
                    171: 
                    172: PHP_HASH_API void PHP_3TIGERInit(PHP_TIGER_CTX *context)
                    173: {
                    174:        memset(context, 0, sizeof(*context));
                    175:        context->state[0] = L64(0x0123456789ABCDEF);
                    176:        context->state[1] = L64(0xFEDCBA9876543210);
                    177:        context->state[2] = L64(0xF096A5B4C3B2E187);
                    178: }
                    179: 
                    180: PHP_HASH_API void PHP_4TIGERInit(PHP_TIGER_CTX *context)
                    181: {
                    182:        memset(context, 0, sizeof(*context));
                    183:        context->passes = 1;
                    184:        context->state[0] = L64(0x0123456789ABCDEF);
                    185:        context->state[1] = L64(0xFEDCBA9876543210);
                    186:        context->state[2] = L64(0xF096A5B4C3B2E187);
                    187: }
                    188: 
                    189: PHP_HASH_API void PHP_TIGERUpdate(PHP_TIGER_CTX *context, const unsigned char *input, size_t len)
                    190: {
                    191:        if (context->length + len < 64) {
                    192:                memcpy(&context->buffer[context->length], input, len);
                    193:                context->length += len;
                    194:        } else {
                    195:                size_t i = 0, r = (context->length + len) % 64;
                    196:                
                    197:                if (context->length) {
                    198:                        i = 64 - context->length;
                    199:                        memcpy(&context->buffer[context->length], input, i);
                    200:                        tiger_compress(context->passes, ((const php_hash_uint64 *) context->buffer), context->state);
                    201:                        memset(context->buffer, 0, 64);
                    202:                        context->passed += 512;
                    203:                }
                    204:                
                    205:                for (; i + 64 <= len; i += 64) {
                    206:                        memcpy(context->buffer, &input[i], 64);
                    207:                        tiger_compress(context->passes, ((const php_hash_uint64 *) context->buffer), context->state);
                    208:                        context->passed += 512;
                    209:                }
                    210:                memset(&context->buffer[r], 0, 64-r);
                    211:                memcpy(context->buffer, &input[i], r);
                    212:                context->length = r;
                    213:        }
                    214: }
                    215: 
                    216: PHP_HASH_API void PHP_TIGER128Final(unsigned char digest[16], PHP_TIGER_CTX *context)
                    217: {
                    218:        TigerFinalize(context);
                    219:        
                    220:        digest[0] = (unsigned char) ((context->state[0] >> 56) & 0xff);
                    221:        digest[1] = (unsigned char) ((context->state[0] >> 48) & 0xff);
                    222:        digest[2] = (unsigned char) ((context->state[0] >> 40) & 0xff);
                    223:        digest[3] = (unsigned char) ((context->state[0] >> 32) & 0xff);
                    224:        digest[4] = (unsigned char) ((context->state[0] >> 24) & 0xff);
                    225:        digest[5] = (unsigned char) ((context->state[0] >> 16) & 0xff);
                    226:        digest[6] = (unsigned char) ((context->state[0] >> 8) & 0xff);
                    227:        digest[7] = (unsigned char) (context->state[0] & 0xff);
                    228:        digest[8] = (unsigned char) ((context->state[1] >> 56) & 0xff);
                    229:        digest[9] = (unsigned char) ((context->state[1] >> 48) & 0xff);
                    230:        digest[10] = (unsigned char) ((context->state[1] >> 40) & 0xff);
                    231:        digest[11] = (unsigned char) ((context->state[1] >> 32) & 0xff);
                    232:        digest[12] = (unsigned char) ((context->state[1] >> 24) & 0xff);
                    233:        digest[13] = (unsigned char) ((context->state[1] >> 16) & 0xff);
                    234:        digest[14] = (unsigned char) ((context->state[1] >> 8) & 0xff);
                    235:        digest[15] = (unsigned char) (context->state[1] & 0xff);
                    236:        
                    237:        memset(context, 0, sizeof(*context));
                    238: }
                    239: 
                    240: PHP_HASH_API void PHP_TIGER160Final(unsigned char digest[20], PHP_TIGER_CTX *context)
                    241: {
                    242:        TigerFinalize(context);
                    243:        
                    244:        digest[0] = (unsigned char) ((context->state[0] >> 56) & 0xff);
                    245:        digest[1] = (unsigned char) ((context->state[0] >> 48) & 0xff);
                    246:        digest[2] = (unsigned char) ((context->state[0] >> 40) & 0xff);
                    247:        digest[3] = (unsigned char) ((context->state[0] >> 32) & 0xff);
                    248:        digest[4] = (unsigned char) ((context->state[0] >> 24) & 0xff);
                    249:        digest[5] = (unsigned char) ((context->state[0] >> 16) & 0xff);
                    250:        digest[6] = (unsigned char) ((context->state[0] >> 8) & 0xff);
                    251:        digest[7] = (unsigned char) (context->state[0] & 0xff);
                    252:        digest[8] = (unsigned char) ((context->state[1] >> 56) & 0xff);
                    253:        digest[9] = (unsigned char) ((context->state[1] >> 48) & 0xff);
                    254:        digest[10] = (unsigned char) ((context->state[1] >> 40) & 0xff);
                    255:        digest[11] = (unsigned char) ((context->state[1] >> 32) & 0xff);
                    256:        digest[12] = (unsigned char) ((context->state[1] >> 24) & 0xff);
                    257:        digest[13] = (unsigned char) ((context->state[1] >> 16) & 0xff);
                    258:        digest[14] = (unsigned char) ((context->state[1] >> 8) & 0xff);
                    259:        digest[15] = (unsigned char) (context->state[1] & 0xff);
                    260:        digest[16] = (unsigned char) ((context->state[2] >> 56) & 0xff);
                    261:        digest[17] = (unsigned char) ((context->state[2] >> 48) & 0xff);
                    262:        digest[18] = (unsigned char) ((context->state[2] >> 40) & 0xff);
                    263:        digest[19] = (unsigned char) ((context->state[2] >> 32) & 0xff);
                    264:        
                    265:        memset(context, 0, sizeof(*context));
                    266: }
                    267: 
                    268: PHP_HASH_API void PHP_TIGER192Final(unsigned char digest[24], PHP_TIGER_CTX *context)
                    269: {
                    270:        TigerFinalize(context);
                    271:        
                    272:        digest[0] = (unsigned char) ((context->state[0] >> 56) & 0xff);
                    273:        digest[1] = (unsigned char) ((context->state[0] >> 48) & 0xff);
                    274:        digest[2] = (unsigned char) ((context->state[0] >> 40) & 0xff);
                    275:        digest[3] = (unsigned char) ((context->state[0] >> 32) & 0xff);
                    276:        digest[4] = (unsigned char) ((context->state[0] >> 24) & 0xff);
                    277:        digest[5] = (unsigned char) ((context->state[0] >> 16) & 0xff);
                    278:        digest[6] = (unsigned char) ((context->state[0] >> 8) & 0xff);
                    279:        digest[7] = (unsigned char) (context->state[0] & 0xff);
                    280:        digest[8] = (unsigned char) ((context->state[1] >> 56) & 0xff);
                    281:        digest[9] = (unsigned char) ((context->state[1] >> 48) & 0xff);
                    282:        digest[10] = (unsigned char) ((context->state[1] >> 40) & 0xff);
                    283:        digest[11] = (unsigned char) ((context->state[1] >> 32) & 0xff);
                    284:        digest[12] = (unsigned char) ((context->state[1] >> 24) & 0xff);
                    285:        digest[13] = (unsigned char) ((context->state[1] >> 16) & 0xff);
                    286:        digest[14] = (unsigned char) ((context->state[1] >> 8) & 0xff);
                    287:        digest[15] = (unsigned char) (context->state[1] & 0xff);
                    288:        digest[16] = (unsigned char) ((context->state[2] >> 56) & 0xff);
                    289:        digest[17] = (unsigned char) ((context->state[2] >> 48) & 0xff);
                    290:        digest[18] = (unsigned char) ((context->state[2] >> 40) & 0xff);
                    291:        digest[19] = (unsigned char) ((context->state[2] >> 32) & 0xff);
                    292:        digest[20] = (unsigned char) ((context->state[2] >> 24) & 0xff);
                    293:        digest[21] = (unsigned char) ((context->state[2] >> 16) & 0xff);
                    294:        digest[22] = (unsigned char) ((context->state[2] >> 8) & 0xff);
                    295:        digest[23] = (unsigned char) (context->state[2] & 0xff);
                    296:        
                    297:        memset(context, 0, sizeof(*context));
                    298: }
                    299: 
                    300: #define PHP_HASH_TIGER_OPS(p, b) \
                    301:        const php_hash_ops php_hash_##p##tiger##b##_ops = { \
                    302:                (php_hash_init_func_t) PHP_##p##TIGERInit, \
                    303:                (php_hash_update_func_t) PHP_TIGERUpdate, \
                    304:                (php_hash_final_func_t) PHP_TIGER##b##Final, \
                    305:                (php_hash_copy_func_t) php_hash_copy, \
                    306:                b/8, \
                    307:                64, \
                    308:                sizeof(PHP_TIGER_CTX) \
                    309:        }
                    310: 
                    311: PHP_HASH_TIGER_OPS(3, 128);
                    312: PHP_HASH_TIGER_OPS(3, 160);
                    313: PHP_HASH_TIGER_OPS(3, 192);
                    314: PHP_HASH_TIGER_OPS(4, 128);
                    315: PHP_HASH_TIGER_OPS(4, 160);
                    316: PHP_HASH_TIGER_OPS(4, 192);
                    317: 
                    318: /*
                    319:  * Local variables:
                    320:  * tab-width: 4
                    321:  * c-basic-offset: 4
                    322:  * End:
                    323:  * vim600: sw=4 ts=4 fdm=marker
                    324:  * vim<600: sw=4 ts=4
                    325:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>