1 /***********************************************************************
3 ** Implementation of the Skein hash function.
5 ** Source code author: Doug Whiting, 2008.
7 ** This algorithm and source code is released to the public domain.
9 ************************************************************************/
11 #define SKEIN_PORT_CODE /* instantiate any code in skein_port.h */
13 #include <linux/string.h> /* get the memcpy/memset functions */
14 #include <skein.h> /* get the Skein API definitions */
15 #include <skein_iv.h> /* get precomputed IVs */
16 #include <skein_block.h>
18 /*****************************************************************/
20 /*****************************************************************/
22 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
23 /* init the context for a straight hashing operation */
24 int Skein_256_Init(struct skein_256_ctx *ctx, size_t hashBitLen)
27 u8 b[SKEIN_256_STATE_BYTES];
28 u64 w[SKEIN_256_STATE_WORDS];
29 } cfg; /* config block */
31 Skein_Assert(hashBitLen > 0, SKEIN_BAD_HASHLEN);
32 ctx->h.hashBitLen = hashBitLen; /* output hash bit count */
34 switch (hashBitLen) { /* use pre-computed values, where available */
36 memcpy(ctx->X, SKEIN_256_IV_256, sizeof(ctx->X));
39 memcpy(ctx->X, SKEIN_256_IV_224, sizeof(ctx->X));
42 memcpy(ctx->X, SKEIN_256_IV_160, sizeof(ctx->X));
45 memcpy(ctx->X, SKEIN_256_IV_128, sizeof(ctx->X));
48 /* here if there is no precomputed IV value available */
50 * build/process the config block, type == CONFIG (could be
53 /* set tweaks: T0=0; T1=CFG | FINAL */
54 Skein_Start_New_Type(ctx, CFG_FINAL);
56 /* set the schema, version */
57 cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);
58 /* hash result length in bits */
59 cfg.w[1] = Skein_Swap64(hashBitLen);
60 cfg.w[2] = Skein_Swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);
61 /* zero pad config block */
62 memset(&cfg.w[3], 0, sizeof(cfg) - 3*sizeof(cfg.w[0]));
64 /* compute the initial chaining values from config block */
65 /* zero the chaining variables */
66 memset(ctx->X, 0, sizeof(ctx->X));
67 Skein_256_Process_Block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
70 /* The chaining vars ctx->X are now initialized for hashBitLen. */
71 /* Set up to process the data message portion of the hash (default) */
72 Skein_Start_New_Type(ctx, MSG); /* T0=0, T1= MSG type */
77 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
78 /* init the context for a MAC and/or tree hash operation */
79 /* [identical to Skein_256_Init() when keyBytes == 0 && \
80 * treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */
81 int Skein_256_InitExt(struct skein_256_ctx *ctx, size_t hashBitLen,
82 u64 treeInfo, const u8 *key, size_t keyBytes)
85 u8 b[SKEIN_256_STATE_BYTES];
86 u64 w[SKEIN_256_STATE_WORDS];
87 } cfg; /* config block */
89 Skein_Assert(hashBitLen > 0, SKEIN_BAD_HASHLEN);
90 Skein_Assert(keyBytes == 0 || key != NULL, SKEIN_FAIL);
92 /* compute the initial chaining values ctx->X[], based on key */
93 if (keyBytes == 0) { /* is there a key? */
94 /* no key: use all zeroes as key for config block */
95 memset(ctx->X, 0, sizeof(ctx->X));
96 } else { /* here to pre-process a key */
97 Skein_assert(sizeof(cfg.b) >= sizeof(ctx->X));
98 /* do a mini-Init right here */
99 /* set output hash bit count = state size */
100 ctx->h.hashBitLen = 8*sizeof(ctx->X);
101 /* set tweaks: T0 = 0; T1 = KEY type */
102 Skein_Start_New_Type(ctx, KEY);
103 /* zero the initial chaining variables */
104 memset(ctx->X, 0, sizeof(ctx->X));
106 Skein_256_Update(ctx, key, keyBytes);
107 /* put result into cfg.b[] */
108 Skein_256_Final_Pad(ctx, cfg.b);
109 /* copy over into ctx->X[] */
110 memcpy(ctx->X, cfg.b, sizeof(cfg.b));
113 * build/process the config block, type == CONFIG (could be
114 * precomputed for each key)
116 /* output hash bit count */
117 ctx->h.hashBitLen = hashBitLen;
118 Skein_Start_New_Type(ctx, CFG_FINAL);
120 /* pre-pad cfg.w[] with zeroes */
121 memset(&cfg.w, 0, sizeof(cfg.w));
122 cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);
123 /* hash result length in bits */
124 cfg.w[1] = Skein_Swap64(hashBitLen);
125 /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */
126 cfg.w[2] = Skein_Swap64(treeInfo);
128 Skein_Show_Key(256, &ctx->h, key, keyBytes);
130 /* compute the initial chaining values from config block */
131 Skein_256_Process_Block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
133 /* The chaining vars ctx->X are now initialized */
134 /* Set up to process the data message portion of the hash (default) */
135 Skein_Start_New_Type(ctx, MSG);
137 return SKEIN_SUCCESS;
140 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
141 /* process the input bytes */
142 int Skein_256_Update(struct skein_256_ctx *ctx, const u8 *msg,
147 /* catch uninitialized context */
148 Skein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES, SKEIN_FAIL);
150 /* process full blocks, if any */
151 if (msgByteCnt + ctx->h.bCnt > SKEIN_256_BLOCK_BYTES) {
152 /* finish up any buffered message data */
154 /* # bytes free in buffer b[] */
155 n = SKEIN_256_BLOCK_BYTES - ctx->h.bCnt;
157 /* check on our logic here */
158 Skein_assert(n < msgByteCnt);
159 memcpy(&ctx->b[ctx->h.bCnt], msg, n);
164 Skein_assert(ctx->h.bCnt == SKEIN_256_BLOCK_BYTES);
165 Skein_256_Process_Block(ctx, ctx->b, 1,
166 SKEIN_256_BLOCK_BYTES);
170 * now process any remaining full blocks, directly from input
173 if (msgByteCnt > SKEIN_256_BLOCK_BYTES) {
174 /* number of full blocks to process */
175 n = (msgByteCnt-1) / SKEIN_256_BLOCK_BYTES;
176 Skein_256_Process_Block(ctx, msg, n,
177 SKEIN_256_BLOCK_BYTES);
178 msgByteCnt -= n * SKEIN_256_BLOCK_BYTES;
179 msg += n * SKEIN_256_BLOCK_BYTES;
181 Skein_assert(ctx->h.bCnt == 0);
184 /* copy any remaining source message data bytes into b[] */
186 Skein_assert(msgByteCnt + ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES);
187 memcpy(&ctx->b[ctx->h.bCnt], msg, msgByteCnt);
188 ctx->h.bCnt += msgByteCnt;
191 return SKEIN_SUCCESS;
194 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
195 /* finalize the hash computation and output the result */
196 int Skein_256_Final(struct skein_256_ctx *ctx, u8 *hashVal)
198 size_t i, n, byteCnt;
199 u64 X[SKEIN_256_STATE_WORDS];
200 /* catch uninitialized context */
201 Skein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES, SKEIN_FAIL);
203 /* tag as the final block */
204 ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;
205 /* zero pad b[] if necessary */
206 if (ctx->h.bCnt < SKEIN_256_BLOCK_BYTES)
207 memset(&ctx->b[ctx->h.bCnt], 0,
208 SKEIN_256_BLOCK_BYTES - ctx->h.bCnt);
210 /* process the final block */
211 Skein_256_Process_Block(ctx, ctx->b, 1, ctx->h.bCnt);
213 /* now output the result */
214 /* total number of output bytes */
215 byteCnt = (ctx->h.hashBitLen + 7) >> 3;
217 /* run Threefish in "counter mode" to generate output */
218 /* zero out b[], so it can hold the counter */
219 memset(ctx->b, 0, sizeof(ctx->b));
220 /* keep a local copy of counter mode "key" */
221 memcpy(X, ctx->X, sizeof(X));
222 for (i = 0; i*SKEIN_256_BLOCK_BYTES < byteCnt; i++) {
223 /* build the counter block */
224 ((u64 *)ctx->b)[0] = Skein_Swap64((u64) i);
225 Skein_Start_New_Type(ctx, OUT_FINAL);
226 /* run "counter mode" */
227 Skein_256_Process_Block(ctx, ctx->b, 1, sizeof(u64));
228 /* number of output bytes left to go */
229 n = byteCnt - i*SKEIN_256_BLOCK_BYTES;
230 if (n >= SKEIN_256_BLOCK_BYTES)
231 n = SKEIN_256_BLOCK_BYTES;
232 /* "output" the ctr mode bytes */
233 Skein_Put64_LSB_First(hashVal+i*SKEIN_256_BLOCK_BYTES, ctx->X,
235 Skein_Show_Final(256, &ctx->h, n,
236 hashVal+i*SKEIN_256_BLOCK_BYTES);
237 /* restore the counter mode key for next time */
238 memcpy(ctx->X, X, sizeof(X));
240 return SKEIN_SUCCESS;
243 /*****************************************************************/
245 /*****************************************************************/
247 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
248 /* init the context for a straight hashing operation */
249 int Skein_512_Init(struct skein_512_ctx *ctx, size_t hashBitLen)
252 u8 b[SKEIN_512_STATE_BYTES];
253 u64 w[SKEIN_512_STATE_WORDS];
254 } cfg; /* config block */
256 Skein_Assert(hashBitLen > 0, SKEIN_BAD_HASHLEN);
257 ctx->h.hashBitLen = hashBitLen; /* output hash bit count */
259 switch (hashBitLen) { /* use pre-computed values, where available */
261 memcpy(ctx->X, SKEIN_512_IV_512, sizeof(ctx->X));
264 memcpy(ctx->X, SKEIN_512_IV_384, sizeof(ctx->X));
267 memcpy(ctx->X, SKEIN_512_IV_256, sizeof(ctx->X));
270 memcpy(ctx->X, SKEIN_512_IV_224, sizeof(ctx->X));
273 /* here if there is no precomputed IV value available */
275 * build/process the config block, type == CONFIG (could be
278 /* set tweaks: T0=0; T1=CFG | FINAL */
279 Skein_Start_New_Type(ctx, CFG_FINAL);
281 /* set the schema, version */
282 cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);
283 /* hash result length in bits */
284 cfg.w[1] = Skein_Swap64(hashBitLen);
285 cfg.w[2] = Skein_Swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);
286 /* zero pad config block */
287 memset(&cfg.w[3], 0, sizeof(cfg) - 3*sizeof(cfg.w[0]));
289 /* compute the initial chaining values from config block */
290 /* zero the chaining variables */
291 memset(ctx->X, 0, sizeof(ctx->X));
292 Skein_512_Process_Block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
297 * The chaining vars ctx->X are now initialized for the given
300 /* Set up to process the data message portion of the hash (default) */
301 Skein_Start_New_Type(ctx, MSG); /* T0=0, T1= MSG type */
303 return SKEIN_SUCCESS;
306 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
307 /* init the context for a MAC and/or tree hash operation */
308 /* [identical to Skein_512_Init() when keyBytes == 0 && \
309 * treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */
310 int Skein_512_InitExt(struct skein_512_ctx *ctx, size_t hashBitLen,
311 u64 treeInfo, const u8 *key, size_t keyBytes)
314 u8 b[SKEIN_512_STATE_BYTES];
315 u64 w[SKEIN_512_STATE_WORDS];
316 } cfg; /* config block */
318 Skein_Assert(hashBitLen > 0, SKEIN_BAD_HASHLEN);
319 Skein_Assert(keyBytes == 0 || key != NULL, SKEIN_FAIL);
321 /* compute the initial chaining values ctx->X[], based on key */
322 if (keyBytes == 0) { /* is there a key? */
323 /* no key: use all zeroes as key for config block */
324 memset(ctx->X, 0, sizeof(ctx->X));
325 } else { /* here to pre-process a key */
326 Skein_assert(sizeof(cfg.b) >= sizeof(ctx->X));
327 /* do a mini-Init right here */
328 /* set output hash bit count = state size */
329 ctx->h.hashBitLen = 8*sizeof(ctx->X);
330 /* set tweaks: T0 = 0; T1 = KEY type */
331 Skein_Start_New_Type(ctx, KEY);
332 /* zero the initial chaining variables */
333 memset(ctx->X, 0, sizeof(ctx->X));
335 Skein_512_Update(ctx, key, keyBytes);
336 /* put result into cfg.b[] */
337 Skein_512_Final_Pad(ctx, cfg.b);
338 /* copy over into ctx->X[] */
339 memcpy(ctx->X, cfg.b, sizeof(cfg.b));
342 * build/process the config block, type == CONFIG (could be
343 * precomputed for each key)
345 ctx->h.hashBitLen = hashBitLen; /* output hash bit count */
346 Skein_Start_New_Type(ctx, CFG_FINAL);
348 /* pre-pad cfg.w[] with zeroes */
349 memset(&cfg.w, 0, sizeof(cfg.w));
350 cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);
351 /* hash result length in bits */
352 cfg.w[1] = Skein_Swap64(hashBitLen);
353 /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */
354 cfg.w[2] = Skein_Swap64(treeInfo);
356 Skein_Show_Key(512, &ctx->h, key, keyBytes);
358 /* compute the initial chaining values from config block */
359 Skein_512_Process_Block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
361 /* The chaining vars ctx->X are now initialized */
362 /* Set up to process the data message portion of the hash (default) */
363 Skein_Start_New_Type(ctx, MSG);
365 return SKEIN_SUCCESS;
368 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
369 /* process the input bytes */
370 int Skein_512_Update(struct skein_512_ctx *ctx, const u8 *msg,
375 /* catch uninitialized context */
376 Skein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES, SKEIN_FAIL);
378 /* process full blocks, if any */
379 if (msgByteCnt + ctx->h.bCnt > SKEIN_512_BLOCK_BYTES) {
380 /* finish up any buffered message data */
382 /* # bytes free in buffer b[] */
383 n = SKEIN_512_BLOCK_BYTES - ctx->h.bCnt;
385 /* check on our logic here */
386 Skein_assert(n < msgByteCnt);
387 memcpy(&ctx->b[ctx->h.bCnt], msg, n);
392 Skein_assert(ctx->h.bCnt == SKEIN_512_BLOCK_BYTES);
393 Skein_512_Process_Block(ctx, ctx->b, 1,
394 SKEIN_512_BLOCK_BYTES);
398 * now process any remaining full blocks, directly from input
401 if (msgByteCnt > SKEIN_512_BLOCK_BYTES) {
402 /* number of full blocks to process */
403 n = (msgByteCnt-1) / SKEIN_512_BLOCK_BYTES;
404 Skein_512_Process_Block(ctx, msg, n,
405 SKEIN_512_BLOCK_BYTES);
406 msgByteCnt -= n * SKEIN_512_BLOCK_BYTES;
407 msg += n * SKEIN_512_BLOCK_BYTES;
409 Skein_assert(ctx->h.bCnt == 0);
412 /* copy any remaining source message data bytes into b[] */
414 Skein_assert(msgByteCnt + ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES);
415 memcpy(&ctx->b[ctx->h.bCnt], msg, msgByteCnt);
416 ctx->h.bCnt += msgByteCnt;
419 return SKEIN_SUCCESS;
422 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
423 /* finalize the hash computation and output the result */
424 int Skein_512_Final(struct skein_512_ctx *ctx, u8 *hashVal)
426 size_t i, n, byteCnt;
427 u64 X[SKEIN_512_STATE_WORDS];
428 /* catch uninitialized context */
429 Skein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES, SKEIN_FAIL);
431 /* tag as the final block */
432 ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;
433 /* zero pad b[] if necessary */
434 if (ctx->h.bCnt < SKEIN_512_BLOCK_BYTES)
435 memset(&ctx->b[ctx->h.bCnt], 0,
436 SKEIN_512_BLOCK_BYTES - ctx->h.bCnt);
438 /* process the final block */
439 Skein_512_Process_Block(ctx, ctx->b, 1, ctx->h.bCnt);
441 /* now output the result */
442 /* total number of output bytes */
443 byteCnt = (ctx->h.hashBitLen + 7) >> 3;
445 /* run Threefish in "counter mode" to generate output */
446 /* zero out b[], so it can hold the counter */
447 memset(ctx->b, 0, sizeof(ctx->b));
448 /* keep a local copy of counter mode "key" */
449 memcpy(X, ctx->X, sizeof(X));
450 for (i = 0; i*SKEIN_512_BLOCK_BYTES < byteCnt; i++) {
451 /* build the counter block */
452 ((u64 *)ctx->b)[0] = Skein_Swap64((u64) i);
453 Skein_Start_New_Type(ctx, OUT_FINAL);
454 /* run "counter mode" */
455 Skein_512_Process_Block(ctx, ctx->b, 1, sizeof(u64));
456 /* number of output bytes left to go */
457 n = byteCnt - i*SKEIN_512_BLOCK_BYTES;
458 if (n >= SKEIN_512_BLOCK_BYTES)
459 n = SKEIN_512_BLOCK_BYTES;
460 /* "output" the ctr mode bytes */
461 Skein_Put64_LSB_First(hashVal+i*SKEIN_512_BLOCK_BYTES, ctx->X,
463 Skein_Show_Final(512, &ctx->h, n,
464 hashVal+i*SKEIN_512_BLOCK_BYTES);
465 /* restore the counter mode key for next time */
466 memcpy(ctx->X, X, sizeof(X));
468 return SKEIN_SUCCESS;
471 /*****************************************************************/
473 /*****************************************************************/
475 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
476 /* init the context for a straight hashing operation */
477 int Skein1024_Init(struct skein1024_ctx *ctx, size_t hashBitLen)
480 u8 b[SKEIN1024_STATE_BYTES];
481 u64 w[SKEIN1024_STATE_WORDS];
482 } cfg; /* config block */
484 Skein_Assert(hashBitLen > 0, SKEIN_BAD_HASHLEN);
485 ctx->h.hashBitLen = hashBitLen; /* output hash bit count */
487 switch (hashBitLen) { /* use pre-computed values, where available */
489 memcpy(ctx->X, SKEIN1024_IV_512, sizeof(ctx->X));
492 memcpy(ctx->X, SKEIN1024_IV_384, sizeof(ctx->X));
495 memcpy(ctx->X, SKEIN1024_IV_1024, sizeof(ctx->X));
498 /* here if there is no precomputed IV value available */
500 * build/process the config block, type == CONFIG
501 * (could be precomputed)
503 /* set tweaks: T0=0; T1=CFG | FINAL */
504 Skein_Start_New_Type(ctx, CFG_FINAL);
506 /* set the schema, version */
507 cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);
508 /* hash result length in bits */
509 cfg.w[1] = Skein_Swap64(hashBitLen);
510 cfg.w[2] = Skein_Swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);
511 /* zero pad config block */
512 memset(&cfg.w[3], 0, sizeof(cfg) - 3*sizeof(cfg.w[0]));
514 /* compute the initial chaining values from config block */
515 /* zero the chaining variables */
516 memset(ctx->X, 0, sizeof(ctx->X));
517 Skein1024_Process_Block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
521 /* The chaining vars ctx->X are now initialized for the hashBitLen. */
522 /* Set up to process the data message portion of the hash (default) */
523 Skein_Start_New_Type(ctx, MSG); /* T0=0, T1= MSG type */
525 return SKEIN_SUCCESS;
528 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
529 /* init the context for a MAC and/or tree hash operation */
530 /* [identical to Skein1024_Init() when keyBytes == 0 && \
531 * treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */
532 int Skein1024_InitExt(struct skein1024_ctx *ctx, size_t hashBitLen,
533 u64 treeInfo, const u8 *key, size_t keyBytes)
536 u8 b[SKEIN1024_STATE_BYTES];
537 u64 w[SKEIN1024_STATE_WORDS];
538 } cfg; /* config block */
540 Skein_Assert(hashBitLen > 0, SKEIN_BAD_HASHLEN);
541 Skein_Assert(keyBytes == 0 || key != NULL, SKEIN_FAIL);
543 /* compute the initial chaining values ctx->X[], based on key */
544 if (keyBytes == 0) { /* is there a key? */
545 /* no key: use all zeroes as key for config block */
546 memset(ctx->X, 0, sizeof(ctx->X));
547 } else { /* here to pre-process a key */
548 Skein_assert(sizeof(cfg.b) >= sizeof(ctx->X));
549 /* do a mini-Init right here */
550 /* set output hash bit count = state size */
551 ctx->h.hashBitLen = 8*sizeof(ctx->X);
552 /* set tweaks: T0 = 0; T1 = KEY type */
553 Skein_Start_New_Type(ctx, KEY);
554 /* zero the initial chaining variables */
555 memset(ctx->X, 0, sizeof(ctx->X));
557 Skein1024_Update(ctx, key, keyBytes);
558 /* put result into cfg.b[] */
559 Skein1024_Final_Pad(ctx, cfg.b);
560 /* copy over into ctx->X[] */
561 memcpy(ctx->X, cfg.b, sizeof(cfg.b));
564 * build/process the config block, type == CONFIG (could be
565 * precomputed for each key)
567 /* output hash bit count */
568 ctx->h.hashBitLen = hashBitLen;
569 Skein_Start_New_Type(ctx, CFG_FINAL);
571 /* pre-pad cfg.w[] with zeroes */
572 memset(&cfg.w, 0, sizeof(cfg.w));
573 cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);
574 /* hash result length in bits */
575 cfg.w[1] = Skein_Swap64(hashBitLen);
576 /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */
577 cfg.w[2] = Skein_Swap64(treeInfo);
579 Skein_Show_Key(1024, &ctx->h, key, keyBytes);
581 /* compute the initial chaining values from config block */
582 Skein1024_Process_Block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
584 /* The chaining vars ctx->X are now initialized */
585 /* Set up to process the data message portion of the hash (default) */
586 Skein_Start_New_Type(ctx, MSG);
588 return SKEIN_SUCCESS;
591 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
592 /* process the input bytes */
593 int Skein1024_Update(struct skein1024_ctx *ctx, const u8 *msg,
598 /* catch uninitialized context */
599 Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES, SKEIN_FAIL);
601 /* process full blocks, if any */
602 if (msgByteCnt + ctx->h.bCnt > SKEIN1024_BLOCK_BYTES) {
603 /* finish up any buffered message data */
605 /* # bytes free in buffer b[] */
606 n = SKEIN1024_BLOCK_BYTES - ctx->h.bCnt;
608 /* check on our logic here */
609 Skein_assert(n < msgByteCnt);
610 memcpy(&ctx->b[ctx->h.bCnt], msg, n);
615 Skein_assert(ctx->h.bCnt == SKEIN1024_BLOCK_BYTES);
616 Skein1024_Process_Block(ctx, ctx->b, 1,
617 SKEIN1024_BLOCK_BYTES);
621 * now process any remaining full blocks, directly from input
624 if (msgByteCnt > SKEIN1024_BLOCK_BYTES) {
625 /* number of full blocks to process */
626 n = (msgByteCnt-1) / SKEIN1024_BLOCK_BYTES;
627 Skein1024_Process_Block(ctx, msg, n,
628 SKEIN1024_BLOCK_BYTES);
629 msgByteCnt -= n * SKEIN1024_BLOCK_BYTES;
630 msg += n * SKEIN1024_BLOCK_BYTES;
632 Skein_assert(ctx->h.bCnt == 0);
635 /* copy any remaining source message data bytes into b[] */
637 Skein_assert(msgByteCnt + ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES);
638 memcpy(&ctx->b[ctx->h.bCnt], msg, msgByteCnt);
639 ctx->h.bCnt += msgByteCnt;
642 return SKEIN_SUCCESS;
645 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
646 /* finalize the hash computation and output the result */
647 int Skein1024_Final(struct skein1024_ctx *ctx, u8 *hashVal)
649 size_t i, n, byteCnt;
650 u64 X[SKEIN1024_STATE_WORDS];
651 /* catch uninitialized context */
652 Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES, SKEIN_FAIL);
654 /* tag as the final block */
655 ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;
656 /* zero pad b[] if necessary */
657 if (ctx->h.bCnt < SKEIN1024_BLOCK_BYTES)
658 memset(&ctx->b[ctx->h.bCnt], 0,
659 SKEIN1024_BLOCK_BYTES - ctx->h.bCnt);
661 /* process the final block */
662 Skein1024_Process_Block(ctx, ctx->b, 1, ctx->h.bCnt);
664 /* now output the result */
665 /* total number of output bytes */
666 byteCnt = (ctx->h.hashBitLen + 7) >> 3;
668 /* run Threefish in "counter mode" to generate output */
669 /* zero out b[], so it can hold the counter */
670 memset(ctx->b, 0, sizeof(ctx->b));
671 /* keep a local copy of counter mode "key" */
672 memcpy(X, ctx->X, sizeof(X));
673 for (i = 0; i*SKEIN1024_BLOCK_BYTES < byteCnt; i++) {
674 /* build the counter block */
675 ((u64 *)ctx->b)[0] = Skein_Swap64((u64) i);
676 Skein_Start_New_Type(ctx, OUT_FINAL);
677 /* run "counter mode" */
678 Skein1024_Process_Block(ctx, ctx->b, 1, sizeof(u64));
679 /* number of output bytes left to go */
680 n = byteCnt - i*SKEIN1024_BLOCK_BYTES;
681 if (n >= SKEIN1024_BLOCK_BYTES)
682 n = SKEIN1024_BLOCK_BYTES;
683 /* "output" the ctr mode bytes */
684 Skein_Put64_LSB_First(hashVal+i*SKEIN1024_BLOCK_BYTES, ctx->X,
686 Skein_Show_Final(1024, &ctx->h, n,
687 hashVal+i*SKEIN1024_BLOCK_BYTES);
688 /* restore the counter mode key for next time */
689 memcpy(ctx->X, X, sizeof(X));
691 return SKEIN_SUCCESS;
694 /**************** Functions to support MAC/tree hashing ***************/
695 /* (this code is identical for Optimized and Reference versions) */
697 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
698 /* finalize the hash computation and output the block, no OUTPUT stage */
699 int Skein_256_Final_Pad(struct skein_256_ctx *ctx, u8 *hashVal)
701 /* catch uninitialized context */
702 Skein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES, SKEIN_FAIL);
704 /* tag as the final block */
705 ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;
706 /* zero pad b[] if necessary */
707 if (ctx->h.bCnt < SKEIN_256_BLOCK_BYTES)
708 memset(&ctx->b[ctx->h.bCnt], 0,
709 SKEIN_256_BLOCK_BYTES - ctx->h.bCnt);
710 /* process the final block */
711 Skein_256_Process_Block(ctx, ctx->b, 1, ctx->h.bCnt);
713 /* "output" the state bytes */
714 Skein_Put64_LSB_First(hashVal, ctx->X, SKEIN_256_BLOCK_BYTES);
716 return SKEIN_SUCCESS;
719 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
720 /* finalize the hash computation and output the block, no OUTPUT stage */
721 int Skein_512_Final_Pad(struct skein_512_ctx *ctx, u8 *hashVal)
723 /* catch uninitialized context */
724 Skein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES, SKEIN_FAIL);
726 /* tag as the final block */
727 ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;
728 /* zero pad b[] if necessary */
729 if (ctx->h.bCnt < SKEIN_512_BLOCK_BYTES)
730 memset(&ctx->b[ctx->h.bCnt], 0,
731 SKEIN_512_BLOCK_BYTES - ctx->h.bCnt);
732 /* process the final block */
733 Skein_512_Process_Block(ctx, ctx->b, 1, ctx->h.bCnt);
735 /* "output" the state bytes */
736 Skein_Put64_LSB_First(hashVal, ctx->X, SKEIN_512_BLOCK_BYTES);
738 return SKEIN_SUCCESS;
741 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
742 /* finalize the hash computation and output the block, no OUTPUT stage */
743 int Skein1024_Final_Pad(struct skein1024_ctx *ctx, u8 *hashVal)
745 /* catch uninitialized context */
746 Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES, SKEIN_FAIL);
748 /* tag as the final block */
749 ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;
750 /* zero pad b[] if necessary */
751 if (ctx->h.bCnt < SKEIN1024_BLOCK_BYTES)
752 memset(&ctx->b[ctx->h.bCnt], 0,
753 SKEIN1024_BLOCK_BYTES - ctx->h.bCnt);
754 /* process the final block */
755 Skein1024_Process_Block(ctx, ctx->b, 1, ctx->h.bCnt);
757 /* "output" the state bytes */
758 Skein_Put64_LSB_First(hashVal, ctx->X, SKEIN1024_BLOCK_BYTES);
760 return SKEIN_SUCCESS;
764 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
765 /* just do the OUTPUT stage */
766 int Skein_256_Output(struct skein_256_ctx *ctx, u8 *hashVal)
768 size_t i, n, byteCnt;
769 u64 X[SKEIN_256_STATE_WORDS];
770 /* catch uninitialized context */
771 Skein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES, SKEIN_FAIL);
773 /* now output the result */
774 /* total number of output bytes */
775 byteCnt = (ctx->h.hashBitLen + 7) >> 3;
777 /* run Threefish in "counter mode" to generate output */
778 /* zero out b[], so it can hold the counter */
779 memset(ctx->b, 0, sizeof(ctx->b));
780 /* keep a local copy of counter mode "key" */
781 memcpy(X, ctx->X, sizeof(X));
782 for (i = 0; i*SKEIN_256_BLOCK_BYTES < byteCnt; i++) {
783 /* build the counter block */
784 ((u64 *)ctx->b)[0] = Skein_Swap64((u64) i);
785 Skein_Start_New_Type(ctx, OUT_FINAL);
786 /* run "counter mode" */
787 Skein_256_Process_Block(ctx, ctx->b, 1, sizeof(u64));
788 /* number of output bytes left to go */
789 n = byteCnt - i*SKEIN_256_BLOCK_BYTES;
790 if (n >= SKEIN_256_BLOCK_BYTES)
791 n = SKEIN_256_BLOCK_BYTES;
792 /* "output" the ctr mode bytes */
793 Skein_Put64_LSB_First(hashVal+i*SKEIN_256_BLOCK_BYTES, ctx->X,
795 Skein_Show_Final(256, &ctx->h, n,
796 hashVal+i*SKEIN_256_BLOCK_BYTES);
797 /* restore the counter mode key for next time */
798 memcpy(ctx->X, X, sizeof(X));
800 return SKEIN_SUCCESS;
803 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
804 /* just do the OUTPUT stage */
805 int Skein_512_Output(struct skein_512_ctx *ctx, u8 *hashVal)
807 size_t i, n, byteCnt;
808 u64 X[SKEIN_512_STATE_WORDS];
809 /* catch uninitialized context */
810 Skein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES, SKEIN_FAIL);
812 /* now output the result */
813 /* total number of output bytes */
814 byteCnt = (ctx->h.hashBitLen + 7) >> 3;
816 /* run Threefish in "counter mode" to generate output */
817 /* zero out b[], so it can hold the counter */
818 memset(ctx->b, 0, sizeof(ctx->b));
819 /* keep a local copy of counter mode "key" */
820 memcpy(X, ctx->X, sizeof(X));
821 for (i = 0; i*SKEIN_512_BLOCK_BYTES < byteCnt; i++) {
822 /* build the counter block */
823 ((u64 *)ctx->b)[0] = Skein_Swap64((u64) i);
824 Skein_Start_New_Type(ctx, OUT_FINAL);
825 /* run "counter mode" */
826 Skein_512_Process_Block(ctx, ctx->b, 1, sizeof(u64));
827 /* number of output bytes left to go */
828 n = byteCnt - i*SKEIN_512_BLOCK_BYTES;
829 if (n >= SKEIN_512_BLOCK_BYTES)
830 n = SKEIN_512_BLOCK_BYTES;
831 /* "output" the ctr mode bytes */
832 Skein_Put64_LSB_First(hashVal+i*SKEIN_512_BLOCK_BYTES, ctx->X,
834 Skein_Show_Final(256, &ctx->h, n,
835 hashVal+i*SKEIN_512_BLOCK_BYTES);
836 /* restore the counter mode key for next time */
837 memcpy(ctx->X, X, sizeof(X));
839 return SKEIN_SUCCESS;
842 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
843 /* just do the OUTPUT stage */
844 int Skein1024_Output(struct skein1024_ctx *ctx, u8 *hashVal)
846 size_t i, n, byteCnt;
847 u64 X[SKEIN1024_STATE_WORDS];
848 /* catch uninitialized context */
849 Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES, SKEIN_FAIL);
851 /* now output the result */
852 /* total number of output bytes */
853 byteCnt = (ctx->h.hashBitLen + 7) >> 3;
855 /* run Threefish in "counter mode" to generate output */
856 /* zero out b[], so it can hold the counter */
857 memset(ctx->b, 0, sizeof(ctx->b));
858 /* keep a local copy of counter mode "key" */
859 memcpy(X, ctx->X, sizeof(X));
860 for (i = 0; i*SKEIN1024_BLOCK_BYTES < byteCnt; i++) {
861 /* build the counter block */
862 ((u64 *)ctx->b)[0] = Skein_Swap64((u64) i);
863 Skein_Start_New_Type(ctx, OUT_FINAL);
864 /* run "counter mode" */
865 Skein1024_Process_Block(ctx, ctx->b, 1, sizeof(u64));
866 /* number of output bytes left to go */
867 n = byteCnt - i*SKEIN1024_BLOCK_BYTES;
868 if (n >= SKEIN1024_BLOCK_BYTES)
869 n = SKEIN1024_BLOCK_BYTES;
870 /* "output" the ctr mode bytes */
871 Skein_Put64_LSB_First(hashVal+i*SKEIN1024_BLOCK_BYTES, ctx->X,
873 Skein_Show_Final(256, &ctx->h, n,
874 hashVal+i*SKEIN1024_BLOCK_BYTES);
875 /* restore the counter mode key for next time */
876 memcpy(ctx->X, X, sizeof(X));
878 return SKEIN_SUCCESS;