1 /***********************************************************************
\r
3 ** Implementation of the AHS API using the Skein hash function.
\r
5 ** Source code author: Doug Whiting, 2008.
\r
7 ** This algorithm and source code is released to the public domain.
\r
9 ************************************************************************/
\r
11 #include <string.h> /* get the memcpy/memset functions */
\r
12 #include "skein.h" /* get the Skein API definitions */
\r
13 #include "skeinapi_ref.h"/* get the AHS API definitions */
\r
15 //#define SKEIN_DEBUG 1
23 /******************************************************************/
\r
25 /******************************************************************/
\r
27 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
\r
28 /* select the context size and init the context */
\r
29 HashReturn Init(hashState *state, int hashbitlen)
\r
31 #if SKEIN_256_NIST_MAX_HASH_BITS
\r
32 if (hashbitlen <= SKEIN_256_NIST_MAX_HASHBITS)
\r
34 Skein_Assert(hashbitlen > 0,BAD_HASHLEN);
\r
35 state->statebits = 64*SKEIN_256_STATE_WORDS;
\r
36 return Skein_256_Init(&state->u.ctx_256,(size_t) hashbitlen);
\r
39 if (hashbitlen <= SKEIN_512_NIST_MAX_HASHBITS)
\r
41 state->statebits = 64*SKEIN_512_STATE_WORDS;
\r
42 return Skein_512_Init(&state->u.ctx_512,(size_t) hashbitlen);
\r
46 state->statebits = 64*SKEIN1024_STATE_WORDS;
\r
47 return Skein1024_Init(&state->u.ctx1024,(size_t) hashbitlen);
\r
51 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
\r
52 /* process data to be hashed */
\r
53 HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen)
\r
55 /* only the final Update() call is allowed do partial bytes, else assert an error */
\r
56 Skein_Assert((state->u.h.T[1] & SKEIN_T1_FLAG_BIT_PAD) == 0 || databitlen == 0, FAIL);
\r
58 Skein_Assert(state->statebits % 256 == 0 && (state->statebits-256) < 1024,FAIL);
\r
59 if ((databitlen & 7) == 0) /* partial bytes? */
\r
61 switch ((state->statebits >> 8) & 3)
\r
63 case 2: return Skein_512_Update(&state->u.ctx_512,data,databitlen >> 3);
\r
64 case 1: return Skein_256_Update(&state->u.ctx_256,data,databitlen >> 3);
\r
65 case 0: return Skein1024_Update(&state->u.ctx1024,data,databitlen >> 3);
\r
66 default: return FAIL;
\r
70 { /* handle partial final byte */
\r
71 size_t bCnt = (databitlen >> 3) + 1; /* number of bytes to handle (nonzero here!) */
\r
74 mask = (u08b_t) (1u << (7 - (databitlen & 7))); /* partial byte bit mask */
\r
75 b = (u08b_t) ((data[bCnt-1] & (0-mask)) | mask); /* apply bit padding on final byte */
\r
77 switch ((state->statebits >> 8) & 3)
\r
79 case 2: Skein_512_Update(&state->u.ctx_512,data,bCnt-1); /* process all but the final byte */
\r
80 Skein_512_Update(&state->u.ctx_512,&b , 1 ); /* process the (masked) partial byte */
\r
82 case 1: Skein_256_Update(&state->u.ctx_256,data,bCnt-1); /* process all but the final byte */
\r
83 Skein_256_Update(&state->u.ctx_256,&b , 1 ); /* process the (masked) partial byte */
\r
85 case 0: Skein1024_Update(&state->u.ctx1024,data,bCnt-1); /* process all but the final byte */
\r
86 Skein1024_Update(&state->u.ctx1024,&b , 1 ); /* process the (masked) partial byte */
\r
88 default: return FAIL;
\r
90 Skein_Set_Bit_Pad_Flag(state->u.h); /* set tweak flag for the final call */
\r
96 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
\r
97 /* finalize hash computation and output the result (hashbitlen bits) */
\r
98 HashReturn Final(hashState *state, BitSequence *hashval)
\r
100 Skein_Assert(state->statebits % 256 == 0 && (state->statebits-256) < 1024,FAIL);
\r
101 switch ((state->statebits >> 8) & 3)
\r
103 case 2: return Skein_512_Final(&state->u.ctx_512,hashval);
\r
104 case 1: return Skein_256_Final(&state->u.ctx_256,hashval);
\r
105 case 0: return Skein1024_Final(&state->u.ctx1024,hashval);
\r
106 default: return FAIL;
\r
110 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
\r
111 /* all-in-one hash function */
\r
112 HashReturn Hash(int hashbitlen, const BitSequence *data, /* all-in-one call */
\r
113 DataLength databitlen,BitSequence *hashval)
\r
116 HashReturn r = Init(&state,hashbitlen);
\r
118 { /* these calls do not fail when called properly */
\r
119 r = Update(&state,data,databitlen);
\r
120 Final(&state,hashval);
\r
122 if (r == SUCCESS && getenv("SKEIN_DEEP_DUMP"))
125 printf("==== Hashbitlen = %d, DataBitLen = %llu, Data:\n%s\n==== Hash:\n",
126 hashbitlen, (long long unsigned)databitlen, (const char*)data);
127 for (i = 0; i < hashbitlen / 8; i++)
128 printf("%02X", hashval[i]);