define(`hashes', `dnl
_(md5) _(md4) _(md2) _(tiger) _(has160) dnl
_(sha) _(sha224) _(sha256) _(sha384) _(sha512) dnl
+_(whirlpool) _(whirlpool256) dnl
_(rmd128) _(rmd160) _(rmd256) _(rmd320)')
define(`hash_modes', `_(mgf) _(hmac)')
define(`gen_tables', `dnl
_(des) _(blowfish) _(twofish) dnl
-_(square) _(rijndael) dnl
+_(square) _(rijndael) _(whirlpool) dnl
_(safer) _(mars) _(tiger) dnl
_(gfshare) _(gfx-sqr)')
twofish.lo: twofish-tab.h
square.lo: square-tab.h
rijndael-base.lo: rijndael-tab.h
+whirlpool.lo: whirlpool-tab.h
safer.lo: safer-tab.h
mars.lo: mars-tab.h
tiger.lo: tiger-tab.h
--- /dev/null
+# Test vectors for the Whirlpool hash function
+#
+# $Id: sha 2187 2004-09-04 07:50:08Z mdw $
+
+# --- Basic hash function ---
+#
+# Some of these are taken from the ISO test vectors from the Whirlpool
+# distribution.
+
+whirlpool {
+ ""
+ 19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3;
+ "a"
+ 8aca2602792aec6f11a67206531fb7d7f0dff59413145e6973c45001d0087b42d11bc645413aeff63a42391a39145a591a92200d560195e53b478584fdae231a;
+ "abc"
+ 4e2448a4c6f486bb16b6562c73b4020bf3043e3a731bce721ae1b303d97e6d4c7181eebdb6c57e277d0e34957114cbd6c797fc9d95d8b582d225292076d4eef5;
+ "message digest"
+ 378c84a4126e2dc6e56dcc7458377aac838d00032230f53ce1f5700c0ffb4d3b8421557659ef55c106b4b52ac5a4aaa692ed920052838f3362e86dbd37a8903e;
+ "abcdefghijklmnopqrstuvwxyz"
+ f1d754662636ffe92c82ebb9212a484a8d38631ead4238f5442ee13b8054e41b08bf2a9251c30b6a0b8aae86177ab4a6f68f673e7207865d5d9819a3dba4eb3b;
+ "abcdbcdecdefdefgefghfghighijhijk"
+ 2a987ea40f917061f5d6f0a0e4644f488a7a5a52deee656207c562f988e95c6916bdc8031bc5be1b7b947639fe050b56939baaa0adff9ae6745b7b181c3be3fd;
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+ dc37e008cf9ee69bf11f00ed9aba26901dd7c28cdec066cc6af42e40f82f3a1e08eba26629129d8fb7cb57211b9281a65517cc879d7b962142c65f5a7af01467;
+}
+
+whirlpool-rep {
+ "1234567890" 8
+ 466ef18babb0154d25b9d38a6414f5c08784372bccb204d6549c4afadb6014294d5bd8df2a6c44e538cd047b2681a51a2c60481e88c5a20b2c2a80cf3a9a083b;
+ "a" 1000000
+ 0c99005beb57eff50a7cf005560ddf5d29057fd86b20bfd62deca0f1ccea4af51fc15490eddc47af32bb2b66c34ff9ad8c6008ad677f77126953b226e4ed8b01;
+}
+
+# --- HMAC mode ---
+#
+# Home-made test vectors, for regression.
+
+whirlpool-hmac {
+ "Hi There"
+ 0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
+ f300802099638aa1df411accbae11c2947fbcb2a4186f1c9bc6daa75dc3ad46dd89739ae5fb39b5c4afc098435c3ba0f7f55900e8c719711cbaee6d473eef0ba;
+
+ "what do ya want for nothing?"
+ 4a656665
+ 3d595ccd1d4f4cfd045af53ba7d5c8283fee6ded6eaf1269071b6b4ea64800056b5077c6a942cfa1221bd4e5aed791276e5dd46a407d2b8007163d3e7cd1de66;
+
+ "ÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝ"
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ 4fb33849b7d0268ab9f3bc90cfc6ca90639338c32bca959b7bc47a61f4d946ca6c6a227e97205a18fe676907ce78d0f8892fcf73f44da714cb210188b92cabc9;
+
+ "ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ"
+ 0102030405060708090a0b0c0d0e0f10111213141516171819
+ 35bc33e2ed71e1cb01c140ddd3291ae3f84e9f0dce18005a1123df199983a211fe744b244449a1c093b17584069359bc6a95352271d78e2ef7a6f21dc28ab3c1;
+
+ "Test With Truncation"
+ 0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c
+ 502a6d22d0f8e67196dfed2a9d9ef988714db9db2e2f0ad6c30e52eed830aa348ee98744ddd3ff1974c7fe275e078b79a6ba8c967c5a41b290f6edca01183b1a;
+
+ "Test Using Larger Than Block-Size Key - Hash Key First"
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ dd90bd637cfcd27ca914c290f33402cf68576d6e70601af0295f6b9dafa9d988d8b8fb4fde8605ac544638158dba2baa90a2bf882546cd0b876d59ab3f18962e;
+
+ "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data"
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ faf529af18a0f569480fd001122bb446b32a3cf758c385cec4adad9c73c77327812e260b7082011a3eb1071e71a50e1c3d37a8963f8b6a64a31cc017db1d619c;
+}
--- /dev/null
+# Test vectors for the Whirlpool hash function
+#
+# $Id: sha 2187 2004-09-04 07:50:08Z mdw $
+
+# --- Basic hash function ---
+#
+# Some of these are taken from the ISO test vectors from the Whirlpool
+# distribution.
+
+whirlpool256 {
+ ""
+ 19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a7;
+ "a"
+ 8aca2602792aec6f11a67206531fb7d7f0dff59413145e6973c45001d0087b42;
+ "abc"
+ 4e2448a4c6f486bb16b6562c73b4020bf3043e3a731bce721ae1b303d97e6d4c;
+ "message digest"
+ 378c84a4126e2dc6e56dcc7458377aac838d00032230f53ce1f5700c0ffb4d3b;
+ "abcdefghijklmnopqrstuvwxyz"
+ f1d754662636ffe92c82ebb9212a484a8d38631ead4238f5442ee13b8054e41b;
+ "abcdbcdecdefdefgefghfghighijhijk"
+ 2a987ea40f917061f5d6f0a0e4644f488a7a5a52deee656207c562f988e95c69;
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+ dc37e008cf9ee69bf11f00ed9aba26901dd7c28cdec066cc6af42e40f82f3a1e;
+}
+
+whirlpool256-rep {
+ "1234567890" 8
+ 466ef18babb0154d25b9d38a6414f5c08784372bccb204d6549c4afadb601429;
+ "a" 1000000
+ 0c99005beb57eff50a7cf005560ddf5d29057fd86b20bfd62deca0f1ccea4af5;
+}
+
+# --- HMAC mode ---
+#
+# Home-made test vectors, for regression.
+
+whirlpool256-hmac {
+ "Hi There"
+ 0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
+ 9ab3bbb27b85df2edc51f2e05c880560439547e7c2772f8cec6ae00bead0bd7e;
+
+ "what do ya want for nothing?"
+ 4a656665
+ 977fd7f1d53e8af854404262630bfac20269ab3fc2fccabecd8feaa05b8cdabb;
+
+ "ÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝ"
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ 6d418c9fe3d422200ea8cf7d0d73591ca5714f49c38907c80fc96b3934ab8fc2;
+
+ "ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ"
+ 0102030405060708090a0b0c0d0e0f10111213141516171819
+ e0a3553419a54385ce04435bbb2bbf1d69d7626d8fab4f60e87a84fab731caab;
+
+ "Test With Truncation"
+ 0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c
+ 2a4f40079e618c3a8467dd1a284af43662f84b137d93d54e5623884a047f546f;
+
+ "Test Using Larger Than Block-Size Key - Hash Key First"
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ 17564185de7d845576f42fbdcd027073bca1a059931ce4a901ae8662ad19caf0;
+
+ "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data"
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ 0bdc8bf26ff0a71201fbeef2d51f35bcbc3e8b0daeddedcbec2ca2b2e8f457b2;
+}
--- /dev/null
+/* -*-c-*-
+ *
+ * $Id$
+ *
+ * Generate tables for Whirlpool hash function
+ *
+ * (c) 2005 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of Catacomb.
+ *
+ * Catacomb is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * Catacomb is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with Catacomb; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <mLib/bits.h>
+
+/*----- Static variables --------------------------------------------------*/
+
+static const octet E[] = {
+ 0x1, 0xb, 0x9, 0xc, 0xd, 0x6, 0xf, 0x3,
+ 0xe, 0x8, 0x7, 0x4, 0xa, 0x2, 0x5, 0x0
+}, R[] = {
+ 0x7, 0xc, 0xb, 0xd, 0xe, 0x4, 0x9, 0xf,
+ 0x6, 0x3, 0x8, 0xa, 0x2, 0x5, 0x1, 0x0
+}, C[] = {
+ 0x1, 0x1, 0x4, 0x1, 0x8, 0x5, 0x2, 0x9
+};
+
+static octet S[256], T[256][8], log[256], alog[256];
+
+/*----- Main code ---------------------------------------------------------*/
+
+#define S_MOD 0x11d
+
+static void logtable(void)
+{
+ unsigned i, x;
+
+ for (i = 0, x = 1; i < 255; i++) {
+ log[x] = i;
+ alog[i] = x;
+ x <<= 1;
+ if (x & 0x100) x ^= S_MOD;
+ }
+}
+
+static octet mul(octet x, octet y)
+ { if (!x || !y) return (0); return (alog[(log[x] + log[y]) % 255]); }
+
+static void sbox(void)
+{
+ unsigned i, j;
+ octet EI[16];
+ octet l, r, y;
+
+ for (i = 0; i < 16; i++) EI[E[i]] = i;
+ for (i = 0; i < 256; i++) {
+ l = (i >> 4) & 0xf;
+ r = (i >> 0) & 0xf;
+ l = E[l]; r = EI[r];
+ y = R[l ^ r];
+ l = E[l ^ y]; r = EI[r ^ y];
+ S[i] = (l << 4) | r;
+ }
+
+ for (i = 0; i < 256; i++) {
+ for (j = 0; j < 8; j++)
+ T[i][j] = mul(S[i], C[j]);
+ }
+}
+
+static unsigned long w32(int i, int j, int k)
+{
+ kludge64 x;
+ LOAD64_L_(x, T[j]);
+ ROL64_(x, x, i * 8);
+ return (k ? LO64(x) : HI64(x));
+}
+
+int main(void)
+{
+ int i, j;
+
+ puts("\
+/* -*-c-*-\n\
+ *\n\
+ * Whirlpool tables [generated]\n\
+ */\n\
+\n\
+#ifndef CATACOMB_WHIRLPOOL_TAB_H\n\
+#define CATACOMB_WHIRLPOOL_TAB_H\n\
+");
+
+ /* --- Write out the S-box --- */
+
+ logtable();
+ sbox();
+ fputs("\
+/* --- The byte substitution --- */\n\
+\n\
+#define WHIRLPOOL_S { \\\n\
+ ", stdout);
+ for (i = 0; i < 256; i++) {
+ printf("0x%02x", S[i]);
+ if (i == 255)
+ fputs(" \\\n}\n\n", stdout);
+ else if (i % 8 == 7)
+ fputs(", \\\n ", stdout);
+ else
+ fputs(", ", stdout);
+ }
+
+ /* --- Write out the key constant tables --- */
+
+ fputs("\
+/* --- The key generation constants --- */\n\
+\n\
+#define WHIRLPOOL_C { \\\n\
+ ", stdout);
+ for (i = 0; i < 10; i++) {
+ printf("X64(%08lx, %08lx)",
+ (unsigned long)LOAD32_L(&S[i * 8 + 4]),
+ (unsigned long)LOAD32_L(&S[i * 8 + 0]));
+ if (i == 9)
+ fputs(" \\\n}\n\n", stdout);
+ else if (i % 2 == 1)
+ fputs(", \\\n ", stdout);
+ else
+ fputs(", ", stdout);
+ }
+
+ /* --- Write out the big T tables --- */
+
+ fputs("\
+/* --- The 64-bit big round tables --- */\n\
+\n\
+#define WHIRLPOOL_T { \\\n\
+ { ", stdout);
+ for (j = 0; j < 8; j++) {
+ for (i = 0; i < 256; i++) {
+ printf("X64(%08lx, %08lx)", w32(j, i, 0), w32(j, i, 1));
+ if (i == 255) {
+ if (j == 7)
+ fputs(" } \\\n}\n\n", stdout);
+ else
+ fputs(" }, \\\n\
+ \\\n\
+ { ", stdout);
+ } else if (i % 2 == 1)
+ fputs(", \\\n ", stdout);
+ else
+ fputs(", ", stdout);
+ }
+ }
+
+ /* --- Write out the smaller U and V tables --- */
+
+ fputs("\
+/* --- The 32-bit round tables --- */\n\
+\n\
+#define WHIRLPOOL_U { \\\n\
+ { ", stdout);
+ for (j = 0; j < 4; j++) {
+ for (i = 0; i < 256; i++) {
+ printf("0x%08lx", w32(j, i, 1));
+ if (i == 255) {
+ if (j == 3)
+ fputs(" } \\\n}\n\n", stdout);
+ else
+ fputs(" }, \\\n\
+ \\\n\
+ { ", stdout);
+ } else if (i % 4 == 3)
+ fputs(", \\\n ", stdout);
+ else
+ fputs(", ", stdout);
+ }
+ }
+
+ fputs("\
+#define WHIRLPOOL_V { \\\n\
+ { ", stdout);
+ for (j = 0; j < 4; j++) {
+ for (i = 0; i < 256; i++) {
+ printf("0x%08lx", w32(j, i, 0));
+ if (i == 255) {
+ if (j == 3)
+ fputs(" } \\\n}\n\n", stdout);
+ else
+ fputs(" }, \\\n\
+ \\\n\
+ { ", stdout);
+ } else if (i % 4 == 3)
+ fputs(", \\\n ", stdout);
+ else
+ fputs(", ", stdout);
+ }
+ }
+
+ /* --- Done --- */
+
+ puts("#endif");
+
+ if (fclose(stdout)) {
+ fprintf(stderr, "error writing data\n");
+ exit(EXIT_FAILURE);
+ }
+
+ return (0);
+}
+
+/*----- That's all, folks -------------------------------------------------*/
--- /dev/null
+/* -*-c-*-
+ *
+ * $Id$
+ *
+ * Whirlpool hash function
+ *
+ * (c) 2005 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of Catacomb.
+ *
+ * Catacomb is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * Catacomb is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with Catacomb; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <mLib/bits.h>
+
+#include "ghash.h"
+#include "ghash-def.h"
+#include "hash.h"
+#include "whirlpool.h"
+#include "whirlpool-tab.h"
+
+#if defined(HAVE_UINT64)
+# define USE64
+#endif
+
+/*----- Static variables --------------------------------------------------*/
+
+static const kludge64 C[10] = WHIRLPOOL_C;
+
+#ifdef USE64
+static const kludge64 T[8][256] = WHIRLPOOL_T;
+#else
+static const uint32 U[4][256] = WHIRLPOOL_U, V[4][256] = WHIRLPOOL_V;
+#endif
+
+/*----- Main code ---------------------------------------------------------*/
+
+#define DUMP(k, v) do { \
+ int i; \
+ printf("\n"); \
+ for (i = 0; i < 8; i++) \
+ printf(" %08x %08x : %08x %08x\n", \
+ HI64(k[i]), LO64(k[i]), \
+ HI64(v[i]), LO64(v[i])); \
+} while (0)
+
+#define OFFSET(i, n) (((i) + 16 - (n)) % 8)
+
+#ifdef USE64
+
+#define BYTE(x, j) \
+ U8((j) < 4 ? \
+ (LO64(x) >> ((j) * 8)) : \
+ (HI64(x) >> ((j) * 8 - 32)))
+
+#define TT(v, i, j) T[j][BYTE(v[OFFSET(i, j)], j)]
+
+#define XROW(vv, v, i) do { \
+ XOR64(vv[i], vv[i], TT(v, i, 1)); \
+ XOR64(vv[i], vv[i], TT(v, i, 2)); \
+ XOR64(vv[i], vv[i], TT(v, i, 3)); \
+ XOR64(vv[i], vv[i], TT(v, i, 4)); \
+ XOR64(vv[i], vv[i], TT(v, i, 5)); \
+ XOR64(vv[i], vv[i], TT(v, i, 6)); \
+ XOR64(vv[i], vv[i], TT(v, i, 7)); \
+} while (0)
+
+#define ROWZ(vv, v, i) do { \
+ vv[i] = TT(v, i, 0); \
+ XROW(vv, v, i); \
+} while (0)
+
+#define ROWK(vv, v, i, k) do { \
+ vv[i] = k; \
+ XOR64(vv[i], vv[i], TT(v, i, 0)); \
+ XROW(vv, v, i); \
+} while (0)
+
+#else
+
+#define BYTE(x, j) U8((x) >> (((j) & 3) * 8))
+
+#define UUL(v, i, j) U[j & 3][BYTE(v[OFFSET(i, j)].lo, j)]
+#define VVL(v, i, j) V[j & 3][BYTE(v[OFFSET(i, j)].lo, j)]
+#define UUH(v, i, j) U[j & 3][BYTE(v[OFFSET(i, j)].hi, j)]
+#define VVH(v, i, j) V[j & 3][BYTE(v[OFFSET(i, j)].hi, j)]
+
+#define XROW(vv, v, i) do { \
+ vv[i].lo ^= UUL(v, i, 1); vv[i].hi ^= VVL(v, i, 1); \
+ vv[i].lo ^= UUL(v, i, 2); vv[i].hi ^= VVL(v, i, 2); \
+ vv[i].lo ^= UUL(v, i, 3); vv[i].hi ^= VVL(v, i, 3); \
+ vv[i].lo ^= VVH(v, i, 4); vv[i].hi ^= UUH(v, i, 4); \
+ vv[i].lo ^= VVH(v, i, 5); vv[i].hi ^= UUH(v, i, 5); \
+ vv[i].lo ^= VVH(v, i, 6); vv[i].hi ^= UUH(v, i, 6); \
+ vv[i].lo ^= VVH(v, i, 7); vv[i].hi ^= UUH(v, i, 7); \
+} while (0)
+
+#define ROWZ(vv, v, i) do { \
+ vv[i].lo = UUL(v, i, 0); vv[i].hi = VVL(v, i, 0); \
+ XROW(vv, v, i); \
+} while (0)
+
+#define ROWK(vv, v, i, k) do { \
+ vv[i] = k; \
+ vv[i].lo ^= UUL(v, i, 0); vv[i].hi ^= VVL(v, i, 0); \
+ XROW(vv, v, i); \
+} while (0)
+
+#endif
+
+#define RHO(vv, v, kk, k) do { \
+ ROWK(kk, k, 0, *c++); ROWK(vv, v, 0, kk[0]); \
+ ROWZ(kk, k, 1); ROWK(vv, v, 1, kk[1]); \
+ ROWZ(kk, k, 2); ROWK(vv, v, 2, kk[2]); \
+ ROWZ(kk, k, 3); ROWK(vv, v, 3, kk[3]); \
+ ROWZ(kk, k, 4); ROWK(vv, v, 4, kk[4]); \
+ ROWZ(kk, k, 5); ROWK(vv, v, 5, kk[5]); \
+ ROWZ(kk, k, 6); ROWK(vv, v, 6, kk[6]); \
+ ROWZ(kk, k, 7); ROWK(vv, v, 7, kk[7]); \
+} while (0)
+
+void whirlpool_compress(whirlpool_ctx *ctx, const void *sbuf)
+{
+ kludge64 m[8], k[8], kk[8], v[8], vv[8];
+ const kludge64 *c = C;
+ const octet *s = sbuf;
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ LOAD64_L_(m[i], &s[i * 8]);
+ XOR64(v[i], m[i], ctx->s[i]);
+ }
+
+ RHO(vv, v, kk, ctx->s);
+ RHO(v, vv, k, kk);
+ RHO(vv, v, kk, k);
+ RHO(v, vv, k, kk);
+ RHO(vv, v, kk, k);
+ RHO(v, vv, k, kk);
+ RHO(vv, v, kk, k);
+ RHO(v, vv, k, kk);
+ RHO(vv, v, kk, k);
+ RHO(v, vv, k, kk);
+
+ for (i = 0; i < 8; i++) {
+ XOR64(ctx->s[i], ctx->s[i], m[i]);
+ XOR64(ctx->s[i], ctx->s[i], v[i]);
+ }
+}
+
+/* --- @whirlpool_init@, @whirlpool256_init@ --- *
+ *
+ * Arguments: @whirlpool_ctx *ctx@ = pointer to context block to initialize
+ *
+ * Returns: ---
+ *
+ * Use: Initializes a context block ready for hashing.
+ */
+
+void whirlpool_init(whirlpool_ctx *ctx)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ SET64(ctx->s[i], 0, 0);
+ ctx->off = 0;
+ ctx->nh = ctx->nl = 0;
+}
+
+/* --- @whirlpool_set@, @whirlpool256_set@ --- *
+ *
+ * Arguments: @whirlpool_ctx *ctx@ = pointer to context block
+ * @const void *buf@ = pointer to state buffer
+ * @unsigned long count@ = current count of bytes processed
+ *
+ * Returns: ---
+ *
+ * Use: Initializes a context block from a given state. This is
+ * useful in cases where the initial hash state is meant to be
+ * secret, e.g., for NMAC and HMAC support.
+ */
+
+void whirlpool_set(whirlpool_ctx *ctx, const void *buf, unsigned long count)
+{
+ const octet *p = buf;
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ LOAD64_L_(ctx->s[i], p);
+ p += 8;
+ }
+ ctx->off = 0;
+ ctx->nl = U32(count);
+ ctx->nh = U32(((count & ~MASK32) >> 16) >> 16);
+}
+
+/* --- @whirlpool_hash@, @whirlpool256_hash@ --- *
+ *
+ * Arguments: @whirlpool_ctx *ctx@ = pointer to context block
+ * @const void *buf@ = buffer of data to hash
+ * @size_t sz@ = size of buffer to hash
+ *
+ * Returns: ---
+ *
+ * Use: Hashes a buffer of data. The buffer may be of any size and
+ * alignment.
+ */
+
+void whirlpool_hash(whirlpool_ctx *ctx, const void *buf, size_t sz)
+{
+ HASH_BUFFER(WHIRLPOOL, whirlpool, ctx, buf, sz);
+}
+
+/* --- @whirlpool_done@, @whirlpool256_done@ --- *
+ *
+ * Arguments: @whirlpool_ctx *ctx@ = pointer to context block
+ * @void *hash@ = pointer to output buffer
+ *
+ * Returns: ---
+ *
+ * Use: Returns the hash of the data read so far.
+ */
+
+static void final(whirlpool_ctx *ctx)
+{
+ HASH_PAD(WHIRLPOOL, whirlpool, ctx, 0x80, 0, 32);
+ memset(ctx->buf + WHIRLPOOL_BUFSZ - 32, 0, 24);
+ STORE32(ctx->buf + WHIRLPOOL_BUFSZ - 8, (ctx->nl >> 29) | (ctx->nh << 3));
+ STORE32(ctx->buf + WHIRLPOOL_BUFSZ - 4, ctx->nl << 3);
+ whirlpool_compress(ctx, ctx->buf);
+}
+
+void whirlpool_done(whirlpool_ctx *ctx, void *hash)
+{
+ octet *p = hash;
+ int i;
+
+ final(ctx);
+ for (i = 0; i < 8; i++) {
+ STORE64_L_(p, ctx->s[i]);
+ p += 8;
+ }
+}
+
+void whirlpool256_done(whirlpool256_ctx *ctx, void *hash)
+{
+ octet *p = hash;
+ int i;
+
+ final(ctx);
+ for (i = 0; i < 4; i++) {
+ STORE64_L_(p, ctx->s[i]);
+ p += 8;
+ }
+}
+
+/* --- @whirlpool_state@, @whirlpool256_state@ --- *
+ *
+ * Arguments: @whirlpool_ctx *ctx@ = pointer to context
+ * @void *state@ = pointer to buffer for current state
+ *
+ * Returns: Number of bytes written to the hash function so far.
+ *
+ * Use: Returns the current state of the hash function such that
+ * it can be passed to @whirlpool_set@.
+ */
+
+unsigned long whirlpool_state(whirlpool_ctx *ctx, void *state)
+{
+ octet *p = state;
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ STORE64_L_(p, ctx->s[i]);
+ p += 8;
+ }
+ return (ctx->nl | ((ctx->nh << 16) << 16));
+}
+
+/* --- Generic interface --- */
+
+GHASH_DEF(WHIRLPOOL, whirlpool)
+
+/* --- Test code --- */
+
+HASH_TEST(WHIRLPOOL, whirlpool)
+
+/*----- That's all, folks -------------------------------------------------*/
--- /dev/null
+/* -*-c-*-
+ *
+ * $Id$
+ *
+ * Implementation of the Whirlpool hash function
+ *
+ * (c) 2000 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of Catacomb.
+ *
+ * Catacomb is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * Catacomb is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with Catacomb; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/*----- Notes on the Whirlpool hash function ------------------------------*
+ *
+ * Whirlpool was designed by Paulo Barreto and Vincent Rijmen. Its
+ * compression function is based on similar ideas to Rijndael (also
+ * codesigned by Rijmen).
+ *
+ * Whirlpool256 is simply Whirlpool with its final output truncated to 256
+ * bits. This is, I hope, about as good as a 256-bit hash function can get.
+ * It isn't vulnerable to the Kelsey-Schneier generic second-preimage attack
+ * against MD hash functions because of its larger internal state (see also
+ * Lucks).
+ */
+
+#ifndef CATACOMB_WHIRLPOOL_H
+#define CATACOMB_WHIRLPOOL_H
+#define CATACOMB_WHIRLPOOL256_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <mLib/bits.h>
+
+#ifndef CATACOMB_GHASH_H
+# include "ghash.h"
+#endif
+
+/*----- Magic numbers -----------------------------------------------------*/
+
+#define WHIRLPOOL_BUFSZ 64
+#define WHIRLPOOL_HASHSZ 64
+#define WHIRLPOOL_STATESZ 64
+
+#define WHIRLPOOL256_BUFSZ 64
+#define WHIRLPOOL256_HASHSZ 32
+#define WHIRLPOOL256_STATESZ 64
+
+/*----- Data structures ---------------------------------------------------*/
+
+typedef struct whirlpool_ctx {
+ kludge64 s[8]; /* Chaining variables */
+ uint32 nh, nl; /* Byte count so far */
+ unsigned off; /* Offset into buffer */
+ octet buf[WHIRLPOOL_BUFSZ]; /* Accumulation buffer */
+} whirlpool_ctx, whirlpool256_ctx;
+
+/*----- Functions provided ------------------------------------------------*/
+
+/* --- @whirlpool_compress@, @whirlpool256_compress@ --- *
+ *
+ * Arguments: @whirlpool_ctx *ctx@ = pointer to context block
+ * @const void *sbuf@ = pointer to buffer of appropriate size
+ *
+ * Returns: ---
+ *
+ * Use: SHA-512 compression function.
+ */
+
+extern void whirlpool_compress(whirlpool_ctx */*ctx*/, const void */*sbuf*/);
+#define whirlpool256_compress whirlpool_compress
+
+/* --- @whirlpool_init@, @whirlpool256_init@ --- *
+ *
+ * Arguments: @whirlpool_ctx *ctx@ = pointer to context block to initialize
+ *
+ * Returns: ---
+ *
+ * Use: Initializes a context block ready for hashing.
+ */
+
+extern void whirlpool_init(whirlpool_ctx */*ctx*/);
+#define whirlpool256_init whirlpool_init
+
+/* --- @whirlpool_set@, @whirlpool256_set@ --- *
+ *
+ * Arguments: @whirlpool_ctx *ctx@ = pointer to context block
+ * @const void *buf@ = pointer to state buffer
+ * @unsigned long count@ = current count of bytes processed
+ *
+ * Returns: ---
+ *
+ * Use: Initializes a context block from a given state. This is
+ * useful in cases where the initial hash state is meant to be
+ * secret, e.g., for NMAC and HMAC support.
+ */
+
+extern void whirlpool_set(whirlpool_ctx */*ctx*/, const void */*buf*/,
+ unsigned long /*count*/);
+#define whirlpool256_set whirlpool_set
+
+/* --- @whirlpool_hash@, @whirlpool256_hash@ --- *
+ *
+ * Arguments: @whirlpool_ctx *ctx@ = pointer to context block
+ * @const void *buf@ = buffer of data to hash
+ * @size_t sz@ = size of buffer to hash
+ *
+ * Returns: ---
+ *
+ * Use: Hashes a buffer of data. The buffer may be of any size and
+ * alignment.
+ */
+
+extern void whirlpool_hash(whirlpool_ctx */*ctx*/,
+ const void */*buf*/, size_t /*sz*/);
+#define whirlpool256_hash whirlpool_hash
+
+/* --- @whirlpool_done@, @whirlpool256_done@ --- *
+ *
+ * Arguments: @whirlpool_ctx *ctx@ = pointer to context block
+ * @void *hash@ = pointer to output buffer
+ *
+ * Returns: ---
+ *
+ * Use: Returns the hash of the data read so far.
+ */
+
+extern void whirlpool_done(whirlpool_ctx */*ctx*/, void */*hash*/);
+extern void whirlpool256_done(whirlpool_ctx */*ctx*/, void */*hash*/);
+
+/* --- @whirlpool_state@, @whirlpool256_state@ --- *
+ *
+ * Arguments: @whirlpool_ctx *ctx@ = pointer to context
+ * @void *state@ = pointer to buffer for current state
+ *
+ * Returns: Number of bytes written to the hash function so far.
+ *
+ * Use: Returns the current state of the hash function such that
+ * it can be passed to @whirlpool_set@.
+ */
+
+extern unsigned long whirlpool_state(whirlpool_ctx */*ctx*/,
+ void */*state*/);
+#define whirlpool256_state whirlpool_state
+
+/*----- Generic hash interface --------------------------------------------*/
+
+extern const gchash whirlpool;
+extern const gchash whirlpool256;
+
+/*----- That's all, folks -------------------------------------------------*/
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif
--- /dev/null
+/* -*-c-*-
+ *
+ * $Id$
+ *
+ * Stub code for Whirlpool-256
+ */
+
+#include "ghash.h"
+#include "ghash-def.h"
+#include "hash.h"
+#include "whirlpool256.h"
+
+GHASH_DEF(WHIRLPOOL256, whirlpool256)
+HASH_TEST(WHIRLPOOL256, whirlpool256)
--- /dev/null
+/* -*-c-*-
+ *
+ * $Id$
+ *
+ * Stub header for Whirlpool-256
+ */
+
+#ifndef CATACOMB_WHIRLPOOL256_H
+#define CATACOMB_WHIRLPOOL256_H
+
+#include "whirlpool.h"
+
+#endif