1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2007 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_tiger.c,v 1.4.2.4.2.2 2007/01/08 22:29:25 nlopess Exp $ */
21 :
22 : #include "php_hash.h"
23 : #include "php_hash_tiger.h"
24 : #include "php_hash_tiger_tables.h"
25 :
26 : /* {{{ */
27 : #define save_abc \
28 : aa = a; \
29 : bb = b; \
30 : cc = c;
31 :
32 : #define round(a,b,c,x,mul) \
33 : c ^= x; \
34 : a -= t1[(unsigned char)(c)] ^ \
35 : t2[(unsigned char)(((php_hash_uint32)(c))>>(2*8))] ^ \
36 : t3[(unsigned char)((c)>>(4*8))] ^ \
37 : t4[(unsigned char)(((php_hash_uint32)((c)>>(4*8)))>>(2*8))] ; \
38 : b += t4[(unsigned char)(((php_hash_uint32)(c))>>(1*8))] ^ \
39 : t3[(unsigned char)(((php_hash_uint32)(c))>>(3*8))] ^ \
40 : t2[(unsigned char)(((php_hash_uint32)((c)>>(4*8)))>>(1*8))] ^ \
41 : t1[(unsigned char)(((php_hash_uint32)((c)>>(4*8)))>>(3*8))]; \
42 : b *= mul;
43 :
44 : #define pass(a,b,c,mul) \
45 : round(a,b,c,x0,mul) \
46 : round(b,c,a,x1,mul) \
47 : round(c,a,b,x2,mul) \
48 : round(a,b,c,x3,mul) \
49 : round(b,c,a,x4,mul) \
50 : round(c,a,b,x5,mul) \
51 : round(a,b,c,x6,mul) \
52 : round(b,c,a,x7,mul)
53 :
54 : #define key_schedule \
55 : x0 -= x7 ^ L64(0xA5A5A5A5A5A5A5A5); \
56 : x1 ^= x0; \
57 : x2 += x1; \
58 : x3 -= x2 ^ ((~x1)<<19); \
59 : x4 ^= x3; \
60 : x5 += x4; \
61 : x6 -= x5 ^ ((~x4)>>23); \
62 : x7 ^= x6; \
63 : x0 += x7; \
64 : x1 -= x0 ^ ((~x7)<<19); \
65 : x2 ^= x1; \
66 : x3 += x2; \
67 : x4 -= x3 ^ ((~x2)>>23); \
68 : x5 ^= x4; \
69 : x6 += x5; \
70 : x7 -= x6 ^ L64(0x0123456789ABCDEF);
71 :
72 : #define feedforward \
73 : a ^= aa; \
74 : b -= bb; \
75 : c += cc;
76 :
77 : #define compress(passes) \
78 : save_abc \
79 : pass(a,b,c,5) \
80 : key_schedule \
81 : pass(c,a,b,7) \
82 : key_schedule \
83 : pass(b,c,a,9) \
84 : for(pass_no=0; pass_no<passes; pass_no++) { \
85 : key_schedule \
86 : pass(a,b,c,9) \
87 : tmpa=a; a=c; c=b; b=tmpa; \
88 : } \
89 : feedforward
90 :
91 : #define split_ex(str) \
92 : x0=str[0]; x1=str[1]; x2=str[2]; x3=str[3]; \
93 : x4=str[4]; x5=str[5]; x6=str[6]; x7=str[7];
94 : #ifdef WORDS_BIGENDIAN
95 : # define split(str) \
96 : { \
97 : int i; \
98 : php_hash_uint64 tmp[8]; \
99 : \
100 : for (i = 0; i < 64; ++i) { \
101 : ((unsigned char *) tmp)[i^7] = ((unsigned char *) str)[i]; \
102 : } \
103 : split_ex(tmp); \
104 : }
105 : #else
106 : # define split split_ex
107 : #endif
108 :
109 : #define tiger_compress(passes, str, state) \
110 : { \
111 : register php_hash_uint64 a, b, c, tmpa, x0, x1, x2, x3, x4, x5, x6, x7; \
112 : php_hash_uint64 aa, bb, cc; \
113 : int pass_no; \
114 : \
115 : a = state[0]; \
116 : b = state[1]; \
117 : c = state[2]; \
118 : \
119 : split(str); \
120 : \
121 : compress(passes); \
122 : \
123 : state[0] = a; \
124 : state[1] = b; \
125 : state[2] = c; \
126 : }
127 : /* }}} */
128 :
129 : static inline void TigerFinalize(PHP_TIGER_CTX *context)
130 0 : {
131 0 : context->passed += (php_hash_uint64) context->length << 3;
132 :
133 0 : context->buffer[context->length++] = 0x1;
134 0 : if (context->length % 8) {
135 0 : memset(&context->buffer[context->length], 0, 8-context->length%8);
136 0 : context->length += 8-context->length%8;
137 : }
138 :
139 0 : if (context->length > 56) {
140 0 : memset(&context->buffer[context->length], 0, 64 - context->length);
141 0 : tiger_compress(context->passes, ((php_hash_uint64 *) context->buffer), context->state);
142 0 : memset(context->buffer, 0, 56);
143 : } else {
144 0 : memset(&context->buffer[context->length], 0, 56 - context->length);
145 : }
146 :
147 : #ifndef WORDS_BIGENDIAN
148 0 : memcpy(&context->buffer[56], &context->passed, sizeof(php_hash_uint64));
149 : #else
150 : context->buffer[56] = (unsigned char) (context->passed & 0xff);
151 : context->buffer[57] = (unsigned char) ((context->passed >> 8) & 0xff);
152 : context->buffer[58] = (unsigned char) ((context->passed >> 16) & 0xff);
153 : context->buffer[59] = (unsigned char) ((context->passed >> 24) & 0xff);
154 : context->buffer[60] = (unsigned char) ((context->passed >> 32) & 0xff);
155 : context->buffer[61] = (unsigned char) ((context->passed >> 40) & 0xff);
156 : context->buffer[62] = (unsigned char) ((context->passed >> 48) & 0xff);
157 : context->buffer[63] = (unsigned char) ((context->passed >> 56) & 0xff);
158 : #endif
159 0 : tiger_compress(context->passes, ((php_hash_uint64 *) context->buffer), context->state);
160 0 : }
161 :
162 : PHP_HASH_API void PHP_3TIGERInit(PHP_TIGER_CTX *context)
163 0 : {
164 0 : memset(context, 0, sizeof(*context));
165 0 : context->state[0] = L64(0x0123456789ABCDEF);
166 0 : context->state[1] = L64(0xFEDCBA9876543210);
167 0 : context->state[2] = L64(0xF096A5B4C3B2E187);
168 0 : }
169 :
170 : PHP_HASH_API void PHP_4TIGERInit(PHP_TIGER_CTX *context)
171 0 : {
172 0 : memset(context, 0, sizeof(*context));
173 0 : context->passes = 1;
174 0 : context->state[0] = L64(0x0123456789ABCDEF);
175 0 : context->state[1] = L64(0xFEDCBA9876543210);
176 0 : context->state[2] = L64(0xF096A5B4C3B2E187);
177 0 : }
178 :
179 : PHP_HASH_API void PHP_TIGERUpdate(PHP_TIGER_CTX *context, const unsigned char *input, size_t len)
180 0 : {
181 0 : if (context->length + len < 64) {
182 0 : memcpy(&context->buffer[context->length], input, len);
183 0 : context->length += len;
184 : } else {
185 0 : size_t i = 0, r = (context->length + len) % 64;
186 :
187 0 : if (context->length) {
188 0 : i = 64 - context->length;
189 0 : memcpy(&context->buffer[context->length], input, i);
190 0 : tiger_compress(context->passes, ((const php_hash_uint64 *) context->buffer), context->state);
191 0 : memset(context->buffer, 0, 64);
192 0 : context->passed += 512;
193 : }
194 :
195 0 : for (; i + 64 <= len; i += 64) {
196 0 : memcpy(context->buffer, &input[i], 64);
197 0 : tiger_compress(context->passes, ((const php_hash_uint64 *) context->buffer), context->state);
198 0 : context->passed += 512;
199 : }
200 0 : memset(&context->buffer[r], 0, 64-r);
201 0 : memcpy(context->buffer, &input[i], r);
202 0 : context->length = r;
203 : }
204 0 : }
205 :
206 : PHP_HASH_API void PHP_TIGER128Final(unsigned char digest[16], PHP_TIGER_CTX *context)
207 0 : {
208 0 : TigerFinalize(context);
209 :
210 0 : digest[0] = (unsigned char) ((context->state[0] >> 56) & 0xff);
211 0 : digest[1] = (unsigned char) ((context->state[0] >> 48) & 0xff);
212 0 : digest[2] = (unsigned char) ((context->state[0] >> 40) & 0xff);
213 0 : digest[3] = (unsigned char) ((context->state[0] >> 32) & 0xff);
214 0 : digest[4] = (unsigned char) ((context->state[0] >> 24) & 0xff);
215 0 : digest[5] = (unsigned char) ((context->state[0] >> 16) & 0xff);
216 0 : digest[6] = (unsigned char) ((context->state[0] >> 8) & 0xff);
217 0 : digest[7] = (unsigned char) (context->state[0] & 0xff);
218 0 : digest[8] = (unsigned char) ((context->state[1] >> 56) & 0xff);
219 0 : digest[9] = (unsigned char) ((context->state[1] >> 48) & 0xff);
220 0 : digest[10] = (unsigned char) ((context->state[1] >> 40) & 0xff);
221 0 : digest[11] = (unsigned char) ((context->state[1] >> 32) & 0xff);
222 0 : digest[12] = (unsigned char) ((context->state[1] >> 24) & 0xff);
223 0 : digest[13] = (unsigned char) ((context->state[1] >> 16) & 0xff);
224 0 : digest[14] = (unsigned char) ((context->state[1] >> 8) & 0xff);
225 0 : digest[15] = (unsigned char) (context->state[1] & 0xff);
226 :
227 0 : memset(context, 0, sizeof(*context));
228 0 : }
229 :
230 : PHP_HASH_API void PHP_TIGER160Final(unsigned char digest[20], PHP_TIGER_CTX *context)
231 0 : {
232 0 : TigerFinalize(context);
233 :
234 0 : digest[0] = (unsigned char) ((context->state[0] >> 56) & 0xff);
235 0 : digest[1] = (unsigned char) ((context->state[0] >> 48) & 0xff);
236 0 : digest[2] = (unsigned char) ((context->state[0] >> 40) & 0xff);
237 0 : digest[3] = (unsigned char) ((context->state[0] >> 32) & 0xff);
238 0 : digest[4] = (unsigned char) ((context->state[0] >> 24) & 0xff);
239 0 : digest[5] = (unsigned char) ((context->state[0] >> 16) & 0xff);
240 0 : digest[6] = (unsigned char) ((context->state[0] >> 8) & 0xff);
241 0 : digest[7] = (unsigned char) (context->state[0] & 0xff);
242 0 : digest[8] = (unsigned char) ((context->state[1] >> 56) & 0xff);
243 0 : digest[9] = (unsigned char) ((context->state[1] >> 48) & 0xff);
244 0 : digest[10] = (unsigned char) ((context->state[1] >> 40) & 0xff);
245 0 : digest[11] = (unsigned char) ((context->state[1] >> 32) & 0xff);
246 0 : digest[12] = (unsigned char) ((context->state[1] >> 24) & 0xff);
247 0 : digest[13] = (unsigned char) ((context->state[1] >> 16) & 0xff);
248 0 : digest[14] = (unsigned char) ((context->state[1] >> 8) & 0xff);
249 0 : digest[15] = (unsigned char) (context->state[1] & 0xff);
250 0 : digest[16] = (unsigned char) ((context->state[2] >> 56) & 0xff);
251 0 : digest[17] = (unsigned char) ((context->state[2] >> 48) & 0xff);
252 0 : digest[18] = (unsigned char) ((context->state[2] >> 40) & 0xff);
253 0 : digest[19] = (unsigned char) ((context->state[2] >> 32) & 0xff);
254 :
255 0 : memset(context, 0, sizeof(*context));
256 0 : }
257 :
258 : PHP_HASH_API void PHP_TIGER192Final(unsigned char digest[24], PHP_TIGER_CTX *context)
259 0 : {
260 0 : TigerFinalize(context);
261 :
262 0 : digest[0] = (unsigned char) ((context->state[0] >> 56) & 0xff);
263 0 : digest[1] = (unsigned char) ((context->state[0] >> 48) & 0xff);
264 0 : digest[2] = (unsigned char) ((context->state[0] >> 40) & 0xff);
265 0 : digest[3] = (unsigned char) ((context->state[0] >> 32) & 0xff);
266 0 : digest[4] = (unsigned char) ((context->state[0] >> 24) & 0xff);
267 0 : digest[5] = (unsigned char) ((context->state[0] >> 16) & 0xff);
268 0 : digest[6] = (unsigned char) ((context->state[0] >> 8) & 0xff);
269 0 : digest[7] = (unsigned char) (context->state[0] & 0xff);
270 0 : digest[8] = (unsigned char) ((context->state[1] >> 56) & 0xff);
271 0 : digest[9] = (unsigned char) ((context->state[1] >> 48) & 0xff);
272 0 : digest[10] = (unsigned char) ((context->state[1] >> 40) & 0xff);
273 0 : digest[11] = (unsigned char) ((context->state[1] >> 32) & 0xff);
274 0 : digest[12] = (unsigned char) ((context->state[1] >> 24) & 0xff);
275 0 : digest[13] = (unsigned char) ((context->state[1] >> 16) & 0xff);
276 0 : digest[14] = (unsigned char) ((context->state[1] >> 8) & 0xff);
277 0 : digest[15] = (unsigned char) (context->state[1] & 0xff);
278 0 : digest[16] = (unsigned char) ((context->state[2] >> 56) & 0xff);
279 0 : digest[17] = (unsigned char) ((context->state[2] >> 48) & 0xff);
280 0 : digest[18] = (unsigned char) ((context->state[2] >> 40) & 0xff);
281 0 : digest[19] = (unsigned char) ((context->state[2] >> 32) & 0xff);
282 0 : digest[20] = (unsigned char) ((context->state[2] >> 24) & 0xff);
283 0 : digest[21] = (unsigned char) ((context->state[2] >> 16) & 0xff);
284 0 : digest[22] = (unsigned char) ((context->state[2] >> 8) & 0xff);
285 0 : digest[23] = (unsigned char) (context->state[2] & 0xff);
286 :
287 0 : memset(context, 0, sizeof(*context));
288 0 : }
289 :
290 : #define PHP_HASH_TIGER_OPS(p, b) \
291 : const php_hash_ops php_hash_##p##tiger##b##_ops = { \
292 : (php_hash_init_func_t) PHP_##p##TIGERInit, \
293 : (php_hash_update_func_t) PHP_TIGERUpdate, \
294 : (php_hash_final_func_t) PHP_TIGER##b##Final, \
295 : b/8, \
296 : 64, \
297 : sizeof(PHP_TIGER_CTX) \
298 : }
299 :
300 : PHP_HASH_TIGER_OPS(3, 128);
301 : PHP_HASH_TIGER_OPS(3, 160);
302 : PHP_HASH_TIGER_OPS(3, 192);
303 : PHP_HASH_TIGER_OPS(4, 128);
304 : PHP_HASH_TIGER_OPS(4, 160);
305 : PHP_HASH_TIGER_OPS(4, 192);
306 :
307 : /*
308 : * Local variables:
309 : * tab-width: 4
310 : * c-basic-offset: 4
311 : * End:
312 : * vim600: sw=4 ts=4 fdm=marker
313 : * vim<600: sw=4 ts=4
314 : */
|