Browse code

Change sha3 implementation used. Initial unsaved data API.

Dario Rodriguez authored on 02/03/2019 16:12:12
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,332 +0,0 @@
1
-/*
2
-Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni,
3
-Joan Daemen, Michaƫl Peeters, Gilles Van Assche and Ronny Van Keer, hereby
4
-denoted as "the implementer".
5
-
6
-For more information, feedback or questions, please refer to our websites:
7
-http://keccak.noekeon.org/
8
-http://keyak.noekeon.org/
9
-http://ketje.noekeon.org/
10
-
11
-To the extent possible under law, the implementer has waived all copyright
12
-and related or neighboring rights to the source code in this file.
13
-http://creativecommons.org/publicdomain/zero/1.0/
14
-*/
15
-
16
-#define JOIN0(a, b)                     a ## b
17
-#define JOIN(a, b)                      JOIN0(a, b)
18
-
19
-#define Sponge                          JOIN(prefix, _Sponge)
20
-#define SpongeInstance                  JOIN(prefix, _SpongeInstance)
21
-#define SpongeInitialize                JOIN(prefix, _SpongeInitialize)
22
-#define SpongeAbsorb                    JOIN(prefix, _SpongeAbsorb)
23
-#define SpongeAbsorbLastFewBits         JOIN(prefix, _SpongeAbsorbLastFewBits)
24
-#define SpongeSqueeze                   JOIN(prefix, _SpongeSqueeze)
25
-
26
-#define SnP_stateSizeInBytes            JOIN(SnP, _stateSizeInBytes)
27
-#define SnP_stateAlignment              JOIN(SnP, _stateAlignment)
28
-#define SnP_StaticInitialize            JOIN(SnP, _StaticInitialize)
29
-#define SnP_Initialize                  JOIN(SnP, _Initialize)
30
-#define SnP_AddByte                     JOIN(SnP, _AddByte)
31
-#define SnP_AddBytes                    JOIN(SnP, _AddBytes)
32
-#define SnP_ExtractBytes                JOIN(SnP, _ExtractBytes)
33
-
34
-int Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen)
35
-{
36
-    ALIGN(SnP_stateAlignment) unsigned char state[SnP_stateSizeInBytes];
37
-    unsigned int partialBlock;
38
-    const unsigned char *curInput = input;
39
-    unsigned char *curOutput = output;
40
-    unsigned int rateInBytes = rate/8;
41
-
42
-    if (rate+capacity != SnP_width)
43
-        return 1;
44
-    if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0))
45
-        return 1;
46
-    if (suffix == 0)
47
-        return 1;
48
-
49
-    /* Initialize the state */
50
-
51
-    SnP_StaticInitialize();
52
-    SnP_Initialize(state);
53
-
54
-    /* First, absorb whole blocks */
55
-
56
-#ifdef SnP_FastLoop_Absorb
57
-    if (((rateInBytes % (SnP_width/200)) == 0) && (inputByteLen >= rateInBytes)) {
58
-        /* fast lane: whole lane rate */
59
-
60
-        size_t j;
61
-        j = SnP_FastLoop_Absorb(state, rateInBytes/(SnP_width/200), curInput, inputByteLen);
62
-        curInput += j;
63
-        inputByteLen -= j;
64
-    }
65
-#endif
66
-    while(inputByteLen >= (size_t)rateInBytes) {
67
-        #ifdef KeccakReference
68
-        displayBytes(1, "Block to be absorbed", curInput, rateInBytes);
69
-        #endif
70
-        SnP_AddBytes(state, curInput, 0, rateInBytes);
71
-        SnP_Permute(state);
72
-        curInput += rateInBytes;
73
-        inputByteLen -= rateInBytes;
74
-    }
75
-
76
-    /* Then, absorb what remains */
77
-
78
-    partialBlock = (unsigned int)inputByteLen;
79
-    #ifdef KeccakReference
80
-    displayBytes(1, "Block to be absorbed (part)", curInput, partialBlock);
81
-    #endif
82
-    SnP_AddBytes(state, curInput, 0, partialBlock);
83
-
84
-    /* Finally, absorb the suffix */
85
-
86
-    #ifdef KeccakReference
87
-    {
88
-        unsigned char delimitedData1[1];
89
-        delimitedData1[0] = suffix;
90
-        displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1);
91
-    }
92
-    #endif
93
-    /* Last few bits, whose delimiter coincides with first bit of padding */
94
-
95
-    SnP_AddByte(state, suffix, partialBlock);
96
-    /* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */
97
-
98
-    if ((suffix >= 0x80) && (partialBlock == (rateInBytes-1)))
99
-        SnP_Permute(state);
100
-    /* Second bit of padding */
101
-
102
-    SnP_AddByte(state, 0x80, rateInBytes-1);
103
-    #ifdef KeccakReference
104
-    {
105
-        unsigned char block[SnP_width/8];
106
-        memset(block, 0, SnP_width/8);
107
-        block[rateInBytes-1] = 0x80;
108
-        displayBytes(1, "Second bit of padding", block, rateInBytes);
109
-    }
110
-    #endif
111
-    SnP_Permute(state);
112
-    #ifdef KeccakReference
113
-    displayText(1, "--- Switching to squeezing phase ---");
114
-    #endif
115
-
116
-    /* First, output whole blocks */
117
-
118
-    while(outputByteLen > (size_t)rateInBytes) {
119
-        SnP_ExtractBytes(state, curOutput, 0, rateInBytes);
120
-        SnP_Permute(state);
121
-        #ifdef KeccakReference
122
-        displayBytes(1, "Squeezed block", curOutput, rateInBytes);
123
-        #endif
124
-        curOutput += rateInBytes;
125
-        outputByteLen -= rateInBytes;
126
-    }
127
-
128
-    /* Finally, output what remains */
129
-
130
-    partialBlock = (unsigned int)outputByteLen;
131
-    SnP_ExtractBytes(state, curOutput, 0, partialBlock);
132
-    #ifdef KeccakReference
133
-    displayBytes(1, "Squeezed block (part)", curOutput, partialBlock);
134
-    #endif
135
-
136
-    return 0;
137
-}
138
-
139
-/* ---------------------------------------------------------------- */
140
-/* ---------------------------------------------------------------- */
141
-/* ---------------------------------------------------------------- */
142
-
143
-int SpongeInitialize(SpongeInstance *instance, unsigned int rate, unsigned int capacity)
144
-{
145
-    if (rate+capacity != SnP_width)
146
-        return 1;
147
-    if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0))
148
-        return 1;
149
-    SnP_StaticInitialize();
150
-    SnP_Initialize(instance->state);
151
-    instance->rate = rate;
152
-    instance->byteIOIndex = 0;
153
-    instance->squeezing = 0;
154
-
155
-    return 0;
156
-}
157
-
158
-/* ---------------------------------------------------------------- */
159
-
160
-int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dataByteLen)
161
-{
162
-    size_t i, j;
163
-    unsigned int partialBlock;
164
-    const unsigned char *curData;
165
-    unsigned int rateInBytes = instance->rate/8;
166
-
167
-    if (instance->squeezing)
168
-        return 1; /* Too late for additional input */
169
-
170
-
171
-    i = 0;
172
-    curData = data;
173
-    while(i < dataByteLen) {
174
-        if ((instance->byteIOIndex == 0) && (dataByteLen >= (i + rateInBytes))) {
175
-#ifdef SnP_FastLoop_Absorb
176
-            /* processing full blocks first */
177
-
178
-            if ((rateInBytes % (SnP_width/200)) == 0) {
179
-                /* fast lane: whole lane rate */
180
-
181
-                j = SnP_FastLoop_Absorb(instance->state, rateInBytes/(SnP_width/200), curData, dataByteLen - i);
182
-                i += j;
183
-                curData += j;
184
-            }
185
-            else {
186
-#endif
187
-                for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) {
188
-                    #ifdef KeccakReference
189
-                    displayBytes(1, "Block to be absorbed", curData, rateInBytes);
190
-                    #endif
191
-                    SnP_AddBytes(instance->state, curData, 0, rateInBytes);
192
-                    SnP_Permute(instance->state);
193
-                    curData+=rateInBytes;
194
-                }
195
-                i = dataByteLen - j;
196
-#ifdef SnP_FastLoop_Absorb
197
-            }
198
-#endif
199
-        }
200
-        else {
201
-            /* normal lane: using the message queue */
202
-
203
-            partialBlock = (unsigned int)(dataByteLen - i);
204
-            if (partialBlock+instance->byteIOIndex > rateInBytes)
205
-                partialBlock = rateInBytes-instance->byteIOIndex;
206
-            #ifdef KeccakReference
207
-            displayBytes(1, "Block to be absorbed (part)", curData, partialBlock);
208
-            #endif
209
-            i += partialBlock;
210
-
211
-            SnP_AddBytes(instance->state, curData, instance->byteIOIndex, partialBlock);
212
-            curData += partialBlock;
213
-            instance->byteIOIndex += partialBlock;
214
-            if (instance->byteIOIndex == rateInBytes) {
215
-                SnP_Permute(instance->state);
216
-                instance->byteIOIndex = 0;
217
-            }
218
-        }
219
-    }
220
-    return 0;
221
-}
222
-
223
-/* ---------------------------------------------------------------- */
224
-
225
-int SpongeAbsorbLastFewBits(SpongeInstance *instance, unsigned char delimitedData)
226
-{
227
-    unsigned int rateInBytes = instance->rate/8;
228
-
229
-    if (delimitedData == 0)
230
-        return 1;
231
-    if (instance->squeezing)
232
-        return 1; /* Too late for additional input */
233
-
234
-
235
-    #ifdef KeccakReference
236
-    {
237
-        unsigned char delimitedData1[1];
238
-        delimitedData1[0] = delimitedData;
239
-        displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1);
240
-    }
241
-    #endif
242
-    /* Last few bits, whose delimiter coincides with first bit of padding */
243
-
244
-    SnP_AddByte(instance->state, delimitedData, instance->byteIOIndex);
245
-    /* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */
246
-
247
-    if ((delimitedData >= 0x80) && (instance->byteIOIndex == (rateInBytes-1)))
248
-        SnP_Permute(instance->state);
249
-    /* Second bit of padding */
250
-
251
-    SnP_AddByte(instance->state, 0x80, rateInBytes-1);
252
-    #ifdef KeccakReference
253
-    {
254
-        unsigned char block[SnP_width/8];
255
-        memset(block, 0, SnP_width/8);
256
-        block[rateInBytes-1] = 0x80;
257
-        displayBytes(1, "Second bit of padding", block, rateInBytes);
258
-    }
259
-    #endif
260
-    SnP_Permute(instance->state);
261
-    instance->byteIOIndex = 0;
262
-    instance->squeezing = 1;
263
-    #ifdef KeccakReference
264
-    displayText(1, "--- Switching to squeezing phase ---");
265
-    #endif
266
-    return 0;
267
-}
268
-
269
-/* ---------------------------------------------------------------- */
270
-
271
-int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByteLen)
272
-{
273
-    size_t i, j;
274
-    unsigned int partialBlock;
275
-    unsigned int rateInBytes = instance->rate/8;
276
-    unsigned char *curData;
277
-
278
-    if (!instance->squeezing)
279
-        SpongeAbsorbLastFewBits(instance, 0x01);
280
-
281
-    i = 0;
282
-    curData = data;
283
-    while(i < dataByteLen) {
284
-        if ((instance->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) {
285
-            for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) {
286
-                SnP_Permute(instance->state);
287
-                SnP_ExtractBytes(instance->state, curData, 0, rateInBytes);
288
-                #ifdef KeccakReference
289
-                displayBytes(1, "Squeezed block", curData, rateInBytes);
290
-                #endif
291
-                curData+=rateInBytes;
292
-            }
293
-            i = dataByteLen - j;
294
-        }
295
-        else {
296
-            /* normal lane: using the message queue */
297
-
298
-            if (instance->byteIOIndex == rateInBytes) {
299
-                SnP_Permute(instance->state);
300
-                instance->byteIOIndex = 0;
301
-            }
302
-            partialBlock = (unsigned int)(dataByteLen - i);
303
-            if (partialBlock+instance->byteIOIndex > rateInBytes)
304
-                partialBlock = rateInBytes-instance->byteIOIndex;
305
-            i += partialBlock;
306
-
307
-            SnP_ExtractBytes(instance->state, curData, instance->byteIOIndex, partialBlock);
308
-            #ifdef KeccakReference
309
-            displayBytes(1, "Squeezed block (part)", curData, partialBlock);
310
-            #endif
311
-            curData += partialBlock;
312
-            instance->byteIOIndex += partialBlock;
313
-        }
314
-    }
315
-    return 0;
316
-}
317
-
318
-/* ---------------------------------------------------------------- */
319
-
320
-#undef Sponge
321
-#undef SpongeInstance
322
-#undef SpongeInitialize
323
-#undef SpongeAbsorb
324
-#undef SpongeAbsorbLastFewBits
325
-#undef SpongeSqueeze
326
-#undef SnP_stateSizeInBytes
327
-#undef SnP_stateAlignment
328
-#undef SnP_StaticInitialize
329
-#undef SnP_Initialize
330
-#undef SnP_AddByte
331
-#undef SnP_AddBytes
332
-#undef SnP_ExtractBytes
Browse code

start implementation of undo and unsaved in redata. tentative sha3-512 support for unsaved integrity check

Dario Rodriguez authored on 26/02/2019 21:26:05
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,332 @@
1
+/*
2
+Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni,
3
+Joan Daemen, Michaƫl Peeters, Gilles Van Assche and Ronny Van Keer, hereby
4
+denoted as "the implementer".
5
+
6
+For more information, feedback or questions, please refer to our websites:
7
+http://keccak.noekeon.org/
8
+http://keyak.noekeon.org/
9
+http://ketje.noekeon.org/
10
+
11
+To the extent possible under law, the implementer has waived all copyright
12
+and related or neighboring rights to the source code in this file.
13
+http://creativecommons.org/publicdomain/zero/1.0/
14
+*/
15
+
16
+#define JOIN0(a, b)                     a ## b
17
+#define JOIN(a, b)                      JOIN0(a, b)
18
+
19
+#define Sponge                          JOIN(prefix, _Sponge)
20
+#define SpongeInstance                  JOIN(prefix, _SpongeInstance)
21
+#define SpongeInitialize                JOIN(prefix, _SpongeInitialize)
22
+#define SpongeAbsorb                    JOIN(prefix, _SpongeAbsorb)
23
+#define SpongeAbsorbLastFewBits         JOIN(prefix, _SpongeAbsorbLastFewBits)
24
+#define SpongeSqueeze                   JOIN(prefix, _SpongeSqueeze)
25
+
26
+#define SnP_stateSizeInBytes            JOIN(SnP, _stateSizeInBytes)
27
+#define SnP_stateAlignment              JOIN(SnP, _stateAlignment)
28
+#define SnP_StaticInitialize            JOIN(SnP, _StaticInitialize)
29
+#define SnP_Initialize                  JOIN(SnP, _Initialize)
30
+#define SnP_AddByte                     JOIN(SnP, _AddByte)
31
+#define SnP_AddBytes                    JOIN(SnP, _AddBytes)
32
+#define SnP_ExtractBytes                JOIN(SnP, _ExtractBytes)
33
+
34
+int Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen)
35
+{
36
+    ALIGN(SnP_stateAlignment) unsigned char state[SnP_stateSizeInBytes];
37
+    unsigned int partialBlock;
38
+    const unsigned char *curInput = input;
39
+    unsigned char *curOutput = output;
40
+    unsigned int rateInBytes = rate/8;
41
+
42
+    if (rate+capacity != SnP_width)
43
+        return 1;
44
+    if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0))
45
+        return 1;
46
+    if (suffix == 0)
47
+        return 1;
48
+
49
+    /* Initialize the state */
50
+
51
+    SnP_StaticInitialize();
52
+    SnP_Initialize(state);
53
+
54
+    /* First, absorb whole blocks */
55
+
56
+#ifdef SnP_FastLoop_Absorb
57
+    if (((rateInBytes % (SnP_width/200)) == 0) && (inputByteLen >= rateInBytes)) {
58
+        /* fast lane: whole lane rate */
59
+
60
+        size_t j;
61
+        j = SnP_FastLoop_Absorb(state, rateInBytes/(SnP_width/200), curInput, inputByteLen);
62
+        curInput += j;
63
+        inputByteLen -= j;
64
+    }
65
+#endif
66
+    while(inputByteLen >= (size_t)rateInBytes) {
67
+        #ifdef KeccakReference
68
+        displayBytes(1, "Block to be absorbed", curInput, rateInBytes);
69
+        #endif
70
+        SnP_AddBytes(state, curInput, 0, rateInBytes);
71
+        SnP_Permute(state);
72
+        curInput += rateInBytes;
73
+        inputByteLen -= rateInBytes;
74
+    }
75
+
76
+    /* Then, absorb what remains */
77
+
78
+    partialBlock = (unsigned int)inputByteLen;
79
+    #ifdef KeccakReference
80
+    displayBytes(1, "Block to be absorbed (part)", curInput, partialBlock);
81
+    #endif
82
+    SnP_AddBytes(state, curInput, 0, partialBlock);
83
+
84
+    /* Finally, absorb the suffix */
85
+
86
+    #ifdef KeccakReference
87
+    {
88
+        unsigned char delimitedData1[1];
89
+        delimitedData1[0] = suffix;
90
+        displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1);
91
+    }
92
+    #endif
93
+    /* Last few bits, whose delimiter coincides with first bit of padding */
94
+
95
+    SnP_AddByte(state, suffix, partialBlock);
96
+    /* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */
97
+
98
+    if ((suffix >= 0x80) && (partialBlock == (rateInBytes-1)))
99
+        SnP_Permute(state);
100
+    /* Second bit of padding */
101
+
102
+    SnP_AddByte(state, 0x80, rateInBytes-1);
103
+    #ifdef KeccakReference
104
+    {
105
+        unsigned char block[SnP_width/8];
106
+        memset(block, 0, SnP_width/8);
107
+        block[rateInBytes-1] = 0x80;
108
+        displayBytes(1, "Second bit of padding", block, rateInBytes);
109
+    }
110
+    #endif
111
+    SnP_Permute(state);
112
+    #ifdef KeccakReference
113
+    displayText(1, "--- Switching to squeezing phase ---");
114
+    #endif
115
+
116
+    /* First, output whole blocks */
117
+
118
+    while(outputByteLen > (size_t)rateInBytes) {
119
+        SnP_ExtractBytes(state, curOutput, 0, rateInBytes);
120
+        SnP_Permute(state);
121
+        #ifdef KeccakReference
122
+        displayBytes(1, "Squeezed block", curOutput, rateInBytes);
123
+        #endif
124
+        curOutput += rateInBytes;
125
+        outputByteLen -= rateInBytes;
126
+    }
127
+
128
+    /* Finally, output what remains */
129
+
130
+    partialBlock = (unsigned int)outputByteLen;
131
+    SnP_ExtractBytes(state, curOutput, 0, partialBlock);
132
+    #ifdef KeccakReference
133
+    displayBytes(1, "Squeezed block (part)", curOutput, partialBlock);
134
+    #endif
135
+
136
+    return 0;
137
+}
138
+
139
+/* ---------------------------------------------------------------- */
140
+/* ---------------------------------------------------------------- */
141
+/* ---------------------------------------------------------------- */
142
+
143
+int SpongeInitialize(SpongeInstance *instance, unsigned int rate, unsigned int capacity)
144
+{
145
+    if (rate+capacity != SnP_width)
146
+        return 1;
147
+    if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0))
148
+        return 1;
149
+    SnP_StaticInitialize();
150
+    SnP_Initialize(instance->state);
151
+    instance->rate = rate;
152
+    instance->byteIOIndex = 0;
153
+    instance->squeezing = 0;
154
+
155
+    return 0;
156
+}
157
+
158
+/* ---------------------------------------------------------------- */
159
+
160
+int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dataByteLen)
161
+{
162
+    size_t i, j;
163
+    unsigned int partialBlock;
164
+    const unsigned char *curData;
165
+    unsigned int rateInBytes = instance->rate/8;
166
+
167
+    if (instance->squeezing)
168
+        return 1; /* Too late for additional input */
169
+
170
+
171
+    i = 0;
172
+    curData = data;
173
+    while(i < dataByteLen) {
174
+        if ((instance->byteIOIndex == 0) && (dataByteLen >= (i + rateInBytes))) {
175
+#ifdef SnP_FastLoop_Absorb
176
+            /* processing full blocks first */
177
+
178
+            if ((rateInBytes % (SnP_width/200)) == 0) {
179
+                /* fast lane: whole lane rate */
180
+
181
+                j = SnP_FastLoop_Absorb(instance->state, rateInBytes/(SnP_width/200), curData, dataByteLen - i);
182
+                i += j;
183
+                curData += j;
184
+            }
185
+            else {
186
+#endif
187
+                for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) {
188
+                    #ifdef KeccakReference
189
+                    displayBytes(1, "Block to be absorbed", curData, rateInBytes);
190
+                    #endif
191
+                    SnP_AddBytes(instance->state, curData, 0, rateInBytes);
192
+                    SnP_Permute(instance->state);
193
+                    curData+=rateInBytes;
194
+                }
195
+                i = dataByteLen - j;
196
+#ifdef SnP_FastLoop_Absorb
197
+            }
198
+#endif
199
+        }
200
+        else {
201
+            /* normal lane: using the message queue */
202
+
203
+            partialBlock = (unsigned int)(dataByteLen - i);
204
+            if (partialBlock+instance->byteIOIndex > rateInBytes)
205
+                partialBlock = rateInBytes-instance->byteIOIndex;
206
+            #ifdef KeccakReference
207
+            displayBytes(1, "Block to be absorbed (part)", curData, partialBlock);
208
+            #endif
209
+            i += partialBlock;
210
+
211
+            SnP_AddBytes(instance->state, curData, instance->byteIOIndex, partialBlock);
212
+            curData += partialBlock;
213
+            instance->byteIOIndex += partialBlock;
214
+            if (instance->byteIOIndex == rateInBytes) {
215
+                SnP_Permute(instance->state);
216
+                instance->byteIOIndex = 0;
217
+            }
218
+        }
219
+    }
220
+    return 0;
221
+}
222
+
223
+/* ---------------------------------------------------------------- */
224
+
225
+int SpongeAbsorbLastFewBits(SpongeInstance *instance, unsigned char delimitedData)
226
+{
227
+    unsigned int rateInBytes = instance->rate/8;
228
+
229
+    if (delimitedData == 0)
230
+        return 1;
231
+    if (instance->squeezing)
232
+        return 1; /* Too late for additional input */
233
+
234
+
235
+    #ifdef KeccakReference
236
+    {
237
+        unsigned char delimitedData1[1];
238
+        delimitedData1[0] = delimitedData;
239
+        displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1);
240
+    }
241
+    #endif
242
+    /* Last few bits, whose delimiter coincides with first bit of padding */
243
+
244
+    SnP_AddByte(instance->state, delimitedData, instance->byteIOIndex);
245
+    /* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */
246
+
247
+    if ((delimitedData >= 0x80) && (instance->byteIOIndex == (rateInBytes-1)))
248
+        SnP_Permute(instance->state);
249
+    /* Second bit of padding */
250
+
251
+    SnP_AddByte(instance->state, 0x80, rateInBytes-1);
252
+    #ifdef KeccakReference
253
+    {
254
+        unsigned char block[SnP_width/8];
255
+        memset(block, 0, SnP_width/8);
256
+        block[rateInBytes-1] = 0x80;
257
+        displayBytes(1, "Second bit of padding", block, rateInBytes);
258
+    }
259
+    #endif
260
+    SnP_Permute(instance->state);
261
+    instance->byteIOIndex = 0;
262
+    instance->squeezing = 1;
263
+    #ifdef KeccakReference
264
+    displayText(1, "--- Switching to squeezing phase ---");
265
+    #endif
266
+    return 0;
267
+}
268
+
269
+/* ---------------------------------------------------------------- */
270
+
271
+int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByteLen)
272
+{
273
+    size_t i, j;
274
+    unsigned int partialBlock;
275
+    unsigned int rateInBytes = instance->rate/8;
276
+    unsigned char *curData;
277
+
278
+    if (!instance->squeezing)
279
+        SpongeAbsorbLastFewBits(instance, 0x01);
280
+
281
+    i = 0;
282
+    curData = data;
283
+    while(i < dataByteLen) {
284
+        if ((instance->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) {
285
+            for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) {
286
+                SnP_Permute(instance->state);
287
+                SnP_ExtractBytes(instance->state, curData, 0, rateInBytes);
288
+                #ifdef KeccakReference
289
+                displayBytes(1, "Squeezed block", curData, rateInBytes);
290
+                #endif
291
+                curData+=rateInBytes;
292
+            }
293
+            i = dataByteLen - j;
294
+        }
295
+        else {
296
+            /* normal lane: using the message queue */
297
+
298
+            if (instance->byteIOIndex == rateInBytes) {
299
+                SnP_Permute(instance->state);
300
+                instance->byteIOIndex = 0;
301
+            }
302
+            partialBlock = (unsigned int)(dataByteLen - i);
303
+            if (partialBlock+instance->byteIOIndex > rateInBytes)
304
+                partialBlock = rateInBytes-instance->byteIOIndex;
305
+            i += partialBlock;
306
+
307
+            SnP_ExtractBytes(instance->state, curData, instance->byteIOIndex, partialBlock);
308
+            #ifdef KeccakReference
309
+            displayBytes(1, "Squeezed block (part)", curData, partialBlock);
310
+            #endif
311
+            curData += partialBlock;
312
+            instance->byteIOIndex += partialBlock;
313
+        }
314
+    }
315
+    return 0;
316
+}
317
+
318
+/* ---------------------------------------------------------------- */
319
+
320
+#undef Sponge
321
+#undef SpongeInstance
322
+#undef SpongeInitialize
323
+#undef SpongeAbsorb
324
+#undef SpongeAbsorbLastFewBits
325
+#undef SpongeSqueeze
326
+#undef SnP_stateSizeInBytes
327
+#undef SnP_stateAlignment
328
+#undef SnP_StaticInitialize
329
+#undef SnP_Initialize
330
+#undef SnP_AddByte
331
+#undef SnP_AddBytes
332
+#undef SnP_ExtractBytes