digest-keccak 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,81 @@
1
+ /*
2
+ The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
3
+ Michaël Peeters and Gilles Van Assche. For more information, feedback or
4
+ questions, please refer to our website: http://keccak.noekeon.org/
5
+
6
+ Implementation by the designers,
7
+ hereby denoted as "the implementer".
8
+
9
+ To the extent possible under law, the implementer has waived all copyright
10
+ and related or neighboring rights to the source code in this file.
11
+ http://creativecommons.org/publicdomain/zero/1.0/
12
+ */
13
+
14
+ #include <string.h>
15
+ #include "KeccakNISTInterface.h"
16
+ #include "KeccakF-1600-interface.h"
17
+
18
+ HashReturn Init(hashState *state, int hashbitlen)
19
+ {
20
+ switch(hashbitlen) {
21
+ case 0: // Default parameters, arbitrary length output
22
+ InitSponge((spongeState*)state, 1024, 576);
23
+ break;
24
+ case 224:
25
+ InitSponge((spongeState*)state, 1152, 448);
26
+ break;
27
+ case 256:
28
+ InitSponge((spongeState*)state, 1088, 512);
29
+ break;
30
+ case 384:
31
+ InitSponge((spongeState*)state, 832, 768);
32
+ break;
33
+ case 512:
34
+ InitSponge((spongeState*)state, 576, 1024);
35
+ break;
36
+ default:
37
+ return BAD_HASHLEN;
38
+ }
39
+ state->fixedOutputLength = hashbitlen;
40
+ return SUCCESS;
41
+ }
42
+
43
+ HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen)
44
+ {
45
+ if ((databitlen % 8) == 0)
46
+ return Absorb((spongeState*)state, data, databitlen);
47
+ else {
48
+ HashReturn ret = Absorb((spongeState*)state, data, databitlen - (databitlen % 8));
49
+ if (ret == SUCCESS) {
50
+ unsigned char lastByte;
51
+ // Align the last partial byte to the least significant bits
52
+ lastByte = data[databitlen/8] >> (8 - (databitlen % 8));
53
+ return Absorb((spongeState*)state, &lastByte, databitlen % 8);
54
+ }
55
+ else
56
+ return ret;
57
+ }
58
+ }
59
+
60
+ HashReturn Final(hashState *state, BitSequence *hashval)
61
+ {
62
+ return Squeeze(state, hashval, state->fixedOutputLength);
63
+ }
64
+
65
+ HashReturn Hash(int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval)
66
+ {
67
+ hashState state;
68
+ HashReturn result;
69
+
70
+ if ((hashbitlen != 224) && (hashbitlen != 256) && (hashbitlen != 384) && (hashbitlen != 512))
71
+ return BAD_HASHLEN; // Only the four fixed output lengths available through this API
72
+ result = Init(&state, hashbitlen);
73
+ if (result != SUCCESS)
74
+ return result;
75
+ result = Update(&state, data, databitlen);
76
+ if (result != SUCCESS)
77
+ return result;
78
+ result = Final(&state, hashval);
79
+ return result;
80
+ }
81
+
@@ -0,0 +1,70 @@
1
+ /*
2
+ The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
3
+ Michaël Peeters and Gilles Van Assche. For more information, feedback or
4
+ questions, please refer to our website: http://keccak.noekeon.org/
5
+
6
+ Implementation by the designers,
7
+ hereby denoted as "the implementer".
8
+
9
+ To the extent possible under law, the implementer has waived all copyright
10
+ and related or neighboring rights to the source code in this file.
11
+ http://creativecommons.org/publicdomain/zero/1.0/
12
+ */
13
+
14
+ #ifndef _KeccakNISTInterface_h_
15
+ #define _KeccakNISTInterface_h_
16
+
17
+ #include "KeccakSponge.h"
18
+
19
+ typedef unsigned char BitSequence;
20
+ typedef unsigned long long DataLength;
21
+ typedef enum { SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2 } HashReturn;
22
+
23
+ typedef spongeState hashState;
24
+
25
+ /**
26
+ * Function to initialize the state of the Keccak[r, c] sponge function.
27
+ * The rate r and capacity c values are determined from @a hashbitlen.
28
+ * @param state Pointer to the state of the sponge function to be initialized.
29
+ * @param hashbitlen The desired number of output bits,
30
+ * or 0 for Keccak[] with default parameters
31
+ * and arbitrarily-long output.
32
+ * @pre The value of hashbitlen must be one of 0, 224, 256, 384 and 512.
33
+ * @return SUCCESS if successful, BAD_HASHLEN if the value of hashbitlen is incorrect.
34
+ */
35
+ HashReturn Init(hashState *state, int hashbitlen);
36
+ /**
37
+ * Function to give input data for the sponge function to absorb.
38
+ * @param state Pointer to the state of the sponge function initialized by Init().
39
+ * @param data Pointer to the input data.
40
+ * When @a databitLen is not a multiple of 8, the last bits of data must be
41
+ * in the most significant bits of the last byte.
42
+ * @param databitLen The number of input bits provided in the input data.
43
+ * @pre In the previous call to Absorb(), databitLen was a multiple of 8.
44
+ * @return SUCCESS if successful, FAIL otherwise.
45
+ */
46
+ HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen);
47
+ /**
48
+ * Function to squeeze output data from the sponge function.
49
+ * If @a hashbitlen was not 0 in the call to Init(), the number of output bits is equal to @a hashbitlen.
50
+ * If @a hashbitlen was 0 in the call to Init(), the output bits must be extracted using the Squeeze() function.
51
+ * @param state Pointer to the state of the sponge function initialized by Init().
52
+ * @param hashval Pointer to the buffer where to store the output data.
53
+ * @return SUCCESS if successful, FAIL otherwise.
54
+ */
55
+ HashReturn Final(hashState *state, BitSequence *hashval);
56
+ /**
57
+ * Function to compute a hash using the Keccak[r, c] sponge function.
58
+ * The rate r and capacity c values are determined from @a hashbitlen.
59
+ * @param hashbitlen The desired number of output bits.
60
+ * @param data Pointer to the input data.
61
+ * When @a databitLen is not a multiple of 8, the last bits of data must be
62
+ * in the most significant bits of the last byte.
63
+ * @param databitLen The number of input bits provided in the input data.
64
+ * @param hashval Pointer to the buffer where to store the output data.
65
+ * @pre The value of hashbitlen must be one of 224, 256, 384 and 512.
66
+ * @return SUCCESS if successful, BAD_HASHLEN if the value of hashbitlen is incorrect.
67
+ */
68
+ HashReturn Hash(int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval);
69
+
70
+ #endif
@@ -0,0 +1,266 @@
1
+ /*
2
+ The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
3
+ Michaël Peeters and Gilles Van Assche. For more information, feedback or
4
+ questions, please refer to our website: http://keccak.noekeon.org/
5
+
6
+ Implementation by the designers,
7
+ hereby denoted as "the implementer".
8
+
9
+ To the extent possible under law, the implementer has waived all copyright
10
+ and related or neighboring rights to the source code in this file.
11
+ http://creativecommons.org/publicdomain/zero/1.0/
12
+ */
13
+
14
+ #include <string.h>
15
+ #include "KeccakSponge.h"
16
+ #include "KeccakF-1600-interface.h"
17
+ #ifdef KeccakReference
18
+ #include "displayIntermediateValues.h"
19
+ #endif
20
+
21
+ int InitSponge(spongeState *state, unsigned int rate, unsigned int capacity)
22
+ {
23
+ if (rate+capacity != 1600)
24
+ return 1;
25
+ if ((rate <= 0) || (rate >= 1600) || ((rate % 64) != 0))
26
+ return 1;
27
+ KeccakInitialize();
28
+ state->rate = rate;
29
+ state->capacity = capacity;
30
+ state->fixedOutputLength = 0;
31
+ KeccakInitializeState(state->state);
32
+ memset(state->dataQueue, 0, KeccakMaximumRateInBytes);
33
+ state->bitsInQueue = 0;
34
+ state->squeezing = 0;
35
+ state->bitsAvailableForSqueezing = 0;
36
+
37
+ return 0;
38
+ }
39
+
40
+ void AbsorbQueue(spongeState *state)
41
+ {
42
+ // state->bitsInQueue is assumed to be equal to state->rate
43
+ #ifdef KeccakReference
44
+ displayBytes(1, "Block to be absorbed", state->dataQueue, state->rate/8);
45
+ #endif
46
+ #ifdef ProvideFast576
47
+ if (state->rate == 576)
48
+ KeccakAbsorb576bits(state->state, state->dataQueue);
49
+ else
50
+ #endif
51
+ #ifdef ProvideFast832
52
+ if (state->rate == 832)
53
+ KeccakAbsorb832bits(state->state, state->dataQueue);
54
+ else
55
+ #endif
56
+ #ifdef ProvideFast1024
57
+ if (state->rate == 1024)
58
+ KeccakAbsorb1024bits(state->state, state->dataQueue);
59
+ else
60
+ #endif
61
+ #ifdef ProvideFast1088
62
+ if (state->rate == 1088)
63
+ KeccakAbsorb1088bits(state->state, state->dataQueue);
64
+ else
65
+ #endif
66
+ #ifdef ProvideFast1152
67
+ if (state->rate == 1152)
68
+ KeccakAbsorb1152bits(state->state, state->dataQueue);
69
+ else
70
+ #endif
71
+ #ifdef ProvideFast1344
72
+ if (state->rate == 1344)
73
+ KeccakAbsorb1344bits(state->state, state->dataQueue);
74
+ else
75
+ #endif
76
+ KeccakAbsorb(state->state, state->dataQueue, state->rate/64);
77
+ state->bitsInQueue = 0;
78
+ }
79
+
80
+ int Absorb(spongeState *state, const unsigned char *data, unsigned long long databitlen)
81
+ {
82
+ unsigned long long i, j, wholeBlocks;
83
+ unsigned int partialBlock, partialByte;
84
+ const unsigned char *curData;
85
+
86
+ if ((state->bitsInQueue % 8) != 0)
87
+ return 1; // Only the last call may contain a partial byte
88
+ if (state->squeezing)
89
+ return 1; // Too late for additional input
90
+
91
+ i = 0;
92
+ while(i < databitlen) {
93
+ if ((state->bitsInQueue == 0) && (databitlen >= state->rate) && (i <= (databitlen-state->rate))) {
94
+ wholeBlocks = (databitlen-i)/state->rate;
95
+ curData = data+i/8;
96
+ #ifdef ProvideFast576
97
+ if (state->rate == 576) {
98
+ for(j=0; j<wholeBlocks; j++, curData+=576/8) {
99
+ #ifdef KeccakReference
100
+ displayBytes(1, "Block to be absorbed", curData, state->rate/8);
101
+ #endif
102
+ KeccakAbsorb576bits(state->state, curData);
103
+ }
104
+ }
105
+ else
106
+ #endif
107
+ #ifdef ProvideFast832
108
+ if (state->rate == 832) {
109
+ for(j=0; j<wholeBlocks; j++, curData+=832/8) {
110
+ #ifdef KeccakReference
111
+ displayBytes(1, "Block to be absorbed", curData, state->rate/8);
112
+ #endif
113
+ KeccakAbsorb832bits(state->state, curData);
114
+ }
115
+ }
116
+ else
117
+ #endif
118
+ #ifdef ProvideFast1024
119
+ if (state->rate == 1024) {
120
+ for(j=0; j<wholeBlocks; j++, curData+=1024/8) {
121
+ #ifdef KeccakReference
122
+ displayBytes(1, "Block to be absorbed", curData, state->rate/8);
123
+ #endif
124
+ KeccakAbsorb1024bits(state->state, curData);
125
+ }
126
+ }
127
+ else
128
+ #endif
129
+ #ifdef ProvideFast1088
130
+ if (state->rate == 1088) {
131
+ for(j=0; j<wholeBlocks; j++, curData+=1088/8) {
132
+ #ifdef KeccakReference
133
+ displayBytes(1, "Block to be absorbed", curData, state->rate/8);
134
+ #endif
135
+ KeccakAbsorb1088bits(state->state, curData);
136
+ }
137
+ }
138
+ else
139
+ #endif
140
+ #ifdef ProvideFast1152
141
+ if (state->rate == 1152) {
142
+ for(j=0; j<wholeBlocks; j++, curData+=1152/8) {
143
+ #ifdef KeccakReference
144
+ displayBytes(1, "Block to be absorbed", curData, state->rate/8);
145
+ #endif
146
+ KeccakAbsorb1152bits(state->state, curData);
147
+ }
148
+ }
149
+ else
150
+ #endif
151
+ #ifdef ProvideFast1344
152
+ if (state->rate == 1344) {
153
+ for(j=0; j<wholeBlocks; j++, curData+=1344/8) {
154
+ #ifdef KeccakReference
155
+ displayBytes(1, "Block to be absorbed", curData, state->rate/8);
156
+ #endif
157
+ KeccakAbsorb1344bits(state->state, curData);
158
+ }
159
+ }
160
+ else
161
+ #endif
162
+ {
163
+ for(j=0; j<wholeBlocks; j++, curData+=state->rate/8) {
164
+ #ifdef KeccakReference
165
+ displayBytes(1, "Block to be absorbed", curData, state->rate/8);
166
+ #endif
167
+ KeccakAbsorb(state->state, curData, state->rate/64);
168
+ }
169
+ }
170
+ i += wholeBlocks*state->rate;
171
+ }
172
+ else {
173
+ partialBlock = (unsigned int)(databitlen - i);
174
+ if (partialBlock+state->bitsInQueue > state->rate)
175
+ partialBlock = state->rate-state->bitsInQueue;
176
+ partialByte = partialBlock % 8;
177
+ partialBlock -= partialByte;
178
+ memcpy(state->dataQueue+state->bitsInQueue/8, data+i/8, partialBlock/8);
179
+ state->bitsInQueue += partialBlock;
180
+ i += partialBlock;
181
+ if (state->bitsInQueue == state->rate)
182
+ AbsorbQueue(state);
183
+ if (partialByte > 0) {
184
+ unsigned char mask = (1 << partialByte)-1;
185
+ state->dataQueue[state->bitsInQueue/8] = data[i/8] & mask;
186
+ state->bitsInQueue += partialByte;
187
+ i += partialByte;
188
+ }
189
+ }
190
+ }
191
+ return 0;
192
+ }
193
+
194
+ void PadAndSwitchToSqueezingPhase(spongeState *state)
195
+ {
196
+ // Note: the bits are numbered from 0=LSB to 7=MSB
197
+ if (state->bitsInQueue + 1 == state->rate) {
198
+ state->dataQueue[state->bitsInQueue/8 ] |= 1 << (state->bitsInQueue % 8);
199
+ AbsorbQueue(state);
200
+ memset(state->dataQueue, 0, state->rate/8);
201
+ }
202
+ else {
203
+ memset(state->dataQueue + (state->bitsInQueue+7)/8, 0, state->rate/8 - (state->bitsInQueue+7)/8);
204
+ state->dataQueue[state->bitsInQueue/8 ] |= 1 << (state->bitsInQueue % 8);
205
+ }
206
+ state->dataQueue[(state->rate-1)/8] |= 1 << ((state->rate-1) % 8);
207
+ AbsorbQueue(state);
208
+
209
+ #ifdef KeccakReference
210
+ displayText(1, "--- Switching to squeezing phase ---");
211
+ #endif
212
+ #ifdef ProvideFast1024
213
+ if (state->rate == 1024) {
214
+ KeccakExtract1024bits(state->state, state->dataQueue);
215
+ state->bitsAvailableForSqueezing = 1024;
216
+ }
217
+ else
218
+ #endif
219
+ {
220
+ KeccakExtract(state->state, state->dataQueue, state->rate/64);
221
+ state->bitsAvailableForSqueezing = state->rate;
222
+ }
223
+ #ifdef KeccakReference
224
+ displayBytes(1, "Block available for squeezing", state->dataQueue, state->bitsAvailableForSqueezing/8);
225
+ #endif
226
+ state->squeezing = 1;
227
+ }
228
+
229
+ int Squeeze(spongeState *state, unsigned char *output, unsigned long long outputLength)
230
+ {
231
+ unsigned long long i;
232
+ unsigned int partialBlock;
233
+
234
+ if (!state->squeezing)
235
+ PadAndSwitchToSqueezingPhase(state);
236
+ if ((outputLength % 8) != 0)
237
+ return 1; // Only multiple of 8 bits are allowed, truncation can be done at user level
238
+
239
+ i = 0;
240
+ while(i < outputLength) {
241
+ if (state->bitsAvailableForSqueezing == 0) {
242
+ KeccakPermutation(state->state);
243
+ #ifdef ProvideFast1024
244
+ if (state->rate == 1024) {
245
+ KeccakExtract1024bits(state->state, state->dataQueue);
246
+ state->bitsAvailableForSqueezing = 1024;
247
+ }
248
+ else
249
+ #endif
250
+ {
251
+ KeccakExtract(state->state, state->dataQueue, state->rate/64);
252
+ state->bitsAvailableForSqueezing = state->rate;
253
+ }
254
+ #ifdef KeccakReference
255
+ displayBytes(1, "Block available for squeezing", state->dataQueue, state->bitsAvailableForSqueezing/8);
256
+ #endif
257
+ }
258
+ partialBlock = state->bitsAvailableForSqueezing;
259
+ if ((unsigned long long)partialBlock > outputLength - i)
260
+ partialBlock = (unsigned int)(outputLength - i);
261
+ memcpy(output+i/8, state->dataQueue+(state->rate-state->bitsAvailableForSqueezing)/8, partialBlock/8);
262
+ state->bitsAvailableForSqueezing -= partialBlock;
263
+ i += partialBlock;
264
+ }
265
+ return 0;
266
+ }
@@ -0,0 +1,76 @@
1
+ /*
2
+ The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
3
+ Michaël Peeters and Gilles Van Assche. For more information, feedback or
4
+ questions, please refer to our website: http://keccak.noekeon.org/
5
+
6
+ Implementation by the designers,
7
+ hereby denoted as "the implementer".
8
+
9
+ To the extent possible under law, the implementer has waived all copyright
10
+ and related or neighboring rights to the source code in this file.
11
+ http://creativecommons.org/publicdomain/zero/1.0/
12
+ */
13
+
14
+ #ifndef _KeccakSponge_h_
15
+ #define _KeccakSponge_h_
16
+
17
+ #define KeccakPermutationSize 1600
18
+ #define KeccakPermutationSizeInBytes (KeccakPermutationSize/8)
19
+ #define KeccakMaximumRate 1536
20
+ #define KeccakMaximumRateInBytes (KeccakMaximumRate/8)
21
+
22
+ #if defined(__GNUC__)
23
+ #define ALIGN __attribute__ ((aligned(32)))
24
+ #elif defined(_MSC_VER)
25
+ #define ALIGN __declspec(align(32))
26
+ #else
27
+ #define ALIGN
28
+ #endif
29
+
30
+ ALIGN typedef struct spongeStateStruct {
31
+ ALIGN unsigned char state[KeccakPermutationSizeInBytes];
32
+ ALIGN unsigned char dataQueue[KeccakMaximumRateInBytes];
33
+ unsigned int rate;
34
+ unsigned int capacity;
35
+ unsigned int bitsInQueue;
36
+ unsigned int fixedOutputLength;
37
+ int squeezing;
38
+ unsigned int bitsAvailableForSqueezing;
39
+ } spongeState;
40
+
41
+ /**
42
+ * Function to initialize the state of the Keccak[r, c] sponge function.
43
+ * The sponge function is set to the absorbing phase.
44
+ * @param state Pointer to the state of the sponge function to be initialized.
45
+ * @param rate The value of the rate r.
46
+ * @param capacity The value of the capacity c.
47
+ * @pre One must have r+c=1600 and the rate a multiple of 64 bits in this implementation.
48
+ * @return Zero if successful, 1 otherwise.
49
+ */
50
+ int InitSponge(spongeState *state, unsigned int rate, unsigned int capacity);
51
+ /**
52
+ * Function to give input data for the sponge function to absorb.
53
+ * @param state Pointer to the state of the sponge function initialized by InitSponge().
54
+ * @param data Pointer to the input data.
55
+ * When @a databitLen is not a multiple of 8, the last bits of data must be
56
+ * in the least significant bits of the last byte.
57
+ * @param databitLen The number of input bits provided in the input data.
58
+ * @pre In the previous call to Absorb(), databitLen was a multiple of 8.
59
+ * @pre The sponge function must be in the absorbing phase,
60
+ * i.e., Squeeze() must not have been called before.
61
+ * @return Zero if successful, 1 otherwise.
62
+ */
63
+ int Absorb(spongeState *state, const unsigned char *data, unsigned long long databitlen);
64
+ /**
65
+ * Function to squeeze output data from the sponge function.
66
+ * If the sponge function was in the absorbing phase, this function
67
+ * switches it to the squeezing phase.
68
+ * @param state Pointer to the state of the sponge function initialized by InitSponge().
69
+ * @param output Pointer to the buffer where to store the output data.
70
+ * @param outputLength The number of output bits desired.
71
+ * It must be a multiple of 8.
72
+ * @return Zero if successful, 1 otherwise.
73
+ */
74
+ int Squeeze(spongeState *state, unsigned char *output, unsigned long long outputLength);
75
+
76
+ #endif