1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2008 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 : | Author: Sara Golemon <pollita@php.net> |
16 : +----------------------------------------------------------------------+
17 : */
18 :
19 : /* $Id: hash_ripemd.c,v 1.5.2.3.2.4 2007/12/31 07:20:07 sebastian Exp $ */
20 :
21 : /* Heavily borrowed from md5.c & sha1.c of PHP archival fame
22 : Note that ripemd laughs in the face of logic and uses
23 : little endian byte ordering */
24 :
25 : #include "php_hash.h"
26 : #include "php_hash_ripemd.h"
27 :
28 : const php_hash_ops php_hash_ripemd128_ops = {
29 : (php_hash_init_func_t) PHP_RIPEMD128Init,
30 : (php_hash_update_func_t) PHP_RIPEMD128Update,
31 : (php_hash_final_func_t) PHP_RIPEMD128Final,
32 : 16,
33 : 64,
34 : sizeof(PHP_RIPEMD128_CTX)
35 : };
36 :
37 : const php_hash_ops php_hash_ripemd160_ops = {
38 : (php_hash_init_func_t) PHP_RIPEMD160Init,
39 : (php_hash_update_func_t) PHP_RIPEMD160Update,
40 : (php_hash_final_func_t) PHP_RIPEMD160Final,
41 : 20,
42 : 64,
43 : sizeof(PHP_RIPEMD160_CTX)
44 : };
45 :
46 : const php_hash_ops php_hash_ripemd256_ops = {
47 : (php_hash_init_func_t) PHP_RIPEMD256Init,
48 : (php_hash_update_func_t) PHP_RIPEMD256Update,
49 : (php_hash_final_func_t) PHP_RIPEMD256Final,
50 : 32,
51 : 64,
52 : sizeof(PHP_RIPEMD256_CTX)
53 : };
54 :
55 : const php_hash_ops php_hash_ripemd320_ops = {
56 : (php_hash_init_func_t) PHP_RIPEMD320Init,
57 : (php_hash_update_func_t) PHP_RIPEMD320Update,
58 : (php_hash_final_func_t) PHP_RIPEMD320Final,
59 : 40,
60 : 64,
61 : sizeof(PHP_RIPEMD320_CTX)
62 : };
63 :
64 : /* {{{ PHP_RIPEMD128Init
65 : * ripemd128 initialization. Begins a ripemd128 operation, writing a new context.
66 : */
67 : PHP_HASH_API void PHP_RIPEMD128Init(PHP_RIPEMD128_CTX * context)
68 9 : {
69 9 : context->count[0] = context->count[1] = 0;
70 : /* Load magic initialization constants.
71 : */
72 9 : context->state[0] = 0x67452301;
73 9 : context->state[1] = 0xEFCDAB89;
74 9 : context->state[2] = 0x98BADCFE;
75 9 : context->state[3] = 0x10325476;
76 9 : }
77 : /* }}} */
78 :
79 : /* {{{ PHP_RIPEMD256Init
80 : * ripemd256 initialization. Begins a ripemd256 operation, writing a new context.
81 : */
82 : PHP_HASH_API void PHP_RIPEMD256Init(PHP_RIPEMD256_CTX * context)
83 9 : {
84 9 : context->count[0] = context->count[1] = 0;
85 : /* Load magic initialization constants.
86 : */
87 9 : context->state[0] = 0x67452301;
88 9 : context->state[1] = 0xEFCDAB89;
89 9 : context->state[2] = 0x98BADCFE;
90 9 : context->state[3] = 0x10325476;
91 9 : context->state[4] = 0x76543210;
92 9 : context->state[5] = 0xFEDCBA98;
93 9 : context->state[6] = 0x89ABCDEF;
94 9 : context->state[7] = 0x01234567;
95 9 : }
96 : /* }}} */
97 :
98 : /* {{{ PHP_RIPEMD160Init
99 : * ripemd160 initialization. Begins a ripemd160 operation, writing a new context.
100 : */
101 : PHP_HASH_API void PHP_RIPEMD160Init(PHP_RIPEMD160_CTX * context)
102 9 : {
103 9 : context->count[0] = context->count[1] = 0;
104 : /* Load magic initialization constants.
105 : */
106 9 : context->state[0] = 0x67452301;
107 9 : context->state[1] = 0xEFCDAB89;
108 9 : context->state[2] = 0x98BADCFE;
109 9 : context->state[3] = 0x10325476;
110 9 : context->state[4] = 0xC3D2E1F0;
111 9 : }
112 : /* }}} */
113 :
114 : /* {{{ PHP_RIPEMD320Init
115 : * ripemd320 initialization. Begins a ripemd320 operation, writing a new context.
116 : */
117 : PHP_HASH_API void PHP_RIPEMD320Init(PHP_RIPEMD320_CTX * context)
118 9 : {
119 9 : context->count[0] = context->count[1] = 0;
120 : /* Load magic initialization constants.
121 : */
122 9 : context->state[0] = 0x67452301;
123 9 : context->state[1] = 0xEFCDAB89;
124 9 : context->state[2] = 0x98BADCFE;
125 9 : context->state[3] = 0x10325476;
126 9 : context->state[4] = 0xC3D2E1F0;
127 9 : context->state[5] = 0x76543210;
128 9 : context->state[6] = 0xFEDCBA98;
129 9 : context->state[7] = 0x89ABCDEF;
130 9 : context->state[8] = 0x01234567;
131 9 : context->state[9] = 0x3C2D1E0F;
132 9 : }
133 : /* }}} */
134 :
135 : /* Basic ripemd function */
136 : #define F0(x,y,z) ((x) ^ (y) ^ (z))
137 : #define F1(x,y,z) (((x) & (y)) | ((~(x)) & (z)))
138 : #define F2(x,y,z) (((x) | (~(y))) ^ (z))
139 : #define F3(x,y,z) (((x) & (z)) | ((y) & (~(z))))
140 : #define F4(x,y,z) ((x) ^ ((y) | (~(z))))
141 :
142 : static const php_hash_uint32 K_values[5] = { 0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E }; /* 128, 256, 160, 320 */
143 : static const php_hash_uint32 KK_values[4] = { 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x00000000 }; /* 128 & 256 */
144 : static const php_hash_uint32 KK160_values[5] = { 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000 }; /* 160 & 320 */
145 :
146 : #define K(n) K_values[ (n) >> 4]
147 : #define KK(n) KK_values[(n) >> 4]
148 : #define KK160(n) KK160_values[(n) >> 4]
149 :
150 : static const unsigned char R[80] = {
151 : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
152 : 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
153 : 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
154 : 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
155 : 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 };
156 :
157 : static const unsigned char RR[80] = {
158 : 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
159 : 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
160 : 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
161 : 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
162 : 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 };
163 :
164 : static const unsigned char S[80] = {
165 : 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
166 : 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
167 : 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
168 : 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
169 : 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 };
170 :
171 : static const unsigned char SS[80] = {
172 : 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
173 : 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
174 : 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
175 : 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
176 : 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 };
177 :
178 : #define ROLS(j, x) (((x) << S[j]) | ((x) >> (32 - S[j])))
179 : #define ROLSS(j, x) (((x) << SS[j]) | ((x) >> (32 - SS[j])))
180 : #define ROL(n, x) (((x) << n) | ((x) >> (32 - n)))
181 :
182 : /* {{{ RIPEMDDecode
183 : Decodes input (unsigned char) into output (php_hash_uint32). Assumes len is
184 : a multiple of 4.
185 : */
186 : static void RIPEMDDecode(php_hash_uint32 *output, const unsigned char *input, unsigned int len)
187 62548 : {
188 : unsigned int i, j;
189 :
190 1063316 : for (i = 0, j = 0; j < len; i++, j += 4)
191 1000768 : output[i] = ((php_hash_uint32) input[j + 0]) | (((php_hash_uint32) input[j + 1]) << 8) |
192 : (((php_hash_uint32) input[j + 2]) << 16) | (((php_hash_uint32) input[j + 3]) << 24);
193 62548 : }
194 : /* }}} */
195 :
196 : /* {{{ RIPEMD128Transform
197 : * ripemd128 basic transformation. Transforms state based on block.
198 : */
199 : static void RIPEMD128Transform(php_hash_uint32 state[4], const unsigned char block[64])
200 15637 : {
201 15637 : php_hash_uint32 a = state[0], b = state[1], c = state[2], d = state[3];
202 15637 : php_hash_uint32 aa = state[0], bb = state[1], cc = state[2], dd = state[3];
203 : php_hash_uint32 tmp, x[16];
204 : int j;
205 :
206 15637 : RIPEMDDecode(x, block, 64);
207 :
208 265829 : for(j = 0; j < 16; j++) {
209 250192 : tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j));
210 250192 : a = d; d = c; c = b; b = tmp;
211 250192 : tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK(j));
212 250192 : aa = dd; dd = cc; cc = bb; bb = tmp;
213 : }
214 :
215 265829 : for(j = 16; j < 32; j++) {
216 250192 : tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j));
217 250192 : a = d; d = c; c = b; b = tmp;
218 250192 : tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK(j));
219 250192 : aa = dd; dd = cc; cc = bb; bb = tmp;
220 : }
221 :
222 265829 : for(j = 32; j < 48; j++) {
223 250192 : tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j));
224 250192 : a = d; d = c; c = b; b = tmp;
225 250192 : tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK(j));
226 250192 : aa = dd; dd = cc; cc = bb; bb = tmp;
227 : }
228 :
229 265829 : for(j = 48; j < 64; j++) {
230 250192 : tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j));
231 250192 : a = d; d = c; c = b; b = tmp;
232 250192 : tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK(j));
233 250192 : aa = dd; dd = cc; cc = bb; bb = tmp;
234 : }
235 :
236 15637 : tmp = state[1] + c + dd;
237 15637 : state[1] = state[2] + d + aa;
238 15637 : state[2] = state[3] + a + bb;
239 15637 : state[3] = state[0] + b + cc;
240 15637 : state[0] = tmp;
241 :
242 15637 : tmp = 0;
243 15637 : memset(x, 0, sizeof(x));
244 15637 : }
245 : /* }}} */
246 :
247 : /* {{{ PHP_RIPEMD128Update
248 : ripemd128 block update operation. Continues a ripemd128 message-digest
249 : operation, processing another message block, and updating the
250 : context.
251 : */
252 : PHP_HASH_API void PHP_RIPEMD128Update(PHP_RIPEMD128_CTX * context, const unsigned char *input, unsigned int inputLen)
253 27 : {
254 : unsigned int i, index, partLen;
255 :
256 : /* Compute number of bytes mod 64 */
257 27 : index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
258 :
259 : /* Update number of bits */
260 27 : if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
261 0 : context->count[1]++;
262 : }
263 27 : context->count[1] += ((php_hash_uint32) inputLen >> 29);
264 :
265 27 : partLen = 64 - index;
266 :
267 : /* Transform as many times as possible.
268 : */
269 27 : if (inputLen >= partLen) {
270 13 : memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
271 13 : RIPEMD128Transform(context->state, context->buffer);
272 :
273 15637 : for (i = partLen; i + 63 < inputLen; i += 64) {
274 15624 : RIPEMD128Transform(context->state, &input[i]);
275 : }
276 :
277 13 : index = 0;
278 : } else {
279 14 : i = 0;
280 : }
281 :
282 : /* Buffer remaining input */
283 27 : memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
284 27 : }
285 : /* }}} */
286 :
287 : /* {{{ RIPEMD256Transform
288 : * ripemd256 basic transformation. Transforms state based on block.
289 : */
290 : static void RIPEMD256Transform(php_hash_uint32 state[8], const unsigned char block[64])
291 15637 : {
292 15637 : php_hash_uint32 a = state[0], b = state[1], c = state[2], d = state[3];
293 15637 : php_hash_uint32 aa = state[4], bb = state[5], cc = state[6], dd = state[7];
294 : php_hash_uint32 tmp, x[16];
295 : int j;
296 :
297 15637 : RIPEMDDecode(x, block, 64);
298 :
299 265829 : for(j = 0; j < 16; j++) {
300 250192 : tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j));
301 250192 : a = d; d = c; c = b; b = tmp;
302 250192 : tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK(j));
303 250192 : aa = dd; dd = cc; cc = bb; bb = tmp;
304 : }
305 15637 : tmp = a; a = aa; aa = tmp;
306 :
307 265829 : for(j = 16; j < 32; j++) {
308 250192 : tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j));
309 250192 : a = d; d = c; c = b; b = tmp;
310 250192 : tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK(j));
311 250192 : aa = dd; dd = cc; cc = bb; bb = tmp;
312 : }
313 15637 : tmp = b; b = bb; bb = tmp;
314 :
315 265829 : for(j = 32; j < 48; j++) {
316 250192 : tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j));
317 250192 : a = d; d = c; c = b; b = tmp;
318 250192 : tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK(j));
319 250192 : aa = dd; dd = cc; cc = bb; bb = tmp;
320 : }
321 15637 : tmp = c; c = cc; cc = tmp;
322 :
323 265829 : for(j = 48; j < 64; j++) {
324 250192 : tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j));
325 250192 : a = d; d = c; c = b; b = tmp;
326 250192 : tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK(j));
327 250192 : aa = dd; dd = cc; cc = bb; bb = tmp;
328 : }
329 15637 : tmp = d; d = dd; dd = tmp;
330 :
331 15637 : state[0] += a;
332 15637 : state[1] += b;
333 15637 : state[2] += c;
334 15637 : state[3] += d;
335 15637 : state[4] += aa;
336 15637 : state[5] += bb;
337 15637 : state[6] += cc;
338 15637 : state[7] += dd;
339 :
340 15637 : tmp = 0;
341 15637 : memset(x, 0, sizeof(x));
342 15637 : }
343 : /* }}} */
344 :
345 : /* {{{ PHP_RIPEMD256Update
346 : ripemd256 block update operation. Continues a ripemd256 message-digest
347 : operation, processing another message block, and updating the
348 : context.
349 : */
350 : PHP_HASH_API void PHP_RIPEMD256Update(PHP_RIPEMD256_CTX * context, const unsigned char *input, unsigned int inputLen)
351 27 : {
352 : unsigned int i, index, partLen;
353 :
354 : /* Compute number of bytes mod 64 */
355 27 : index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
356 :
357 : /* Update number of bits */
358 27 : if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
359 0 : context->count[1]++;
360 : }
361 27 : context->count[1] += ((php_hash_uint32) inputLen >> 29);
362 :
363 27 : partLen = 64 - index;
364 :
365 : /* Transform as many times as possible.
366 : */
367 27 : if (inputLen >= partLen) {
368 13 : memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
369 13 : RIPEMD256Transform(context->state, context->buffer);
370 :
371 15637 : for (i = partLen; i + 63 < inputLen; i += 64) {
372 15624 : RIPEMD256Transform(context->state, &input[i]);
373 : }
374 :
375 13 : index = 0;
376 : } else {
377 14 : i = 0;
378 : }
379 :
380 : /* Buffer remaining input */
381 27 : memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
382 27 : }
383 : /* }}} */
384 :
385 : /* {{{ RIPEMD160Transform
386 : * ripemd160 basic transformation. Transforms state based on block.
387 : */
388 : static void RIPEMD160Transform(php_hash_uint32 state[5], const unsigned char block[64])
389 15637 : {
390 15637 : php_hash_uint32 a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
391 15637 : php_hash_uint32 aa = state[0], bb = state[1], cc = state[2], dd = state[3], ee = state[4];
392 : php_hash_uint32 tmp, x[16];
393 : int j;
394 :
395 15637 : RIPEMDDecode(x, block, 64);
396 :
397 265829 : for(j = 0; j < 16; j++) {
398 250192 : tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j)) + e;
399 250192 : a = e; e = d; d = ROL(10, c); c = b; b = tmp;
400 250192 : tmp = ROLSS(j, aa + F4(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
401 250192 : aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
402 : }
403 :
404 265829 : for(j = 16; j < 32; j++) {
405 250192 : tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j)) + e;
406 250192 : a = e; e = d; d = ROL(10, c); c = b; b = tmp;
407 250192 : tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
408 250192 : aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
409 : }
410 :
411 265829 : for(j = 32; j < 48; j++) {
412 250192 : tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j)) + e;
413 250192 : a = e; e = d; d = ROL(10, c); c = b; b = tmp;
414 250192 : tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
415 250192 : aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
416 : }
417 :
418 265829 : for(j = 48; j < 64; j++) {
419 250192 : tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j)) + e;
420 250192 : a = e; e = d; d = ROL(10, c); c = b; b = tmp;
421 250192 : tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
422 250192 : aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
423 : }
424 :
425 265829 : for(j = 64; j < 80; j++) {
426 250192 : tmp = ROLS( j, a + F4(b, c, d) + x[R[j]] + K(j)) + e;
427 250192 : a = e; e = d; d = ROL(10, c); c = b; b = tmp;
428 250192 : tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
429 250192 : aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
430 : }
431 :
432 15637 : tmp = state[1] + c + dd;
433 15637 : state[1] = state[2] + d + ee;
434 15637 : state[2] = state[3] + e + aa;
435 15637 : state[3] = state[4] + a + bb;
436 15637 : state[4] = state[0] + b + cc;
437 15637 : state[0] = tmp;
438 :
439 15637 : tmp = 0;
440 15637 : memset(x, 0, sizeof(x));
441 15637 : }
442 : /* }}} */
443 :
444 : /* {{{ PHP_RIPEMD160Update
445 : ripemd160 block update operation. Continues a ripemd160 message-digest
446 : operation, processing another message block, and updating the
447 : context.
448 : */
449 : PHP_HASH_API void PHP_RIPEMD160Update(PHP_RIPEMD160_CTX * context, const unsigned char *input, unsigned int inputLen)
450 27 : {
451 : unsigned int i, index, partLen;
452 :
453 : /* Compute number of bytes mod 64 */
454 27 : index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
455 :
456 : /* Update number of bits */
457 27 : if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
458 0 : context->count[1]++;
459 : }
460 27 : context->count[1] += ((php_hash_uint32) inputLen >> 29);
461 :
462 27 : partLen = 64 - index;
463 :
464 : /* Transform as many times as possible.
465 : */
466 27 : if (inputLen >= partLen) {
467 13 : memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
468 13 : RIPEMD160Transform(context->state, context->buffer);
469 :
470 15637 : for (i = partLen; i + 63 < inputLen; i += 64) {
471 15624 : RIPEMD160Transform(context->state, &input[i]);
472 : }
473 :
474 13 : index = 0;
475 : } else {
476 14 : i = 0;
477 : }
478 :
479 : /* Buffer remaining input */
480 27 : memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
481 27 : }
482 : /* }}} */
483 :
484 : /* {{{ RIPEMD320Transform
485 : * ripemd320 basic transformation. Transforms state based on block.
486 : */
487 : static void RIPEMD320Transform(php_hash_uint32 state[10], const unsigned char block[64])
488 15637 : {
489 15637 : php_hash_uint32 a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
490 15637 : php_hash_uint32 aa = state[5], bb = state[6], cc = state[7], dd = state[8], ee = state[9];
491 : php_hash_uint32 tmp, x[16];
492 : int j;
493 :
494 15637 : RIPEMDDecode(x, block, 64);
495 :
496 265829 : for(j = 0; j < 16; j++) {
497 250192 : tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j)) + e;
498 250192 : a = e; e = d; d = ROL(10, c); c = b; b = tmp;
499 250192 : tmp = ROLSS(j, aa + F4(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
500 250192 : aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
501 : }
502 15637 : tmp = b; b = bb; bb = tmp;
503 :
504 265829 : for(j = 16; j < 32; j++) {
505 250192 : tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j)) + e;
506 250192 : a = e; e = d; d = ROL(10, c); c = b; b = tmp;
507 250192 : tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
508 250192 : aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
509 : }
510 15637 : tmp = d; d = dd; dd = tmp;
511 :
512 265829 : for(j = 32; j < 48; j++) {
513 250192 : tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j)) + e;
514 250192 : a = e; e = d; d = ROL(10, c); c = b; b = tmp;
515 250192 : tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
516 250192 : aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
517 : }
518 15637 : tmp = a; a = aa; aa = tmp;
519 :
520 265829 : for(j = 48; j < 64; j++) {
521 250192 : tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j)) + e;
522 250192 : a = e; e = d; d = ROL(10, c); c = b; b = tmp;
523 250192 : tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
524 250192 : aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
525 : }
526 15637 : tmp = c; c = cc; cc = tmp;
527 :
528 265829 : for(j = 64; j < 80; j++) {
529 250192 : tmp = ROLS( j, a + F4(b, c, d) + x[R[j]] + K(j)) + e;
530 250192 : a = e; e = d; d = ROL(10, c); c = b; b = tmp;
531 250192 : tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
532 250192 : aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
533 : }
534 15637 : tmp = e; e = ee; ee = tmp;
535 :
536 15637 : state[0] += a;
537 15637 : state[1] += b;
538 15637 : state[2] += c;
539 15637 : state[3] += d;
540 15637 : state[4] += e;
541 15637 : state[5] += aa;
542 15637 : state[6] += bb;
543 15637 : state[7] += cc;
544 15637 : state[8] += dd;
545 15637 : state[9] += ee;
546 :
547 15637 : tmp = 0;
548 15637 : memset(x, 0, sizeof(x));
549 15637 : }
550 : /* }}} */
551 :
552 : /* {{{ PHP_RIPEMD320Update
553 : ripemd320 block update operation. Continues a ripemd320 message-digest
554 : operation, processing another message block, and updating the
555 : context.
556 : */
557 : PHP_HASH_API void PHP_RIPEMD320Update(PHP_RIPEMD320_CTX * context, const unsigned char *input, unsigned int inputLen)
558 27 : {
559 : unsigned int i, index, partLen;
560 :
561 : /* Compute number of bytes mod 64 */
562 27 : index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
563 :
564 : /* Update number of bits */
565 27 : if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
566 0 : context->count[1]++;
567 : }
568 27 : context->count[1] += ((php_hash_uint32) inputLen >> 29);
569 :
570 27 : partLen = 64 - index;
571 :
572 : /* Transform as many times as possible.
573 : */
574 27 : if (inputLen >= partLen) {
575 13 : memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
576 13 : RIPEMD320Transform(context->state, context->buffer);
577 :
578 15637 : for (i = partLen; i + 63 < inputLen; i += 64) {
579 15624 : RIPEMD320Transform(context->state, &input[i]);
580 : }
581 :
582 13 : index = 0;
583 : } else {
584 14 : i = 0;
585 : }
586 :
587 : /* Buffer remaining input */
588 27 : memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
589 27 : }
590 : /* }}} */
591 :
592 : static const unsigned char PADDING[64] =
593 : {
594 : 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
595 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
596 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
597 : };
598 :
599 : /* {{{ RIPEMDEncode
600 : Encodes input (php_hash_uint32) into output (unsigned char). Assumes len is
601 : a multiple of 4.
602 : */
603 : static void RIPEMDEncode(unsigned char *output, php_hash_uint32 *input, unsigned int len)
604 36 : {
605 : unsigned int i, j;
606 :
607 279 : for (i = 0, j = 0; j < len; i++, j += 4) {
608 243 : output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
609 243 : output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
610 243 : output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
611 243 : output[j + 0] = (unsigned char) (input[i] & 0xff);
612 : }
613 36 : }
614 : /* }}} */
615 :
616 : /* {{{ PHP_RIPEMD128Final
617 : ripemd128 finalization. Ends a ripemd128 message-digest operation, writing the
618 : the message digest and zeroizing the context.
619 : */
620 : PHP_HASH_API void PHP_RIPEMD128Final(unsigned char digest[16], PHP_RIPEMD128_CTX * context)
621 9 : {
622 : unsigned char bits[8];
623 : unsigned int index, padLen;
624 :
625 : /* Save number of bits */
626 9 : bits[0] = (unsigned char) (context->count[0] & 0xFF);
627 9 : bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
628 9 : bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
629 9 : bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
630 9 : bits[4] = (unsigned char) (context->count[1] & 0xFF);
631 9 : bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
632 9 : bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
633 9 : bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
634 :
635 : /* Pad out to 56 mod 64.
636 : */
637 9 : index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
638 9 : padLen = (index < 56) ? (56 - index) : (120 - index);
639 9 : PHP_RIPEMD128Update(context, PADDING, padLen);
640 :
641 : /* Append length (before padding) */
642 9 : PHP_RIPEMD128Update(context, bits, 8);
643 :
644 : /* Store state in digest */
645 9 : RIPEMDEncode(digest, context->state, 16);
646 :
647 : /* Zeroize sensitive information.
648 : */
649 9 : memset((unsigned char*) context, 0, sizeof(*context));
650 9 : }
651 : /* }}} */
652 :
653 : /* {{{ PHP_RIPEMD256Final
654 : ripemd256 finalization. Ends a ripemd256 message-digest operation, writing the
655 : the message digest and zeroizing the context.
656 : */
657 : PHP_HASH_API void PHP_RIPEMD256Final(unsigned char digest[32], PHP_RIPEMD256_CTX * context)
658 9 : {
659 : unsigned char bits[8];
660 : unsigned int index, padLen;
661 :
662 : /* Save number of bits */
663 9 : bits[0] = (unsigned char) (context->count[0] & 0xFF);
664 9 : bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
665 9 : bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
666 9 : bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
667 9 : bits[4] = (unsigned char) (context->count[1] & 0xFF);
668 9 : bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
669 9 : bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
670 9 : bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
671 :
672 : /* Pad out to 56 mod 64.
673 : */
674 9 : index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
675 9 : padLen = (index < 56) ? (56 - index) : (120 - index);
676 9 : PHP_RIPEMD256Update(context, PADDING, padLen);
677 :
678 : /* Append length (before padding) */
679 9 : PHP_RIPEMD256Update(context, bits, 8);
680 :
681 : /* Store state in digest */
682 9 : RIPEMDEncode(digest, context->state, 32);
683 :
684 : /* Zeroize sensitive information.
685 : */
686 9 : memset((unsigned char*) context, 0, sizeof(*context));
687 9 : }
688 : /* }}} */
689 :
690 : /* {{{ PHP_RIPEMD160Final
691 : ripemd160 finalization. Ends a ripemd160 message-digest operation, writing the
692 : the message digest and zeroizing the context.
693 : */
694 : PHP_HASH_API void PHP_RIPEMD160Final(unsigned char digest[20], PHP_RIPEMD160_CTX * context)
695 9 : {
696 : unsigned char bits[8];
697 : unsigned int index, padLen;
698 :
699 : /* Save number of bits */
700 9 : bits[0] = (unsigned char) (context->count[0] & 0xFF);
701 9 : bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
702 9 : bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
703 9 : bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
704 9 : bits[4] = (unsigned char) (context->count[1] & 0xFF);
705 9 : bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
706 9 : bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
707 9 : bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
708 :
709 : /* Pad out to 56 mod 64.
710 : */
711 9 : index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
712 9 : padLen = (index < 56) ? (56 - index) : (120 - index);
713 9 : PHP_RIPEMD160Update(context, PADDING, padLen);
714 :
715 : /* Append length (before padding) */
716 9 : PHP_RIPEMD160Update(context, bits, 8);
717 :
718 : /* Store state in digest */
719 9 : RIPEMDEncode(digest, context->state, 20);
720 :
721 : /* Zeroize sensitive information.
722 : */
723 9 : memset((unsigned char*) context, 0, sizeof(*context));
724 9 : }
725 : /* }}} */
726 :
727 : /* {{{ PHP_RIPEMD320Final
728 : ripemd320 finalization. Ends a ripemd320 message-digest operation, writing the
729 : the message digest and zeroizing the context.
730 : */
731 : PHP_HASH_API void PHP_RIPEMD320Final(unsigned char digest[40], PHP_RIPEMD320_CTX * context)
732 9 : {
733 : unsigned char bits[8];
734 : unsigned int index, padLen;
735 :
736 : /* Save number of bits */
737 9 : bits[0] = (unsigned char) (context->count[0] & 0xFF);
738 9 : bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
739 9 : bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
740 9 : bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
741 9 : bits[4] = (unsigned char) (context->count[1] & 0xFF);
742 9 : bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
743 9 : bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
744 9 : bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
745 :
746 : /* Pad out to 56 mod 64.
747 : */
748 9 : index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
749 9 : padLen = (index < 56) ? (56 - index) : (120 - index);
750 9 : PHP_RIPEMD320Update(context, PADDING, padLen);
751 :
752 : /* Append length (before padding) */
753 9 : PHP_RIPEMD320Update(context, bits, 8);
754 :
755 : /* Store state in digest */
756 9 : RIPEMDEncode(digest, context->state, 40);
757 :
758 : /* Zeroize sensitive information.
759 : */
760 9 : memset((unsigned char*) context, 0, sizeof(*context));
761 9 : }
762 : /* }}} */
763 :
764 : /*
765 : * Local variables:
766 : * tab-width: 4
767 : * c-basic-offset: 4
768 : * End:
769 : * vim600: sw=4 ts=4 fdm=marker
770 : * vim<600: sw=4 ts=4
771 : */
|