comparison src/hashes/whirl/whirl.c @ 191:1c15b283127b libtomcrypt-orig

Import of libtomcrypt 1.02 with manual path rename rearrangement etc
author Matt Johnston <matt@ucc.asn.au>
date Fri, 06 May 2005 13:23:02 +0000
parents
children 39d5d58461d6
comparison
equal deleted inserted replaced
143:5d99163f7e32 191:1c15b283127b
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2 *
3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner.
5 *
6 * The library is free for all purposes without any express
7 * guarantee it works.
8 *
9 * Tom St Denis, [email protected], http://libtomcrypt.org
10 */
11
12 /**
13 @file whirl.c
14 WHIRLPOOL (using their new sbox) hash function by Tom St Denis
15 */
16
17 #include "tomcrypt.h"
18
19 #ifdef WHIRLPOOL
20
21 const struct ltc_hash_descriptor whirlpool_desc =
22 {
23 "whirlpool",
24 11,
25 64,
26 64,
27
28 /* DER encoding (not yet supported) */
29 { 0x00 },
30 0,
31
32 &whirlpool_init,
33 &whirlpool_process,
34 &whirlpool_done,
35 &whirlpool_test
36 };
37
38 /* the sboxes */
39 #include "whirltab.c"
40
41 /* get a_{i,j} */
42 #define GB(a,i,j) ((a[(i) & 7] >> (8 * (j))) & 255)
43
44 /* shortcut macro to perform three functions at once */
45 #define theta_pi_gamma(a, i) \
46 SB0(GB(a, i-0, 7)) ^ \
47 SB1(GB(a, i-1, 6)) ^ \
48 SB2(GB(a, i-2, 5)) ^ \
49 SB3(GB(a, i-3, 4)) ^ \
50 SB4(GB(a, i-4, 3)) ^ \
51 SB5(GB(a, i-5, 2)) ^ \
52 SB6(GB(a, i-6, 1)) ^ \
53 SB7(GB(a, i-7, 0))
54
55 #ifdef LTC_CLEAN_STACK
56 static int _whirlpool_compress(hash_state *md, unsigned char *buf)
57 #else
58 static int whirlpool_compress(hash_state *md, unsigned char *buf)
59 #endif
60 {
61 ulong64 K[2][8], T[3][8];
62 int x, y;
63
64 /* load the block/state */
65 for (x = 0; x < 8; x++) {
66 K[0][x] = md->whirlpool.state[x];
67
68 LOAD64H(T[0][x], buf + (8 * x));
69 T[2][x] = T[0][x];
70 T[0][x] ^= K[0][x];
71 }
72
73 /* do rounds 1..10 */
74 for (x = 0; x < 10; x += 2) {
75 /* odd round */
76 /* apply main transform to K[0] into K[1] */
77 for (y = 0; y < 8; y++) {
78 K[1][y] = theta_pi_gamma(K[0], y);
79 }
80 /* xor the constant */
81 K[1][0] ^= cont[x];
82
83 /* apply main transform to T[0] into T[1] */
84 for (y = 0; y < 8; y++) {
85 T[1][y] = theta_pi_gamma(T[0], y) ^ K[1][y];
86 }
87
88 /* even round */
89 /* apply main transform to K[1] into K[0] */
90 for (y = 0; y < 8; y++) {
91 K[0][y] = theta_pi_gamma(K[1], y);
92 }
93 /* xor the constant */
94 K[0][0] ^= cont[x+1];
95
96 /* apply main transform to T[1] into T[0] */
97 for (y = 0; y < 8; y++) {
98 T[0][y] = theta_pi_gamma(T[1], y) ^ K[0][y];
99 }
100 }
101
102 /* store state */
103 for (x = 0; x < 8; x++) {
104 md->whirlpool.state[x] ^= T[0][x] ^ T[2][x];
105 }
106
107 return CRYPT_OK;
108 }
109
110
111 #ifdef LTC_CLEAN_STACK
112 static int whirlpool_compress(hash_state *md, unsigned char *buf)
113 {
114 int err;
115 err = _whirlpool_compress(md, buf);
116 burn_stack((5 * 8 * sizeof(ulong64)) + (2 * sizeof(int)));
117 return err;
118 }
119 #endif
120
121
122 /**
123 Initialize the hash state
124 @param md The hash state you wish to initialize
125 @return CRYPT_OK if successful
126 */
127 int whirlpool_init(hash_state * md)
128 {
129 LTC_ARGCHK(md != NULL);
130 zeromem(&md->whirlpool, sizeof(md->whirlpool));
131 return CRYPT_OK;
132 }
133
134 /**
135 Process a block of memory though the hash
136 @param md The hash state
137 @param in The data to hash
138 @param inlen The length of the data (octets)
139 @return CRYPT_OK if successful
140 */
141 HASH_PROCESS(whirlpool_process, whirlpool_compress, whirlpool, 64)
142
143 /**
144 Terminate the hash to get the digest
145 @param md The hash state
146 @param out [out] The destination of the hash (64 bytes)
147 @return CRYPT_OK if successful
148 */
149 int whirlpool_done(hash_state * md, unsigned char *out)
150 {
151 int i;
152
153 LTC_ARGCHK(md != NULL);
154 LTC_ARGCHK(out != NULL);
155
156 if (md->whirlpool.curlen >= sizeof(md->whirlpool.buf)) {
157 return CRYPT_INVALID_ARG;
158 }
159
160 /* increase the length of the message */
161 md->whirlpool.length += md->whirlpool.curlen * 8;
162
163 /* append the '1' bit */
164 md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0x80;
165
166 /* if the length is currently above 32 bytes we append zeros
167 * then compress. Then we can fall back to padding zeros and length
168 * encoding like normal.
169 */
170 if (md->whirlpool.curlen > 32) {
171 while (md->whirlpool.curlen < 64) {
172 md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0;
173 }
174 whirlpool_compress(md, md->whirlpool.buf);
175 md->whirlpool.curlen = 0;
176 }