Annotation of embedaddon/php/ext/hash/hash_gost.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:   | Authors: Michael Wallner <mike@php.net>                              |
        !            16:   |          Sara Golemon <pollita@php.net>                              |
        !            17:   +----------------------------------------------------------------------+
        !            18: */
        !            19: 
        !            20: /* $Id: hash_gost.c 321634 2012-01-01 13:15:04Z felipe $ */
        !            21: 
        !            22: #include "php_hash.h"
        !            23: #include "php_hash_gost.h"
        !            24: #include "php_hash_gost_tables.h"
        !            25: 
        !            26: /* {{{ Gost()
        !            27:  * derived from gost_compress() by Markku-Juhani Saarinen <mjos@ssh.fi>
        !            28:  */
        !            29: 
        !            30: #define round(k1, k2) \
        !            31:        t = (k1) + r; \
        !            32:        l ^= tables[0][t & 0xff] ^ tables[1][(t >> 8) & 0xff] ^ \
        !            33:                tables[2][(t >> 16) & 0xff] ^ tables[3][t >> 24]; \
        !            34:        t = (k2) + l; \
        !            35:        r ^= tables[0][t & 0xff] ^ tables[1][(t >> 8) & 0xff] ^ \
        !            36:                tables[2][(t >> 16) & 0xff] ^ tables[3][t >> 24];
        !            37: 
        !            38: #define R(key, h, i, t, l, r) \
        !            39:        r = h[i]; \
        !            40:        l = h[i + 1]; \
        !            41:        round(key[0], key[1]) \
        !            42:        round(key[2], key[3]) \
        !            43:        round(key[4], key[5]) \
        !            44:        round(key[6], key[7]) \
        !            45:        round(key[0], key[1]) \
        !            46:        round(key[2], key[3]) \
        !            47:        round(key[4], key[5]) \
        !            48:        round(key[6], key[7]) \
        !            49:        round(key[0], key[1]) \
        !            50:        round(key[2], key[3]) \
        !            51:        round(key[4], key[5]) \
        !            52:        round(key[6], key[7]) \
        !            53:        round(key[7], key[6]) \
        !            54:        round(key[5], key[4]) \
        !            55:        round(key[3], key[2]) \
        !            56:        round(key[1], key[0]) \
        !            57:        t = r; \
        !            58:        r = l; \
        !            59:        l = t; \
        !            60: 
        !            61: #define X(w, u, v) \
        !            62:        w[0] = u[0] ^ v[0]; \
        !            63:        w[1] = u[1] ^ v[1]; \
        !            64:        w[2] = u[2] ^ v[2]; \
        !            65:        w[3] = u[3] ^ v[3]; \
        !            66:        w[4] = u[4] ^ v[4]; \
        !            67:        w[5] = u[5] ^ v[5]; \
        !            68:        w[6] = u[6] ^ v[6]; \
        !            69:        w[7] = u[7] ^ v[7];
        !            70: 
        !            71: #define P(key, w) \
        !            72:        key[0] = (w[0]  & 0x000000ff) | ((w[2] & 0x000000ff) << 8) | \
        !            73:                ((w[4] & 0x000000ff) << 16) | ((w[6] & 0x000000ff) << 24); \
        !            74:        key[1] = ((w[0] & 0x0000ff00) >> 8)  | (w[2]  & 0x0000ff00) | \
        !            75:                ((w[4] & 0x0000ff00) << 8) | ((w[6] & 0x0000ff00) << 16); \
        !            76:        key[2] = ((w[0] & 0x00ff0000) >> 16) | ((w[2] & 0x00ff0000) >> 8) | \
        !            77:                (w[4] & 0x00ff0000) | ((w[6] & 0x00ff0000) << 8); \
        !            78:        key[3] = ((w[0] & 0xff000000) >> 24) | ((w[2] & 0xff000000) >> 16) | \
        !            79:                ((w[4] & 0xff000000) >> 8) | (w[6] & 0xff000000); \
        !            80:        key[4] = (w[1] & 0x000000ff) | ((w[3] & 0x000000ff) << 8) | \
        !            81:                ((w[5] & 0x000000ff) << 16) | ((w[7] & 0x000000ff) << 24); \
        !            82:        key[5] = ((w[1] & 0x0000ff00) >> 8) | (w[3]  & 0x0000ff00) | \
        !            83:                ((w[5] & 0x0000ff00) << 8) | ((w[7] & 0x0000ff00) << 16); \
        !            84:        key[6] = ((w[1] & 0x00ff0000) >> 16) | ((w[3] & 0x00ff0000) >> 8) | \
        !            85:                (w[5] & 0x00ff0000) | ((w[7] & 0x00ff0000) << 8); \
        !            86:        key[7] = ((w[1] & 0xff000000) >> 24) | ((w[3] & 0xff000000) >> 16) | \
        !            87:                ((w[5] & 0xff000000) >> 8) | (w[7] & 0xff000000);  
        !            88: 
        !            89: #define A(x, l, r) \
        !            90:        l = x[0] ^ x[2]; \
        !            91:        r = x[1] ^ x[3]; \
        !            92:        x[0] = x[2]; \
        !            93:        x[1] = x[3]; \
        !            94:        x[2] = x[4]; \
        !            95:        x[3] = x[5]; \
        !            96:        x[4] = x[6]; \
        !            97:        x[5] = x[7]; \
        !            98:        x[6] = l; \
        !            99:        x[7] = r;
        !           100: 
        !           101: #define AA(x, l, r) \
        !           102:        l = x[0]; \
        !           103:        r = x[2]; \
        !           104:        x[0] = x[4]; \
        !           105:        x[2] = x[6]; \
        !           106:        x[4] = l ^ r; \
        !           107:        x[6] = x[0] ^ r; \
        !           108:        l = x[1]; \
        !           109:        r = x[3]; \
        !           110:        x[1] = x[5]; \
        !           111:        x[3] = x[7]; \
        !           112:        x[5] = l ^ r; \
        !           113:        x[7] = x[1] ^ r;
        !           114: 
        !           115: #define C(x) \
        !           116:        x[0] ^= 0xff00ff00; \
        !           117:        x[1] ^= 0xff00ff00; \
        !           118:        x[2] ^= 0x00ff00ff; \
        !           119:        x[3] ^= 0x00ff00ff; \
        !           120:        x[4] ^= 0x00ffff00; \
        !           121:        x[5] ^= 0xff0000ff; \
        !           122:        x[6] ^= 0x000000ff; \
        !           123:        x[7] ^= 0xff00ffff;
        !           124: 
        !           125: #define S(s, l, r) \
        !           126:                s[i] = r; \
        !           127:                s[i + 1] = l;
        !           128: 
        !           129: #define SHIFT12(u, m, s) \
        !           130:        u[0] = m[0] ^ s[6]; \
        !           131:        u[1] = m[1] ^ s[7]; \
        !           132:        u[2] = m[2] ^ (s[0] << 16) ^ (s[0] >> 16) ^ (s[0] & 0xffff) ^ \
        !           133:                (s[1] & 0xffff) ^ (s[1] >> 16) ^ (s[2] << 16) ^ s[6] ^ (s[6] << 16) ^ \
        !           134:                (s[7] & 0xffff0000) ^ (s[7] >> 16); \
        !           135:        u[3] = m[3] ^ (s[0] & 0xffff) ^ (s[0] << 16) ^ (s[1] & 0xffff) ^ \
        !           136:                (s[1] << 16) ^ (s[1] >> 16) ^ (s[2] << 16) ^ (s[2] >> 16) ^ \
        !           137:                (s[3] << 16) ^ s[6] ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff) ^ \
        !           138:                (s[7] << 16) ^ (s[7] >> 16); \
        !           139:        u[4] = m[4] ^ \
        !           140:                (s[0] & 0xffff0000) ^ (s[0] << 16) ^ (s[0] >> 16) ^ \
        !           141:                (s[1] & 0xffff0000) ^ (s[1] >> 16) ^ (s[2] << 16) ^ (s[2] >> 16) ^ \
        !           142:                (s[3] << 16) ^ (s[3] >> 16) ^ (s[4] << 16) ^ (s[6] << 16) ^ \
        !           143:                (s[6] >> 16) ^(s[7] & 0xffff) ^ (s[7] << 16) ^ (s[7] >> 16); \
        !           144:        u[5] = m[5] ^ (s[0] << 16) ^ (s[0] >> 16) ^ (s[0] & 0xffff0000) ^ \
        !           145:                (s[1] & 0xffff) ^ s[2] ^ (s[2] >> 16) ^ (s[3] << 16) ^ (s[3] >> 16) ^ \
        !           146:                (s[4] << 16) ^ (s[4] >> 16) ^ (s[5] << 16) ^  (s[6] << 16) ^ \
        !           147:                (s[6] >> 16) ^ (s[7] & 0xffff0000) ^ (s[7] << 16) ^ (s[7] >> 16); \
        !           148:        u[6] = m[6] ^ s[0] ^ (s[1] >> 16) ^ (s[2] << 16) ^ s[3] ^ (s[3] >> 16) ^ \
        !           149:                (s[4] << 16) ^ (s[4] >> 16) ^ (s[5] << 16) ^ (s[5] >> 16) ^ s[6] ^ \
        !           150:                (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] << 16); \
        !           151:        u[7] = m[7] ^ (s[0] & 0xffff0000) ^ (s[0] << 16) ^ (s[1] & 0xffff) ^ \
        !           152:                (s[1] << 16) ^ (s[2] >> 16) ^ (s[3] << 16) ^ s[4] ^ (s[4] >> 16) ^ \
        !           153:                (s[5] << 16) ^ (s[5] >> 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff) ^ \
        !           154:                (s[7] << 16) ^ (s[7] >> 16);
        !           155: 
        !           156: #define SHIFT16(h, v, u) \
        !           157:        v[0] = h[0] ^ (u[1] << 16) ^ (u[0] >> 16); \
        !           158:        v[1] = h[1] ^ (u[2] << 16) ^ (u[1] >> 16); \
        !           159:        v[2] = h[2] ^ (u[3] << 16) ^ (u[2] >> 16); \
        !           160:        v[3] = h[3] ^ (u[4] << 16) ^ (u[3] >> 16); \
        !           161:        v[4] = h[4] ^ (u[5] << 16) ^ (u[4] >> 16); \
        !           162:        v[5] = h[5] ^ (u[6] << 16) ^ (u[5] >> 16); \
        !           163:        v[6] = h[6] ^ (u[7] << 16) ^ (u[6] >> 16); \
        !           164:        v[7] = h[7] ^ (u[0] & 0xffff0000) ^ (u[0] << 16) ^ (u[7] >> 16) ^ \
        !           165:                (u[1] & 0xffff0000) ^ (u[1] << 16) ^ (u[6] << 16) ^ (u[7] & 0xffff0000);
        !           166: 
        !           167: #define SHIFT61(h, v) \
        !           168:        h[0] = (v[0] & 0xffff0000) ^ (v[0] << 16) ^ (v[0] >> 16) ^ (v[1] >> 16) ^ \
        !           169:                (v[1] & 0xffff0000) ^ (v[2] << 16) ^ (v[3] >> 16) ^ (v[4] << 16) ^ \
        !           170:                (v[5] >> 16) ^ v[5] ^ (v[6] >> 16) ^ (v[7] << 16) ^ (v[7] >> 16) ^ \
        !           171:                (v[7] & 0xffff); \
        !           172:        h[1] = (v[0] << 16) ^ (v[0] >> 16) ^ (v[0] & 0xffff0000) ^ (v[1] & 0xffff) ^ \
        !           173:        v[2] ^ (v[2] >> 16) ^ (v[3] << 16) ^ (v[4] >> 16) ^ (v[5] << 16) ^ \
        !           174:                (v[6] << 16) ^ v[6] ^ (v[7] & 0xffff0000) ^ (v[7] >> 16); \
        !           175:        h[2] = (v[0] & 0xffff) ^ (v[0] << 16) ^ (v[1] << 16) ^ (v[1] >> 16) ^ \
        !           176:                (v[1] & 0xffff0000) ^ (v[2] << 16) ^ (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ \
        !           177:                (v[5] >> 16) ^ v[6] ^ (v[6] >> 16) ^ (v[7] & 0xffff) ^ (v[7] << 16) ^ \
        !           178:                (v[7] >> 16); \
        !           179:        h[3] = (v[0] << 16) ^ (v[0] >> 16) ^ (v[0] & 0xffff0000) ^ \
        !           180:                (v[1] & 0xffff0000) ^ (v[1] >> 16) ^ (v[2] << 16) ^ (v[2] >> 16) ^ v[2] ^ \
        !           181:                (v[3] << 16) ^ (v[4] >> 16) ^ v[4] ^ (v[5] << 16) ^ (v[6] << 16) ^ \
        !           182:                (v[7] & 0xffff) ^ (v[7] >> 16); \
        !           183:        h[4] = (v[0] >> 16) ^ (v[1] << 16) ^ v[1] ^ (v[2] >> 16) ^ v[2] ^ \
        !           184:                (v[3] << 16) ^ (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ (v[5] >> 16) ^ \
        !           185:        v[5] ^ (v[6] << 16) ^ (v[6] >> 16) ^ (v[7] << 16); \
        !           186:        h[5] = (v[0] << 16) ^ (v[0] & 0xffff0000) ^ (v[1] << 16) ^ (v[1] >> 16) ^ \
        !           187:                (v[1] & 0xffff0000) ^ (v[2] << 16) ^ v[2] ^ (v[3] >> 16) ^ v[3] ^ \
        !           188:                (v[4] << 16) ^ (v[4] >> 16) ^ v[4] ^ (v[5] << 16) ^ (v[6] << 16) ^ \
        !           189:                (v[6] >> 16) ^ v[6] ^ (v[7] << 16) ^ (v[7] >> 16) ^ (v[7] & 0xffff0000); \
        !           190:        h[6] = v[0] ^ v[2] ^ (v[2] >> 16) ^ v[3] ^ (v[3] << 16) ^ v[4] ^ \
        !           191:                (v[4] >> 16) ^ (v[5] << 16) ^ (v[5] >> 16) ^ v[5] ^ (v[6] << 16) ^ \
        !           192:                (v[6] >> 16) ^ v[6] ^ (v[7] << 16) ^ v[7]; \
        !           193:        h[7] = v[0] ^ (v[0] >> 16) ^ (v[1] << 16) ^ (v[1] >> 16) ^ (v[2] << 16) ^ \
        !           194:                (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ v[4] ^ (v[5] >> 16) ^ v[5] ^ \
        !           195:                (v[6] << 16) ^ (v[6] >> 16) ^ (v[7] << 16) ^ v[7];
        !           196: 
        !           197: #define PASS \
        !           198:        X(w, u, v); \
        !           199:        P(key, w); \
        !           200:        R(key, h, i, t, l, r); \
        !           201:        S(s, l, r); \
        !           202:        if (i != 6) { \
        !           203:                A(u, l, r); \
        !           204:                if (i == 2)     { \
        !           205:                        C(u); \
        !           206:                } \
        !           207:                AA(v, l, r); \
        !           208:        }
        !           209: 
        !           210: static inline void Gost(php_hash_uint32 state[8], php_hash_uint32 data[8])
        !           211: {
        !           212:        int i;
        !           213:        php_hash_uint32 l, r, t, key[8], u[8], v[8], w[8], s[8], *h = state, *m = data;
        !           214:        
        !           215:        memcpy(u, state, sizeof(u));
        !           216:        memcpy(v, data, sizeof(v));
        !           217:        
        !           218:        for (i = 0; i < 8; i += 2) {
        !           219:                PASS;
        !           220:        }
        !           221:        SHIFT12(u, m, s);
        !           222:        SHIFT16(h, v, u);
        !           223:        SHIFT61(h, v);
        !           224: }
        !           225: /* }}} */
        !           226: 
        !           227: static inline void GostTransform(PHP_GOST_CTX *context, const unsigned char input[32])
        !           228: {
        !           229:        int i, j;
        !           230:        php_hash_uint32 data[8], temp = 0, save = 0;
        !           231:        
        !           232:        for (i = 0, j = 0; i < 8; ++i, j += 4) {
        !           233:                data[i] =       ((php_hash_uint32) input[j]) | (((php_hash_uint32) input[j + 1]) << 8) | 
        !           234:                                        (((php_hash_uint32) input[j + 2]) << 16) | (((php_hash_uint32) input[j + 3]) << 24);
        !           235:                save = context->state[i + 8];
        !           236:                context->state[i + 8] += data[i] + temp;
        !           237:                temp = ((context->state[i + 8] < data[i]) || (context->state[i + 8] < save)) ? 1 : 0;     
        !           238:        }
        !           239:        
        !           240:        Gost(context->state, data);
        !           241: }
        !           242: 
        !           243: PHP_HASH_API void PHP_GOSTInit(PHP_GOST_CTX *context)
        !           244: {
        !           245:        memset(context, 0, sizeof(*context));
        !           246: }
        !           247: 
        !           248: static const php_hash_uint32 MAX32 = 0xffffffffLU;
        !           249: 
        !           250: PHP_HASH_API void PHP_GOSTUpdate(PHP_GOST_CTX *context, const unsigned char *input, size_t len)
        !           251: {
        !           252:        if ((MAX32 - context->count[0]) < (len * 8)) {
        !           253:                context->count[1]++;
        !           254:                context->count[0] = MAX32 - context->count[0];
        !           255:                context->count[0] = (len * 8) - context->count[0];
        !           256:        } else {
        !           257:                context->count[0] += len * 8;
        !           258:        }
        !           259:        
        !           260:        if (context->length + len < 32) {
        !           261:                memcpy(&context->buffer[context->length], input, len);
        !           262:                context->length += len;
        !           263:        } else {
        !           264:                size_t i = 0, r = (context->length + len) % 32;
        !           265:                
        !           266:                if (context->length) {
        !           267:                        i = 32 - context->length;
        !           268:                        memcpy(&context->buffer[context->length], input, i);
        !           269:                        GostTransform(context, context->buffer);
        !           270:                }
        !           271:                
        !           272:                for (; i + 32 <= len; i += 32) {
        !           273:                        GostTransform(context, input + i);
        !           274:                }
        !           275:                
        !           276:                memcpy(context->buffer, input + i, r);
        !           277:                memset(&context->buffer[r], 0, 32 - r);
        !           278:                context->length = r;
        !           279:        }
        !           280: }
        !           281: 
        !           282: PHP_HASH_API void PHP_GOSTFinal(unsigned char digest[32], PHP_GOST_CTX *context)
        !           283: {
        !           284:        php_hash_uint32 i, j, l[8] = {0};
        !           285:        
        !           286:        if (context->length) {
        !           287:                GostTransform(context, context->buffer);
        !           288:        }
        !           289:        
        !           290:        memcpy(l, context->count, sizeof(context->count));
        !           291:        Gost(context->state, l);
        !           292:        memcpy(l, &context->state[8], sizeof(l));
        !           293:        Gost(context->state, l);
        !           294:        
        !           295:        for (i = 0, j = 0; j < 32; i++, j += 4) {
        !           296:                digest[j] = (unsigned char) (context->state[i] & 0xff);
        !           297:                digest[j + 1] = (unsigned char) ((context->state[i] >> 8) & 0xff);
        !           298:                digest[j + 2] = (unsigned char) ((context->state[i] >> 16) & 0xff);
        !           299:                digest[j + 3] = (unsigned char) ((context->state[i] >> 24) & 0xff);
        !           300:        }
        !           301:        
        !           302:        memset(context, 0, sizeof(*context));
        !           303: }
        !           304: 
        !           305: const php_hash_ops php_hash_gost_ops = {
        !           306:        (php_hash_init_func_t) PHP_GOSTInit,
        !           307:        (php_hash_update_func_t) PHP_GOSTUpdate,
        !           308:        (php_hash_final_func_t) PHP_GOSTFinal,
        !           309:        (php_hash_copy_func_t) php_hash_copy,
        !           310:        32,
        !           311:        32,
        !           312:        sizeof(PHP_GOST_CTX)
        !           313: };
        !           314: 
        !           315: /*
        !           316:  * Local variables:
        !           317:  * tab-width: 4
        !           318:  * c-basic-offset: 4
        !           319:  * End:
        !           320:  * vim600: sw=4 ts=4 fdm=marker
        !           321:  * vim<600: sw=4 ts=4
        !           322:  */

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