1/*
2 *  haval.c:  specifies the routines in the HAVAL (V.1) hashing library.
3 *
4 *      HAVAL is a one-way hashing algorithm with the following
5 *      collision-resistant property:
6 *             It is computationally infeasible to find two or more
7 *             messages that are hashed into the same fingerprint.
8 *
9 *  Reference:
10 *       Y. Zheng, J. Pieprzyk and J. Seberry:
11 *       ``HAVAL --- a one-way hashing algorithm with variable
12 *       length of output'', Advances in Cryptology --- AUSCRYPT'92,
13 *       Lecture Notes in Computer Science, Springer-Verlag, 1993.
14 *
15 *  Descriptions:
16 *      -  haval_string:      hash a string
17 *      -  haval_file:        hash a file
18 *      -  haval_stdin:       filter -- hash input from the stdin device
19 *      -  haval_hash:        hash a string of specified length
20 *                            (Haval_hash is used in conjunction with
21 *                             haval_start & haval_end.)
22 *      -  haval_hash_block:  hash a 32-word block
23 *      -  haval_start:       initialization
24 *      -  haval_end:         finalization
25 *
26 *  Author:     Yuliang Zheng
27 *              Department of Computer Science
28 *              University of Wollongong
29 *              Wollongong, NSW 2522, Australia
30 *              Email: yuliang@cs.uow.edu.au
31 *              Voice: +61 42 21 4331 (office)
32 *
33 *  Date:       June 1993
34 *
35 *      Copyright (C) 1993 by C^3SR. All rights reserved.
36 *      This program may not be sold or used as inducement to
37 *      buy a product without the written permission of C^3SR.
38 */
39
40#include <stdio.h>
41#include <memory.h>
42#include "transformInt.h"
43#include "havalapp.h"
44#include "tcl.h"
45#include "haval.h"
46
47#define VERSION    1                         /* current version number */
48
49void haval_string _ANSI_ARGS_((char *, unsigned char *)); /* hash a string */
50int  haval_file _ANSI_ARGS_((char *, unsigned char *));   /* hash a file */
51void haval_stdin _ANSI_ARGS_((void));                     /* hash input from stdin */
52void haval_start _ANSI_ARGS_((haval_state *));            /* initialization */
53void haval_hash _ANSI_ARGS_((haval_state *,
54        unsigned char *, unsigned int));      /* updating routine */
55void haval_end _ANSI_ARGS_((haval_state *, unsigned char *)); /* finalization */
56void haval_hash_block _ANSI_ARGS_((haval_state *));       /* hash a 32-word block */
57static void haval_tailor _ANSI_ARGS_((haval_state *));    /* folding the last output */
58
59static unsigned char padding[128] = {        /* constants for padding */
600x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
61   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
66   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
67   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
68};
69
70/* aku, Sep 23, 1996, added () to eliminate gcc warnings:
71 * "suggest parentheses around arithmetic in operand of ^"
72 * semantics not changed!
73 */
74#define f_1(x6, x5, x4, x3, x2, x1, x0)          \
75           (((x1) & ((x0) ^ (x4))) ^ ((x2) & (x5)) ^ \
76            ((x3) & (x6)) ^ (x0))
77
78#define f_2(x6, x5, x4, x3, x2, x1, x0)                         \
79           (((x2) & (((x1) & ~(x3)) ^ ((x4) & (x5)) ^ (x6) ^ (x0))) ^ \
80            ((x4) & ((x1) ^ (x5))) ^ ((x3) & (x5)) ^ (x0))
81
82#define f_3(x6, x5, x4, x3, x2, x1, x0)          \
83           (((x3) & (((x1) & (x2)) ^ (x6) ^ (x0))) ^ \
84            ((x1) & (x4)) ^ ((x2) & (x5)) ^ (x0))
85
86#define f_4(x6, x5, x4, x3, x2, x1, x0)                                 \
87           (((x4) & (((x5) & ~(x2)) ^ ((x3) & ~(x6)) ^ (x1) ^ (x6) ^ (x0))) ^ \
88            ((x3) & (((x1) & (x2)) ^ (x5) ^ (x6))) ^                        \
89            ((x2) & (x6)) ^ (x0))
90
91#define f_5(x6, x5, x4, x3, x2, x1, x0)                \
92           (((x0) & (((x1) & (x2) & (x3)) ^ ~(x5))) ^   \
93            ((x1) & (x4)) ^ ((x2) & (x5)) ^ ((x3) & (x6)))
94
95/*
96 * Permutations phi_{i,j}, i=3,4,5, j=1,...,i.
97 *
98 * PASS = 3:
99 *               6 5 4 3 2 1 0
100 *               | | | | | | | (replaced by)
101 *  phi_{3,1}:   1 0 3 5 6 2 4
102 *  phi_{3,2}:   4 2 1 0 5 3 6
103 *  phi_{3,3}:   6 1 2 3 4 5 0
104 *
105 * PASS = 4:
106 *               6 5 4 3 2 1 0
107 *               | | | | | | | (replaced by)
108 *  phi_{4,1}:   2 6 1 4 5 3 0
109 *  phi_{4,2}:   3 5 2 0 1 6 4
110 *  phi_{4,3}:   1 4 3 6 0 2 5
111 *  phi_{4,4}:   6 4 0 5 2 1 3
112 *
113 * PASS = 5:
114 *               6 5 4 3 2 1 0
115 *               | | | | | | | (replaced by)
116 *  phi_{5,1}:   3 4 1 0 5 2 6
117 *  phi_{5,2}:   6 2 1 0 3 4 5
118 *  phi_{5,3}:   2 6 0 4 3 1 5
119 *  phi_{5,4}:   1 5 3 2 0 4 6
120 *  phi_{5,5}:   2 5 0 6 4 3 1
121 */
122
123#if   PASS == 3
124#define Fphi_1(x6, x5, x4, x3, x2, x1, x0) \
125           f_1(x1, x0, x3, x5, x6, x2, x4)
126#elif PASS == 4
127#define Fphi_1(x6, x5, x4, x3, x2, x1, x0) \
128           f_1(x2, x6, x1, x4, x5, x3, x0)
129#else
130#define Fphi_1(x6, x5, x4, x3, x2, x1, x0) \
131           f_1(x3, x4, x1, x0, x5, x2, x6)
132#endif
133
134#if   PASS == 3
135#define Fphi_2(x6, x5, x4, x3, x2, x1, x0) \
136           f_2(x4, x2, x1, x0, x5, x3, x6)
137#elif PASS == 4
138#define Fphi_2(x6, x5, x4, x3, x2, x1, x0) \
139           f_2(x3, x5, x2, x0, x1, x6, x4)
140#else
141#define Fphi_2(x6, x5, x4, x3, x2, x1, x0) \
142           f_2(x6, x2, x1, x0, x3, x4, x5)
143#endif
144
145#if   PASS == 3
146#define Fphi_3(x6, x5, x4, x3, x2, x1, x0) \
147           f_3(x6, x1, x2, x3, x4, x5, x0)
148#elif PASS == 4
149#define Fphi_3(x6, x5, x4, x3, x2, x1, x0) \
150           f_3(x1, x4, x3, x6, x0, x2, x5)
151#else
152#define Fphi_3(x6, x5, x4, x3, x2, x1, x0) \
153           f_3(x2, x6, x0, x4, x3, x1, x5)
154#endif
155
156#if   PASS == 4
157#define Fphi_4(x6, x5, x4, x3, x2, x1, x0) \
158           f_4(x6, x4, x0, x5, x2, x1, x3)
159#else
160#define Fphi_4(x6, x5, x4, x3, x2, x1, x0) \
161            f_4(x1, x5, x3, x2, x0, x4, x6)
162#endif
163
164#define Fphi_5(x6, x5, x4, x3, x2, x1, x0) \
165           f_5(x2, x5, x0, x6, x4, x3, x1)
166
167#define rotate_right(x, n) (((x) >> (n)) | ((x) << (32-(n))))
168
169#define FF_1(x7, x6, x5, x4, x3, x2, x1, x0, w) {                        \
170      register haval_word temp = Fphi_1(x6, x5, x4, x3, x2, x1, x0);     \
171      (x7) = rotate_right(temp, 7) + rotate_right((x7), 11) + (w);       \
172      }
173
174#define FF_2(x7, x6, x5, x4, x3, x2, x1, x0, w, c) {                      \
175      register haval_word temp = Fphi_2(x6, x5, x4, x3, x2, x1, x0);      \
176      (x7) = rotate_right(temp, 7) + rotate_right((x7), 11) + (w) + (c);  \
177      }
178
179#define FF_3(x7, x6, x5, x4, x3, x2, x1, x0, w, c) {                      \
180      register haval_word temp = Fphi_3(x6, x5, x4, x3, x2, x1, x0);      \
181      (x7) = rotate_right(temp, 7) + rotate_right((x7), 11) + (w) + (c);  \
182      }
183
184#define FF_4(x7, x6, x5, x4, x3, x2, x1, x0, w, c) {                      \
185      register haval_word temp = Fphi_4(x6, x5, x4, x3, x2, x1, x0);      \
186      (x7) = rotate_right(temp, 7) + rotate_right((x7), 11) + (w) + (c);  \
187      }
188
189#define FF_5(x7, x6, x5, x4, x3, x2, x1, x0, w, c) {                      \
190      register haval_word temp = Fphi_5(x6, x5, x4, x3, x2, x1, x0);      \
191      (x7) = rotate_right(temp, 7) + rotate_right((x7), 11) + (w) + (c);  \
192      }
193
194/*
195 * translate every four characters into a word.
196 * assume the number of characters is a multiple of four.
197 */
198#define ch2uint(string, word, slen) {      \
199  unsigned char *sp = string;              \
200  haval_word    *wp = word;                \
201  while (sp < (string) + (slen)) {         \
202    *wp++ =  (haval_word)*sp            |  \
203            ((haval_word)*(sp+1) <<  8) |  \
204            ((haval_word)*(sp+2) << 16) |  \
205            ((haval_word)*(sp+3) << 24);   \
206    sp += 4;                               \
207  }                                        \
208}
209
210/* translate each word into four characters */
211#define uint2ch(word, string, wlen) {              \
212  haval_word    *wp = word;                        \
213  unsigned char *sp = string;                      \
214  while (wp < (word) + (wlen)) {                   \
215    *(sp++) = (unsigned char)( *wp        & 0xFF); \
216    *(sp++) = (unsigned char)((*wp >>  8) & 0xFF); \
217    *(sp++) = (unsigned char)((*wp >> 16) & 0xFF); \
218    *(sp++) = (unsigned char)((*wp >> 24) & 0xFF); \
219    wp++;                                          \
220  }                                                \
221}
222
223
224/* hash a string */
225void haval_string (string, fingerprint)
226    char *string;
227    unsigned char fingerprint[FPTLEN >> 3];
228{
229  haval_state   state;
230  unsigned int  len = strlen (string);
231
232  haval_start (&state);
233  haval_hash (&state, (unsigned char *)string, len);
234  haval_end (&state, fingerprint);
235}
236
237/* hash a file */
238int haval_file (file_name, fingerprint)
239    char *file_name;
240    unsigned char fingerprint[FPTLEN >> 3];
241{
242  FILE          *file;
243  haval_state   state;
244  int           len;
245  unsigned char buffer[1024];
246
247  if ((file = fopen (file_name, "rb")) == NULL){
248    return (1);                                    /* fail */
249  } else {
250    haval_start (&state);
251    /* aku, Sep 23 1996, added () around assignment, as suggested by gcc -Wall */
252    while ((len = fread (buffer, 1, 1024, file))) {
253      haval_hash (&state, buffer, len);
254    }
255    fclose (file);
256    haval_end (&state, fingerprint);
257    return (0);                                    /* success */
258 }
259}
260
261/* hash input from stdin */
262void haval_stdin ()
263{
264  haval_state   state;
265  int           i, len;
266  unsigned char buffer[32],
267                fingerprint[FPTLEN >> 3];
268
269  haval_start (&state);
270  /* aku, Sep 23 1996, added () around assignment, as suggested by gcc -Wall */
271  while ((len = fread (buffer, 1, 32, stdin))) {
272    haval_hash (&state, buffer, len);
273  }
274  haval_end (&state, fingerprint);
275
276  for (i = 0; i < FPTLEN >> 3; i++) {
277    putchar(fingerprint[i]);
278  }
279}
280
281/* initialization */
282void haval_start (state)
283    haval_state *state;
284{
285    state->count[0]       = state->count[1] = 0;   /* clear count */
286    state->fingerprint[0] = 0x243F6A88;            /* initial fingerprint */
287    state->fingerprint[1] = 0x85A308D3;
288    state->fingerprint[2] = 0x13198A2E;
289    state->fingerprint[3] = 0x03707344;
290    state->fingerprint[4] = 0xA4093822;
291    state->fingerprint[5] = 0x299F31D0;
292    state->fingerprint[6] = 0x082EFA98;
293    state->fingerprint[7] = 0xEC4E6C89;
294}
295
296/*
297 * hash a string of specified length.
298 * to be used in conjunction with haval_start and haval_end.
299 */
300void haval_hash (state, str, str_len)
301    haval_state *state;
302    unsigned char *str;
303    unsigned int str_len;
304{
305  unsigned int i,
306           rmd_len,
307           fill_len;
308
309  /* calculate the number of bytes in the remainder */
310  rmd_len  = (unsigned int)((state->count[0] >> 3) & 0x7F);
311  fill_len = 128 - rmd_len;
312
313  /* update the number of bits */
314  if ((state->count[0] +=  (haval_word)str_len << 3)
315                        < ((haval_word)str_len << 3)) {
316     state->count[1]++;
317  }
318  state->count[1] += (haval_word)str_len >> 29;
319
320#ifdef LITTLE_ENDIAN
321
322  /* hash as many blocks as possible */
323  if (rmd_len + str_len >= 128) {
324    memcpy (((unsigned char *)state->block)+rmd_len, str, fill_len);
325    haval_hash_block (state);
326    for (i = fill_len; i + 127 < str_len; i += 128){
327      memcpy ((unsigned char *)state->block, str+i, 128);
328      haval_hash_block (state);
329    }
330    rmd_len = 0;
331  } else {
332    i = 0;
333  }
334  memcpy (((unsigned char *)state->block)+rmd_len, str+i, str_len-i);
335
336#else
337
338  /* hash as many blocks as possible */
339  if (rmd_len + str_len >= 128) {
340    memcpy (&state->remainder[rmd_len], str, fill_len);
341    ch2uint(state->remainder, state->block, 128);
342    haval_hash_block (state);
343    for (i = fill_len; i + 127 < str_len; i += 128){
344      memcpy (state->remainder, str+i, 128);
345      ch2uint(state->remainder, state->block, 128);
346      haval_hash_block (state);
347    }
348    rmd_len = 0;
349  } else {
350    i = 0;
351  }
352  /* save the remaining input chars */
353  memcpy (&state->remainder[rmd_len], str+i, str_len-i);
354
355#endif
356}
357
358/* finalization */
359void haval_end (state, final_fpt)
360    haval_state *state;
361    unsigned char final_fpt[FPTLEN >> 3];
362{
363  unsigned char tail[10];
364  unsigned int  rmd_len, pad_len;
365
366  /*
367   * save the version number, the number of passes, the fingerprint
368   * length and the number of bits in the unpadded message.
369   */
370  tail[0] = (unsigned char)(((FPTLEN  & 0x3) << 6) |
371                            ((PASS    & 0x7) << 3) |
372                             (VERSION & 0x7));
373  tail[1] = (unsigned char)((FPTLEN >> 2) & 0xFF);
374  uint2ch (state->count, &tail[2], 2);
375
376  /* pad out to 118 mod 128 */
377  rmd_len = (unsigned int)((state->count[0] >> 3) & 0x7f);
378  pad_len = (rmd_len < 118) ? (118 - rmd_len) : (246 - rmd_len);
379  haval_hash (state, padding, pad_len);
380
381  /*
382   * append the version number, the number of passes,
383   * the fingerprint length and the number of bits
384   */
385  haval_hash (state, tail, 10);
386
387  /* tailor the last output */
388  haval_tailor(state);
389
390  /* translate and save the final fingerprint */
391  uint2ch (state->fingerprint, final_fpt, FPTLEN >> 5);
392
393  /* clear the state information */
394  memset ((unsigned char *)state, 0, sizeof (*state));
395}
396
397/* hash a 32-word block */
398void haval_hash_block (state)
399    haval_state *state;
400{
401  register haval_word t0 = state->fingerprint[0],    /* make use of */
402                      t1 = state->fingerprint[1],    /* internal registers */
403                      t2 = state->fingerprint[2],
404                      t3 = state->fingerprint[3],
405                      t4 = state->fingerprint[4],
406                      t5 = state->fingerprint[5],
407                      t6 = state->fingerprint[6],
408                      t7 = state->fingerprint[7],
409                      *w = state->block;
410
411  /* Pass 1 */
412  FF_1(t7, t6, t5, t4, t3, t2, t1, t0, *(w   ));
413  FF_1(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 1));
414  FF_1(t5, t4, t3, t2, t1, t0, t7, t6, *(w+ 2));
415  FF_1(t4, t3, t2, t1, t0, t7, t6, t5, *(w+ 3));
416  FF_1(t3, t2, t1, t0, t7, t6, t5, t4, *(w+ 4));
417  FF_1(t2, t1, t0, t7, t6, t5, t4, t3, *(w+ 5));
418  FF_1(t1, t0, t7, t6, t5, t4, t3, t2, *(w+ 6));
419  FF_1(t0, t7, t6, t5, t4, t3, t2, t1, *(w+ 7));
420
421  FF_1(t7, t6, t5, t4, t3, t2, t1, t0, *(w+ 8));
422  FF_1(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 9));
423  FF_1(t5, t4, t3, t2, t1, t0, t7, t6, *(w+10));
424  FF_1(t4, t3, t2, t1, t0, t7, t6, t5, *(w+11));
425  FF_1(t3, t2, t1, t0, t7, t6, t5, t4, *(w+12));
426  FF_1(t2, t1, t0, t7, t6, t5, t4, t3, *(w+13));
427  FF_1(t1, t0, t7, t6, t5, t4, t3, t2, *(w+14));
428  FF_1(t0, t7, t6, t5, t4, t3, t2, t1, *(w+15));
429
430  FF_1(t7, t6, t5, t4, t3, t2, t1, t0, *(w+16));
431  FF_1(t6, t5, t4, t3, t2, t1, t0, t7, *(w+17));
432  FF_1(t5, t4, t3, t2, t1, t0, t7, t6, *(w+18));
433  FF_1(t4, t3, t2, t1, t0, t7, t6, t5, *(w+19));
434  FF_1(t3, t2, t1, t0, t7, t6, t5, t4, *(w+20));
435  FF_1(t2, t1, t0, t7, t6, t5, t4, t3, *(w+21));
436  FF_1(t1, t0, t7, t6, t5, t4, t3, t2, *(w+22));
437  FF_1(t0, t7, t6, t5, t4, t3, t2, t1, *(w+23));
438
439  FF_1(t7, t6, t5, t4, t3, t2, t1, t0, *(w+24));
440  FF_1(t6, t5, t4, t3, t2, t1, t0, t7, *(w+25));
441  FF_1(t5, t4, t3, t2, t1, t0, t7, t6, *(w+26));
442  FF_1(t4, t3, t2, t1, t0, t7, t6, t5, *(w+27));
443  FF_1(t3, t2, t1, t0, t7, t6, t5, t4, *(w+28));
444  FF_1(t2, t1, t0, t7, t6, t5, t4, t3, *(w+29));
445  FF_1(t1, t0, t7, t6, t5, t4, t3, t2, *(w+30));
446  FF_1(t0, t7, t6, t5, t4, t3, t2, t1, *(w+31));
447
448  /* Pass 2 */
449  FF_2(t7, t6, t5, t4, t3, t2, t1, t0, *(w+ 5), 0x452821E6);
450  FF_2(t6, t5, t4, t3, t2, t1, t0, t7, *(w+14), 0x38D01377);
451  FF_2(t5, t4, t3, t2, t1, t0, t7, t6, *(w+26), 0xBE5466CF);
452  FF_2(t4, t3, t2, t1, t0, t7, t6, t5, *(w+18), 0x34E90C6C);
453  FF_2(t3, t2, t1, t0, t7, t6, t5, t4, *(w+11), 0xC0AC29B7);
454  FF_2(t2, t1, t0, t7, t6, t5, t4, t3, *(w+28), 0xC97C50DD);
455  FF_2(t1, t0, t7, t6, t5, t4, t3, t2, *(w+ 7), 0x3F84D5B5);
456  FF_2(t0, t7, t6, t5, t4, t3, t2, t1, *(w+16), 0xB5470917);
457
458  FF_2(t7, t6, t5, t4, t3, t2, t1, t0, *(w   ), 0x9216D5D9);
459  FF_2(t6, t5, t4, t3, t2, t1, t0, t7, *(w+23), 0x8979FB1B);
460  FF_2(t5, t4, t3, t2, t1, t0, t7, t6, *(w+20), 0xD1310BA6);
461  FF_2(t4, t3, t2, t1, t0, t7, t6, t5, *(w+22), 0x98DFB5AC);
462  FF_2(t3, t2, t1, t0, t7, t6, t5, t4, *(w+ 1), 0x2FFD72DB);
463  FF_2(t2, t1, t0, t7, t6, t5, t4, t3, *(w+10), 0xD01ADFB7);
464  FF_2(t1, t0, t7, t6, t5, t4, t3, t2, *(w+ 4), 0xB8E1AFED);
465  FF_2(t0, t7, t6, t5, t4, t3, t2, t1, *(w+ 8), 0x6A267E96);
466
467  FF_2(t7, t6, t5, t4, t3, t2, t1, t0, *(w+30), 0xBA7C9045);
468  FF_2(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 3), 0xF12C7F99);
469  FF_2(t5, t4, t3, t2, t1, t0, t7, t6, *(w+21), 0x24A19947);
470  FF_2(t4, t3, t2, t1, t0, t7, t6, t5, *(w+ 9), 0xB3916CF7);
471  FF_2(t3, t2, t1, t0, t7, t6, t5, t4, *(w+17), 0x0801F2E2);
472  FF_2(t2, t1, t0, t7, t6, t5, t4, t3, *(w+24), 0x858EFC16);
473  FF_2(t1, t0, t7, t6, t5, t4, t3, t2, *(w+29), 0x636920D8);
474  FF_2(t0, t7, t6, t5, t4, t3, t2, t1, *(w+ 6), 0x71574E69);
475
476  FF_2(t7, t6, t5, t4, t3, t2, t1, t0, *(w+19), 0xA458FEA3);
477  FF_2(t6, t5, t4, t3, t2, t1, t0, t7, *(w+12), 0xF4933D7E);
478  FF_2(t5, t4, t3, t2, t1, t0, t7, t6, *(w+15), 0x0D95748F);
479  FF_2(t4, t3, t2, t1, t0, t7, t6, t5, *(w+13), 0x728EB658);
480  FF_2(t3, t2, t1, t0, t7, t6, t5, t4, *(w+ 2), 0x718BCD58);
481  FF_2(t2, t1, t0, t7, t6, t5, t4, t3, *(w+25), 0x82154AEE);
482  FF_2(t1, t0, t7, t6, t5, t4, t3, t2, *(w+31), 0x7B54A41D);
483  FF_2(t0, t7, t6, t5, t4, t3, t2, t1, *(w+27), 0xC25A59B5);
484
485  /* Pass 3 */
486  FF_3(t7, t6, t5, t4, t3, t2, t1, t0, *(w+19), 0x9C30D539);
487  FF_3(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 9), 0x2AF26013);
488  FF_3(t5, t4, t3, t2, t1, t0, t7, t6, *(w+ 4), 0xC5D1B023);
489  FF_3(t4, t3, t2, t1, t0, t7, t6, t5, *(w+20), 0x286085F0);
490  FF_3(t3, t2, t1, t0, t7, t6, t5, t4, *(w+28), 0xCA417918);
491  FF_3(t2, t1, t0, t7, t6, t5, t4, t3, *(w+17), 0xB8DB38EF);
492  FF_3(t1, t0, t7, t6, t5, t4, t3, t2, *(w+ 8), 0x8E79DCB0);
493  FF_3(t0, t7, t6, t5, t4, t3, t2, t1, *(w+22), 0x603A180E);
494
495  FF_3(t7, t6, t5, t4, t3, t2, t1, t0, *(w+29), 0x6C9E0E8B);
496  FF_3(t6, t5, t4, t3, t2, t1, t0, t7, *(w+14), 0xB01E8A3E);
497  FF_3(t5, t4, t3, t2, t1, t0, t7, t6, *(w+25), 0xD71577C1);
498  FF_3(t4, t3, t2, t1, t0, t7, t6, t5, *(w+12), 0xBD314B27);
499  FF_3(t3, t2, t1, t0, t7, t6, t5, t4, *(w+24), 0x78AF2FDA);
500  FF_3(t2, t1, t0, t7, t6, t5, t4, t3, *(w+30), 0x55605C60);
501  FF_3(t1, t0, t7, t6, t5, t4, t3, t2, *(w+16), 0xE65525F3);
502  FF_3(t0, t7, t6, t5, t4, t3, t2, t1, *(w+26), 0xAA55AB94);
503
504  FF_3(t7, t6, t5, t4, t3, t2, t1, t0, *(w+31), 0x57489862);
505  FF_3(t6, t5, t4, t3, t2, t1, t0, t7, *(w+15), 0x63E81440);
506  FF_3(t5, t4, t3, t2, t1, t0, t7, t6, *(w+ 7), 0x55CA396A);
507  FF_3(t4, t3, t2, t1, t0, t7, t6, t5, *(w+ 3), 0x2AAB10B6);
508  FF_3(t3, t2, t1, t0, t7, t6, t5, t4, *(w+ 1), 0xB4CC5C34);
509  FF_3(t2, t1, t0, t7, t6, t5, t4, t3, *(w   ), 0x1141E8CE);
510  FF_3(t1, t0, t7, t6, t5, t4, t3, t2, *(w+18), 0xA15486AF);
511  FF_3(t0, t7, t6, t5, t4, t3, t2, t1, *(w+27), 0x7C72E993);
512
513  FF_3(t7, t6, t5, t4, t3, t2, t1, t0, *(w+13), 0xB3EE1411);
514  FF_3(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 6), 0x636FBC2A);
515  FF_3(t5, t4, t3, t2, t1, t0, t7, t6, *(w+21), 0x2BA9C55D);
516  FF_3(t4, t3, t2, t1, t0, t7, t6, t5, *(w+10), 0x741831F6);
517  FF_3(t3, t2, t1, t0, t7, t6, t5, t4, *(w+23), 0xCE5C3E16);
518  FF_3(t2, t1, t0, t7, t6, t5, t4, t3, *(w+11), 0x9B87931E);
519  FF_3(t1, t0, t7, t6, t5, t4, t3, t2, *(w+ 5), 0xAFD6BA33);
520  FF_3(t0, t7, t6, t5, t4, t3, t2, t1, *(w+ 2), 0x6C24CF5C);
521
522#if PASS >= 4
523  /* Pass 4. executed only when PASS =4 or 5 */
524  FF_4(t7, t6, t5, t4, t3, t2, t1, t0, *(w+24), 0x7A325381);
525  FF_4(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 4), 0x28958677);
526  FF_4(t5, t4, t3, t2, t1, t0, t7, t6, *(w   ), 0x3B8F4898);
527  FF_4(t4, t3, t2, t1, t0, t7, t6, t5, *(w+14), 0x6B4BB9AF);
528  FF_4(t3, t2, t1, t0, t7, t6, t5, t4, *(w+ 2), 0xC4BFE81B);
529  FF_4(t2, t1, t0, t7, t6, t5, t4, t3, *(w+ 7), 0x66282193);
530  FF_4(t1, t0, t7, t6, t5, t4, t3, t2, *(w+28), 0x61D809CC);
531  FF_4(t0, t7, t6, t5, t4, t3, t2, t1, *(w+23), 0xFB21A991);
532
533  FF_4(t7, t6, t5, t4, t3, t2, t1, t0, *(w+26), 0x487CAC60);
534  FF_4(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 6), 0x5DEC8032);
535  FF_4(t5, t4, t3, t2, t1, t0, t7, t6, *(w+30), 0xEF845D5D);
536  FF_4(t4, t3, t2, t1, t0, t7, t6, t5, *(w+20), 0xE98575B1);
537  FF_4(t3, t2, t1, t0, t7, t6, t5, t4, *(w+18), 0xDC262302);
538  FF_4(t2, t1, t0, t7, t6, t5, t4, t3, *(w+25), 0xEB651B88);
539  FF_4(t1, t0, t7, t6, t5, t4, t3, t2, *(w+19), 0x23893E81);
540  FF_4(t0, t7, t6, t5, t4, t3, t2, t1, *(w+ 3), 0xD396ACC5);
541
542  FF_4(t7, t6, t5, t4, t3, t2, t1, t0, *(w+22), 0x0F6D6FF3);
543  FF_4(t6, t5, t4, t3, t2, t1, t0, t7, *(w+11), 0x83F44239);
544  FF_4(t5, t4, t3, t2, t1, t0, t7, t6, *(w+31), 0x2E0B4482);
545  FF_4(t4, t3, t2, t1, t0, t7, t6, t5, *(w+21), 0xA4842004);
546  FF_4(t3, t2, t1, t0, t7, t6, t5, t4, *(w+ 8), 0x69C8F04A);
547  FF_4(t2, t1, t0, t7, t6, t5, t4, t3, *(w+27), 0x9E1F9B5E);
548  FF_4(t1, t0, t7, t6, t5, t4, t3, t2, *(w+12), 0x21C66842);
549  FF_4(t0, t7, t6, t5, t4, t3, t2, t1, *(w+ 9), 0xF6E96C9A);
550
551  FF_4(t7, t6, t5, t4, t3, t2, t1, t0, *(w+ 1), 0x670C9C61);
552  FF_4(t6, t5, t4, t3, t2, t1, t0, t7, *(w+29), 0xABD388F0);
553  FF_4(t5, t4, t3, t2, t1, t0, t7, t6, *(w+ 5), 0x6A51A0D2);
554  FF_4(t4, t3, t2, t1, t0, t7, t6, t5, *(w+15), 0xD8542F68);
555  FF_4(t3, t2, t1, t0, t7, t6, t5, t4, *(w+17), 0x960FA728);
556  FF_4(t2, t1, t0, t7, t6, t5, t4, t3, *(w+10), 0xAB5133A3);
557  FF_4(t1, t0, t7, t6, t5, t4, t3, t2, *(w+16), 0x6EEF0B6C);
558  FF_4(t0, t7, t6, t5, t4, t3, t2, t1, *(w+13), 0x137A3BE4);
559#endif
560
561#if PASS == 5
562  /* Pass 5. executed only when PASS = 5 */
563  FF_5(t7, t6, t5, t4, t3, t2, t1, t0, *(w+27), 0xBA3BF050);
564  FF_5(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 3), 0x7EFB2A98);
565  FF_5(t5, t4, t3, t2, t1, t0, t7, t6, *(w+21), 0xA1F1651D);
566  FF_5(t4, t3, t2, t1, t0, t7, t6, t5, *(w+26), 0x39AF0176);
567  FF_5(t3, t2, t1, t0, t7, t6, t5, t4, *(w+17), 0x66CA593E);
568  FF_5(t2, t1, t0, t7, t6, t5, t4, t3, *(w+11), 0x82430E88);
569  FF_5(t1, t0, t7, t6, t5, t4, t3, t2, *(w+20), 0x8CEE8619);
570  FF_5(t0, t7, t6, t5, t4, t3, t2, t1, *(w+29), 0x456F9FB4);
571
572  FF_5(t7, t6, t5, t4, t3, t2, t1, t0, *(w+19), 0x7D84A5C3);
573  FF_5(t6, t5, t4, t3, t2, t1, t0, t7, *(w   ), 0x3B8B5EBE);
574  FF_5(t5, t4, t3, t2, t1, t0, t7, t6, *(w+12), 0xE06F75D8);
575  FF_5(t4, t3, t2, t1, t0, t7, t6, t5, *(w+ 7), 0x85C12073);
576  FF_5(t3, t2, t1, t0, t7, t6, t5, t4, *(w+13), 0x401A449F);
577  FF_5(t2, t1, t0, t7, t6, t5, t4, t3, *(w+ 8), 0x56C16AA6);
578  FF_5(t1, t0, t7, t6, t5, t4, t3, t2, *(w+31), 0x4ED3AA62);
579  FF_5(t0, t7, t6, t5, t4, t3, t2, t1, *(w+10), 0x363F7706);
580
581  FF_5(t7, t6, t5, t4, t3, t2, t1, t0, *(w+ 5), 0x1BFEDF72);
582  FF_5(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 9), 0x429B023D);
583  FF_5(t5, t4, t3, t2, t1, t0, t7, t6, *(w+14), 0x37D0D724);
584  FF_5(t4, t3, t2, t1, t0, t7, t6, t5, *(w+30), 0xD00A1248);
585  FF_5(t3, t2, t1, t0, t7, t6, t5, t4, *(w+18), 0xDB0FEAD3);
586  FF_5(t2, t1, t0, t7, t6, t5, t4, t3, *(w+ 6), 0x49F1C09B);
587  FF_5(t1, t0, t7, t6, t5, t4, t3, t2, *(w+28), 0x075372C9);
588  FF_5(t0, t7, t6, t5, t4, t3, t2, t1, *(w+24), 0x80991B7B);
589
590  FF_5(t7, t6, t5, t4, t3, t2, t1, t0, *(w+ 2), 0x25D479D8);
591  FF_5(t6, t5, t4, t3, t2, t1, t0, t7, *(w+23), 0xF6E8DEF7);
592  FF_5(t5, t4, t3, t2, t1, t0, t7, t6, *(w+16), 0xE3FE501A);
593  FF_5(t4, t3, t2, t1, t0, t7, t6, t5, *(w+22), 0xB6794C3B);
594  FF_5(t3, t2, t1, t0, t7, t6, t5, t4, *(w+ 4), 0x976CE0BD);
595  FF_5(t2, t1, t0, t7, t6, t5, t4, t3, *(w+ 1), 0x04C006BA);
596  FF_5(t1, t0, t7, t6, t5, t4, t3, t2, *(w+25), 0xC1A94FB6);
597  FF_5(t0, t7, t6, t5, t4, t3, t2, t1, *(w+15), 0x409F60C4);
598#endif
599
600  state->fingerprint[0] += t0;
601  state->fingerprint[1] += t1;
602  state->fingerprint[2] += t2;
603  state->fingerprint[3] += t3;
604  state->fingerprint[4] += t4;
605  state->fingerprint[5] += t5;
606  state->fingerprint[6] += t6;
607  state->fingerprint[7] += t7;
608}
609
610/* tailor the last output */
611static void haval_tailor (state)
612haval_state *state;
613{
614#if (FPTLEN != 224) && (FPTLEN != 256) /* aku, Sep 23, 1996, define temp only if necessary */
615  haval_word temp;
616#endif
617
618#if FPTLEN == 128
619  temp = (state->fingerprint[7] & 0x000000FF) |
620         (state->fingerprint[6] & 0xFF000000) |
621         (state->fingerprint[5] & 0x00FF0000) |
622         (state->fingerprint[4] & 0x0000FF00);
623  state->fingerprint[0] += rotate_right(temp,  8);
624
625  temp = (state->fingerprint[7] & 0x0000FF00) |
626         (state->fingerprint[6] & 0x000000FF) |
627         (state->fingerprint[5] & 0xFF000000) |
628         (state->fingerprint[4] & 0x00FF0000);
629  state->fingerprint[1] += rotate_right(temp, 16);
630
631  temp  = (state->fingerprint[7] & 0x00FF0000) |
632          (state->fingerprint[6] & 0x0000FF00) |
633          (state->fingerprint[5] & 0x000000FF) |
634          (state->fingerprint[4] & 0xFF000000);
635  state->fingerprint[2] += rotate_right(temp, 24);
636
637  temp = (state->fingerprint[7] & 0xFF000000) |
638         (state->fingerprint[6] & 0x00FF0000) |
639         (state->fingerprint[5] & 0x0000FF00) |
640         (state->fingerprint[4] & 0x000000FF);
641  state->fingerprint[3] += temp;
642
643#elif FPTLEN == 160
644  temp = (state->fingerprint[7] &  (haval_word)0x3F) |
645         (state->fingerprint[6] & ((haval_word)0x7F << 25)) |
646         (state->fingerprint[5] & ((haval_word)0x3F << 19));
647  state->fingerprint[0] += rotate_right(temp, 19);
648
649  temp = (state->fingerprint[7] & ((haval_word)0x3F <<  6)) |
650         (state->fingerprint[6] &  (haval_word)0x3F) |
651         (state->fingerprint[5] & ((haval_word)0x7F << 25));
652  state->fingerprint[1] += rotate_right(temp, 25);
653
654  temp = (state->fingerprint[7] & ((haval_word)0x7F << 12)) |
655         (state->fingerprint[6] & ((haval_word)0x3F <<  6)) |
656         (state->fingerprint[5] &  (haval_word)0x3F);
657  state->fingerprint[2] += temp;
658
659  temp = (state->fingerprint[7] & ((haval_word)0x3F << 19)) |
660         (state->fingerprint[6] & ((haval_word)0x7F << 12)) |
661         (state->fingerprint[5] & ((haval_word)0x3F <<  6));
662  state->fingerprint[3] += temp >> 6;
663
664  temp = (state->fingerprint[7] & ((haval_word)0x7F << 25)) |
665         (state->fingerprint[6] & ((haval_word)0x3F << 19)) |
666         (state->fingerprint[5] & ((haval_word)0x7F << 12));
667  state->fingerprint[4] += temp >> 12;
668
669#elif FPTLEN == 192
670  temp = (state->fingerprint[7] &  (haval_word)0x1F) |
671         (state->fingerprint[6] & ((haval_word)0x3F << 26));
672  state->fingerprint[0] += rotate_right(temp, 26);
673
674  temp = (state->fingerprint[7] & ((haval_word)0x1F <<  5)) |
675         (state->fingerprint[6] &  (haval_word)0x1F);
676  state->fingerprint[1] += temp;
677
678  temp = (state->fingerprint[7] & ((haval_word)0x3F << 10)) |
679         (state->fingerprint[6] & ((haval_word)0x1F <<  5));
680  state->fingerprint[2] += temp >> 5;
681
682  temp = (state->fingerprint[7] & ((haval_word)0x1F << 16)) |
683         (state->fingerprint[6] & ((haval_word)0x3F << 10));
684  state->fingerprint[3] += temp >> 10;
685
686  temp = (state->fingerprint[7] & ((haval_word)0x1F << 21)) |
687         (state->fingerprint[6] & ((haval_word)0x1F << 16));
688  state->fingerprint[4] += temp >> 16;
689
690  temp = (state->fingerprint[7] & ((haval_word)0x3F << 26)) |
691         (state->fingerprint[6] & ((haval_word)0x1F << 21));
692  state->fingerprint[5] += temp >> 21;
693
694#elif FPTLEN == 224
695  state->fingerprint[0] += (state->fingerprint[7] >> 27) & 0x1F;
696  state->fingerprint[1] += (state->fingerprint[7] >> 22) & 0x1F;
697  state->fingerprint[2] += (state->fingerprint[7] >> 18) & 0x0F;
698  state->fingerprint[3] += (state->fingerprint[7] >> 13) & 0x1F;
699  state->fingerprint[4] += (state->fingerprint[7] >>  9) & 0x0F;
700  state->fingerprint[5] += (state->fingerprint[7] >>  4) & 0x1F;
701  state->fingerprint[6] +=  state->fingerprint[7]        & 0x0F;
702#endif
703}
704
705
706