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