comparison whirl.c @ 3:7faae8f46238 libtomcrypt-orig

Branch renaming
author Matt Johnston <matt@ucc.asn.au>
date Mon, 31 May 2004 18:25:41 +0000
parents
children 6362d3854bb4
comparison
equal deleted inserted replaced
-1:000000000000 3:7faae8f46238
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 /* WHIRLPOOL (using their new sbox) hash function by Tom St Denis */
13
14 #include "mycrypt.h"
15
16 #ifdef WHIRLPOOL
17
18 const struct _hash_descriptor whirlpool_desc =
19 {
20 "whirlpool",
21 11,
22 64,
23 64,
24 &whirlpool_init,
25 &whirlpool_process,
26 &whirlpool_done,
27 &whirlpool_test
28 };
29
30 /* the sboxes */
31 #include "whirltab.c"
32
33 /* get a_{i,j} */
34 #define GB(a,i,j) ((a[(i) & 7] >> (8 * (j))) & 255)
35
36 /* shortcut macro to perform three functions at once */
37 #define theta_pi_gamma(a, i) \
38 SB0(GB(a, i-0, 7)) ^ \
39 SB1(GB(a, i-1, 6)) ^ \
40 SB2(GB(a, i-2, 5)) ^ \
41 SB3(GB(a, i-3, 4)) ^ \
42 SB4(GB(a, i-4, 3)) ^ \
43 SB5(GB(a, i-5, 2)) ^ \
44 SB6(GB(a, i-6, 1)) ^ \
45 SB7(GB(a, i-7, 0))
46
47 #ifdef CLEAN_STACK
48 static void _whirlpool_compress(hash_state *md, unsigned char *buf)
49 #else
50 static void whirlpool_compress(hash_state *md, unsigned char *buf)
51 #endif
52 {
53 ulong64 K[2][8], T[3][8];
54 int x, y;
55
56 /* load the block/state */
57 for (x = 0; x < 8; x++) {
58 K[0][x] = md->whirlpool.state[x];
59
60 LOAD64H(T[0][x], buf + (8 * x));
61 T[2][x] = T[0][x];
62 T[0][x] ^= K[0][x];
63 }
64
65 /* do rounds 1..10 */
66 for (x = 0; x < 10; x += 2) {
67 /* odd round */
68 /* apply main transform to K[0] into K[1] */
69 for (y = 0; y < 8; y++) {
70 K[1][y] = theta_pi_gamma(K[0], y);
71 }
72 /* xor the constant */
73 K[1][0] ^= cont[x];
74
75 /* apply main transform to T[0] into T[1] */
76 for (y = 0; y < 8; y++) {
77 T[1][y] = theta_pi_gamma(T[0], y) ^ K[1][y];
78 }
79
80 /* even round */
81 /* apply main transform to K[1] into K[0] */
82 for (y = 0; y < 8; y++) {
83 K[0][y] = theta_pi_gamma(K[1], y);
84 }
85 /* xor the constant */
86 K[0][0] ^= cont[x+1];
87
88 /* apply main transform to T[0] into T[1] */
89 for (y = 0; y < 8; y++) {
90 T[0][y] = theta_pi_gamma(T[1], y) ^ K[0][y];
91 }
92 }
93
94 /* store state */
95 for (x = 0; x < 8; x++) {
96 md->whirlpool.state[x] ^= T[0][x] ^ T[2][x];
97 }
98 }
99
100
101 #ifdef CLEAN_STACK
102 static void whirlpool_compress(hash_state *md, unsigned char *buf)
103 {
104 _whirlpool_compress(md, buf);
105 burn_stack((5 * 8 * sizeof(ulong64)) + (2 * sizeof(int)));
106 }
107 #endif
108
109
110 void whirlpool_init(hash_state * md)
111 {
112 _ARGCHK(md != NULL);
113 zeromem(&md->whirlpool, sizeof(md->whirlpool));
114 }
115
116 HASH_PROCESS(whirlpool_process, whirlpool_compress, whirlpool, 64)
117
118 int whirlpool_done(hash_state * md, unsigned char *hash)
119 {
120 int i;
121
122 _ARGCHK(md != NULL);
123 _ARGCHK(hash != NULL);
124
125 if (md->whirlpool.curlen >= sizeof(md->whirlpool.buf)) {
126 return CRYPT_INVALID_ARG;
127 }
128
129 /* increase the length of the message */
130 md->whirlpool.length += md->whirlpool.curlen * 8;
131
132 /* append the '1' bit */
133 md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0x80;
134
135 /* if the length is currently above 32 bytes we append zeros
136 * then compress. Then we can fall back to padding zeros and length
137 * encoding like normal.
138 */
139 if (md->whirlpool.curlen > 32) {
140 while (md->whirlpool.curlen < 64) {
141 md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0;
142 }
143 whirlpool_compress(md, md->whirlpool.buf);
144 md->whirlpool.curlen = 0;
145 }
146
147 /* pad upto 56 bytes of zeroes (should be 32 but we only support 64-bit lengths) */
148 while (md->whirlpool.curlen < 56) {
149 md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0;
150 }
151
152 /* store length */
153 STORE64H(md->whirlpool.length, md->whirlpool.buf+56);
154 whirlpool_compress(md, md->whirlpool.buf);
155
156 /* copy output */
157 for (i = 0; i < 8; i++) {
158 STORE64H(md->whirlpool.state[i], hash+(8*i));
159 }
160 #ifdef CLEAN_STACK
161 zeromem(md, sizeof(*md));
162 #endif
163 return CRYPT_OK;
164 }
165
166
167 int whirlpool_test(void)
168 {
169 #ifndef LTC_TEST
170 return CRYPT_NOP;
171 #else
172 static const struct {
173 int len;
174 unsigned char msg[128], hash[64];
175 } tests[] = {
176
177 /* NULL Message */
178 {
179 0,
180 { 0x00 },
181 { 0x19, 0xFA, 0x61, 0xD7, 0x55, 0x22, 0xA4, 0x66, 0x9B, 0x44, 0xE3, 0x9C, 0x1D, 0x2E, 0x17, 0x26,
182 0xC5, 0x30, 0x23, 0x21, 0x30, 0xD4, 0x07, 0xF8, 0x9A, 0xFE, 0xE0, 0x96, 0x49, 0x97, 0xF7, 0xA7,
183 0x3E, 0x83, 0xBE, 0x69, 0x8B, 0x28, 0x8F, 0xEB, 0xCF, 0x88, 0xE3, 0xE0, 0x3C, 0x4F, 0x07, 0x57,
184 0xEA, 0x89, 0x64, 0xE5, 0x9B, 0x63, 0xD9, 0x37, 0x08, 0xB1, 0x38, 0xCC, 0x42, 0xA6, 0x6E, 0xB3 }
185 },
186
187
188 /* 448-bits of 0 bits */
189 {
190
191 56,
192 { 0x00 },
193 { 0x0B, 0x3F, 0x53, 0x78, 0xEB, 0xED, 0x2B, 0xF4, 0xD7, 0xBE, 0x3C, 0xFD, 0x81, 0x8C, 0x1B, 0x03,
194 0xB6, 0xBB, 0x03, 0xD3, 0x46, 0x94, 0x8B, 0x04, 0xF4, 0xF4, 0x0C, 0x72, 0x6F, 0x07, 0x58, 0x70,
195 0x2A, 0x0F, 0x1E, 0x22, 0x58, 0x80, 0xE3, 0x8D, 0xD5, 0xF6, 0xED, 0x6D, 0xE9, 0xB1, 0xE9, 0x61,
196 0xE4, 0x9F, 0xC1, 0x31, 0x8D, 0x7C, 0xB7, 0x48, 0x22, 0xF3, 0xD0, 0xE2, 0xE9, 0xA7, 0xE7, 0xB0 }
197 },
198
199 /* 520-bits of 0 bits */
200 {
201 65,
202 { 0x00 },
203 { 0x85, 0xE1, 0x24, 0xC4, 0x41, 0x5B, 0xCF, 0x43, 0x19, 0x54, 0x3E, 0x3A, 0x63, 0xFF, 0x57, 0x1D,
204 0x09, 0x35, 0x4C, 0xEE, 0xBE, 0xE1, 0xE3, 0x25, 0x30, 0x8C, 0x90, 0x69, 0xF4, 0x3E, 0x2A, 0xE4,
205 0xD0, 0xE5, 0x1D, 0x4E, 0xB1, 0xE8, 0x64, 0x28, 0x70, 0x19, 0x4E, 0x95, 0x30, 0xD8, 0xD8, 0xAF,
206 0x65, 0x89, 0xD1, 0xBF, 0x69, 0x49, 0xDD, 0xF9, 0x0A, 0x7F, 0x12, 0x08, 0x62, 0x37, 0x95, 0xB9 }
207 },
208
209 /* 512-bits, leading set */
210 {
211 64,
212 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
214 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
216 { 0x10, 0x3E, 0x00, 0x55, 0xA9, 0xB0, 0x90, 0xE1, 0x1C, 0x8F, 0xDD, 0xEB, 0xBA, 0x06, 0xC0, 0x5A,
217 0xCE, 0x8B, 0x64, 0xB8, 0x96, 0x12, 0x8F, 0x6E, 0xED, 0x30, 0x71, 0xFC, 0xF3, 0xDC, 0x16, 0x94,
218 0x67, 0x78, 0xE0, 0x72, 0x23, 0x23, 0x3F, 0xD1, 0x80, 0xFC, 0x40, 0xCC, 0xDB, 0x84, 0x30, 0xA6,
219 0x40, 0xE3, 0x76, 0x34, 0x27, 0x1E, 0x65, 0x5C, 0xA1, 0x67, 0x4E, 0xBF, 0xF5, 0x07, 0xF8, 0xCB }
220 },
221
222 /* 512-bits, leading set of second byte */
223 {
224 64,
225 { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
227 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
228 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
229 { 0x35, 0x7B, 0x42, 0xEA, 0x79, 0xBC, 0x97, 0x86, 0x97, 0x5A, 0x3C, 0x44, 0x70, 0xAA, 0xB2, 0x3E,
230 0x62, 0x29, 0x79, 0x7B, 0xAD, 0xBD, 0x54, 0x36, 0x5B, 0x54, 0x96, 0xE5, 0x5D, 0x9D, 0xD7, 0x9F,
231 0xE9, 0x62, 0x4F, 0xB4, 0x22, 0x66, 0x93, 0x0A, 0x62, 0x8E, 0xD4, 0xDB, 0x08, 0xF9, 0xDD, 0x35,
232 0xEF, 0x1B, 0xE1, 0x04, 0x53, 0xFC, 0x18, 0xF4, 0x2C, 0x7F, 0x5E, 0x1F, 0x9B, 0xAE, 0x55, 0xE0 }
233 },
234
235 /* 512-bits, leading set of last byte */
236 {
237 64,
238 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
239 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
240 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
241 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 },
242 { 0x8B, 0x39, 0x04, 0xDD, 0x19, 0x81, 0x41, 0x26, 0xFD, 0x02, 0x74, 0xAB, 0x49, 0xC5, 0x97, 0xF6,
243 0xD7, 0x75, 0x33, 0x52, 0xA2, 0xDD, 0x91, 0xFD, 0x8F, 0x9F, 0x54, 0x05, 0x4C, 0x54, 0xBF, 0x0F,
244 0x06, 0xDB, 0x4F, 0xF7, 0x08, 0xA3, 0xA2, 0x8B, 0xC3, 0x7A, 0x92, 0x1E, 0xEE, 0x11, 0xED, 0x7B,
245 0x6A, 0x53, 0x79, 0x32, 0xCC, 0x5E, 0x94, 0xEE, 0x1E, 0xA6, 0x57, 0x60, 0x7E, 0x36, 0xC9, 0xF7 }
246 },
247
248 };
249
250 int i;
251 unsigned char tmp[64];
252 hash_state md;
253
254 for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
255 whirlpool_init(&md);
256 whirlpool_process(&md, (unsigned char *)tests[i].msg, tests[i].len);
257 whirlpool_done(&md, tmp);
258 if (memcmp(tmp, tests[i].hash, 64) != 0) {
259 #if 0
260 printf("\nFailed test %d\n", i);
261 for (i = 0; i < 64; ) {
262 printf("%02x ", tmp[i]);
263 if (!(++i & 15)) printf("\n");
264 }
265 #endif
266 return CRYPT_FAIL_TESTVECTOR;
267 }
268 }
269 return CRYPT_OK;
270 #endif
271 }
272
273
274 #endif
275