1b468a9ffSAllan Jude /***********************************************************************
2b468a9ffSAllan Jude **
3b468a9ffSAllan Jude ** Implementation of the Skein hash function.
4b468a9ffSAllan Jude **
5b468a9ffSAllan Jude ** Source code author: Doug Whiting, 2008.
6b468a9ffSAllan Jude **
7b468a9ffSAllan Jude ** This algorithm and source code is released to the public domain.
8b468a9ffSAllan Jude **
9b468a9ffSAllan Jude ************************************************************************/
10b468a9ffSAllan Jude
11b468a9ffSAllan Jude #include <sys/cdefs.h>
12b468a9ffSAllan Jude #include <sys/endian.h>
13b468a9ffSAllan Jude #include <sys/types.h>
14b468a9ffSAllan Jude
15b468a9ffSAllan Jude /* get the memcpy/memset functions */
16b468a9ffSAllan Jude #ifdef _KERNEL
17b468a9ffSAllan Jude #include <sys/systm.h>
18b468a9ffSAllan Jude #else
19b468a9ffSAllan Jude #include <string.h>
20b468a9ffSAllan Jude #endif
21b468a9ffSAllan Jude
22b468a9ffSAllan Jude #define SKEIN_PORT_CODE /* instantiate any code in skein_port.h */
23b468a9ffSAllan Jude
24b468a9ffSAllan Jude #include "skein.h" /* get the Skein API definitions */
25b468a9ffSAllan Jude #include "skein_iv.h" /* get precomputed IVs */
26b468a9ffSAllan Jude
27b468a9ffSAllan Jude /*****************************************************************/
28b468a9ffSAllan Jude /* External function to process blkCnt (nonzero) full block(s) of data. */
29b468a9ffSAllan Jude void Skein_256_Process_Block(Skein_256_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd);
30b468a9ffSAllan Jude void Skein_512_Process_Block(Skein_512_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd);
31b468a9ffSAllan Jude void Skein1024_Process_Block(Skein1024_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd);
32b468a9ffSAllan Jude
33b468a9ffSAllan Jude /*****************************************************************/
34b468a9ffSAllan Jude /* 256-bit Skein */
35b468a9ffSAllan Jude /*****************************************************************/
36b468a9ffSAllan Jude
37b468a9ffSAllan Jude /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
38b468a9ffSAllan Jude /* init the context for a straight hashing operation */
Skein_256_Init(Skein_256_Ctxt_t * ctx,size_t hashBitLen)39b468a9ffSAllan Jude int Skein_256_Init(Skein_256_Ctxt_t *ctx, size_t hashBitLen)
40b468a9ffSAllan Jude {
41b468a9ffSAllan Jude union
42b468a9ffSAllan Jude {
43b468a9ffSAllan Jude u08b_t b[SKEIN_256_STATE_BYTES];
44b468a9ffSAllan Jude u64b_t w[SKEIN_256_STATE_WORDS];
45b468a9ffSAllan Jude } cfg; /* config block */
46b468a9ffSAllan Jude
47b468a9ffSAllan Jude Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);
48b468a9ffSAllan Jude ctx->h.hashBitLen = hashBitLen; /* output hash bit count */
49b468a9ffSAllan Jude
50b468a9ffSAllan Jude switch (hashBitLen)
51b468a9ffSAllan Jude { /* use pre-computed values, where available */
52b468a9ffSAllan Jude #ifndef SKEIN_NO_PRECOMP
53b468a9ffSAllan Jude case 256: memcpy(ctx->X,SKEIN_256_IV_256,sizeof(ctx->X)); break;
54b468a9ffSAllan Jude case 224: memcpy(ctx->X,SKEIN_256_IV_224,sizeof(ctx->X)); break;
55b468a9ffSAllan Jude case 160: memcpy(ctx->X,SKEIN_256_IV_160,sizeof(ctx->X)); break;
56b468a9ffSAllan Jude case 128: memcpy(ctx->X,SKEIN_256_IV_128,sizeof(ctx->X)); break;
57b468a9ffSAllan Jude #endif
58b468a9ffSAllan Jude default:
59b468a9ffSAllan Jude /* here if there is no precomputed IV value available */
60b468a9ffSAllan Jude /* build/process the config block, type == CONFIG (could be precomputed) */
61b468a9ffSAllan Jude Skein_Start_New_Type(ctx,CFG_FINAL); /* set tweaks: T0=0; T1=CFG | FINAL */
62b468a9ffSAllan Jude
63b468a9ffSAllan Jude cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER); /* set the schema, version */
64b468a9ffSAllan Jude cfg.w[1] = Skein_Swap64(hashBitLen); /* hash result length in bits */
65b468a9ffSAllan Jude cfg.w[2] = Skein_Swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);
66b468a9ffSAllan Jude memset(&cfg.w[3],0,sizeof(cfg) - 3*sizeof(cfg.w[0])); /* zero pad config block */
67b468a9ffSAllan Jude
68b468a9ffSAllan Jude /* compute the initial chaining values from config block */
69b468a9ffSAllan Jude memset(ctx->X,0,sizeof(ctx->X)); /* zero the chaining variables */
70b468a9ffSAllan Jude Skein_256_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);
71b468a9ffSAllan Jude break;
72b468a9ffSAllan Jude }
73b468a9ffSAllan Jude /* The chaining vars ctx->X are now initialized for the given hashBitLen. */
74b468a9ffSAllan Jude /* Set up to process the data message portion of the hash (default) */
75b468a9ffSAllan Jude Skein_Start_New_Type(ctx,MSG); /* T0=0, T1= MSG type */
76b468a9ffSAllan Jude
77b468a9ffSAllan Jude return SKEIN_SUCCESS;
78b468a9ffSAllan Jude }
79b468a9ffSAllan Jude
80b468a9ffSAllan Jude /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
81b468a9ffSAllan Jude /* init the context for a MAC and/or tree hash operation */
82b468a9ffSAllan Jude /* [identical to Skein_256_Init() when keyBytes == 0 && treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */
Skein_256_InitExt(Skein_256_Ctxt_t * ctx,size_t hashBitLen,u64b_t treeInfo,const u08b_t * key,size_t keyBytes)83b468a9ffSAllan Jude int Skein_256_InitExt(Skein_256_Ctxt_t *ctx,size_t hashBitLen,u64b_t treeInfo, const u08b_t *key, size_t keyBytes)
84b468a9ffSAllan Jude {
85b468a9ffSAllan Jude union
86b468a9ffSAllan Jude {
87b468a9ffSAllan Jude u08b_t b[SKEIN_256_STATE_BYTES];
88b468a9ffSAllan Jude u64b_t w[SKEIN_256_STATE_WORDS];
89b468a9ffSAllan Jude } cfg; /* config block */
90b468a9ffSAllan Jude
91b468a9ffSAllan Jude Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);
92b468a9ffSAllan Jude Skein_Assert(keyBytes == 0 || key != NULL,SKEIN_FAIL);
93b468a9ffSAllan Jude
94b468a9ffSAllan Jude /* compute the initial chaining values ctx->X[], based on key */
95b468a9ffSAllan Jude if (keyBytes == 0) /* is there a key? */
96b468a9ffSAllan Jude {
97b468a9ffSAllan Jude memset(ctx->X,0,sizeof(ctx->X)); /* no key: use all zeroes as key for config block */
98b468a9ffSAllan Jude }
99b468a9ffSAllan Jude else /* here to pre-process a key */
100b468a9ffSAllan Jude {
101b468a9ffSAllan Jude Skein_assert(sizeof(cfg.b) >= sizeof(ctx->X));
102b468a9ffSAllan Jude /* do a mini-Init right here */
103b468a9ffSAllan Jude ctx->h.hashBitLen=8*sizeof(ctx->X); /* set output hash bit count = state size */
104b468a9ffSAllan Jude Skein_Start_New_Type(ctx,KEY); /* set tweaks: T0 = 0; T1 = KEY type */
105b468a9ffSAllan Jude memset(ctx->X,0,sizeof(ctx->X)); /* zero the initial chaining variables */
106b468a9ffSAllan Jude Skein_256_Update(ctx,key,keyBytes); /* hash the key */
107b468a9ffSAllan Jude Skein_256_Final_Pad(ctx,cfg.b); /* put result into cfg.b[] */
108b468a9ffSAllan Jude memcpy(ctx->X,cfg.b,sizeof(cfg.b)); /* copy over into ctx->X[] */
109b468a9ffSAllan Jude #if SKEIN_NEED_SWAP
110b468a9ffSAllan Jude {
111b468a9ffSAllan Jude uint_t i;
112b468a9ffSAllan Jude for (i=0;i<SKEIN_256_STATE_WORDS;i++) /* convert key bytes to context words */
113b468a9ffSAllan Jude ctx->X[i] = Skein_Swap64(ctx->X[i]);
114b468a9ffSAllan Jude }
115b468a9ffSAllan Jude #endif
116b468a9ffSAllan Jude }
117b468a9ffSAllan Jude /* build/process the config block, type == CONFIG (could be precomputed for each key) */
118b468a9ffSAllan Jude ctx->h.hashBitLen = hashBitLen; /* output hash bit count */
119b468a9ffSAllan Jude Skein_Start_New_Type(ctx,CFG_FINAL);
120b468a9ffSAllan Jude
121b468a9ffSAllan Jude memset(&cfg.w,0,sizeof(cfg.w)); /* pre-pad cfg.w[] with zeroes */
122b468a9ffSAllan Jude cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);
123b468a9ffSAllan Jude cfg.w[1] = Skein_Swap64(hashBitLen); /* hash result length in bits */
124b468a9ffSAllan Jude cfg.w[2] = Skein_Swap64(treeInfo); /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */
125b468a9ffSAllan Jude
126b468a9ffSAllan Jude Skein_Show_Key(256,&ctx->h,key,keyBytes);
127b468a9ffSAllan Jude
128b468a9ffSAllan Jude /* compute the initial chaining values from config block */
129b468a9ffSAllan Jude Skein_256_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);
130b468a9ffSAllan Jude
131b468a9ffSAllan Jude /* The chaining vars ctx->X are now initialized */
132b468a9ffSAllan Jude /* Set up to process the data message portion of the hash (default) */
133b468a9ffSAllan Jude ctx->h.bCnt = 0; /* buffer b[] starts out empty */
134b468a9ffSAllan Jude Skein_Start_New_Type(ctx,MSG);
135b468a9ffSAllan Jude
136b468a9ffSAllan Jude return SKEIN_SUCCESS;
137b468a9ffSAllan Jude }
138b468a9ffSAllan Jude
139b468a9ffSAllan Jude /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
140b468a9ffSAllan Jude /* process the input bytes */
Skein_256_Update(Skein_256_Ctxt_t * ctx,const u08b_t * msg,size_t msgByteCnt)141b468a9ffSAllan Jude int Skein_256_Update(Skein_256_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt)
142b468a9ffSAllan Jude {
143b468a9ffSAllan Jude size_t n;
144b468a9ffSAllan Jude
145b468a9ffSAllan Jude Skein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES,SKEIN_FAIL); /* catch uninitialized context */
146b468a9ffSAllan Jude
147b468a9ffSAllan Jude /* process full blocks, if any */
148b468a9ffSAllan Jude if (msgByteCnt + ctx->h.bCnt > SKEIN_256_BLOCK_BYTES)
149b468a9ffSAllan Jude {
150b468a9ffSAllan Jude if (ctx->h.bCnt) /* finish up any buffered message data */
151b468a9ffSAllan Jude {
152b468a9ffSAllan Jude n = SKEIN_256_BLOCK_BYTES - ctx->h.bCnt; /* # bytes free in buffer b[] */
153b468a9ffSAllan Jude if (n)
154b468a9ffSAllan Jude {
155b468a9ffSAllan Jude Skein_assert(n < msgByteCnt); /* check on our logic here */
156b468a9ffSAllan Jude memcpy(&ctx->b[ctx->h.bCnt],msg,n);
157b468a9ffSAllan Jude msgByteCnt -= n;
158b468a9ffSAllan Jude msg += n;
159b468a9ffSAllan Jude ctx->h.bCnt += n;
160b468a9ffSAllan Jude }
161b468a9ffSAllan Jude Skein_assert(ctx->h.bCnt == SKEIN_256_BLOCK_BYTES);
162b468a9ffSAllan Jude Skein_256_Process_Block(ctx,ctx->b,1,SKEIN_256_BLOCK_BYTES);
163b468a9ffSAllan Jude ctx->h.bCnt = 0;
164b468a9ffSAllan Jude }
165b468a9ffSAllan Jude /* now process any remaining full blocks, directly from input message data */
166b468a9ffSAllan Jude if (msgByteCnt > SKEIN_256_BLOCK_BYTES)
167b468a9ffSAllan Jude {
168b468a9ffSAllan Jude n = (msgByteCnt-1) / SKEIN_256_BLOCK_BYTES; /* number of full blocks to process */
169b468a9ffSAllan Jude Skein_256_Process_Block(ctx,msg,n,SKEIN_256_BLOCK_BYTES);
170b468a9ffSAllan Jude msgByteCnt -= n * SKEIN_256_BLOCK_BYTES;
171b468a9ffSAllan Jude msg += n * SKEIN_256_BLOCK_BYTES;
172b468a9ffSAllan Jude }
173b468a9ffSAllan Jude Skein_assert(ctx->h.bCnt == 0);
174b468a9ffSAllan Jude }
175b468a9ffSAllan Jude
176b468a9ffSAllan Jude /* copy any remaining source message data bytes into b[] */
177b468a9ffSAllan Jude if (msgByteCnt)
178b468a9ffSAllan Jude {
179b468a9ffSAllan Jude Skein_assert(msgByteCnt + ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES);
180b468a9ffSAllan Jude memcpy(&ctx->b[ctx->h.bCnt],msg,msgByteCnt);
181b468a9ffSAllan Jude ctx->h.bCnt += msgByteCnt;
182b468a9ffSAllan Jude }
183b468a9ffSAllan Jude
184b468a9ffSAllan Jude return SKEIN_SUCCESS;
185b468a9ffSAllan Jude }
186b468a9ffSAllan Jude
187b468a9ffSAllan Jude /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
188b468a9ffSAllan Jude /* finalize the hash computation and output the result */
Skein_256_Final(Skein_256_Ctxt_t * ctx,u08b_t * hashVal)189b468a9ffSAllan Jude int Skein_256_Final(Skein_256_Ctxt_t *ctx, u08b_t *hashVal)
190b468a9ffSAllan Jude {
191b468a9ffSAllan Jude size_t i,n,byteCnt;
192b468a9ffSAllan Jude u64b_t X[SKEIN_256_STATE_WORDS];
193b468a9ffSAllan Jude Skein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES,SKEIN_FAIL); /* catch uninitialized context */
194b468a9ffSAllan Jude
195b468a9ffSAllan Jude ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL; /* tag as the final block */
196b468a9ffSAllan Jude if (ctx->h.bCnt < SKEIN_256_BLOCK_BYTES) /* zero pad b[] if necessary */
197b468a9ffSAllan Jude memset(&ctx->b[ctx->h.bCnt],0,SKEIN_256_BLOCK_BYTES - ctx->h.bCnt);
198b468a9ffSAllan Jude
199b468a9ffSAllan Jude Skein_256_Process_Block(ctx,ctx->b,1,ctx->h.bCnt); /* process the final block */
200b468a9ffSAllan Jude
201b468a9ffSAllan Jude /* now output the result */
202b468a9ffSAllan Jude byteCnt = (ctx->h.hashBitLen + 7) >> 3; /* total number of output bytes */
203b468a9ffSAllan Jude
204b468a9ffSAllan Jude /* run Threefish in "counter mode" to generate output */
205b468a9ffSAllan Jude memset(ctx->b,0,sizeof(ctx->b)); /* zero out b[], so it can hold the counter */
206b468a9ffSAllan Jude memcpy(X,ctx->X,sizeof(X)); /* keep a local copy of counter mode "key" */
207b468a9ffSAllan Jude for (i=0;i*SKEIN_256_BLOCK_BYTES < byteCnt;i++)
208b468a9ffSAllan Jude {
209b468a9ffSAllan Jude ((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */
210b468a9ffSAllan Jude Skein_Start_New_Type(ctx,OUT_FINAL);
211b468a9ffSAllan Jude Skein_256_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run "counter mode" */
212b468a9ffSAllan Jude n = byteCnt - i*SKEIN_256_BLOCK_BYTES; /* number of output bytes left to go */
213b468a9ffSAllan Jude if (n >= SKEIN_256_BLOCK_BYTES)
214b468a9ffSAllan Jude n = SKEIN_256_BLOCK_BYTES;
215b468a9ffSAllan Jude Skein_Put64_LSB_First(hashVal+i*SKEIN_256_BLOCK_BYTES,ctx->X,n); /* "output" the ctr mode bytes */
216b468a9ffSAllan Jude Skein_Show_Final(256,&ctx->h,n,hashVal+i*SKEIN_256_BLOCK_BYTES);
217b468a9ffSAllan Jude memcpy(ctx->X,X,sizeof(X)); /* restore the counter mode key for next time */
218b468a9ffSAllan Jude }
219b468a9ffSAllan Jude return SKEIN_SUCCESS;
220b468a9ffSAllan Jude }
221b468a9ffSAllan Jude
222b468a9ffSAllan Jude #if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)
Skein_256_API_CodeSize(void)223b468a9ffSAllan Jude size_t Skein_256_API_CodeSize(void)
224b468a9ffSAllan Jude {
225b468a9ffSAllan Jude return ((u08b_t *) Skein_256_API_CodeSize) -
226b468a9ffSAllan Jude ((u08b_t *) Skein_256_Init);
227b468a9ffSAllan Jude }
228b468a9ffSAllan Jude #endif
229b468a9ffSAllan Jude
230b468a9ffSAllan Jude /*****************************************************************/
231b468a9ffSAllan Jude /* 512-bit Skein */
232b468a9ffSAllan Jude /*****************************************************************/
233b468a9ffSAllan Jude
234b468a9ffSAllan Jude /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
235b468a9ffSAllan Jude /* init the context for a straight hashing operation */
Skein_512_Init(Skein_512_Ctxt_t * ctx,size_t hashBitLen)236b468a9ffSAllan Jude int Skein_512_Init(Skein_512_Ctxt_t *ctx, size_t hashBitLen)
237b468a9ffSAllan Jude {
238b468a9ffSAllan Jude union
239b468a9ffSAllan Jude {
240b468a9ffSAllan Jude u08b_t b[SKEIN_512_STATE_BYTES];
241b468a9ffSAllan Jude u64b_t w[SKEIN_512_STATE_WORDS];
242b468a9ffSAllan Jude } cfg; /* config block */
243b468a9ffSAllan Jude
244b468a9ffSAllan Jude Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);
245b468a9ffSAllan Jude ctx->h.hashBitLen = hashBitLen; /* output hash bit count */
246b468a9ffSAllan Jude
247b468a9ffSAllan Jude switch (hashBitLen)
248b468a9ffSAllan Jude { /* use pre-computed values, where available */
249b468a9ffSAllan Jude #ifndef SKEIN_NO_PRECOMP
250b468a9ffSAllan Jude case 512: memcpy(ctx->X,SKEIN_512_IV_512,sizeof(ctx->X)); break;
251b468a9ffSAllan Jude case 384: memcpy(ctx->X,SKEIN_512_IV_384,sizeof(ctx->X)); break;
252b468a9ffSAllan Jude case 256: memcpy(ctx->X,SKEIN_512_IV_256,sizeof(ctx->X)); break;
253b468a9ffSAllan Jude case 224: memcpy(ctx->X,SKEIN_512_IV_224,sizeof(ctx->X)); break;
254b468a9ffSAllan Jude #endif
255b468a9ffSAllan Jude default:
256b468a9ffSAllan Jude /* here if there is no precomputed IV value available */
257b468a9ffSAllan Jude /* build/process the config block, type == CONFIG (could be precomputed) */
258b468a9ffSAllan Jude Skein_Start_New_Type(ctx,CFG_FINAL); /* set tweaks: T0=0; T1=CFG | FINAL */
259b468a9ffSAllan Jude
260b468a9ffSAllan Jude cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER); /* set the schema, version */
261b468a9ffSAllan Jude cfg.w[1] = Skein_Swap64(hashBitLen); /* hash result length in bits */
262b468a9ffSAllan Jude cfg.w[2] = Skein_Swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);
263b468a9ffSAllan Jude memset(&cfg.w[3],0,sizeof(cfg) - 3*sizeof(cfg.w[0])); /* zero pad config block */
264b468a9ffSAllan Jude
265b468a9ffSAllan Jude /* compute the initial chaining values from config block */
266b468a9ffSAllan Jude memset(ctx->X,0,sizeof(ctx->X)); /* zero the chaining variables */
267b468a9ffSAllan Jude Skein_512_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);
268b468a9ffSAllan Jude break;
269b468a9ffSAllan Jude }
270b468a9ffSAllan Jude
271b468a9ffSAllan Jude /* The chaining vars ctx->X are now initialized for the given hashBitLen. */
272b468a9ffSAllan Jude /* Set up to process the data message portion of the hash (default) */
273b468a9ffSAllan Jude Skein_Start_New_Type(ctx,MSG); /* T0=0, T1= MSG type */
274b468a9ffSAllan Jude
275b468a9ffSAllan Jude return SKEIN_SUCCESS;
276b468a9ffSAllan Jude }
277b468a9ffSAllan Jude
278b468a9ffSAllan Jude /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
279b468a9ffSAllan Jude /* init the context for a MAC and/or tree hash operation */
280b468a9ffSAllan Jude /* [identical to Skein_512_Init() when keyBytes == 0 && treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */
Skein_512_InitExt(Skein_512_Ctxt_t * ctx,size_t hashBitLen,u64b_t treeInfo,const u08b_t * key,size_t keyBytes)281b468a9ffSAllan Jude int Skein_512_InitExt(Skein_512_Ctxt_t *ctx,size_t hashBitLen,u64b_t treeInfo, const u08b_t *key, size_t keyBytes)
282b468a9ffSAllan Jude {
283b468a9ffSAllan Jude union
284b468a9ffSAllan Jude {
285b468a9ffSAllan Jude u08b_t b[SKEIN_512_STATE_BYTES];
286b468a9ffSAllan Jude u64b_t w[SKEIN_512_STATE_WORDS];
287b468a9ffSAllan Jude } cfg; /* config block */
288b468a9ffSAllan Jude
289b468a9ffSAllan Jude Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);
290b468a9ffSAllan Jude Skein_Assert(keyBytes == 0 || key != NULL,SKEIN_FAIL);
291b468a9ffSAllan Jude
292b468a9ffSAllan Jude /* compute the initial chaining values ctx->X[], based on key */
293b468a9ffSAllan Jude if (keyBytes == 0) /* is there a key? */
294b468a9ffSAllan Jude {
295b468a9ffSAllan Jude memset(ctx->X,0,sizeof(ctx->X)); /* no key: use all zeroes as key for config block */
296b468a9ffSAllan Jude }
297b468a9ffSAllan Jude else /* here to pre-process a key */
298b468a9ffSAllan Jude {
299b468a9ffSAllan Jude Skein_assert(sizeof(cfg.b) >= sizeof(ctx->X));
300b468a9ffSAllan Jude /* do a mini-Init right here */
301b468a9ffSAllan Jude ctx->h.hashBitLen=8*sizeof(ctx->X); /* set output hash bit count = state size */
302b468a9ffSAllan Jude Skein_Start_New_Type(ctx,KEY); /* set tweaks: T0 = 0; T1 = KEY type */
303b468a9ffSAllan Jude memset(ctx->X,0,sizeof(ctx->X)); /* zero the initial chaining variables */
304b468a9ffSAllan Jude Skein_512_Update(ctx,key,keyBytes); /* hash the key */
305b468a9ffSAllan Jude Skein_512_Final_Pad(ctx,cfg.b); /* put result into cfg.b[] */
306b468a9ffSAllan Jude memcpy(ctx->X,cfg.b,sizeof(cfg.b)); /* copy over into ctx->X[] */
307b468a9ffSAllan Jude #if SKEIN_NEED_SWAP
308b468a9ffSAllan Jude {
309b468a9ffSAllan Jude uint_t i;
310b468a9ffSAllan Jude for (i=0;i<SKEIN_512_STATE_WORDS;i++) /* convert key bytes to context words */
311b468a9ffSAllan Jude ctx->X[i] = Skein_Swap64(ctx->X[i]);
312b468a9ffSAllan Jude }
313b468a9ffSAllan Jude #endif
314b468a9ffSAllan Jude }
315b468a9ffSAllan Jude /* build/process the config block, type == CONFIG (could be precomputed for each key) */
316b468a9ffSAllan Jude ctx->h.hashBitLen = hashBitLen; /* output hash bit count */
317b468a9ffSAllan Jude Skein_Start_New_Type(ctx,CFG_FINAL);
318b468a9ffSAllan Jude
319b468a9ffSAllan Jude memset(&cfg.w,0,sizeof(cfg.w)); /* pre-pad cfg.w[] with zeroes */
320b468a9ffSAllan Jude cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);
321b468a9ffSAllan Jude cfg.w[1] = Skein_Swap64(hashBitLen); /* hash result length in bits */
322b468a9ffSAllan Jude cfg.w[2] = Skein_Swap64(treeInfo); /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */
323b468a9ffSAllan Jude
324b468a9ffSAllan Jude Skein_Show_Key(512,&ctx->h,key,keyBytes);
325b468a9ffSAllan Jude
326b468a9ffSAllan Jude /* compute the initial chaining values from config block */
327b468a9ffSAllan Jude Skein_512_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);
328b468a9ffSAllan Jude
329b468a9ffSAllan Jude /* The chaining vars ctx->X are now initialized */
330b468a9ffSAllan Jude /* Set up to process the data message portion of the hash (default) */
331b468a9ffSAllan Jude ctx->h.bCnt = 0; /* buffer b[] starts out empty */
332b468a9ffSAllan Jude Skein_Start_New_Type(ctx,MSG);
333b468a9ffSAllan Jude
334b468a9ffSAllan Jude return SKEIN_SUCCESS;
335b468a9ffSAllan Jude }
336b468a9ffSAllan Jude
337b468a9ffSAllan Jude /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
338b468a9ffSAllan Jude /* process the input bytes */
Skein_512_Update(Skein_512_Ctxt_t * ctx,const u08b_t * msg,size_t msgByteCnt)339b468a9ffSAllan Jude int Skein_512_Update(Skein_512_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt)
340b468a9ffSAllan Jude {
341b468a9ffSAllan Jude size_t n;
342b468a9ffSAllan Jude
343b468a9ffSAllan Jude Skein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES,SKEIN_FAIL); /* catch uninitialized context */
344b468a9ffSAllan Jude
345b468a9ffSAllan Jude /* process full blocks, if any */
346b468a9ffSAllan Jude if (msgByteCnt + ctx->h.bCnt > SKEIN_512_BLOCK_BYTES)
347b468a9ffSAllan Jude {
348b468a9ffSAllan Jude if (ctx->h.bCnt) /* finish up any buffered message data */
349b468a9ffSAllan Jude {
350b468a9ffSAllan Jude n = SKEIN_512_BLOCK_BYTES - ctx->h.bCnt; /* # bytes free in buffer b[] */
351b468a9ffSAllan Jude if (n)
352b468a9ffSAllan Jude {
353b468a9ffSAllan Jude Skein_assert(n < msgByteCnt); /* check on our logic here */
354b468a9ffSAllan Jude memcpy(&ctx->b[ctx->h.bCnt],msg,n);
355b468a9ffSAllan Jude msgByteCnt -= n;
356b468a9ffSAllan Jude msg += n;
357b468a9ffSAllan Jude ctx->h.bCnt += n;
358b468a9ffSAllan Jude }
359b468a9ffSAllan Jude Skein_assert(ctx->h.bCnt == SKEIN_512_BLOCK_BYTES);
360b468a9ffSAllan Jude Skein_512_Process_Block(ctx,ctx->b,1,SKEIN_512_BLOCK_BYTES);
361b468a9ffSAllan Jude ctx->h.bCnt = 0;
362b468a9ffSAllan Jude }
363b468a9ffSAllan Jude /* now process any remaining full blocks, directly from input message data */
364b468a9ffSAllan Jude if (msgByteCnt > SKEIN_512_BLOCK_BYTES)
365b468a9ffSAllan Jude {
366b468a9ffSAllan Jude n = (msgByteCnt-1) / SKEIN_512_BLOCK_BYTES; /* number of full blocks to process */
367b468a9ffSAllan Jude Skein_512_Process_Block(ctx,msg,n,SKEIN_512_BLOCK_BYTES);
368b468a9ffSAllan Jude msgByteCnt -= n * SKEIN_512_BLOCK_BYTES;
369b468a9ffSAllan Jude msg += n * SKEIN_512_BLOCK_BYTES;
370b468a9ffSAllan Jude }
371b468a9ffSAllan Jude Skein_assert(ctx->h.bCnt == 0);
372b468a9ffSAllan Jude }
373b468a9ffSAllan Jude
374b468a9ffSAllan Jude /* copy any remaining source message data bytes into b[] */
375b468a9ffSAllan Jude if (msgByteCnt)
376b468a9ffSAllan Jude {
377b468a9ffSAllan Jude Skein_assert(msgByteCnt + ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES);
378b468a9ffSAllan Jude memcpy(&ctx->b[ctx->h.bCnt],msg,msgByteCnt);
379b468a9ffSAllan Jude ctx->h.bCnt += msgByteCnt;
380b468a9ffSAllan Jude }
381b468a9ffSAllan Jude
382b468a9ffSAllan Jude return SKEIN_SUCCESS;
383b468a9ffSAllan Jude }
384b468a9ffSAllan Jude
385b468a9ffSAllan Jude /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
386b468a9ffSAllan Jude /* finalize the hash computation and output the result */
Skein_512_Final(Skein_512_Ctxt_t * ctx,u08b_t * hashVal)387b468a9ffSAllan Jude int Skein_512_Final(Skein_512_Ctxt_t *ctx, u08b_t *hashVal)
388b468a9ffSAllan Jude {
389b468a9ffSAllan Jude size_t i,n,byteCnt;
390b468a9ffSAllan Jude u64b_t X[SKEIN_512_STATE_WORDS];
391b468a9ffSAllan Jude Skein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES,SKEIN_FAIL); /* catch uninitialized context */
392b468a9ffSAllan Jude
393b468a9ffSAllan Jude ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL; /* tag as the final block */
394b468a9ffSAllan Jude if (ctx->h.bCnt < SKEIN_512_BLOCK_BYTES) /* zero pad b[] if necessary */
395b468a9ffSAllan Jude memset(&ctx->b[ctx->h.bCnt],0,SKEIN_512_BLOCK_BYTES - ctx->h.bCnt);
396b468a9ffSAllan Jude
397b468a9ffSAllan Jude Skein_512_Process_Block(ctx,ctx->b,1,ctx->h.bCnt); /* process the final block */
398b468a9ffSAllan Jude
399b468a9ffSAllan Jude /* now output the result */
400b468a9ffSAllan Jude byteCnt = (ctx->h.hashBitLen + 7) >> 3; /* total number of output bytes */
401b468a9ffSAllan Jude
402b468a9ffSAllan Jude /* run Threefish in "counter mode" to generate output */
403b468a9ffSAllan Jude memset(ctx->b,0,sizeof(ctx->b)); /* zero out b[], so it can hold the counter */
404b468a9ffSAllan Jude memcpy(X,ctx->X,sizeof(X)); /* keep a local copy of counter mode "key" */
405b468a9ffSAllan Jude for (i=0;i*SKEIN_512_BLOCK_BYTES < byteCnt;i++)
406b468a9ffSAllan Jude {
407b468a9ffSAllan Jude ((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */
408b468a9ffSAllan Jude Skein_Start_New_Type(ctx,OUT_FINAL);
409b468a9ffSAllan Jude Skein_512_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run "counter mode" */
410b468a9ffSAllan Jude n = byteCnt - i*SKEIN_512_BLOCK_BYTES; /* number of output bytes left to go */
411b468a9ffSAllan Jude if (n >= SKEIN_512_BLOCK_BYTES)
412b468a9ffSAllan Jude n = SKEIN_512_BLOCK_BYTES;
413b468a9ffSAllan Jude Skein_Put64_LSB_First(hashVal+i*SKEIN_512_BLOCK_BYTES,ctx->X,n); /* "output" the ctr mode bytes */
414b468a9ffSAllan Jude Skein_Show_Final(512,&ctx->h,n,hashVal+i*SKEIN_512_BLOCK_BYTES);
415b468a9ffSAllan Jude memcpy(ctx->X,X,sizeof(X)); /* restore the counter mode key for next time */
416b468a9ffSAllan Jude }
417b468a9ffSAllan Jude return SKEIN_SUCCESS;
418b468a9ffSAllan Jude }
419b468a9ffSAllan Jude
420b468a9ffSAllan Jude #if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)
Skein_512_API_CodeSize(void)421b468a9ffSAllan Jude size_t Skein_512_API_CodeSize(void)
422b468a9ffSAllan Jude {
423b468a9ffSAllan Jude return ((u08b_t *) Skein_512_API_CodeSize) -
424b468a9ffSAllan Jude ((u08b_t *) Skein_512_Init);
425b468a9ffSAllan Jude }
426b468a9ffSAllan Jude #endif
427b468a9ffSAllan Jude
428b468a9ffSAllan Jude /*****************************************************************/
429b468a9ffSAllan Jude /* 1024-bit Skein */
430b468a9ffSAllan Jude /*****************************************************************/
431b468a9ffSAllan Jude
432b468a9ffSAllan Jude /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
433b468a9ffSAllan Jude /* init the context for a straight hashing operation */
Skein1024_Init(Skein1024_Ctxt_t * ctx,size_t hashBitLen)434b468a9ffSAllan Jude int Skein1024_Init(Skein1024_Ctxt_t *ctx, size_t hashBitLen)
435b468a9ffSAllan Jude {
436b468a9ffSAllan Jude union
437b468a9ffSAllan Jude {
438b468a9ffSAllan Jude u08b_t b[SKEIN1024_STATE_BYTES];
439b468a9ffSAllan Jude u64b_t w[SKEIN1024_STATE_WORDS];
440b468a9ffSAllan Jude } cfg; /* config block */
441b468a9ffSAllan Jude
442b468a9ffSAllan Jude Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);
443b468a9ffSAllan Jude ctx->h.hashBitLen = hashBitLen; /* output hash bit count */
444b468a9ffSAllan Jude
445b468a9ffSAllan Jude switch (hashBitLen)
446b468a9ffSAllan Jude { /* use pre-computed values, where available */
447b468a9ffSAllan Jude #ifndef SKEIN_NO_PRECOMP
448b468a9ffSAllan Jude case 512: memcpy(ctx->X,SKEIN1024_IV_512 ,sizeof(ctx->X)); break;
449b468a9ffSAllan Jude case 384: memcpy(ctx->X,SKEIN1024_IV_384 ,sizeof(ctx->X)); break;
450b468a9ffSAllan Jude case 1024: memcpy(ctx->X,SKEIN1024_IV_1024,sizeof(ctx->X)); break;
451b468a9ffSAllan Jude #endif
452b468a9ffSAllan Jude default:
453b468a9ffSAllan Jude /* here if there is no precomputed IV value available */
454b468a9ffSAllan Jude /* build/process the config block, type == CONFIG (could be precomputed) */
455b468a9ffSAllan Jude Skein_Start_New_Type(ctx,CFG_FINAL); /* set tweaks: T0=0; T1=CFG | FINAL */
456b468a9ffSAllan Jude
457b468a9ffSAllan Jude cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER); /* set the schema, version */
458b468a9ffSAllan Jude cfg.w[1] = Skein_Swap64(hashBitLen); /* hash result length in bits */
459b468a9ffSAllan Jude cfg.w[2] = Skein_Swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);
460b468a9ffSAllan Jude memset(&cfg.w[3],0,sizeof(cfg) - 3*sizeof(cfg.w[0])); /* zero pad config block */
461b468a9ffSAllan Jude
462b468a9ffSAllan Jude /* compute the initial chaining values from config block */
463b468a9ffSAllan Jude memset(ctx->X,0,sizeof(ctx->X)); /* zero the chaining variables */
464b468a9ffSAllan Jude Skein1024_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);
465b468a9ffSAllan Jude break;
466b468a9ffSAllan Jude }
467b468a9ffSAllan Jude
468b468a9ffSAllan Jude /* The chaining vars ctx->X are now initialized for the given hashBitLen. */
469b468a9ffSAllan Jude /* Set up to process the data message portion of the hash (default) */
470b468a9ffSAllan Jude Skein_Start_New_Type(ctx,MSG); /* T0=0, T1= MSG type */
471b468a9ffSAllan Jude
472b468a9ffSAllan Jude return SKEIN_SUCCESS;
473b468a9ffSAllan Jude }
474b468a9ffSAllan Jude
475b468a9ffSAllan Jude /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
476b468a9ffSAllan Jude /* init the context for a MAC and/or tree hash operation */
477b468a9ffSAllan Jude /* [identical to Skein1024_Init() when keyBytes == 0 && treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */
Skein1024_InitExt(Skein1024_Ctxt_t * ctx,size_t hashBitLen,u64b_t treeInfo,const u08b_t * key,size_t keyBytes)478b468a9ffSAllan Jude int Skein1024_InitExt(Skein1024_Ctxt_t *ctx,size_t hashBitLen,u64b_t treeInfo, const u08b_t *key, size_t keyBytes)
479b468a9ffSAllan Jude {
480b468a9ffSAllan Jude union
481b468a9ffSAllan Jude {
482b468a9ffSAllan Jude u08b_t b[SKEIN1024_STATE_BYTES];
483b468a9ffSAllan Jude u64b_t w[SKEIN1024_STATE_WORDS];
484b468a9ffSAllan Jude } cfg; /* config block */
485b468a9ffSAllan Jude
486b468a9ffSAllan Jude Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);
487b468a9ffSAllan Jude Skein_Assert(keyBytes == 0 || key != NULL,SKEIN_FAIL);
488b468a9ffSAllan Jude
489b468a9ffSAllan Jude /* compute the initial chaining values ctx->X[], based on key */
490b468a9ffSAllan Jude if (keyBytes == 0) /* is there a key? */
491b468a9ffSAllan Jude {
492b468a9ffSAllan Jude memset(ctx->X,0,sizeof(ctx->X)); /* no key: use all zeroes as key for config block */
493b468a9ffSAllan Jude }
494b468a9ffSAllan Jude else /* here to pre-process a key */
495b468a9ffSAllan Jude {
496b468a9ffSAllan Jude Skein_assert(sizeof(cfg.b) >= sizeof(ctx->X));
497b468a9ffSAllan Jude /* do a mini-Init right here */
498b468a9ffSAllan Jude ctx->h.hashBitLen=8*sizeof(ctx->X); /* set output hash bit count = state size */
499b468a9ffSAllan Jude Skein_Start_New_Type(ctx,KEY); /* set tweaks: T0 = 0; T1 = KEY type */
500b468a9ffSAllan Jude memset(ctx->X,0,sizeof(ctx->X)); /* zero the initial chaining variables */
501b468a9ffSAllan Jude Skein1024_Update(ctx,key,keyBytes); /* hash the key */
502b468a9ffSAllan Jude Skein1024_Final_Pad(ctx,cfg.b); /* put result into cfg.b[] */
503b468a9ffSAllan Jude memcpy(ctx->X,cfg.b,sizeof(cfg.b)); /* copy over into ctx->X[] */
504b468a9ffSAllan Jude #if SKEIN_NEED_SWAP
505b468a9ffSAllan Jude {
506b468a9ffSAllan Jude uint_t i;
507b468a9ffSAllan Jude for (i=0;i<SKEIN1024_STATE_WORDS;i++) /* convert key bytes to context words */
508b468a9ffSAllan Jude ctx->X[i] = Skein_Swap64(ctx->X[i]);
509b468a9ffSAllan Jude }
510b468a9ffSAllan Jude #endif
511b468a9ffSAllan Jude }
512b468a9ffSAllan Jude /* build/process the config block, type == CONFIG (could be precomputed for each key) */
513b468a9ffSAllan Jude ctx->h.hashBitLen = hashBitLen; /* output hash bit count */
514b468a9ffSAllan Jude Skein_Start_New_Type(ctx,CFG_FINAL);
515b468a9ffSAllan Jude
516b468a9ffSAllan Jude memset(&cfg.w,0,sizeof(cfg.w)); /* pre-pad cfg.w[] with zeroes */
517b468a9ffSAllan Jude cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);
518b468a9ffSAllan Jude cfg.w[1] = Skein_Swap64(hashBitLen); /* hash result length in bits */
519b468a9ffSAllan Jude cfg.w[2] = Skein_Swap64(treeInfo); /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */
520b468a9ffSAllan Jude
521b468a9ffSAllan Jude Skein_Show_Key(1024,&ctx->h,key,keyBytes);
522b468a9ffSAllan Jude
523b468a9ffSAllan Jude /* compute the initial chaining values from config block */
524b468a9ffSAllan Jude Skein1024_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);
525b468a9ffSAllan Jude
526b468a9ffSAllan Jude /* The chaining vars ctx->X are now initialized */
527b468a9ffSAllan Jude /* Set up to process the data message portion of the hash (default) */
528b468a9ffSAllan Jude ctx->h.bCnt = 0; /* buffer b[] starts out empty */
529b468a9ffSAllan Jude Skein_Start_New_Type(ctx,MSG);
530b468a9ffSAllan Jude
531b468a9ffSAllan Jude return SKEIN_SUCCESS;
532b468a9ffSAllan Jude }
533b468a9ffSAllan Jude
534b468a9ffSAllan Jude /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
535b468a9ffSAllan Jude /* process the input bytes */
Skein1024_Update(Skein1024_Ctxt_t * ctx,const u08b_t * msg,size_t msgByteCnt)536b468a9ffSAllan Jude int Skein1024_Update(Skein1024_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt)
537b468a9ffSAllan Jude {
538b468a9ffSAllan Jude size_t n;
539b468a9ffSAllan Jude
540b468a9ffSAllan Jude Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES,SKEIN_FAIL); /* catch uninitialized context */
541b468a9ffSAllan Jude
542b468a9ffSAllan Jude /* process full blocks, if any */
543b468a9ffSAllan Jude if (msgByteCnt + ctx->h.bCnt > SKEIN1024_BLOCK_BYTES)
544b468a9ffSAllan Jude {
545b468a9ffSAllan Jude if (ctx->h.bCnt) /* finish up any buffered message data */
546b468a9ffSAllan Jude {
547b468a9ffSAllan Jude n = SKEIN1024_BLOCK_BYTES - ctx->h.bCnt; /* # bytes free in buffer b[] */
548b468a9ffSAllan Jude if (n)
549b468a9ffSAllan Jude {
550b468a9ffSAllan Jude Skein_assert(n < msgByteCnt); /* check on our logic here */
551b468a9ffSAllan Jude memcpy(&ctx->b[ctx->h.bCnt],msg,n);
552b468a9ffSAllan Jude msgByteCnt -= n;
553b468a9ffSAllan Jude msg += n;
554b468a9ffSAllan Jude ctx->h.bCnt += n;
555b468a9ffSAllan Jude }
556b468a9ffSAllan Jude Skein_assert(ctx->h.bCnt == SKEIN1024_BLOCK_BYTES);
557b468a9ffSAllan Jude Skein1024_Process_Block(ctx,ctx->b,1,SKEIN1024_BLOCK_BYTES);
558b468a9ffSAllan Jude ctx->h.bCnt = 0;
559b468a9ffSAllan Jude }
560b468a9ffSAllan Jude /* now process any remaining full blocks, directly from input message data */
561b468a9ffSAllan Jude if (msgByteCnt > SKEIN1024_BLOCK_BYTES)
562b468a9ffSAllan Jude {
563b468a9ffSAllan Jude n = (msgByteCnt-1) / SKEIN1024_BLOCK_BYTES; /* number of full blocks to process */
564b468a9ffSAllan Jude Skein1024_Process_Block(ctx,msg,n,SKEIN1024_BLOCK_BYTES);
565b468a9ffSAllan Jude msgByteCnt -= n * SKEIN1024_BLOCK_BYTES;
566b468a9ffSAllan Jude msg += n * SKEIN1024_BLOCK_BYTES;
567b468a9ffSAllan Jude }
568b468a9ffSAllan Jude Skein_assert(ctx->h.bCnt == 0);
569b468a9ffSAllan Jude }
570b468a9ffSAllan Jude
571b468a9ffSAllan Jude /* copy any remaining source message data bytes into b[] */
572b468a9ffSAllan Jude if (msgByteCnt)
573b468a9ffSAllan Jude {
574b468a9ffSAllan Jude Skein_assert(msgByteCnt + ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES);
575b468a9ffSAllan Jude memcpy(&ctx->b[ctx->h.bCnt],msg,msgByteCnt);
576b468a9ffSAllan Jude ctx->h.bCnt += msgByteCnt;
577b468a9ffSAllan Jude }
578b468a9ffSAllan Jude
579b468a9ffSAllan Jude return SKEIN_SUCCESS;
580b468a9ffSAllan Jude }
581b468a9ffSAllan Jude
582b468a9ffSAllan Jude /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
583b468a9ffSAllan Jude /* finalize the hash computation and output the result */
Skein1024_Final(Skein1024_Ctxt_t * ctx,u08b_t * hashVal)584b468a9ffSAllan Jude int Skein1024_Final(Skein1024_Ctxt_t *ctx, u08b_t *hashVal)
585b468a9ffSAllan Jude {
586b468a9ffSAllan Jude size_t i,n,byteCnt;
587b468a9ffSAllan Jude u64b_t X[SKEIN1024_STATE_WORDS];
588b468a9ffSAllan Jude Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES,SKEIN_FAIL); /* catch uninitialized context */
589b468a9ffSAllan Jude
590b468a9ffSAllan Jude ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL; /* tag as the final block */
591b468a9ffSAllan Jude if (ctx->h.bCnt < SKEIN1024_BLOCK_BYTES) /* zero pad b[] if necessary */
592b468a9ffSAllan Jude memset(&ctx->b[ctx->h.bCnt],0,SKEIN1024_BLOCK_BYTES - ctx->h.bCnt);
593b468a9ffSAllan Jude
594b468a9ffSAllan Jude Skein1024_Process_Block(ctx,ctx->b,1,ctx->h.bCnt); /* process the final block */
595b468a9ffSAllan Jude
596b468a9ffSAllan Jude /* now output the result */
597b468a9ffSAllan Jude byteCnt = (ctx->h.hashBitLen + 7) >> 3; /* total number of output bytes */
598b468a9ffSAllan Jude
599b468a9ffSAllan Jude /* run Threefish in "counter mode" to generate output */
600b468a9ffSAllan Jude memset(ctx->b,0,sizeof(ctx->b)); /* zero out b[], so it can hold the counter */
601b468a9ffSAllan Jude memcpy(X,ctx->X,sizeof(X)); /* keep a local copy of counter mode "key" */
602b468a9ffSAllan Jude for (i=0;i*SKEIN1024_BLOCK_BYTES < byteCnt;i++)
603b468a9ffSAllan Jude {
604b468a9ffSAllan Jude ((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */
605b468a9ffSAllan Jude Skein_Start_New_Type(ctx,OUT_FINAL);
606b468a9ffSAllan Jude Skein1024_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run "counter mode" */
607b468a9ffSAllan Jude n = byteCnt - i*SKEIN1024_BLOCK_BYTES; /* number of output bytes left to go */
608b468a9ffSAllan Jude if (n >= SKEIN1024_BLOCK_BYTES)
609b468a9ffSAllan Jude n = SKEIN1024_BLOCK_BYTES;
610b468a9ffSAllan Jude Skein_Put64_LSB_First(hashVal+i*SKEIN1024_BLOCK_BYTES,ctx->X,n); /* "output" the ctr mode bytes */
611b468a9ffSAllan Jude Skein_Show_Final(1024,&ctx->h,n,hashVal+i*SKEIN1024_BLOCK_BYTES);
612b468a9ffSAllan Jude memcpy(ctx->X,X,sizeof(X)); /* restore the counter mode key for next time */
613b468a9ffSAllan Jude }
614b468a9ffSAllan Jude return SKEIN_SUCCESS;
615b468a9ffSAllan Jude }
616b468a9ffSAllan Jude
617b468a9ffSAllan Jude #if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)
Skein1024_API_CodeSize(void)618b468a9ffSAllan Jude size_t Skein1024_API_CodeSize(void)
619b468a9ffSAllan Jude {
620b468a9ffSAllan Jude return ((u08b_t *) Skein1024_API_CodeSize) -
621b468a9ffSAllan Jude ((u08b_t *) Skein1024_Init);
622b468a9ffSAllan Jude }
623b468a9ffSAllan Jude #endif
624b468a9ffSAllan Jude
625b468a9ffSAllan Jude /**************** Functions to support MAC/tree hashing ***************/
626b468a9ffSAllan Jude /* (this code is identical for Optimized and Reference versions) */
627b468a9ffSAllan Jude
628b468a9ffSAllan Jude /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
629b468a9ffSAllan Jude /* finalize the hash computation and output the block, no OUTPUT stage */
Skein_256_Final_Pad(Skein_256_Ctxt_t * ctx,u08b_t * hashVal)630b468a9ffSAllan Jude int Skein_256_Final_Pad(Skein_256_Ctxt_t *ctx, u08b_t *hashVal)
631b468a9ffSAllan Jude {
632b468a9ffSAllan Jude Skein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES,SKEIN_FAIL); /* catch uninitialized context */
633b468a9ffSAllan Jude
634b468a9ffSAllan Jude ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL; /* tag as the final block */
635b468a9ffSAllan Jude if (ctx->h.bCnt < SKEIN_256_BLOCK_BYTES) /* zero pad b[] if necessary */
636b468a9ffSAllan Jude memset(&ctx->b[ctx->h.bCnt],0,SKEIN_256_BLOCK_BYTES - ctx->h.bCnt);
637b468a9ffSAllan Jude Skein_256_Process_Block(ctx,ctx->b,1,ctx->h.bCnt); /* process the final block */
638b468a9ffSAllan Jude
639b468a9ffSAllan Jude Skein_Put64_LSB_First(hashVal,ctx->X,SKEIN_256_BLOCK_BYTES); /* "output" the state bytes */
640b468a9ffSAllan Jude
641b468a9ffSAllan Jude return SKEIN_SUCCESS;
642b468a9ffSAllan Jude }
643b468a9ffSAllan Jude
644b468a9ffSAllan Jude /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
645b468a9ffSAllan Jude /* finalize the hash computation and output the block, no OUTPUT stage */
Skein_512_Final_Pad(Skein_512_Ctxt_t * ctx,u08b_t * hashVal)646b468a9ffSAllan Jude int Skein_512_Final_Pad(Skein_512_Ctxt_t *ctx, u08b_t *hashVal)
647b468a9ffSAllan Jude {
648b468a9ffSAllan Jude Skein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES,SKEIN_FAIL); /* catch uninitialized context */
649b468a9ffSAllan Jude
650b468a9ffSAllan Jude ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL; /* tag as the final block */
651b468a9ffSAllan Jude if (ctx->h.bCnt < SKEIN_512_BLOCK_BYTES) /* zero pad b[] if necessary */
652b468a9ffSAllan Jude memset(&ctx->b[ctx->h.bCnt],0,SKEIN_512_BLOCK_BYTES - ctx->h.bCnt);
653b468a9ffSAllan Jude Skein_512_Process_Block(ctx,ctx->b,1,ctx->h.bCnt); /* process the final block */
654b468a9ffSAllan Jude
655b468a9ffSAllan Jude Skein_Put64_LSB_First(hashVal,ctx->X,SKEIN_512_BLOCK_BYTES); /* "output" the state bytes */
656b468a9ffSAllan Jude
657b468a9ffSAllan Jude return SKEIN_SUCCESS;
658b468a9ffSAllan Jude }
659b468a9ffSAllan Jude
660b468a9ffSAllan Jude /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
661b468a9ffSAllan Jude /* finalize the hash computation and output the block, no OUTPUT stage */
Skein1024_Final_Pad(Skein1024_Ctxt_t * ctx,u08b_t * hashVal)662b468a9ffSAllan Jude int Skein1024_Final_Pad(Skein1024_Ctxt_t *ctx, u08b_t *hashVal)
663b468a9ffSAllan Jude {
664b468a9ffSAllan Jude Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES,SKEIN_FAIL); /* catch uninitialized context */
665b468a9ffSAllan Jude
666b468a9ffSAllan Jude ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL; /* tag as the final block */
667b468a9ffSAllan Jude if (ctx->h.bCnt < SKEIN1024_BLOCK_BYTES) /* zero pad b[] if necessary */
668b468a9ffSAllan Jude memset(&ctx->b[ctx->h.bCnt],0,SKEIN1024_BLOCK_BYTES - ctx->h.bCnt);
669b468a9ffSAllan Jude Skein1024_Process_Block(ctx,ctx->b,1,ctx->h.bCnt); /* process the final block */
670b468a9ffSAllan Jude
671b468a9ffSAllan Jude Skein_Put64_LSB_First(hashVal,ctx->X,SKEIN1024_BLOCK_BYTES); /* "output" the state bytes */
672b468a9ffSAllan Jude
673b468a9ffSAllan Jude return SKEIN_SUCCESS;
674b468a9ffSAllan Jude }
675b468a9ffSAllan Jude
676b468a9ffSAllan Jude #if SKEIN_TREE_HASH
677b468a9ffSAllan Jude /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
678b468a9ffSAllan Jude /* just do the OUTPUT stage */
Skein_256_Output(Skein_256_Ctxt_t * ctx,u08b_t * hashVal)679b468a9ffSAllan Jude int Skein_256_Output(Skein_256_Ctxt_t *ctx, u08b_t *hashVal)
680b468a9ffSAllan Jude {
681b468a9ffSAllan Jude size_t i,n,byteCnt;
682b468a9ffSAllan Jude u64b_t X[SKEIN_256_STATE_WORDS];
683b468a9ffSAllan Jude Skein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES,SKEIN_FAIL); /* catch uninitialized context */
684b468a9ffSAllan Jude
685b468a9ffSAllan Jude /* now output the result */
686b468a9ffSAllan Jude byteCnt = (ctx->h.hashBitLen + 7) >> 3; /* total number of output bytes */
687b468a9ffSAllan Jude
688b468a9ffSAllan Jude /* run Threefish in "counter mode" to generate output */
689b468a9ffSAllan Jude memset(ctx->b,0,sizeof(ctx->b)); /* zero out b[], so it can hold the counter */
690b468a9ffSAllan Jude memcpy(X,ctx->X,sizeof(X)); /* keep a local copy of counter mode "key" */
691b468a9ffSAllan Jude for (i=0;i*SKEIN_256_BLOCK_BYTES < byteCnt;i++)
692b468a9ffSAllan Jude {
693b468a9ffSAllan Jude ((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */
694b468a9ffSAllan Jude Skein_Start_New_Type(ctx,OUT_FINAL);
695b468a9ffSAllan Jude Skein_256_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run "counter mode" */
696b468a9ffSAllan Jude n = byteCnt - i*SKEIN_256_BLOCK_BYTES; /* number of output bytes left to go */
697b468a9ffSAllan Jude if (n >= SKEIN_256_BLOCK_BYTES)
698b468a9ffSAllan Jude n = SKEIN_256_BLOCK_BYTES;
699b468a9ffSAllan Jude Skein_Put64_LSB_First(hashVal+i*SKEIN_256_BLOCK_BYTES,ctx->X,n); /* "output" the ctr mode bytes */
700b468a9ffSAllan Jude Skein_Show_Final(256,&ctx->h,n,hashVal+i*SKEIN_256_BLOCK_BYTES);
701b468a9ffSAllan Jude memcpy(ctx->X,X,sizeof(X)); /* restore the counter mode key for next time */
702b468a9ffSAllan Jude }
703b468a9ffSAllan Jude return SKEIN_SUCCESS;
704b468a9ffSAllan Jude }
705b468a9ffSAllan Jude
706b468a9ffSAllan Jude /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
707b468a9ffSAllan Jude /* just do the OUTPUT stage */
Skein_512_Output(Skein_512_Ctxt_t * ctx,u08b_t * hashVal)708b468a9ffSAllan Jude int Skein_512_Output(Skein_512_Ctxt_t *ctx, u08b_t *hashVal)
709b468a9ffSAllan Jude {
710b468a9ffSAllan Jude size_t i,n,byteCnt;
711b468a9ffSAllan Jude u64b_t X[SKEIN_512_STATE_WORDS];
712b468a9ffSAllan Jude Skein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES,SKEIN_FAIL); /* catch uninitialized context */
713b468a9ffSAllan Jude
714b468a9ffSAllan Jude /* now output the result */
715b468a9ffSAllan Jude byteCnt = (ctx->h.hashBitLen + 7) >> 3; /* total number of output bytes */
716b468a9ffSAllan Jude
717b468a9ffSAllan Jude /* run Threefish in "counter mode" to generate output */
718b468a9ffSAllan Jude memset(ctx->b,0,sizeof(ctx->b)); /* zero out b[], so it can hold the counter */
719b468a9ffSAllan Jude memcpy(X,ctx->X,sizeof(X)); /* keep a local copy of counter mode "key" */
720b468a9ffSAllan Jude for (i=0;i*SKEIN_512_BLOCK_BYTES < byteCnt;i++)
721b468a9ffSAllan Jude {
722b468a9ffSAllan Jude ((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */
723b468a9ffSAllan Jude Skein_Start_New_Type(ctx,OUT_FINAL);
724b468a9ffSAllan Jude Skein_512_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run "counter mode" */
725b468a9ffSAllan Jude n = byteCnt - i*SKEIN_512_BLOCK_BYTES; /* number of output bytes left to go */
726b468a9ffSAllan Jude if (n >= SKEIN_512_BLOCK_BYTES)
727b468a9ffSAllan Jude n = SKEIN_512_BLOCK_BYTES;
728b468a9ffSAllan Jude Skein_Put64_LSB_First(hashVal+i*SKEIN_512_BLOCK_BYTES,ctx->X,n); /* "output" the ctr mode bytes */
729b468a9ffSAllan Jude Skein_Show_Final(256,&ctx->h,n,hashVal+i*SKEIN_512_BLOCK_BYTES);
730b468a9ffSAllan Jude memcpy(ctx->X,X,sizeof(X)); /* restore the counter mode key for next time */
731b468a9ffSAllan Jude }
732b468a9ffSAllan Jude return SKEIN_SUCCESS;
733b468a9ffSAllan Jude }
734b468a9ffSAllan Jude
735b468a9ffSAllan Jude /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
736b468a9ffSAllan Jude /* just do the OUTPUT stage */
Skein1024_Output(Skein1024_Ctxt_t * ctx,u08b_t * hashVal)737b468a9ffSAllan Jude int Skein1024_Output(Skein1024_Ctxt_t *ctx, u08b_t *hashVal)
738b468a9ffSAllan Jude {
739b468a9ffSAllan Jude size_t i,n,byteCnt;
740b468a9ffSAllan Jude u64b_t X[SKEIN1024_STATE_WORDS];
741b468a9ffSAllan Jude Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES,SKEIN_FAIL); /* catch uninitialized context */
742b468a9ffSAllan Jude
743b468a9ffSAllan Jude /* now output the result */
744b468a9ffSAllan Jude byteCnt = (ctx->h.hashBitLen + 7) >> 3; /* total number of output bytes */
745b468a9ffSAllan Jude
746b468a9ffSAllan Jude /* run Threefish in "counter mode" to generate output */
747b468a9ffSAllan Jude memset(ctx->b,0,sizeof(ctx->b)); /* zero out b[], so it can hold the counter */
748b468a9ffSAllan Jude memcpy(X,ctx->X,sizeof(X)); /* keep a local copy of counter mode "key" */
749b468a9ffSAllan Jude for (i=0;i*SKEIN1024_BLOCK_BYTES < byteCnt;i++)
750b468a9ffSAllan Jude {
751b468a9ffSAllan Jude ((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */
752b468a9ffSAllan Jude Skein_Start_New_Type(ctx,OUT_FINAL);
753b468a9ffSAllan Jude Skein1024_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run "counter mode" */
754b468a9ffSAllan Jude n = byteCnt - i*SKEIN1024_BLOCK_BYTES; /* number of output bytes left to go */
755b468a9ffSAllan Jude if (n >= SKEIN1024_BLOCK_BYTES)
756b468a9ffSAllan Jude n = SKEIN1024_BLOCK_BYTES;
757b468a9ffSAllan Jude Skein_Put64_LSB_First(hashVal+i*SKEIN1024_BLOCK_BYTES,ctx->X,n); /* "output" the ctr mode bytes */
758b468a9ffSAllan Jude Skein_Show_Final(256,&ctx->h,n,hashVal+i*SKEIN1024_BLOCK_BYTES);
759b468a9ffSAllan Jude memcpy(ctx->X,X,sizeof(X)); /* restore the counter mode key for next time */
760b468a9ffSAllan Jude }
761b468a9ffSAllan Jude return SKEIN_SUCCESS;
762b468a9ffSAllan Jude }
763b468a9ffSAllan Jude
764b468a9ffSAllan Jude
765b468a9ffSAllan Jude /* Adapt the functions to match the prototype expected by libmd */
766b468a9ffSAllan Jude void
SKEIN256_Init(SKEIN256_CTX * ctx)767b468a9ffSAllan Jude SKEIN256_Init(SKEIN256_CTX * ctx)
768b468a9ffSAllan Jude {
769b468a9ffSAllan Jude
770b468a9ffSAllan Jude Skein_256_Init(ctx, 256);
771b468a9ffSAllan Jude }
772b468a9ffSAllan Jude
773b468a9ffSAllan Jude void
SKEIN512_Init(SKEIN512_CTX * ctx)774b468a9ffSAllan Jude SKEIN512_Init(SKEIN512_CTX * ctx)
775b468a9ffSAllan Jude {
776b468a9ffSAllan Jude
777b468a9ffSAllan Jude Skein_512_Init(ctx, 512);
778b468a9ffSAllan Jude }
779b468a9ffSAllan Jude
780b468a9ffSAllan Jude void
SKEIN1024_Init(SKEIN1024_CTX * ctx)781b468a9ffSAllan Jude SKEIN1024_Init(SKEIN1024_CTX * ctx)
782b468a9ffSAllan Jude {
783b468a9ffSAllan Jude
784b468a9ffSAllan Jude Skein1024_Init(ctx, 1024);
785b468a9ffSAllan Jude }
786b468a9ffSAllan Jude
787b468a9ffSAllan Jude void
SKEIN256_Update(SKEIN256_CTX * ctx,const void * in,size_t len)788b468a9ffSAllan Jude SKEIN256_Update(SKEIN256_CTX * ctx, const void *in, size_t len)
789b468a9ffSAllan Jude {
790b468a9ffSAllan Jude
791b468a9ffSAllan Jude Skein_256_Update(ctx, in, len);
792b468a9ffSAllan Jude }
793b468a9ffSAllan Jude
794b468a9ffSAllan Jude void
SKEIN512_Update(SKEIN512_CTX * ctx,const void * in,size_t len)795b468a9ffSAllan Jude SKEIN512_Update(SKEIN512_CTX * ctx, const void *in, size_t len)
796b468a9ffSAllan Jude {
797b468a9ffSAllan Jude
798b468a9ffSAllan Jude Skein_512_Update(ctx, in, len);
799b468a9ffSAllan Jude }
800b468a9ffSAllan Jude
801b468a9ffSAllan Jude void
SKEIN1024_Update(SKEIN1024_CTX * ctx,const void * in,size_t len)802b468a9ffSAllan Jude SKEIN1024_Update(SKEIN1024_CTX * ctx, const void *in, size_t len)
803b468a9ffSAllan Jude {
804b468a9ffSAllan Jude
805b468a9ffSAllan Jude Skein1024_Update(ctx, in, len);
806b468a9ffSAllan Jude }
807b468a9ffSAllan Jude
808b468a9ffSAllan Jude void
SKEIN256_Final(unsigned char digest[static SKEIN_256_BLOCK_BYTES],SKEIN256_CTX * ctx)809b468a9ffSAllan Jude SKEIN256_Final(unsigned char digest[static SKEIN_256_BLOCK_BYTES], SKEIN256_CTX *ctx)
810b468a9ffSAllan Jude {
811b468a9ffSAllan Jude
812b468a9ffSAllan Jude Skein_256_Final(ctx, digest);
813*66bdf50fSXin LI explicit_bzero(ctx, sizeof(*ctx));
814b468a9ffSAllan Jude }
815b468a9ffSAllan Jude
816b468a9ffSAllan Jude void
SKEIN512_Final(unsigned char digest[static SKEIN_512_BLOCK_BYTES],SKEIN512_CTX * ctx)817b468a9ffSAllan Jude SKEIN512_Final(unsigned char digest[static SKEIN_512_BLOCK_BYTES], SKEIN512_CTX *ctx)
818b468a9ffSAllan Jude {
819b468a9ffSAllan Jude
820b468a9ffSAllan Jude Skein_512_Final(ctx, digest);
821*66bdf50fSXin LI explicit_bzero(ctx, sizeof(*ctx));
822b468a9ffSAllan Jude }
823b468a9ffSAllan Jude
824b468a9ffSAllan Jude void
SKEIN1024_Final(unsigned char digest[static SKEIN1024_BLOCK_BYTES],SKEIN1024_CTX * ctx)825b468a9ffSAllan Jude SKEIN1024_Final(unsigned char digest[static SKEIN1024_BLOCK_BYTES], SKEIN1024_CTX *ctx)
826b468a9ffSAllan Jude {
827b468a9ffSAllan Jude
828b468a9ffSAllan Jude Skein1024_Final(ctx, digest);
829*66bdf50fSXin LI explicit_bzero(ctx, sizeof(*ctx));
830b468a9ffSAllan Jude }
831b468a9ffSAllan Jude
832b468a9ffSAllan Jude #ifdef WEAK_REFS
833b468a9ffSAllan Jude /* When building libmd, provide weak references. Note: this is not
834b468a9ffSAllan Jude activated in the context of compiling these sources for internal
835b468a9ffSAllan Jude use in libcrypt.
836b468a9ffSAllan Jude */
837b468a9ffSAllan Jude #undef SKEIN256_Init
838b468a9ffSAllan Jude __weak_reference(_libmd_SKEIN256_Init, SKEIN256_Init);
839b468a9ffSAllan Jude #undef SKEIN256_Update
840b468a9ffSAllan Jude __weak_reference(_libmd_SKEIN256_Update, SKEIN256_Update);
841b468a9ffSAllan Jude #undef SKEIN256_Final
842b468a9ffSAllan Jude __weak_reference(_libmd_SKEIN256_Final, SKEIN256_Final);
843b468a9ffSAllan Jude
844b468a9ffSAllan Jude #undef SKEIN512_Init
845b468a9ffSAllan Jude __weak_reference(_libmd_SKEIN512_Init, SKEIN512_Init);
846b468a9ffSAllan Jude #undef SKEIN512_Update
847b468a9ffSAllan Jude __weak_reference(_libmd_SKEIN512_Update, SKEIN512_Update);
848b468a9ffSAllan Jude #undef SKEIN512_Final
849b468a9ffSAllan Jude __weak_reference(_libmd_SKEIN512_Final, SKEIN512_Final);
850b468a9ffSAllan Jude
851b468a9ffSAllan Jude #undef SKEIN1024_Init
852b468a9ffSAllan Jude __weak_reference(_libmd_SKEIN1024_Init, SKEIN1024_Init);
853b468a9ffSAllan Jude #undef SKEIN1024_Update
854b468a9ffSAllan Jude __weak_reference(_libmd_SKEIN1024_Update, SKEIN1024_Update);
855b468a9ffSAllan Jude #undef SKEIN1024_Final
856b468a9ffSAllan Jude __weak_reference(_libmd_SKEIN1024_Final, SKEIN1024_Final);
857b468a9ffSAllan Jude #endif
858b468a9ffSAllan Jude
859b468a9ffSAllan Jude #endif
860