1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2009 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_snefru.c 272370 2008-12-31 11:15:49Z sebastian $ */
21 :
22 : #include "php_hash.h"
23 : #include "php_hash_snefru.h"
24 : #include "php_hash_snefru_tables.h"
25 :
26 : #define round(L, C, N, SB) \
27 : SBE = SB[C & 0xff]; \
28 : L ^= SBE; \
29 : N ^= SBE
30 :
31 : #ifndef DBG_SNEFRU
32 : #define DBG_SNEFRU 0
33 : #endif
34 :
35 : #if DBG_SNEFRU
36 : void ph(php_hash_uint32 h[16])
37 : {
38 : int i;
39 : for (i = 0; i < 16; i++)
40 : printf ("%08lx", h[i]); printf("\n");
41 : }
42 : #endif
43 :
44 : static inline void Snefru(php_hash_uint32 input[16])
45 51 : {
46 : static int shifts[4] = {16, 8, 16, 24};
47 : int b, index, rshift, lshift;
48 : const php_hash_uint32 *t0,*t1;
49 : php_hash_uint32 SBE,B00,B01,B02,B03,B04,B05,B06,B07,B08,B09,B10,B11,B12,B13,B14,B15;
50 :
51 51 : B00 = input[0];
52 51 : B01 = input[1];
53 51 : B02 = input[2];
54 51 : B03 = input[3];
55 51 : B04 = input[4];
56 51 : B05 = input[5];
57 51 : B06 = input[6];
58 51 : B07 = input[7];
59 51 : B08 = input[8];
60 51 : B09 = input[9];
61 51 : B10 = input[10];
62 51 : B11 = input[11];
63 51 : B12 = input[12];
64 51 : B13 = input[13];
65 51 : B14 = input[14];
66 51 : B15 = input[15];
67 :
68 459 : for (index = 0; index < 8; index++) {
69 408 : t0 = tables[2*index+0];
70 408 : t1 = tables[2*index+1];
71 2040 : for (b = 0; b < 4; b++) {
72 1632 : round(B15, B00, B01, t0);
73 1632 : round(B00, B01, B02, t0);
74 1632 : round(B01, B02, B03, t1);
75 1632 : round(B02, B03, B04, t1);
76 1632 : round(B03, B04, B05, t0);
77 1632 : round(B04, B05, B06, t0);
78 1632 : round(B05, B06, B07, t1);
79 1632 : round(B06, B07, B08, t1);
80 1632 : round(B07, B08, B09, t0);
81 1632 : round(B08, B09, B10, t0);
82 1632 : round(B09, B10, B11, t1);
83 1632 : round(B10, B11, B12, t1);
84 1632 : round(B11, B12, B13, t0);
85 1632 : round(B12, B13, B14, t0);
86 1632 : round(B13, B14, B15, t1);
87 1632 : round(B14, B15, B00, t1);
88 :
89 1632 : rshift = shifts[b];
90 1632 : lshift = 32-rshift;
91 :
92 1632 : B00 = (B00 >> rshift) | (B00 << lshift);
93 1632 : B01 = (B01 >> rshift) | (B01 << lshift);
94 1632 : B02 = (B02 >> rshift) | (B02 << lshift);
95 1632 : B03 = (B03 >> rshift) | (B03 << lshift);
96 1632 : B04 = (B04 >> rshift) | (B04 << lshift);
97 1632 : B05 = (B05 >> rshift) | (B05 << lshift);
98 1632 : B06 = (B06 >> rshift) | (B06 << lshift);
99 1632 : B07 = (B07 >> rshift) | (B07 << lshift);
100 1632 : B08 = (B08 >> rshift) | (B08 << lshift);
101 1632 : B09 = (B09 >> rshift) | (B09 << lshift);
102 1632 : B10 = (B10 >> rshift) | (B10 << lshift);
103 1632 : B11 = (B11 >> rshift) | (B11 << lshift);
104 1632 : B12 = (B12 >> rshift) | (B12 << lshift);
105 1632 : B13 = (B13 >> rshift) | (B13 << lshift);
106 1632 : B14 = (B14 >> rshift) | (B14 << lshift);
107 1632 : B15 = (B15 >> rshift) | (B15 << lshift);
108 : }
109 : }
110 51 : input[0] ^= B15;
111 51 : input[1] ^= B14;
112 51 : input[2] ^= B13;
113 51 : input[3] ^= B12;
114 51 : input[4] ^= B11;
115 51 : input[5] ^= B10;
116 51 : input[6] ^= B09;
117 51 : input[7] ^= B08;
118 : #if DBG_SNEFRU
119 : ph(input);
120 : #endif
121 51 : }
122 :
123 : static inline void SnefruTransform(PHP_SNEFRU_CTX *context, const unsigned char input[32])
124 33 : {
125 : int i, j;
126 :
127 297 : for (i = 0, j = 0; i < 32; i += 4, ++j) {
128 264 : context->state[8+j] = ((input[i] & 0xff) << 24) | ((input[i+1] & 0xff) << 16) |
129 : ((input[i+2] & 0xff) << 8) | (input[i+3] & 0xff);
130 : }
131 33 : Snefru(context->state);
132 33 : memset(&context->state[8], 0, sizeof(php_hash_uint32) * 8);
133 33 : }
134 :
135 : PHP_HASH_API void PHP_SNEFRUInit(PHP_SNEFRU_CTX *context)
136 18 : {
137 18 : memset(context, 0, sizeof(*context));
138 18 : }
139 :
140 : static const php_hash_uint32 MAX32 = 0xffffffffLU;
141 :
142 : PHP_HASH_API void PHP_SNEFRUUpdate(PHP_SNEFRU_CTX *context, const unsigned char *input, size_t len)
143 20 : {
144 20 : if ((MAX32 - context->count[1]) < (len * 8)) {
145 0 : context->count[0]++;
146 0 : context->count[1] = MAX32 - context->count[1];
147 0 : context->count[1] = (len * 8) - context->count[1];
148 : } else {
149 20 : context->count[1] += len * 8;
150 : }
151 :
152 20 : if (context->length + len < 32) {
153 5 : memcpy(&context->buffer[context->length], input, len);
154 5 : context->length += len;
155 : } else {
156 15 : size_t i = 0, r = (context->length + len) % 32;
157 :
158 15 : if (context->length) {
159 2 : i = 32 - context->length;
160 2 : memcpy(&context->buffer[context->length], input, i);
161 2 : SnefruTransform(context, context->buffer);
162 : }
163 :
164 33 : for (; i + 32 <= len; i += 32) {
165 18 : SnefruTransform(context, input + i);
166 : }
167 :
168 15 : memcpy(context->buffer, input + i, r);
169 15 : memset(&context->buffer[r], 0, 32 - r);
170 15 : context->length = r;
171 : }
172 20 : }
173 :
174 : PHP_HASH_API void PHP_SNEFRUFinal(unsigned char digest[32], PHP_SNEFRU_CTX *context)
175 18 : {
176 : php_hash_uint32 i, j;
177 :
178 18 : if (context->length) {
179 13 : SnefruTransform(context, context->buffer);
180 : }
181 :
182 18 : context->state[14] = context->count[0];
183 18 : context->state[15] = context->count[1];
184 18 : Snefru(context->state);
185 :
186 162 : for (i = 0, j = 0; j < 32; i++, j += 4) {
187 144 : digest[j] = (unsigned char) ((context->state[i] >> 24) & 0xff);
188 144 : digest[j + 1] = (unsigned char) ((context->state[i] >> 16) & 0xff);
189 144 : digest[j + 2] = (unsigned char) ((context->state[i] >> 8) & 0xff);
190 144 : digest[j + 3] = (unsigned char) (context->state[i] & 0xff);
191 : }
192 :
193 18 : memset(context, 0, sizeof(*context));
194 18 : }
195 :
196 : const php_hash_ops php_hash_snefru_ops = {
197 : (php_hash_init_func_t) PHP_SNEFRUInit,
198 : (php_hash_update_func_t) PHP_SNEFRUUpdate,
199 : (php_hash_final_func_t) PHP_SNEFRUFinal,
200 : (php_hash_copy_func_t) php_hash_copy,
201 : 32,
202 : 32,
203 : sizeof(PHP_SNEFRU_CTX)
204 : };
205 :
206 : /*
207 : * Local variables:
208 : * tab-width: 4
209 : * c-basic-offset: 4
210 : * End:
211 : * vim600: sw=4 ts=4 fdm=marker
212 : * vim<600: sw=4 ts=4
213 : */
|