Annotation of embedaddon/php/ext/hash/hash_tiger.c, revision 1.1.1.2

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: 
1.1.1.2 ! misho      20: /* $Id$ */
1.1       misho      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; \
1.1.1.2 ! misho     123:        unsigned int pass_no; \
1.1       misho     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: 
1.1.1.2 ! misho     172: static inline void TigerDigest(unsigned char *digest_str, unsigned int digest_len, PHP_TIGER_CTX *context)
        !           173: {
        !           174:        unsigned int i;
        !           175: 
        !           176:        for (i = 0; i < digest_len; ++i) {
        !           177:                digest_str[i] = (unsigned char) ((context->state[i/8] >> (8 * (i%8))) & 0xff);
        !           178:        }
        !           179: }
        !           180: 
1.1       misho     181: PHP_HASH_API void PHP_3TIGERInit(PHP_TIGER_CTX *context)
                    182: {
                    183:        memset(context, 0, sizeof(*context));
                    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_4TIGERInit(PHP_TIGER_CTX *context)
                    190: {
                    191:        memset(context, 0, sizeof(*context));
                    192:        context->passes = 1;
                    193:        context->state[0] = L64(0x0123456789ABCDEF);
                    194:        context->state[1] = L64(0xFEDCBA9876543210);
                    195:        context->state[2] = L64(0xF096A5B4C3B2E187);
                    196: }
                    197: 
                    198: PHP_HASH_API void PHP_TIGERUpdate(PHP_TIGER_CTX *context, const unsigned char *input, size_t len)
                    199: {
                    200:        if (context->length + len < 64) {
                    201:                memcpy(&context->buffer[context->length], input, len);
                    202:                context->length += len;
                    203:        } else {
                    204:                size_t i = 0, r = (context->length + len) % 64;
                    205:                
                    206:                if (context->length) {
                    207:                        i = 64 - context->length;
                    208:                        memcpy(&context->buffer[context->length], input, i);
                    209:                        tiger_compress(context->passes, ((const php_hash_uint64 *) context->buffer), context->state);
                    210:                        memset(context->buffer, 0, 64);
                    211:                        context->passed += 512;
                    212:                }
                    213:                
                    214:                for (; i + 64 <= len; i += 64) {
                    215:                        memcpy(context->buffer, &input[i], 64);
                    216:                        tiger_compress(context->passes, ((const php_hash_uint64 *) context->buffer), context->state);
                    217:                        context->passed += 512;
                    218:                }
                    219:                memset(&context->buffer[r], 0, 64-r);
                    220:                memcpy(context->buffer, &input[i], r);
                    221:                context->length = r;
                    222:        }
                    223: }
                    224: 
                    225: PHP_HASH_API void PHP_TIGER128Final(unsigned char digest[16], PHP_TIGER_CTX *context)
                    226: {
                    227:        TigerFinalize(context);
1.1.1.2 ! misho     228:        TigerDigest(digest, 16, context);
1.1       misho     229:        memset(context, 0, sizeof(*context));
                    230: }
                    231: 
                    232: PHP_HASH_API void PHP_TIGER160Final(unsigned char digest[20], PHP_TIGER_CTX *context)
                    233: {
                    234:        TigerFinalize(context);
1.1.1.2 ! misho     235:        TigerDigest(digest, 20, context);
1.1       misho     236:        memset(context, 0, sizeof(*context));
                    237: }
                    238: 
                    239: PHP_HASH_API void PHP_TIGER192Final(unsigned char digest[24], PHP_TIGER_CTX *context)
                    240: {
                    241:        TigerFinalize(context);
1.1.1.2 ! misho     242:        TigerDigest(digest, 24, context);
1.1       misho     243:        memset(context, 0, sizeof(*context));
                    244: }
                    245: 
                    246: #define PHP_HASH_TIGER_OPS(p, b) \
                    247:        const php_hash_ops php_hash_##p##tiger##b##_ops = { \
                    248:                (php_hash_init_func_t) PHP_##p##TIGERInit, \
                    249:                (php_hash_update_func_t) PHP_TIGERUpdate, \
                    250:                (php_hash_final_func_t) PHP_TIGER##b##Final, \
                    251:                (php_hash_copy_func_t) php_hash_copy, \
                    252:                b/8, \
                    253:                64, \
                    254:                sizeof(PHP_TIGER_CTX) \
                    255:        }
                    256: 
                    257: PHP_HASH_TIGER_OPS(3, 128);
                    258: PHP_HASH_TIGER_OPS(3, 160);
                    259: PHP_HASH_TIGER_OPS(3, 192);
                    260: PHP_HASH_TIGER_OPS(4, 128);
                    261: PHP_HASH_TIGER_OPS(4, 160);
                    262: PHP_HASH_TIGER_OPS(4, 192);
                    263: 
                    264: /*
                    265:  * Local variables:
                    266:  * tab-width: 4
                    267:  * c-basic-offset: 4
                    268:  * End:
                    269:  * vim600: sw=4 ts=4 fdm=marker
                    270:  * vim<600: sw=4 ts=4
                    271:  */

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