comparison whirl.c @ 16:09ab3354aa21 libtomcrypt

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