haval.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. /* Modified version of the HAVAL hash algorithm implementation
  2. * by Calyptix Security Corporation.
  3. * Use freely.
  4. *
  5. * Changes to the original version:
  6. * - Renamed some function and constants
  7. * - Added new include file to the haval.h header file
  8. * - Removed config.h from include directives
  9. */
  10. /* $Id: haval.c,v 1.8 2003/01/20 05:44:48 lteo Exp $ */
  11. /*
  12. * haval.c: specifies the routines in the HAVAL (V.1) hashing library.
  13. *
  14. * Copyright (c) 2003 Calyptix Security Corporation
  15. * All rights reserved.
  16. *
  17. * This code is derived from software contributed to Calyptix Security
  18. * Corporation by Yuliang Zheng.
  19. *
  20. * Redistribution and use in source and binary forms, with or without
  21. * modification, are permitted provided that the following conditions
  22. * are met:
  23. * 1. Redistributions of source code must retain the above copyright
  24. * notice, this list of conditions and the following disclaimer.
  25. * 2. Redistributions in binary form must reproduce the above
  26. * copyright notice, this list of conditions and the following
  27. * disclaimer in the documentation and/or other materials provided
  28. * with the distribution.
  29. * 3. Neither the name of Calyptix Security Corporation nor the
  30. * names of its contributors may be used to endorse or promote
  31. * products derived from this software without specific prior
  32. * written permission.
  33. *
  34. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  35. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  36. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  37. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  38. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  39. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  40. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  41. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  42. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  43. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  44. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  45. * POSSIBILITY OF SUCH DAMAGE.
  46. *
  47. * -------------------------------------------------------------------
  48. *
  49. * HAVAL is a one-way hashing algorithm with the following
  50. * collision-resistant property:
  51. * It is computationally infeasible to find two or more
  52. * messages that are hashed into the same fingerprint.
  53. *
  54. * Reference:
  55. * Y. Zheng, J. Pieprzyk and J. Seberry:
  56. * ``HAVAL --- a one-way hashing algorithm with variable
  57. * length of output'', Advances in Cryptology --- AUSCRYPT'92,
  58. * Lecture Notes in Computer Science, Vol.718, pp.83-104,
  59. * Springer-Verlag, 1993.
  60. *
  61. * Descriptions:
  62. * - haval_string: hash a string
  63. * - haval_file: hash a file
  64. * - haval_stdin: filter -- hash input from the stdin device
  65. * - haval_hash: hash a string of specified length
  66. * (Haval_hash is used in conjunction with
  67. * haval_start & haval_end.)
  68. * - haval_hash_block: hash a 32-word block
  69. * - haval_start: initialization
  70. * - haval_end: finalization
  71. *
  72. * Authors: Yuliang Zheng and Lawrence Teo
  73. * Calyptix Security Corporation
  74. * P.O. Box 561508, Charlotte, NC 28213, USA
  75. * Email: info@calyptix.com
  76. * URL: http://www.calyptix.com/
  77. * Voice: +1 704 806 8635
  78. *
  79. * For a list of changes, see the ChangeLog file.
  80. */
  81. static char rcsid[] = "$Id: haval.c,v 1.8 2003/01/20 05:44:48 lteo Exp $";
  82. #include <stdio.h>
  83. #include <string.h>
  84. /* #include "havalapp.h" */
  85. /* #include "config.h" */
  86. #include "haval.h"
  87. #include "../rhsyscfg.h"
  88. #define HAVAL_VERSION 1 /* current version number */
  89. void haval_string (char *, unsigned char *); /* hash a string */
  90. int haval_file (char *, unsigned char *); /* hash a file */
  91. void haval_stdin (void); /* hash input from stdin */
  92. void haval_start (haval_state *); /* initialization */
  93. void haval_hash (haval_state *,
  94. unsigned char *, unsigned int); /* updating routine */
  95. void haval_end (haval_state *, unsigned char *); /* finalization */
  96. void haval_hash_block (haval_state *); /* hash a 32-word block */
  97. static void haval_tailor (haval_state *); /* folding the last output */
  98. static unsigned char haval_padding[128] = { /* constants for haval_padding */
  99. 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  100. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  101. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  102. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  103. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  104. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  105. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  106. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  107. };
  108. #define haval_f_1(x6, x5, x4, x3, x2, x1, x0) \
  109. ((x1) & ((x0) ^ (x4)) ^ (x2) & (x5) ^ \
  110. (x3) & (x6) ^ (x0))
  111. #define haval_f_2(x6, x5, x4, x3, x2, x1, x0) \
  112. ((x2) & ((x1) & ~(x3) ^ (x4) & (x5) ^ (x6) ^ (x0)) ^ \
  113. (x4) & ((x1) ^ (x5)) ^ (x3) & (x5) ^ (x0))
  114. #define haval_f_3(x6, x5, x4, x3, x2, x1, x0) \
  115. ((x3) & ((x1) & (x2) ^ (x6) ^ (x0)) ^ \
  116. (x1) & (x4) ^ (x2) & (x5) ^ (x0))
  117. #define haval_f_4(x6, x5, x4, x3, x2, x1, x0) \
  118. ((x4) & ((x5) & ~(x2) ^ (x3) & ~(x6) ^ (x1) ^ (x6) ^ (x0)) ^ \
  119. (x3) & ((x1) & (x2) ^ (x5) ^ (x6)) ^ \
  120. (x2) & (x6) ^ (x0))
  121. #define haval_f_5(x6, x5, x4, x3, x2, x1, x0) \
  122. ((x0) & ((x1) & (x2) & (x3) ^ ~(x5)) ^ \
  123. (x1) & (x4) ^ (x2) & (x5) ^ (x3) & (x6))
  124. /*
  125. * Permutations phi_{i,j}, i=3,4,5, j=1,...,i.
  126. *
  127. * HAVAL_PASS = 3:
  128. * 6 5 4 3 2 1 0
  129. * | | | | | | | (replaced by)
  130. * phi_{3,1}: 1 0 3 5 6 2 4
  131. * phi_{3,2}: 4 2 1 0 5 3 6
  132. * phi_{3,3}: 6 1 2 3 4 5 0
  133. *
  134. * HAVAL_PASS = 4:
  135. * 6 5 4 3 2 1 0
  136. * | | | | | | | (replaced by)
  137. * phi_{4,1}: 2 6 1 4 5 3 0
  138. * phi_{4,2}: 3 5 2 0 1 6 4
  139. * phi_{4,3}: 1 4 3 6 0 2 5
  140. * phi_{4,4}: 6 4 0 5 2 1 3
  141. *
  142. * HAVAL_PASS = 5:
  143. * 6 5 4 3 2 1 0
  144. * | | | | | | | (replaced by)
  145. * phi_{5,1}: 3 4 1 0 5 2 6
  146. * phi_{5,2}: 6 2 1 0 3 4 5
  147. * phi_{5,3}: 2 6 0 4 3 1 5
  148. * phi_{5,4}: 1 5 3 2 0 4 6
  149. * phi_{5,5}: 2 5 0 6 4 3 1
  150. */
  151. #if HAVAL_PASS == 3
  152. #define haval_Fphi_1(x6, x5, x4, x3, x2, x1, x0) \
  153. haval_f_1(x1, x0, x3, x5, x6, x2, x4)
  154. #elif HAVAL_PASS == 4
  155. #define haval_Fphi_1(x6, x5, x4, x3, x2, x1, x0) \
  156. haval_f_1(x2, x6, x1, x4, x5, x3, x0)
  157. #else
  158. #define haval_Fphi_1(x6, x5, x4, x3, x2, x1, x0) \
  159. haval_f_1(x3, x4, x1, x0, x5, x2, x6)
  160. #endif
  161. #if HAVAL_PASS == 3
  162. #define haval_Fphi_2(x6, x5, x4, x3, x2, x1, x0) \
  163. haval_f_2(x4, x2, x1, x0, x5, x3, x6)
  164. #elif HAVAL_PASS == 4
  165. #define haval_Fphi_2(x6, x5, x4, x3, x2, x1, x0) \
  166. haval_f_2(x3, x5, x2, x0, x1, x6, x4)
  167. #else
  168. #define haval_Fphi_2(x6, x5, x4, x3, x2, x1, x0) \
  169. haval_f_2(x6, x2, x1, x0, x3, x4, x5)
  170. #endif
  171. #if HAVAL_PASS == 3
  172. #define haval_Fphi_3(x6, x5, x4, x3, x2, x1, x0) \
  173. haval_f_3(x6, x1, x2, x3, x4, x5, x0)
  174. #elif HAVAL_PASS == 4
  175. #define haval_Fphi_3(x6, x5, x4, x3, x2, x1, x0) \
  176. haval_f_3(x1, x4, x3, x6, x0, x2, x5)
  177. #else
  178. #define haval_Fphi_3(x6, x5, x4, x3, x2, x1, x0) \
  179. haval_f_3(x2, x6, x0, x4, x3, x1, x5)
  180. #endif
  181. #if HAVAL_PASS == 4
  182. #define haval_Fphi_4(x6, x5, x4, x3, x2, x1, x0) \
  183. haval_f_4(x6, x4, x0, x5, x2, x1, x3)
  184. #else
  185. #define haval_Fphi_4(x6, x5, x4, x3, x2, x1, x0) \
  186. haval_f_4(x1, x5, x3, x2, x0, x4, x6)
  187. #endif
  188. #define haval_Fphi_5(x6, x5, x4, x3, x2, x1, x0) \
  189. haval_f_5(x2, x5, x0, x6, x4, x3, x1)
  190. #define haval_rotate_right(x, n) (((x) >> (n)) | ((x) << (32-(n))))
  191. #define haval_FF_1(x7, x6, x5, x4, x3, x2, x1, x0, w) { \
  192. register haval_word temp = haval_Fphi_1(x6, x5, x4, x3, x2, x1, x0); \
  193. (x7) = haval_rotate_right(temp, 7) + haval_rotate_right((x7), 11) + (w); \
  194. }
  195. #define haval_FF_2(x7, x6, x5, x4, x3, x2, x1, x0, w, c) { \
  196. register haval_word temp = haval_Fphi_2(x6, x5, x4, x3, x2, x1, x0); \
  197. (x7) = haval_rotate_right(temp, 7) + haval_rotate_right((x7), 11) + (w) + (c); \
  198. }
  199. #define haval_FF_3(x7, x6, x5, x4, x3, x2, x1, x0, w, c) { \
  200. register haval_word temp = haval_Fphi_3(x6, x5, x4, x3, x2, x1, x0); \
  201. (x7) = haval_rotate_right(temp, 7) + haval_rotate_right((x7), 11) + (w) + (c); \
  202. }
  203. #define haval_FF_4(x7, x6, x5, x4, x3, x2, x1, x0, w, c) { \
  204. register haval_word temp = haval_Fphi_4(x6, x5, x4, x3, x2, x1, x0); \
  205. (x7) = haval_rotate_right(temp, 7) + haval_rotate_right((x7), 11) + (w) + (c); \
  206. }
  207. #define haval_FF_5(x7, x6, x5, x4, x3, x2, x1, x0, w, c) { \
  208. register haval_word temp = haval_Fphi_5(x6, x5, x4, x3, x2, x1, x0); \
  209. (x7) = haval_rotate_right(temp, 7) + haval_rotate_right((x7), 11) + (w) + (c); \
  210. }
  211. /*
  212. * translate every four characters into a word.
  213. * assume the number of characters is a multiple of four.
  214. */
  215. #define haval_ch2uint(string, word, slen) { \
  216. unsigned char *sp = string; \
  217. haval_word *wp = word; \
  218. while (sp < (string) + (slen)) { \
  219. *wp++ = (haval_word)*sp | \
  220. ((haval_word)*(sp+1) << 8) | \
  221. ((haval_word)*(sp+2) << 16) | \
  222. ((haval_word)*(sp+3) << 24); \
  223. sp += 4; \
  224. } \
  225. }
  226. /* translate each word into four characters */
  227. #define haval_uint2ch(word, string, wlen) { \
  228. haval_word *wp = word; \
  229. unsigned char *sp = string; \
  230. while (wp < (word) + (wlen)) { \
  231. *(sp++) = (unsigned char)( *wp & 0xFF); \
  232. *(sp++) = (unsigned char)((*wp >> 8) & 0xFF); \
  233. *(sp++) = (unsigned char)((*wp >> 16) & 0xFF); \
  234. *(sp++) = (unsigned char)((*wp >> 24) & 0xFF); \
  235. wp++; \
  236. } \
  237. }
  238. /* hash a string */
  239. void haval_string (char *string, unsigned char *fingerprint)
  240. {
  241. haval_state hstate;
  242. unsigned int len = strlen (string);
  243. haval_start (&hstate);
  244. haval_hash (&hstate, (unsigned char *)string, len);
  245. haval_end (&hstate, fingerprint);
  246. }
  247. /* hash a file */
  248. int haval_file (char *file_name, unsigned char *fingerprint)
  249. {
  250. FILE *file;
  251. haval_state hstate;
  252. int len;
  253. unsigned char buffer[1024];
  254. if ((file = fopen (file_name, "rb")) == NULL){
  255. return (1); /* fail */
  256. } else {
  257. haval_start (&hstate);
  258. while ((len = fread (buffer, 1, 1024, file))) {
  259. haval_hash (&hstate, buffer, len);
  260. }
  261. fclose (file);
  262. haval_end (&hstate, fingerprint);
  263. return (0); /* success */
  264. }
  265. }
  266. /* hash input from stdin */
  267. void haval_stdin (void)
  268. {
  269. haval_state hstate;
  270. int i, len;
  271. unsigned char buffer[32],
  272. fingerprint[HAVAL_FPTLEN >> 3];
  273. haval_start (&hstate);
  274. /* while (len = fread (buffer, 1, 32, stdin)) { */
  275. while ((len = fread (buffer, 1, 32, stdin))) {
  276. haval_hash (&hstate, buffer, len);
  277. }
  278. haval_end (&hstate, fingerprint);
  279. for (i = 0; i < HAVAL_FPTLEN >> 3; i++) {
  280. /* putchar(fingerprint[i]); */
  281. printf ("%02X", fingerprint[i]);
  282. }
  283. printf("\n");
  284. }
  285. /* initialization */
  286. void haval_start (haval_state *hstate)
  287. {
  288. hstate->count[0] = hstate->count[1] = 0; /* clear count */
  289. hstate->fingerprint[0] = 0x243F6A88L; /* initial fingerprint */
  290. hstate->fingerprint[1] = 0x85A308D3L;
  291. hstate->fingerprint[2] = 0x13198A2EL;
  292. hstate->fingerprint[3] = 0x03707344L;
  293. hstate->fingerprint[4] = 0xA4093822L;
  294. hstate->fingerprint[5] = 0x299F31D0L;
  295. hstate->fingerprint[6] = 0x082EFA98L;
  296. hstate->fingerprint[7] = 0xEC4E6C89L;
  297. }
  298. /*
  299. * hash a string of specified length.
  300. * to be used in conjunction with haval_start and haval_end.
  301. */
  302. void haval_hash (haval_state *hstate,
  303. unsigned char *str, unsigned int str_len)
  304. {
  305. unsigned int i,
  306. rmd_len,
  307. fill_len;
  308. /* calculate the number of bytes in the remainder */
  309. rmd_len = (unsigned int)((hstate->count[0] >> 3) & 0x7F);
  310. fill_len = 128 - rmd_len;
  311. /* update the number of bits */
  312. if ((hstate->count[0] += (haval_word)str_len << 3)
  313. < ((haval_word)str_len << 3)) {
  314. hstate->count[1]++;
  315. }
  316. hstate->count[1] += (haval_word)str_len >> 29;
  317. #ifdef RH_LITTLE_ENDIAN
  318. /* hash as many blocks as possible */
  319. if (rmd_len + str_len >= 128) {
  320. memcpy (((unsigned char *)hstate->block)+rmd_len, str, fill_len);
  321. haval_hash_block (hstate);
  322. for (i = fill_len; i + 127 < str_len; i += 128){
  323. memcpy ((unsigned char *)hstate->block, str+i, 128);
  324. haval_hash_block (hstate);
  325. }
  326. rmd_len = 0;
  327. } else {
  328. i = 0;
  329. }
  330. memcpy (((unsigned char *)hstate->block)+rmd_len, str+i, str_len-i);
  331. #else
  332. /* hash as many blocks as possible */
  333. if (rmd_len + str_len >= 128) {
  334. memcpy (&hstate->remainder[rmd_len], str, fill_len);
  335. haval_ch2uint(hstate->remainder, hstate->block, 128);
  336. haval_hash_block (hstate);
  337. for (i = fill_len; i + 127 < str_len; i += 128){
  338. memcpy (hstate->remainder, str+i, 128);
  339. haval_ch2uint(hstate->remainder, hstate->block, 128);
  340. haval_hash_block (hstate);
  341. }
  342. rmd_len = 0;
  343. } else {
  344. i = 0;
  345. }
  346. /* save the remaining input chars */
  347. memcpy (&hstate->remainder[rmd_len], str+i, str_len-i);
  348. #endif
  349. }
  350. /* finalization */
  351. void haval_end (haval_state *hstate, unsigned char *final_fpt)
  352. {
  353. unsigned char tail[10];
  354. unsigned int rmd_len, pad_len;
  355. /*
  356. * save the version number, the number of passes, the fingerprint
  357. * length and the number of bits in the unpadded message.
  358. */
  359. tail[0] = (unsigned char)(((HAVAL_FPTLEN & 0x3) << 6) |
  360. ((HAVAL_PASS & 0x7) << 3) |
  361. (HAVAL_VERSION & 0x7));
  362. tail[1] = (unsigned char)((HAVAL_FPTLEN >> 2) & 0xFF);
  363. haval_uint2ch (hstate->count, &tail[2], 2);
  364. /* pad out to 118 mod 128 */
  365. rmd_len = (unsigned int)((hstate->count[0] >> 3) & 0x7f);
  366. pad_len = (rmd_len < 118) ? (118 - rmd_len) : (246 - rmd_len);
  367. haval_hash (hstate, haval_padding, pad_len);
  368. /*
  369. * append the version number, the number of passes,
  370. * the fingerprint length and the number of bits
  371. */
  372. haval_hash (hstate, tail, 10);
  373. /* tailor the last output */
  374. haval_tailor(hstate);
  375. /* translate and save the final fingerprint */
  376. haval_uint2ch (hstate->fingerprint, final_fpt, HAVAL_FPTLEN >> 5);
  377. /* clear the hstate information */
  378. memset ((unsigned char *)hstate, 0, sizeof (*hstate));
  379. }
  380. /* hash a 32-word block */
  381. void haval_hash_block (haval_state *hstate)
  382. {
  383. register haval_word t0 = hstate->fingerprint[0], /* make use of */
  384. t1 = hstate->fingerprint[1], /* internal registers */
  385. t2 = hstate->fingerprint[2],
  386. t3 = hstate->fingerprint[3],
  387. t4 = hstate->fingerprint[4],
  388. t5 = hstate->fingerprint[5],
  389. t6 = hstate->fingerprint[6],
  390. t7 = hstate->fingerprint[7],
  391. *w = hstate->block;
  392. /* Pass 1 */
  393. haval_FF_1(t7, t6, t5, t4, t3, t2, t1, t0, *(w ));
  394. haval_FF_1(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 1));
  395. haval_FF_1(t5, t4, t3, t2, t1, t0, t7, t6, *(w+ 2));
  396. haval_FF_1(t4, t3, t2, t1, t0, t7, t6, t5, *(w+ 3));
  397. haval_FF_1(t3, t2, t1, t0, t7, t6, t5, t4, *(w+ 4));
  398. haval_FF_1(t2, t1, t0, t7, t6, t5, t4, t3, *(w+ 5));
  399. haval_FF_1(t1, t0, t7, t6, t5, t4, t3, t2, *(w+ 6));
  400. haval_FF_1(t0, t7, t6, t5, t4, t3, t2, t1, *(w+ 7));
  401. haval_FF_1(t7, t6, t5, t4, t3, t2, t1, t0, *(w+ 8));
  402. haval_FF_1(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 9));
  403. haval_FF_1(t5, t4, t3, t2, t1, t0, t7, t6, *(w+10));
  404. haval_FF_1(t4, t3, t2, t1, t0, t7, t6, t5, *(w+11));
  405. haval_FF_1(t3, t2, t1, t0, t7, t6, t5, t4, *(w+12));
  406. haval_FF_1(t2, t1, t0, t7, t6, t5, t4, t3, *(w+13));
  407. haval_FF_1(t1, t0, t7, t6, t5, t4, t3, t2, *(w+14));
  408. haval_FF_1(t0, t7, t6, t5, t4, t3, t2, t1, *(w+15));
  409. haval_FF_1(t7, t6, t5, t4, t3, t2, t1, t0, *(w+16));
  410. haval_FF_1(t6, t5, t4, t3, t2, t1, t0, t7, *(w+17));
  411. haval_FF_1(t5, t4, t3, t2, t1, t0, t7, t6, *(w+18));
  412. haval_FF_1(t4, t3, t2, t1, t0, t7, t6, t5, *(w+19));
  413. haval_FF_1(t3, t2, t1, t0, t7, t6, t5, t4, *(w+20));
  414. haval_FF_1(t2, t1, t0, t7, t6, t5, t4, t3, *(w+21));
  415. haval_FF_1(t1, t0, t7, t6, t5, t4, t3, t2, *(w+22));
  416. haval_FF_1(t0, t7, t6, t5, t4, t3, t2, t1, *(w+23));
  417. haval_FF_1(t7, t6, t5, t4, t3, t2, t1, t0, *(w+24));
  418. haval_FF_1(t6, t5, t4, t3, t2, t1, t0, t7, *(w+25));
  419. haval_FF_1(t5, t4, t3, t2, t1, t0, t7, t6, *(w+26));
  420. haval_FF_1(t4, t3, t2, t1, t0, t7, t6, t5, *(w+27));
  421. haval_FF_1(t3, t2, t1, t0, t7, t6, t5, t4, *(w+28));
  422. haval_FF_1(t2, t1, t0, t7, t6, t5, t4, t3, *(w+29));
  423. haval_FF_1(t1, t0, t7, t6, t5, t4, t3, t2, *(w+30));
  424. haval_FF_1(t0, t7, t6, t5, t4, t3, t2, t1, *(w+31));
  425. /* Pass 2 */
  426. haval_FF_2(t7, t6, t5, t4, t3, t2, t1, t0, *(w+ 5), 0x452821E6L);
  427. haval_FF_2(t6, t5, t4, t3, t2, t1, t0, t7, *(w+14), 0x38D01377L);
  428. haval_FF_2(t5, t4, t3, t2, t1, t0, t7, t6, *(w+26), 0xBE5466CFL);
  429. haval_FF_2(t4, t3, t2, t1, t0, t7, t6, t5, *(w+18), 0x34E90C6CL);
  430. haval_FF_2(t3, t2, t1, t0, t7, t6, t5, t4, *(w+11), 0xC0AC29B7L);
  431. haval_FF_2(t2, t1, t0, t7, t6, t5, t4, t3, *(w+28), 0xC97C50DDL);
  432. haval_FF_2(t1, t0, t7, t6, t5, t4, t3, t2, *(w+ 7), 0x3F84D5B5L);
  433. haval_FF_2(t0, t7, t6, t5, t4, t3, t2, t1, *(w+16), 0xB5470917L);
  434. haval_FF_2(t7, t6, t5, t4, t3, t2, t1, t0, *(w ), 0x9216D5D9L);
  435. haval_FF_2(t6, t5, t4, t3, t2, t1, t0, t7, *(w+23), 0x8979FB1BL);
  436. haval_FF_2(t5, t4, t3, t2, t1, t0, t7, t6, *(w+20), 0xD1310BA6L);
  437. haval_FF_2(t4, t3, t2, t1, t0, t7, t6, t5, *(w+22), 0x98DFB5ACL);
  438. haval_FF_2(t3, t2, t1, t0, t7, t6, t5, t4, *(w+ 1), 0x2FFD72DBL);
  439. haval_FF_2(t2, t1, t0, t7, t6, t5, t4, t3, *(w+10), 0xD01ADFB7L);
  440. haval_FF_2(t1, t0, t7, t6, t5, t4, t3, t2, *(w+ 4), 0xB8E1AFEDL);
  441. haval_FF_2(t0, t7, t6, t5, t4, t3, t2, t1, *(w+ 8), 0x6A267E96L);
  442. haval_FF_2(t7, t6, t5, t4, t3, t2, t1, t0, *(w+30), 0xBA7C9045L);
  443. haval_FF_2(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 3), 0xF12C7F99L);
  444. haval_FF_2(t5, t4, t3, t2, t1, t0, t7, t6, *(w+21), 0x24A19947L);
  445. haval_FF_2(t4, t3, t2, t1, t0, t7, t6, t5, *(w+ 9), 0xB3916CF7L);
  446. haval_FF_2(t3, t2, t1, t0, t7, t6, t5, t4, *(w+17), 0x0801F2E2L);
  447. haval_FF_2(t2, t1, t0, t7, t6, t5, t4, t3, *(w+24), 0x858EFC16L);
  448. haval_FF_2(t1, t0, t7, t6, t5, t4, t3, t2, *(w+29), 0x636920D8L);
  449. haval_FF_2(t0, t7, t6, t5, t4, t3, t2, t1, *(w+ 6), 0x71574E69L);
  450. haval_FF_2(t7, t6, t5, t4, t3, t2, t1, t0, *(w+19), 0xA458FEA3L);
  451. haval_FF_2(t6, t5, t4, t3, t2, t1, t0, t7, *(w+12), 0xF4933D7EL);
  452. haval_FF_2(t5, t4, t3, t2, t1, t0, t7, t6, *(w+15), 0x0D95748FL);
  453. haval_FF_2(t4, t3, t2, t1, t0, t7, t6, t5, *(w+13), 0x728EB658L);
  454. haval_FF_2(t3, t2, t1, t0, t7, t6, t5, t4, *(w+ 2), 0x718BCD58L);
  455. haval_FF_2(t2, t1, t0, t7, t6, t5, t4, t3, *(w+25), 0x82154AEEL);
  456. haval_FF_2(t1, t0, t7, t6, t5, t4, t3, t2, *(w+31), 0x7B54A41DL);
  457. haval_FF_2(t0, t7, t6, t5, t4, t3, t2, t1, *(w+27), 0xC25A59B5L);
  458. /* Pass 3 */
  459. haval_FF_3(t7, t6, t5, t4, t3, t2, t1, t0, *(w+19), 0x9C30D539L);
  460. haval_FF_3(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 9), 0x2AF26013L);
  461. haval_FF_3(t5, t4, t3, t2, t1, t0, t7, t6, *(w+ 4), 0xC5D1B023L);
  462. haval_FF_3(t4, t3, t2, t1, t0, t7, t6, t5, *(w+20), 0x286085F0L);
  463. haval_FF_3(t3, t2, t1, t0, t7, t6, t5, t4, *(w+28), 0xCA417918L);
  464. haval_FF_3(t2, t1, t0, t7, t6, t5, t4, t3, *(w+17), 0xB8DB38EFL);
  465. haval_FF_3(t1, t0, t7, t6, t5, t4, t3, t2, *(w+ 8), 0x8E79DCB0L);
  466. haval_FF_3(t0, t7, t6, t5, t4, t3, t2, t1, *(w+22), 0x603A180EL);
  467. haval_FF_3(t7, t6, t5, t4, t3, t2, t1, t0, *(w+29), 0x6C9E0E8BL);
  468. haval_FF_3(t6, t5, t4, t3, t2, t1, t0, t7, *(w+14), 0xB01E8A3EL);
  469. haval_FF_3(t5, t4, t3, t2, t1, t0, t7, t6, *(w+25), 0xD71577C1L);
  470. haval_FF_3(t4, t3, t2, t1, t0, t7, t6, t5, *(w+12), 0xBD314B27L);
  471. haval_FF_3(t3, t2, t1, t0, t7, t6, t5, t4, *(w+24), 0x78AF2FDAL);
  472. haval_FF_3(t2, t1, t0, t7, t6, t5, t4, t3, *(w+30), 0x55605C60L);
  473. haval_FF_3(t1, t0, t7, t6, t5, t4, t3, t2, *(w+16), 0xE65525F3L);
  474. haval_FF_3(t0, t7, t6, t5, t4, t3, t2, t1, *(w+26), 0xAA55AB94L);
  475. haval_FF_3(t7, t6, t5, t4, t3, t2, t1, t0, *(w+31), 0x57489862L);
  476. haval_FF_3(t6, t5, t4, t3, t2, t1, t0, t7, *(w+15), 0x63E81440L);
  477. haval_FF_3(t5, t4, t3, t2, t1, t0, t7, t6, *(w+ 7), 0x55CA396AL);
  478. haval_FF_3(t4, t3, t2, t1, t0, t7, t6, t5, *(w+ 3), 0x2AAB10B6L);
  479. haval_FF_3(t3, t2, t1, t0, t7, t6, t5, t4, *(w+ 1), 0xB4CC5C34L);
  480. haval_FF_3(t2, t1, t0, t7, t6, t5, t4, t3, *(w ), 0x1141E8CEL);
  481. haval_FF_3(t1, t0, t7, t6, t5, t4, t3, t2, *(w+18), 0xA15486AFL);
  482. haval_FF_3(t0, t7, t6, t5, t4, t3, t2, t1, *(w+27), 0x7C72E993L);
  483. haval_FF_3(t7, t6, t5, t4, t3, t2, t1, t0, *(w+13), 0xB3EE1411L);
  484. haval_FF_3(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 6), 0x636FBC2AL);
  485. haval_FF_3(t5, t4, t3, t2, t1, t0, t7, t6, *(w+21), 0x2BA9C55DL);
  486. haval_FF_3(t4, t3, t2, t1, t0, t7, t6, t5, *(w+10), 0x741831F6L);
  487. haval_FF_3(t3, t2, t1, t0, t7, t6, t5, t4, *(w+23), 0xCE5C3E16L);
  488. haval_FF_3(t2, t1, t0, t7, t6, t5, t4, t3, *(w+11), 0x9B87931EL);
  489. haval_FF_3(t1, t0, t7, t6, t5, t4, t3, t2, *(w+ 5), 0xAFD6BA33L);
  490. haval_FF_3(t0, t7, t6, t5, t4, t3, t2, t1, *(w+ 2), 0x6C24CF5CL);
  491. #if HAVAL_PASS >= 4
  492. /* Pass 4. executed only when HAVAL_PASS =4 or 5 */
  493. haval_FF_4(t7, t6, t5, t4, t3, t2, t1, t0, *(w+24), 0x7A325381L);
  494. haval_FF_4(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 4), 0x28958677L);
  495. haval_FF_4(t5, t4, t3, t2, t1, t0, t7, t6, *(w ), 0x3B8F4898L);
  496. haval_FF_4(t4, t3, t2, t1, t0, t7, t6, t5, *(w+14), 0x6B4BB9AFL);
  497. haval_FF_4(t3, t2, t1, t0, t7, t6, t5, t4, *(w+ 2), 0xC4BFE81BL);
  498. haval_FF_4(t2, t1, t0, t7, t6, t5, t4, t3, *(w+ 7), 0x66282193L);
  499. haval_FF_4(t1, t0, t7, t6, t5, t4, t3, t2, *(w+28), 0x61D809CCL);
  500. haval_FF_4(t0, t7, t6, t5, t4, t3, t2, t1, *(w+23), 0xFB21A991L);
  501. haval_FF_4(t7, t6, t5, t4, t3, t2, t1, t0, *(w+26), 0x487CAC60L);
  502. haval_FF_4(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 6), 0x5DEC8032L);
  503. haval_FF_4(t5, t4, t3, t2, t1, t0, t7, t6, *(w+30), 0xEF845D5DL);
  504. haval_FF_4(t4, t3, t2, t1, t0, t7, t6, t5, *(w+20), 0xE98575B1L);
  505. haval_FF_4(t3, t2, t1, t0, t7, t6, t5, t4, *(w+18), 0xDC262302L);
  506. haval_FF_4(t2, t1, t0, t7, t6, t5, t4, t3, *(w+25), 0xEB651B88L);
  507. haval_FF_4(t1, t0, t7, t6, t5, t4, t3, t2, *(w+19), 0x23893E81L);
  508. haval_FF_4(t0, t7, t6, t5, t4, t3, t2, t1, *(w+ 3), 0xD396ACC5L);
  509. haval_FF_4(t7, t6, t5, t4, t3, t2, t1, t0, *(w+22), 0x0F6D6FF3L);
  510. haval_FF_4(t6, t5, t4, t3, t2, t1, t0, t7, *(w+11), 0x83F44239L);
  511. haval_FF_4(t5, t4, t3, t2, t1, t0, t7, t6, *(w+31), 0x2E0B4482L);
  512. haval_FF_4(t4, t3, t2, t1, t0, t7, t6, t5, *(w+21), 0xA4842004L);
  513. haval_FF_4(t3, t2, t1, t0, t7, t6, t5, t4, *(w+ 8), 0x69C8F04AL);
  514. haval_FF_4(t2, t1, t0, t7, t6, t5, t4, t3, *(w+27), 0x9E1F9B5EL);
  515. haval_FF_4(t1, t0, t7, t6, t5, t4, t3, t2, *(w+12), 0x21C66842L);
  516. haval_FF_4(t0, t7, t6, t5, t4, t3, t2, t1, *(w+ 9), 0xF6E96C9AL);
  517. haval_FF_4(t7, t6, t5, t4, t3, t2, t1, t0, *(w+ 1), 0x670C9C61L);
  518. haval_FF_4(t6, t5, t4, t3, t2, t1, t0, t7, *(w+29), 0xABD388F0L);
  519. haval_FF_4(t5, t4, t3, t2, t1, t0, t7, t6, *(w+ 5), 0x6A51A0D2L);
  520. haval_FF_4(t4, t3, t2, t1, t0, t7, t6, t5, *(w+15), 0xD8542F68L);
  521. haval_FF_4(t3, t2, t1, t0, t7, t6, t5, t4, *(w+17), 0x960FA728L);
  522. haval_FF_4(t2, t1, t0, t7, t6, t5, t4, t3, *(w+10), 0xAB5133A3L);
  523. haval_FF_4(t1, t0, t7, t6, t5, t4, t3, t2, *(w+16), 0x6EEF0B6CL);
  524. haval_FF_4(t0, t7, t6, t5, t4, t3, t2, t1, *(w+13), 0x137A3BE4L);
  525. #endif
  526. #if HAVAL_PASS == 5
  527. /* Pass 5. executed only when HAVAL_PASS = 5 */
  528. haval_FF_5(t7, t6, t5, t4, t3, t2, t1, t0, *(w+27), 0xBA3BF050L);
  529. haval_FF_5(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 3), 0x7EFB2A98L);
  530. haval_FF_5(t5, t4, t3, t2, t1, t0, t7, t6, *(w+21), 0xA1F1651DL);
  531. haval_FF_5(t4, t3, t2, t1, t0, t7, t6, t5, *(w+26), 0x39AF0176L);
  532. haval_FF_5(t3, t2, t1, t0, t7, t6, t5, t4, *(w+17), 0x66CA593EL);
  533. haval_FF_5(t2, t1, t0, t7, t6, t5, t4, t3, *(w+11), 0x82430E88L);
  534. haval_FF_5(t1, t0, t7, t6, t5, t4, t3, t2, *(w+20), 0x8CEE8619L);
  535. haval_FF_5(t0, t7, t6, t5, t4, t3, t2, t1, *(w+29), 0x456F9FB4L);
  536. haval_FF_5(t7, t6, t5, t4, t3, t2, t1, t0, *(w+19), 0x7D84A5C3L);
  537. haval_FF_5(t6, t5, t4, t3, t2, t1, t0, t7, *(w ), 0x3B8B5EBEL);
  538. haval_FF_5(t5, t4, t3, t2, t1, t0, t7, t6, *(w+12), 0xE06F75D8L);
  539. haval_FF_5(t4, t3, t2, t1, t0, t7, t6, t5, *(w+ 7), 0x85C12073L);
  540. haval_FF_5(t3, t2, t1, t0, t7, t6, t5, t4, *(w+13), 0x401A449FL);
  541. haval_FF_5(t2, t1, t0, t7, t6, t5, t4, t3, *(w+ 8), 0x56C16AA6L);
  542. haval_FF_5(t1, t0, t7, t6, t5, t4, t3, t2, *(w+31), 0x4ED3AA62L);
  543. haval_FF_5(t0, t7, t6, t5, t4, t3, t2, t1, *(w+10), 0x363F7706L);
  544. haval_FF_5(t7, t6, t5, t4, t3, t2, t1, t0, *(w+ 5), 0x1BFEDF72L);
  545. haval_FF_5(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 9), 0x429B023DL);
  546. haval_FF_5(t5, t4, t3, t2, t1, t0, t7, t6, *(w+14), 0x37D0D724L);
  547. haval_FF_5(t4, t3, t2, t1, t0, t7, t6, t5, *(w+30), 0xD00A1248L);
  548. haval_FF_5(t3, t2, t1, t0, t7, t6, t5, t4, *(w+18), 0xDB0FEAD3L);
  549. haval_FF_5(t2, t1, t0, t7, t6, t5, t4, t3, *(w+ 6), 0x49F1C09BL);
  550. haval_FF_5(t1, t0, t7, t6, t5, t4, t3, t2, *(w+28), 0x075372C9L);
  551. haval_FF_5(t0, t7, t6, t5, t4, t3, t2, t1, *(w+24), 0x80991B7BL);
  552. haval_FF_5(t7, t6, t5, t4, t3, t2, t1, t0, *(w+ 2), 0x25D479D8L);
  553. haval_FF_5(t6, t5, t4, t3, t2, t1, t0, t7, *(w+23), 0xF6E8DEF7L);
  554. haval_FF_5(t5, t4, t3, t2, t1, t0, t7, t6, *(w+16), 0xE3FE501AL);
  555. haval_FF_5(t4, t3, t2, t1, t0, t7, t6, t5, *(w+22), 0xB6794C3BL);
  556. haval_FF_5(t3, t2, t1, t0, t7, t6, t5, t4, *(w+ 4), 0x976CE0BDL);
  557. haval_FF_5(t2, t1, t0, t7, t6, t5, t4, t3, *(w+ 1), 0x04C006BAL);
  558. haval_FF_5(t1, t0, t7, t6, t5, t4, t3, t2, *(w+25), 0xC1A94FB6L);
  559. haval_FF_5(t0, t7, t6, t5, t4, t3, t2, t1, *(w+15), 0x409F60C4L);
  560. #endif
  561. hstate->fingerprint[0] += t0;
  562. hstate->fingerprint[1] += t1;
  563. hstate->fingerprint[2] += t2;
  564. hstate->fingerprint[3] += t3;
  565. hstate->fingerprint[4] += t4;
  566. hstate->fingerprint[5] += t5;
  567. hstate->fingerprint[6] += t6;
  568. hstate->fingerprint[7] += t7;
  569. }
  570. /* tailor the last output */
  571. static void haval_tailor (haval_state *hstate)
  572. {
  573. haval_word temp;
  574. #if HAVAL_FPTLEN == 128
  575. temp = (hstate->fingerprint[7] & 0x000000FFL) |
  576. (hstate->fingerprint[6] & 0xFF000000L) |
  577. (hstate->fingerprint[5] & 0x00FF0000L) |
  578. (hstate->fingerprint[4] & 0x0000FF00L);
  579. hstate->fingerprint[0] += haval_rotate_right(temp, 8);
  580. temp = (hstate->fingerprint[7] & 0x0000FF00L) |
  581. (hstate->fingerprint[6] & 0x000000FFL) |
  582. (hstate->fingerprint[5] & 0xFF000000L) |
  583. (hstate->fingerprint[4] & 0x00FF0000L);
  584. hstate->fingerprint[1] += haval_rotate_right(temp, 16);
  585. temp = (hstate->fingerprint[7] & 0x00FF0000L) |
  586. (hstate->fingerprint[6] & 0x0000FF00L) |
  587. (hstate->fingerprint[5] & 0x000000FFL) |
  588. (hstate->fingerprint[4] & 0xFF000000L);
  589. hstate->fingerprint[2] += haval_rotate_right(temp, 24);
  590. temp = (hstate->fingerprint[7] & 0xFF000000L) |
  591. (hstate->fingerprint[6] & 0x00FF0000L) |
  592. (hstate->fingerprint[5] & 0x0000FF00L) |
  593. (hstate->fingerprint[4] & 0x000000FFL);
  594. hstate->fingerprint[3] += temp;
  595. #elif HAVAL_FPTLEN == 160
  596. temp = (hstate->fingerprint[7] & (haval_word)0x3F) |
  597. (hstate->fingerprint[6] & ((haval_word)0x7F << 25)) |
  598. (hstate->fingerprint[5] & ((haval_word)0x3F << 19));
  599. hstate->fingerprint[0] += haval_rotate_right(temp, 19);
  600. temp = (hstate->fingerprint[7] & ((haval_word)0x3F << 6)) |
  601. (hstate->fingerprint[6] & (haval_word)0x3F) |
  602. (hstate->fingerprint[5] & ((haval_word)0x7F << 25));
  603. hstate->fingerprint[1] += haval_rotate_right(temp, 25);
  604. temp = (hstate->fingerprint[7] & ((haval_word)0x7F << 12)) |
  605. (hstate->fingerprint[6] & ((haval_word)0x3F << 6)) |
  606. (hstate->fingerprint[5] & (haval_word)0x3F);
  607. hstate->fingerprint[2] += temp;
  608. temp = (hstate->fingerprint[7] & ((haval_word)0x3F << 19)) |
  609. (hstate->fingerprint[6] & ((haval_word)0x7F << 12)) |
  610. (hstate->fingerprint[5] & ((haval_word)0x3F << 6));
  611. hstate->fingerprint[3] += temp >> 6;
  612. temp = (hstate->fingerprint[7] & ((haval_word)0x7F << 25)) |
  613. (hstate->fingerprint[6] & ((haval_word)0x3F << 19)) |
  614. (hstate->fingerprint[5] & ((haval_word)0x7F << 12));
  615. hstate->fingerprint[4] += temp >> 12;
  616. #elif HAVAL_FPTLEN == 192
  617. temp = (hstate->fingerprint[7] & (haval_word)0x1F) |
  618. (hstate->fingerprint[6] & ((haval_word)0x3F << 26));
  619. hstate->fingerprint[0] += haval_rotate_right(temp, 26);
  620. temp = (hstate->fingerprint[7] & ((haval_word)0x1F << 5)) |
  621. (hstate->fingerprint[6] & (haval_word)0x1F);
  622. hstate->fingerprint[1] += temp;
  623. temp = (hstate->fingerprint[7] & ((haval_word)0x3F << 10)) |
  624. (hstate->fingerprint[6] & ((haval_word)0x1F << 5));
  625. hstate->fingerprint[2] += temp >> 5;
  626. temp = (hstate->fingerprint[7] & ((haval_word)0x1F << 16)) |
  627. (hstate->fingerprint[6] & ((haval_word)0x3F << 10));
  628. hstate->fingerprint[3] += temp >> 10;
  629. temp = (hstate->fingerprint[7] & ((haval_word)0x1F << 21)) |
  630. (hstate->fingerprint[6] & ((haval_word)0x1F << 16));
  631. hstate->fingerprint[4] += temp >> 16;
  632. temp = (hstate->fingerprint[7] & ((haval_word)0x3F << 26)) |
  633. (hstate->fingerprint[6] & ((haval_word)0x1F << 21));
  634. hstate->fingerprint[5] += temp >> 21;
  635. #elif HAVAL_FPTLEN == 224
  636. hstate->fingerprint[0] += (hstate->fingerprint[7] >> 27) & 0x1F;
  637. hstate->fingerprint[1] += (hstate->fingerprint[7] >> 22) & 0x1F;
  638. hstate->fingerprint[2] += (hstate->fingerprint[7] >> 18) & 0x0F;
  639. hstate->fingerprint[3] += (hstate->fingerprint[7] >> 13) & 0x1F;
  640. hstate->fingerprint[4] += (hstate->fingerprint[7] >> 9) & 0x0F;
  641. hstate->fingerprint[5] += (hstate->fingerprint[7] >> 4) & 0x1F;
  642. hstate->fingerprint[6] += hstate->fingerprint[7] & 0x0F;
  643. #endif
  644. }