Better vertical alignment
[skeinsum.git] / SHA3api_ref.c
1 /***********************************************************************\r
2 **\r
3 ** Implementation of the AHS API using the Skein hash function.\r
4 **\r
5 ** Source code author: Doug Whiting, 2008.\r
6 **\r
7 ** This algorithm and source code is released to the public domain.\r
8 ** \r
9 ************************************************************************/\r
10 \r
11 #include <string.h>     /* get the memcpy/memset functions */\r
12 #include "skein.h"      /* get the Skein API definitions   */\r
13 #include "SHA3api_ref.h"/* get the  AHS  API definitions   */\r
14 \r
15 /******************************************************************/\r
16 /*     AHS API code                                               */\r
17 /******************************************************************/\r
18 \r
19 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r
20 /* select the context size and init the context */\r
21 HashReturn Init(hashState *state, int hashbitlen)\r
22     {\r
23 #if SKEIN_256_NIST_MAX_HASH_BITS\r
24     if (hashbitlen <= SKEIN_256_NIST_MAX_HASHBITS)\r
25         {\r
26         Skein_Assert(hashbitlen > 0,BAD_HASHLEN);\r
27         state->statebits = 64*SKEIN_256_STATE_WORDS;\r
28         return Skein_256_Init(&state->u.ctx_256,(size_t) hashbitlen);\r
29         }\r
30 #endif\r
31     if (hashbitlen <= SKEIN_512_NIST_MAX_HASHBITS)\r
32         {\r
33         state->statebits = 64*SKEIN_512_STATE_WORDS;\r
34         return Skein_512_Init(&state->u.ctx_512,(size_t) hashbitlen);\r
35         }\r
36     else\r
37         {\r
38         state->statebits = 64*SKEIN1024_STATE_WORDS;\r
39         return Skein1024_Init(&state->u.ctx1024,(size_t) hashbitlen);\r
40         }\r
41     }\r
42 \r
43 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r
44 /* process data to be hashed */\r
45 HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen)\r
46     {\r
47     /* only the final Update() call is allowed do partial bytes, else assert an error */\r
48     Skein_Assert((state->u.h.T[1] & SKEIN_T1_FLAG_BIT_PAD) == 0 || databitlen == 0, FAIL);\r
49 \r
50     Skein_Assert(state->statebits % 256 == 0 && (state->statebits-256) < 1024,FAIL);\r
51     if ((databitlen & 7) == 0)  /* partial bytes? */\r
52         {\r
53         switch ((state->statebits >> 8) & 3)\r
54             {\r
55             case 2:  return Skein_512_Update(&state->u.ctx_512,data,databitlen >> 3);\r
56             case 1:  return Skein_256_Update(&state->u.ctx_256,data,databitlen >> 3);\r
57             case 0:  return Skein1024_Update(&state->u.ctx1024,data,databitlen >> 3);\r
58             default: return FAIL;\r
59             }\r
60         }\r
61     else\r
62         {   /* handle partial final byte */\r
63         size_t bCnt = (databitlen >> 3) + 1;                  /* number of bytes to handle (nonzero here!) */\r
64         u08b_t b,mask;\r
65 \r
66         mask = (u08b_t) (1u << (7 - (databitlen & 7)));       /* partial byte bit mask */\r
67         b    = (u08b_t) ((data[bCnt-1] & (0-mask)) | mask);   /* apply bit padding on final byte */\r
68 \r
69         switch ((state->statebits >> 8) & 3)\r
70             {\r
71             case 2:  Skein_512_Update(&state->u.ctx_512,data,bCnt-1); /* process all but the final byte    */\r
72                      Skein_512_Update(&state->u.ctx_512,&b  ,  1   ); /* process the (masked) partial byte */\r
73                      break;\r
74             case 1:  Skein_256_Update(&state->u.ctx_256,data,bCnt-1); /* process all but the final byte    */\r
75                      Skein_256_Update(&state->u.ctx_256,&b  ,  1   ); /* process the (masked) partial byte */\r
76                      break;\r
77             case 0:  Skein1024_Update(&state->u.ctx1024,data,bCnt-1); /* process all but the final byte    */\r
78                      Skein1024_Update(&state->u.ctx1024,&b  ,  1   ); /* process the (masked) partial byte */\r
79                      break;\r
80             default: return FAIL;\r
81             }\r
82         Skein_Set_Bit_Pad_Flag(state->u.h);                    /* set tweak flag for the final call */\r
83         \r
84         return SUCCESS;\r
85         }\r
86     }\r
87 \r
88 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r
89 /* finalize hash computation and output the result (hashbitlen bits) */\r
90 HashReturn Final(hashState *state, BitSequence *hashval)\r
91     {\r
92     Skein_Assert(state->statebits % 256 == 0 && (state->statebits-256) < 1024,FAIL);\r
93     switch ((state->statebits >> 8) & 3)\r
94         {\r
95         case 2:  return Skein_512_Final(&state->u.ctx_512,hashval);\r
96         case 1:  return Skein_256_Final(&state->u.ctx_256,hashval);\r
97         case 0:  return Skein1024_Final(&state->u.ctx1024,hashval);\r
98         default: return FAIL;\r
99         }\r
100     }\r
101 \r
102 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r
103 /* all-in-one hash function */\r
104 HashReturn Hash(int hashbitlen, const BitSequence *data, /* all-in-one call */\r
105                 DataLength databitlen,BitSequence *hashval)\r
106     {\r
107     hashState  state;\r
108     HashReturn r = Init(&state,hashbitlen);\r
109     if (r == SUCCESS)\r
110         { /* these calls do not fail when called properly */\r
111         r = Update(&state,data,databitlen);\r
112         Final(&state,hashval);\r
113         }\r
114     return r;\r
115     }\r