Coverage Report

Created: 2025-06-13 06:43

/src/php-src/ext/hash/sha3/generic64lc/KeccakSponge.inc
Line
Count
Source (jump to first uncovered line)
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
537
#define JOIN0(a, b)                     a ## b
17
537
#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
0
#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
147
#define SnP_Initialize                  JOIN(SnP, _Initialize)
30
186
#define SnP_AddByte                     JOIN(SnP, _AddByte)
31
111
#define SnP_AddBytes                    JOIN(SnP, _AddBytes)
32
93
#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
0
{
36
0
    ALIGN(SnP_stateAlignment) unsigned char state[SnP_stateSizeInBytes];
37
0
    unsigned int partialBlock;
38
0
    const unsigned char *curInput = input;
39
0
    unsigned char *curOutput = output;
40
0
    unsigned int rateInBytes = rate/8;
41
42
0
    if (rate+capacity != SnP_width)
43
0
        return 1;
44
0
    if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0))
45
0
        return 1;
46
0
    if (suffix == 0)
47
0
        return 1;
48
49
    /* Initialize the state */
50
0
    SnP_StaticInitialize();
51
0
    SnP_Initialize(state);
52
53
    /* First, absorb whole blocks */
54
#ifdef SnP_FastLoop_Absorb
55
0
    if (((rateInBytes % (SnP_width/200)) == 0) && (inputByteLen >= rateInBytes)) {
56
        /* fast lane: whole lane rate */
57
0
        size_t j;
58
0
        j = SnP_FastLoop_Absorb(state, rateInBytes/(SnP_width/200), curInput, inputByteLen);
59
0
        curInput += j;
60
0
        inputByteLen -= j;
61
0
    }
62
#endif
63
0
    while(inputByteLen >= (size_t)rateInBytes) {
64
        #ifdef KeccakReference
65
        displayBytes(1, "Block to be absorbed", curInput, rateInBytes);
66
        #endif
67
0
        SnP_AddBytes(state, curInput, 0, rateInBytes);
68
0
        SnP_Permute(state);
69
0
        curInput += rateInBytes;
70
0
        inputByteLen -= rateInBytes;
71
0
    }
72
73
    /* Then, absorb what remains */
74
0
    partialBlock = (unsigned int)inputByteLen;
75
    #ifdef KeccakReference
76
    displayBytes(1, "Block to be absorbed (part)", curInput, partialBlock);
77
    #endif
78
0
    SnP_AddBytes(state, curInput, 0, partialBlock);
79
80
    /* Finally, absorb the suffix */
81
    #ifdef KeccakReference
82
    {
83
        unsigned char delimitedData1[1];
84
        delimitedData1[0] = suffix;
85
        displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1);
86
    }
87
    #endif
88
    /* Last few bits, whose delimiter coincides with first bit of padding */
89
0
    SnP_AddByte(state, suffix, partialBlock);
90
    /* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */
91
0
    if ((suffix >= 0x80) && (partialBlock == (rateInBytes-1)))
92
0
        SnP_Permute(state);
93
    /* Second bit of padding */
94
0
    SnP_AddByte(state, 0x80, rateInBytes-1);
95
    #ifdef KeccakReference
96
    {
97
        unsigned char block[SnP_width/8];
98
        memset(block, 0, SnP_width/8);
99
        block[rateInBytes-1] = 0x80;
100
        displayBytes(1, "Second bit of padding", block, rateInBytes);
101
    }
102
    #endif
103
0
    SnP_Permute(state);
104
    #ifdef KeccakReference
105
    displayText(1, "--- Switching to squeezing phase ---");
106
    #endif
107
108
    /* First, output whole blocks */
109
0
    while(outputByteLen > (size_t)rateInBytes) {
110
0
        SnP_ExtractBytes(state, curOutput, 0, rateInBytes);
111
0
        SnP_Permute(state);
112
        #ifdef KeccakReference
113
        displayBytes(1, "Squeezed block", curOutput, rateInBytes);
114
        #endif
115
0
        curOutput += rateInBytes;
116
0
        outputByteLen -= rateInBytes;
117
0
    }
118
119
    /* Finally, output what remains */
120
0
    partialBlock = (unsigned int)outputByteLen;
121
0
    SnP_ExtractBytes(state, curOutput, 0, partialBlock);
122
    #ifdef KeccakReference
123
    displayBytes(1, "Squeezed block (part)", curOutput, partialBlock);
124
    #endif
125
126
0
    return 0;
127
0
}
Unexecuted instantiation: KeccakWidth1600_Sponge
Unexecuted instantiation: KeccakWidth1600_12rounds_Sponge
128
129
/* ---------------------------------------------------------------- */
130
/* ---------------------------------------------------------------- */
131
/* ---------------------------------------------------------------- */
132
133
int SpongeInitialize(SpongeInstance *instance, unsigned int rate, unsigned int capacity)
134
147
{
135
147
    if (rate+capacity != SnP_width)
136
0
        return 1;
137
147
    if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0))
138
0
        return 1;
139
147
    SnP_StaticInitialize();
140
147
    SnP_Initialize(instance->state);
141
147
    instance->rate = rate;
142
147
    instance->byteIOIndex = 0;
143
147
    instance->squeezing = 0;
144
145
147
    return 0;
146
147
}
KeccakWidth1600_SpongeInitialize
Line
Count
Source
134
147
{
135
147
    if (rate+capacity != SnP_width)
136
0
        return 1;
137
147
    if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0))
138
0
        return 1;
139
147
    SnP_StaticInitialize();
140
147
    SnP_Initialize(instance->state);
141
147
    instance->rate = rate;
142
147
    instance->byteIOIndex = 0;
143
147
    instance->squeezing = 0;
144
145
147
    return 0;
146
147
}
Unexecuted instantiation: KeccakWidth1600_12rounds_SpongeInitialize
147
148
/* ---------------------------------------------------------------- */
149
150
int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dataByteLen)
151
93
{
152
93
    size_t i, j;
153
93
    unsigned int partialBlock;
154
93
    const unsigned char *curData;
155
93
    unsigned int rateInBytes = instance->rate/8;
156
157
93
    if (instance->squeezing)
158
0
        return 1; /* Too late for additional input */
159
160
93
    i = 0;
161
93
    curData = data;
162
270
    while(i < dataByteLen) {
163
177
        if ((instance->byteIOIndex == 0) && (dataByteLen-i >= rateInBytes)) {
164
#ifdef SnP_FastLoop_Absorb
165
            /* processing full blocks first */
166
66
            if ((rateInBytes % (SnP_width/200)) == 0) {
167
                /* fast lane: whole lane rate */
168
66
                j = SnP_FastLoop_Absorb(instance->state, rateInBytes/(SnP_width/200), curData, dataByteLen - i);
169
66
                i += j;
170
66
                curData += j;
171
66
            }
172
0
            else {
173
0
#endif
174
0
                for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) {
175
                    #ifdef KeccakReference
176
                    displayBytes(1, "Block to be absorbed", curData, rateInBytes);
177
                    #endif
178
0
                    SnP_AddBytes(instance->state, curData, 0, rateInBytes);
179
0
                    SnP_Permute(instance->state);
180
0
                    curData+=rateInBytes;
181
0
                }
182
0
                i = dataByteLen - j;
183
#ifdef SnP_FastLoop_Absorb
184
            }
185
#endif
186
66
        }
187
111
        else {
188
            /* normal lane: using the message queue */
189
111
            if (dataByteLen-i > rateInBytes-instance->byteIOIndex)
190
52
                partialBlock = rateInBytes-instance->byteIOIndex;
191
59
            else
192
59
                partialBlock = (unsigned int)(dataByteLen - i);
193
            #ifdef KeccakReference
194
            displayBytes(1, "Block to be absorbed (part)", curData, partialBlock);
195
            #endif
196
111
            i += partialBlock;
197
198
111
            SnP_AddBytes(instance->state, curData, instance->byteIOIndex, partialBlock);
199
111
            curData += partialBlock;
200
111
            instance->byteIOIndex += partialBlock;
201
111
            if (instance->byteIOIndex == rateInBytes) {
202
52
                SnP_Permute(instance->state);
203
52
                instance->byteIOIndex = 0;
204
52
            }
205
111
        }
206
177
    }
207
93
    return 0;
208
93
}
KeccakWidth1600_SpongeAbsorb
Line
Count
Source
151
93
{
152
93
    size_t i, j;
153
93
    unsigned int partialBlock;
154
93
    const unsigned char *curData;
155
93
    unsigned int rateInBytes = instance->rate/8;
156
157
93
    if (instance->squeezing)
158
0
        return 1; /* Too late for additional input */
159
160
93
    i = 0;
161
93
    curData = data;
162
270
    while(i < dataByteLen) {
163
177
        if ((instance->byteIOIndex == 0) && (dataByteLen-i >= rateInBytes)) {
164
66
#ifdef SnP_FastLoop_Absorb
165
            /* processing full blocks first */
166
66
            if ((rateInBytes % (SnP_width/200)) == 0) {
167
                /* fast lane: whole lane rate */
168
66
                j = SnP_FastLoop_Absorb(instance->state, rateInBytes/(SnP_width/200), curData, dataByteLen - i);
169
66
                i += j;
170
66
                curData += j;
171
66
            }
172
0
            else {
173
0
#endif
174
0
                for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) {
175
                    #ifdef KeccakReference
176
                    displayBytes(1, "Block to be absorbed", curData, rateInBytes);
177
                    #endif
178
0
                    SnP_AddBytes(instance->state, curData, 0, rateInBytes);
179
0
                    SnP_Permute(instance->state);
180
0
                    curData+=rateInBytes;
181
0
                }
182
0
                i = dataByteLen - j;
183
0
#ifdef SnP_FastLoop_Absorb
184
0
            }
185
66
#endif
186
66
        }
187
111
        else {
188
            /* normal lane: using the message queue */
189
111
            if (dataByteLen-i > rateInBytes-instance->byteIOIndex)
190
52
                partialBlock = rateInBytes-instance->byteIOIndex;
191
59
            else
192
59
                partialBlock = (unsigned int)(dataByteLen - i);
193
            #ifdef KeccakReference
194
            displayBytes(1, "Block to be absorbed (part)", curData, partialBlock);
195
            #endif
196
111
            i += partialBlock;
197
198
111
            SnP_AddBytes(instance->state, curData, instance->byteIOIndex, partialBlock);
199
111
            curData += partialBlock;
200
111
            instance->byteIOIndex += partialBlock;
201
111
            if (instance->byteIOIndex == rateInBytes) {
202
52
                SnP_Permute(instance->state);
203
52
                instance->byteIOIndex = 0;
204
52
            }
205
111
        }
206
177
    }
207
93
    return 0;
208
93
}
Unexecuted instantiation: KeccakWidth1600_12rounds_SpongeAbsorb
209
210
/* ---------------------------------------------------------------- */
211
212
int SpongeAbsorbLastFewBits(SpongeInstance *instance, unsigned char delimitedData)
213
93
{
214
93
    unsigned int rateInBytes = instance->rate/8;
215
216
93
    if (delimitedData == 0)
217
0
        return 1;
218
93
    if (instance->squeezing)
219
0
        return 1; /* Too late for additional input */
220
221
    #ifdef KeccakReference
222
    {
223
        unsigned char delimitedData1[1];
224
        delimitedData1[0] = delimitedData;
225
        displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1);
226
    }
227
    #endif
228
    /* Last few bits, whose delimiter coincides with first bit of padding */
229
93
    SnP_AddByte(instance->state, delimitedData, instance->byteIOIndex);
230
    /* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */
231
93
    if ((delimitedData >= 0x80) && (instance->byteIOIndex == (rateInBytes-1)))
232
0
        SnP_Permute(instance->state);
233
    /* Second bit of padding */
234
93
    SnP_AddByte(instance->state, 0x80, rateInBytes-1);
235
    #ifdef KeccakReference
236
    {
237
        unsigned char block[SnP_width/8];
238
        memset(block, 0, SnP_width/8);
239
        block[rateInBytes-1] = 0x80;
240
        displayBytes(1, "Second bit of padding", block, rateInBytes);
241
    }
242
    #endif
243
93
    SnP_Permute(instance->state);
244
93
    instance->byteIOIndex = 0;
245
93
    instance->squeezing = 1;
246
    #ifdef KeccakReference
247
    displayText(1, "--- Switching to squeezing phase ---");
248
    #endif
249
93
    return 0;
250
93
}
KeccakWidth1600_SpongeAbsorbLastFewBits
Line
Count
Source
213
93
{
214
93
    unsigned int rateInBytes = instance->rate/8;
215
216
93
    if (delimitedData == 0)
217
0
        return 1;
218
93
    if (instance->squeezing)
219
0
        return 1; /* Too late for additional input */
220
221
    #ifdef KeccakReference
222
    {
223
        unsigned char delimitedData1[1];
224
        delimitedData1[0] = delimitedData;
225
        displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1);
226
    }
227
    #endif
228
    /* Last few bits, whose delimiter coincides with first bit of padding */
229
93
    SnP_AddByte(instance->state, delimitedData, instance->byteIOIndex);
230
    /* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */
231
93
    if ((delimitedData >= 0x80) && (instance->byteIOIndex == (rateInBytes-1)))
232
0
        SnP_Permute(instance->state);
233
    /* Second bit of padding */
234
93
    SnP_AddByte(instance->state, 0x80, rateInBytes-1);
235
    #ifdef KeccakReference
236
    {
237
        unsigned char block[SnP_width/8];
238
        memset(block, 0, SnP_width/8);
239
        block[rateInBytes-1] = 0x80;
240
        displayBytes(1, "Second bit of padding", block, rateInBytes);
241
    }
242
    #endif
243
93
    SnP_Permute(instance->state);
244
93
    instance->byteIOIndex = 0;
245
93
    instance->squeezing = 1;
246
    #ifdef KeccakReference
247
    displayText(1, "--- Switching to squeezing phase ---");
248
    #endif
249
93
    return 0;
250
93
}
Unexecuted instantiation: KeccakWidth1600_12rounds_SpongeAbsorbLastFewBits
251
252
/* ---------------------------------------------------------------- */
253
254
int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByteLen)
255
93
{
256
93
    size_t i, j;
257
93
    unsigned int partialBlock;
258
93
    unsigned int rateInBytes = instance->rate/8;
259
93
    unsigned char *curData;
260
261
93
    if (!instance->squeezing)
262
0
        SpongeAbsorbLastFewBits(instance, 0x01);
263
264
93
    i = 0;
265
93
    curData = data;
266
186
    while(i < dataByteLen) {
267
93
        if ((instance->byteIOIndex == rateInBytes) && (dataByteLen-i >= rateInBytes)) {
268
0
            for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) {
269
0
                SnP_Permute(instance->state);
270
0
                SnP_ExtractBytes(instance->state, curData, 0, rateInBytes);
271
                #ifdef KeccakReference
272
                displayBytes(1, "Squeezed block", curData, rateInBytes);
273
                #endif
274
0
                curData+=rateInBytes;
275
0
            }
276
0
            i = dataByteLen - j;
277
0
        }
278
93
        else {
279
            /* normal lane: using the message queue */
280
93
            if (instance->byteIOIndex == rateInBytes) {
281
0
                SnP_Permute(instance->state);
282
0
                instance->byteIOIndex = 0;
283
0
            }
284
93
            if (dataByteLen-i > rateInBytes-instance->byteIOIndex)
285
0
                partialBlock = rateInBytes-instance->byteIOIndex;
286
93
            else
287
93
                partialBlock = (unsigned int)(dataByteLen - i);
288
93
            i += partialBlock;
289
290
93
            SnP_ExtractBytes(instance->state, curData, instance->byteIOIndex, partialBlock);
291
            #ifdef KeccakReference
292
            displayBytes(1, "Squeezed block (part)", curData, partialBlock);
293
            #endif
294
93
            curData += partialBlock;
295
93
            instance->byteIOIndex += partialBlock;
296
93
        }
297
93
    }
298
93
    return 0;
299
93
}
KeccakWidth1600_SpongeSqueeze
Line
Count
Source
255
93
{
256
93
    size_t i, j;
257
93
    unsigned int partialBlock;
258
93
    unsigned int rateInBytes = instance->rate/8;
259
93
    unsigned char *curData;
260
261
93
    if (!instance->squeezing)
262
0
        SpongeAbsorbLastFewBits(instance, 0x01);
263
264
93
    i = 0;
265
93
    curData = data;
266
186
    while(i < dataByteLen) {
267
93
        if ((instance->byteIOIndex == rateInBytes) && (dataByteLen-i >= rateInBytes)) {
268
0
            for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) {
269
0
                SnP_Permute(instance->state);
270
0
                SnP_ExtractBytes(instance->state, curData, 0, rateInBytes);
271
                #ifdef KeccakReference
272
                displayBytes(1, "Squeezed block", curData, rateInBytes);
273
                #endif
274
0
                curData+=rateInBytes;
275
0
            }
276
0
            i = dataByteLen - j;
277
0
        }
278
93
        else {
279
            /* normal lane: using the message queue */
280
93
            if (instance->byteIOIndex == rateInBytes) {
281
0
                SnP_Permute(instance->state);
282
0
                instance->byteIOIndex = 0;
283
0
            }
284
93
            if (dataByteLen-i > rateInBytes-instance->byteIOIndex)
285
0
                partialBlock = rateInBytes-instance->byteIOIndex;
286
93
            else
287
93
                partialBlock = (unsigned int)(dataByteLen - i);
288
93
            i += partialBlock;
289
290
93
            SnP_ExtractBytes(instance->state, curData, instance->byteIOIndex, partialBlock);
291
            #ifdef KeccakReference
292
            displayBytes(1, "Squeezed block (part)", curData, partialBlock);
293
            #endif
294
93
            curData += partialBlock;
295
93
            instance->byteIOIndex += partialBlock;
296
93
        }
297
93
    }
298
93
    return 0;
299
93
}
Unexecuted instantiation: KeccakWidth1600_12rounds_SpongeSqueeze
300
301
/* ---------------------------------------------------------------- */
302
303
#undef Sponge
304
#undef SpongeInstance
305
#undef SpongeInitialize
306
#undef SpongeAbsorb
307
#undef SpongeAbsorbLastFewBits
308
#undef SpongeSqueeze
309
#undef SnP_stateSizeInBytes
310
#undef SnP_stateAlignment
311
#undef SnP_StaticInitialize
312
#undef SnP_Initialize
313
#undef SnP_AddByte
314
#undef SnP_AddBytes
315
#undef SnP_ExtractBytes