Back to index

php5  5.3.10
hash_snefru.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   | Authors: Michael Wallner <mike@php.net>                              |
00016   |          Sara Golemon <pollita@php.net>                              |
00017   +----------------------------------------------------------------------+
00018 */
00019 
00020 /* $Id: hash_snefru.c 321634 2012-01-01 13:15:04Z felipe $ */
00021 
00022 #include "php_hash.h"
00023 #include "php_hash_snefru.h"
00024 #include "php_hash_snefru_tables.h"
00025 
00026 #define round(L, C, N, SB)  \
00027        SBE = SB[C & 0xff]; \
00028        L ^= SBE; \
00029        N ^= SBE
00030 
00031 #ifndef DBG_SNEFRU
00032 #define DBG_SNEFRU 0
00033 #endif
00034 
00035 #if DBG_SNEFRU
00036 void ph(php_hash_uint32 h[16])
00037 {
00038        int i;
00039        for (i = 0; i < 16; i++)
00040               printf ("%08lx", h[i]); printf("\n");
00041 }
00042 #endif
00043 
00044 static inline void Snefru(php_hash_uint32 input[16])
00045 {
00046        static int shifts[4] = {16, 8, 16, 24};
00047        int b, index, rshift, lshift;
00048        const php_hash_uint32 *t0,*t1;
00049        php_hash_uint32 SBE,B00,B01,B02,B03,B04,B05,B06,B07,B08,B09,B10,B11,B12,B13,B14,B15;
00050 
00051        B00 = input[0];
00052        B01 = input[1];
00053        B02 = input[2];
00054        B03 = input[3];
00055        B04 = input[4];
00056        B05 = input[5];
00057        B06 = input[6];
00058        B07 = input[7];
00059        B08 = input[8];
00060        B09 = input[9];
00061        B10 = input[10];
00062        B11 = input[11];
00063        B12 = input[12];
00064        B13 = input[13];
00065        B14 = input[14];
00066        B15 = input[15];
00067 
00068        for (index = 0; index < 8; index++) {
00069               t0 = tables[2*index+0];
00070               t1 = tables[2*index+1];
00071               for (b = 0; b < 4; b++) {
00072                      round(B15, B00, B01, t0);
00073                      round(B00, B01, B02, t0);
00074                      round(B01, B02, B03, t1);
00075                      round(B02, B03, B04, t1);
00076                      round(B03, B04, B05, t0);
00077                      round(B04, B05, B06, t0);
00078                      round(B05, B06, B07, t1);
00079                      round(B06, B07, B08, t1);
00080                      round(B07, B08, B09, t0);
00081                      round(B08, B09, B10, t0);
00082                      round(B09, B10, B11, t1);
00083                      round(B10, B11, B12, t1);
00084                      round(B11, B12, B13, t0);
00085                      round(B12, B13, B14, t0);
00086                      round(B13, B14, B15, t1);
00087                      round(B14, B15, B00, t1);
00088                      
00089                      rshift = shifts[b]; 
00090                      lshift = 32-rshift;
00091                      
00092                      B00 = (B00 >> rshift) | (B00 << lshift);
00093                      B01 = (B01 >> rshift) | (B01 << lshift);
00094                      B02 = (B02 >> rshift) | (B02 << lshift);
00095                      B03 = (B03 >> rshift) | (B03 << lshift);
00096                      B04 = (B04 >> rshift) | (B04 << lshift);
00097                      B05 = (B05 >> rshift) | (B05 << lshift);
00098                      B06 = (B06 >> rshift) | (B06 << lshift);
00099                      B07 = (B07 >> rshift) | (B07 << lshift);
00100                      B08 = (B08 >> rshift) | (B08 << lshift);
00101                      B09 = (B09 >> rshift) | (B09 << lshift);
00102                      B10 = (B10 >> rshift) | (B10 << lshift);
00103                      B11 = (B11 >> rshift) | (B11 << lshift);
00104                      B12 = (B12 >> rshift) | (B12 << lshift);
00105                      B13 = (B13 >> rshift) | (B13 << lshift);
00106                      B14 = (B14 >> rshift) | (B14 << lshift);
00107                      B15 = (B15 >> rshift) | (B15 << lshift);
00108               }
00109        }
00110        input[0] ^= B15;
00111        input[1] ^= B14;
00112        input[2] ^= B13;
00113        input[3] ^= B12;
00114        input[4] ^= B11;
00115        input[5] ^= B10;
00116        input[6] ^= B09;
00117        input[7] ^= B08;
00118 #if DBG_SNEFRU
00119        ph(input);
00120 #endif
00121 }
00122 
00123 static inline void SnefruTransform(PHP_SNEFRU_CTX *context, const unsigned char input[32])
00124 {
00125        int i, j;
00126 
00127        for (i = 0, j = 0; i < 32; i += 4, ++j) {
00128               context->state[8+j] =       ((input[i] & 0xff) << 24) | ((input[i+1] & 0xff) << 16) |
00129                                                         ((input[i+2] & 0xff) << 8) | (input[i+3] & 0xff);
00130        }
00131        Snefru(context->state);
00132        memset(&context->state[8], 0, sizeof(php_hash_uint32) * 8);
00133 }
00134 
00135 PHP_HASH_API void PHP_SNEFRUInit(PHP_SNEFRU_CTX *context)
00136 {
00137        memset(context, 0, sizeof(*context));
00138 }
00139 
00140 static const php_hash_uint32 MAX32 = 0xffffffffLU;
00141 
00142 PHP_HASH_API void PHP_SNEFRUUpdate(PHP_SNEFRU_CTX *context, const unsigned char *input, size_t len)
00143 {
00144        if ((MAX32 - context->count[1]) < (len * 8)) {
00145               context->count[0]++;
00146               context->count[1] = MAX32 - context->count[1];
00147               context->count[1] = (len * 8) - context->count[1];
00148        } else {
00149               context->count[1] += len * 8;
00150        }
00151        
00152        if (context->length + len < 32) {
00153               memcpy(&context->buffer[context->length], input, len);
00154               context->length += len;
00155        } else {
00156               size_t i = 0, r = (context->length + len) % 32;
00157               
00158               if (context->length) {
00159                      i = 32 - context->length;
00160                      memcpy(&context->buffer[context->length], input, i);
00161                      SnefruTransform(context, context->buffer);
00162               }
00163               
00164               for (; i + 32 <= len; i += 32) {
00165                      SnefruTransform(context, input + i);
00166               }
00167               
00168               memcpy(context->buffer, input + i, r);
00169               memset(&context->buffer[r], 0, 32 - r);
00170               context->length = r;
00171        }
00172 }
00173 
00174 PHP_HASH_API void PHP_SNEFRUFinal(unsigned char digest[32], PHP_SNEFRU_CTX *context)
00175 {
00176        php_hash_uint32 i, j;
00177        
00178        if (context->length) {
00179               SnefruTransform(context, context->buffer);
00180        }
00181        
00182        context->state[14] = context->count[0];
00183        context->state[15] = context->count[1];
00184        Snefru(context->state);
00185        
00186        for (i = 0, j = 0; j < 32; i++, j += 4) {
00187               digest[j] = (unsigned char) ((context->state[i] >> 24) & 0xff);
00188               digest[j + 1] = (unsigned char) ((context->state[i] >> 16) & 0xff);
00189               digest[j + 2] = (unsigned char) ((context->state[i] >> 8) & 0xff);
00190               digest[j + 3] = (unsigned char) (context->state[i] & 0xff);
00191        }
00192        
00193        memset(context, 0, sizeof(*context));
00194 }
00195 
00196 const php_hash_ops php_hash_snefru_ops = {
00197        (php_hash_init_func_t) PHP_SNEFRUInit,
00198        (php_hash_update_func_t) PHP_SNEFRUUpdate,
00199        (php_hash_final_func_t) PHP_SNEFRUFinal,
00200        (php_hash_copy_func_t) php_hash_copy,
00201        32,
00202        32,
00203        sizeof(PHP_SNEFRU_CTX)
00204 };
00205 
00206 /*
00207  * Local variables:
00208  * tab-width: 4
00209  * c-basic-offset: 4
00210  * End:
00211  * vim600: sw=4 ts=4 fdm=marker
00212  * vim<600: sw=4 ts=4
00213  */