Annotation of embedaddon/php/ext/hash/hash_salsa.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_salsa.c 321634 2012-01-01 13:15:04Z felipe $ */
        !            21: 
        !            22: #include "php_hash.h"
        !            23: #include "php_hash_salsa.h"
        !            24: 
        !            25: #define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
        !            26: 
        !            27: /* {{{ Salsa10
        !            28:  
        !            29:  The 64-byte input x to Salsa10 is viewed in little-endian form as 16 integers 
        !            30:  x0, x1, x2, ..., x15 in {0,1,...,2^32-1}. These 16 integers are fed through 
        !            31:  320 invertible modifications, where each modification changes one integer. 
        !            32:  The modifications involve, overall,
        !            33: 
        !            34:     * 10 additions of constants modulo 2^32;
        !            35:     * 320 more additions modulo 2^32;
        !            36:     * 80 ``or'' operations;
        !            37:     * 240 ``xor'' operations; and
        !            38:     * 320 constant-distance rotations. 
        !            39: 
        !            40:  The resulting 16 integers are added to the original x0, x1, x2, ..., x15 
        !            41:  respectively modulo 2^32, producing, in little-endian form, the 64-byte output 
        !            42:  Salsa10(x).
        !            43:  
        !            44:  D.J.Bernstein
        !            45: */
        !            46: static void Salsa10(php_hash_uint32 x[16], php_hash_uint32 in[16])
        !            47: {
        !            48:        int i;
        !            49:        
        !            50:        for (i = 10; i > 0; --i) {
        !            51:                x[ 4] ^= R(x[ 0]+x[12], 6);  x[ 8] ^= R(x[ 4]+x[ 0],17);
        !            52:                x[12] += R(x[ 8]|x[ 4],16);  x[ 0] += R(x[12]^x[ 8], 5);
        !            53:                x[ 9] += R(x[ 5]|x[ 1], 8);  x[13] += R(x[ 9]|x[ 5], 7);
        !            54:                x[ 1] ^= R(x[13]+x[ 9],17);  x[ 5] += R(x[ 1]^x[13],12);
        !            55:                x[14] ^= R(x[10]+x[ 6], 7);  x[ 2] += R(x[14]^x[10],15);
        !            56:                x[ 6] ^= R(x[ 2]+x[14],13);  x[10] ^= R(x[ 6]+x[ 2],15);
        !            57:                x[ 3] += R(x[15]|x[11],20);  x[ 7] ^= R(x[ 3]+x[15],16);
        !            58:                x[11] += R(x[ 7]^x[ 3], 7);  x[15] += R(x[11]^x[ 7], 8);
        !            59:                x[ 1] += R(x[ 0]|x[ 3], 8)^i;x[ 2] ^= R(x[ 1]+x[ 0],14);
        !            60:                x[ 3] ^= R(x[ 2]+x[ 1], 6);  x[ 0] += R(x[ 3]^x[ 2],18);
        !            61:                x[ 6] += R(x[ 5]^x[ 4], 8);  x[ 7] += R(x[ 6]^x[ 5],12);
        !            62:                x[ 4] += R(x[ 7]|x[ 6],13);  x[ 5] ^= R(x[ 4]+x[ 7],15);
        !            63:                x[11] ^= R(x[10]+x[ 9],18);  x[ 8] += R(x[11]^x[10],11);
        !            64:                x[ 9] ^= R(x[ 8]+x[11], 8);  x[10] += R(x[ 9]|x[ 8], 6);
        !            65:                x[12] += R(x[15]^x[14],17);  x[13] ^= R(x[12]+x[15],15);
        !            66:                x[14] += R(x[13]|x[12], 9);  x[15] += R(x[14]^x[13], 7);
        !            67:        }
        !            68:        for (i = 0; i < 16; ++i) {
        !            69:                x[i] += in[i];
        !            70:        }
        !            71: }
        !            72: /* }}} */
        !            73: 
        !            74: /* {{{ Salsa20
        !            75:  
        !            76:  The 64-byte input x to Salsa20 is viewed in little-endian form as 16 words 
        !            77:  x0, x1, x2, ..., x15 in {0,1,...,2^32-1}. These 16 words are fed through 320 
        !            78:  invertible modifications, where each modification changes one word. The 
        !            79:  resulting 16 words are added to the original x0, x1, x2, ..., x15 respectively 
        !            80:  modulo 2^32, producing, in little-endian form, the 64-byte output Salsa20(x).
        !            81: 
        !            82:  Each modification involves xor'ing into one word a rotated version of the sum 
        !            83:  of two other words modulo 2^32. Thus the 320 modifications involve, overall, 
        !            84:  320 additions, 320 xor's, and 320 rotations. The rotations are all by constant 
        !            85:  distances.
        !            86: 
        !            87:  The entire series of modifications is a series of 10 identical double-rounds. 
        !            88:  Each double-round is a series of 2 rounds. Each round is a set of 4 parallel 
        !            89:  quarter-rounds. Each quarter-round modifies 4 words.
        !            90:  
        !            91:  D.J.Bernstein
        !            92: */
        !            93: static void Salsa20(php_hash_uint32 x[16], php_hash_uint32 in[16])
        !            94: {
        !            95:        int i;
        !            96:        
        !            97:        for (i = 20; i > 0; i -= 2) {
        !            98:                x[ 4] ^= R(x[ 0]+x[12], 7);  x[ 8] ^= R(x[ 4]+x[ 0], 9);
        !            99:                x[12] ^= R(x[ 8]+x[ 4],13);  x[ 0] ^= R(x[12]+x[ 8],18);
        !           100:                x[ 9] ^= R(x[ 5]+x[ 1], 7);  x[13] ^= R(x[ 9]+x[ 5], 9);
        !           101:                x[ 1] ^= R(x[13]+x[ 9],13);  x[ 5] ^= R(x[ 1]+x[13],18);
        !           102:                x[14] ^= R(x[10]+x[ 6], 7);  x[ 2] ^= R(x[14]+x[10], 9);
        !           103:                x[ 6] ^= R(x[ 2]+x[14],13);  x[10] ^= R(x[ 6]+x[ 2],18);
        !           104:                x[ 3] ^= R(x[15]+x[11], 7);  x[ 7] ^= R(x[ 3]+x[15], 9);
        !           105:                x[11] ^= R(x[ 7]+x[ 3],13);  x[15] ^= R(x[11]+x[ 7],18);
        !           106:                x[ 1] ^= R(x[ 0]+x[ 3], 7);  x[ 2] ^= R(x[ 1]+x[ 0], 9);
        !           107:                x[ 3] ^= R(x[ 2]+x[ 1],13);  x[ 0] ^= R(x[ 3]+x[ 2],18);
        !           108:                x[ 6] ^= R(x[ 5]+x[ 4], 7);  x[ 7] ^= R(x[ 6]+x[ 5], 9);
        !           109:                x[ 4] ^= R(x[ 7]+x[ 6],13);  x[ 5] ^= R(x[ 4]+x[ 7],18);
        !           110:                x[11] ^= R(x[10]+x[ 9], 7);  x[ 8] ^= R(x[11]+x[10], 9);
        !           111:                x[ 9] ^= R(x[ 8]+x[11],13);  x[10] ^= R(x[ 9]+x[ 8],18);
        !           112:                x[12] ^= R(x[15]+x[14], 7);  x[13] ^= R(x[12]+x[15], 9);
        !           113:                x[14] ^= R(x[13]+x[12],13);  x[15] ^= R(x[14]+x[13],18);
        !           114:        }
        !           115:        for (i = 0; i < 16; ++i) {
        !           116:                x[i] += in[i];
        !           117:        }
        !           118: }
        !           119: /* }}} */
        !           120: 
        !           121: static inline void SalsaTransform(PHP_SALSA_CTX *context, const unsigned char input[64])
        !           122: {
        !           123:        php_hash_uint32 i, j, a[16];
        !           124: 
        !           125: #if 0
        !           126:        fprintf(stderr, "> INPUT: %.*s\n", 64, input);
        !           127: #endif
        !           128:        
        !           129:        for (i = 0, j = 0; j < 64; i++, j += 4) {
        !           130:                a[i] = ((php_hash_uint32) input[j + 3]) | (((php_hash_uint32) input[j + 2]) << 8) |
        !           131:                        (((php_hash_uint32) input[j + 1]) << 16) | (((php_hash_uint32) input[j]) << 24);
        !           132:        }
        !           133:        
        !           134:        if (!context->init) {
        !           135:                memcpy(context->state, a, sizeof(a));
        !           136:                context->init = 1;
        !           137:        }
        !           138:        
        !           139:        context->Transform(context->state, a);
        !           140:        memset(a, 0, sizeof(a));
        !           141: }
        !           142: 
        !           143: PHP_HASH_API void PHP_SALSA10Init(PHP_SALSA_CTX *context)
        !           144: {
        !           145:        memset(context, 0, sizeof(*context));
        !           146:        context->Transform = Salsa10;
        !           147: }
        !           148: 
        !           149: PHP_HASH_API void PHP_SALSA20Init(PHP_SALSA_CTX *context)
        !           150: {
        !           151:        memset(context, 0, sizeof(*context));
        !           152:        context->Transform = Salsa20;
        !           153: }
        !           154: 
        !           155: PHP_HASH_API void PHP_SALSAUpdate(PHP_SALSA_CTX *context, const unsigned char *input, size_t len)
        !           156: {
        !           157:        if (context->length + len < 64) {
        !           158:                memcpy(&context->buffer[context->length], input, len);
        !           159:                context->length += len;
        !           160:        } else {
        !           161:                size_t i = 0, r = (context->length + len) % 64;
        !           162:                
        !           163:                if (context->length) {
        !           164:                        i = 64 - context->length;
        !           165:                        memcpy(&context->buffer[context->length], input, i);
        !           166:                        SalsaTransform(context, context->buffer);
        !           167:                        memset(context->buffer, 0, 64);
        !           168:                }
        !           169:                
        !           170:                for (; i + 64 <= len; i += 64) {
        !           171:                        SalsaTransform(context, input + i);
        !           172:                }
        !           173:                
        !           174:                memcpy(context->buffer, input + i, r);
        !           175:                context->length = r;
        !           176:        }
        !           177: }
        !           178: 
        !           179: PHP_HASH_API void PHP_SALSAFinal(unsigned char digest[64], PHP_SALSA_CTX *context)
        !           180: {
        !           181:        php_hash_uint32 i, j;
        !           182:        
        !           183:        if (context->length) {
        !           184:                SalsaTransform(context, context->buffer);
        !           185:        }
        !           186:        
        !           187:        for (i = 0, j = 0; j < 64; i++, j += 4) {
        !           188:                digest[j] = (unsigned char) ((context->state[i] >> 24) & 0xff);
        !           189:                digest[j + 1] = (unsigned char) ((context->state[i] >> 16) & 0xff);
        !           190:                digest[j + 2] = (unsigned char) ((context->state[i] >> 8) & 0xff);
        !           191:                digest[j + 3] = (unsigned char) (context->state[i] & 0xff);
        !           192:        }
        !           193:        
        !           194:        memset(context, 0, sizeof(*context));
        !           195: }
        !           196: 
        !           197: const php_hash_ops php_hash_salsa10_ops = {
        !           198:        (php_hash_init_func_t) PHP_SALSA10Init,
        !           199:        (php_hash_update_func_t) PHP_SALSAUpdate,
        !           200:        (php_hash_final_func_t) PHP_SALSAFinal,
        !           201:        (php_hash_copy_func_t) php_hash_copy,
        !           202:        64,
        !           203:        64,
        !           204:        sizeof(PHP_SALSA_CTX)
        !           205: };
        !           206: 
        !           207: const php_hash_ops php_hash_salsa20_ops = {
        !           208:        (php_hash_init_func_t) PHP_SALSA20Init,
        !           209:        (php_hash_update_func_t) PHP_SALSAUpdate,
        !           210:        (php_hash_final_func_t) PHP_SALSAFinal,
        !           211:        (php_hash_copy_func_t) php_hash_copy,
        !           212:        64,
        !           213:        64,
        !           214:        sizeof(PHP_SALSA_CTX)
        !           215: };
        !           216: 
        !           217: /*
        !           218:  * Local variables:
        !           219:  * tab-width: 4
        !           220:  * c-basic-offset: 4
        !           221:  * End:
        !           222:  * vim600: sw=4 ts=4 fdm=marker
        !           223:  * vim<600: sw=4 ts=4
        !           224:  */

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