»Core Development>Code coverage>Modules/_sha3/keccak/KeccakSponge.c

Python code coverage for Modules/_sha3/keccak/KeccakSponge.c

#countcontent
1n/a/*
2n/aThe Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
3n/aMichaël Peeters and Gilles Van Assche. For more information, feedback or
4n/aquestions, please refer to our website: http://keccak.noekeon.org/
5n/a
6n/aImplementation by the designers,
7n/ahereby denoted as "the implementer".
8n/a
9n/aTo the extent possible under law, the implementer has waived all copyright
10n/aand related or neighboring rights to the source code in this file.
11n/ahttp://creativecommons.org/publicdomain/zero/1.0/
12n/a*/
13n/a
14n/a#include <string.h>
15n/a#include "KeccakSponge.h"
16n/a#include "KeccakF-1600-interface.h"
17n/a#ifdef KeccakReference
18n/a#include "displayIntermediateValues.h"
19n/a#endif
20n/a
21n/astatic int InitSponge(spongeState *state, unsigned int rate, unsigned int capacity)
22n/a{
23n/a if (rate+capacity != 1600)
24n/a return 1;
25n/a if ((rate <= 0) || (rate >= 1600) || ((rate % 64) != 0))
26n/a return 1;
27n/a KeccakInitialize();
28n/a state->rate = rate;
29n/a state->capacity = capacity;
30n/a state->fixedOutputLength = 0;
31n/a KeccakInitializeState(state->state);
32n/a memset(state->dataQueue, 0, KeccakMaximumRateInBytes);
33n/a state->bitsInQueue = 0;
34n/a state->squeezing = 0;
35n/a state->bitsAvailableForSqueezing = 0;
36n/a
37n/a return 0;
38n/a}
39n/a
40n/astatic void AbsorbQueue(spongeState *state)
41n/a{
42n/a /* state->bitsInQueue is assumed to be equal to state->rate */
43n/a #ifdef KeccakReference
44n/a displayBytes(1, "Block to be absorbed", state->dataQueue, state->rate/8);
45n/a #endif
46n/a#ifdef ProvideFast576
47n/a if (state->rate == 576)
48n/a KeccakAbsorb576bits(state->state, state->dataQueue);
49n/a else
50n/a#endif
51n/a#ifdef ProvideFast832
52n/a if (state->rate == 832)
53n/a KeccakAbsorb832bits(state->state, state->dataQueue);
54n/a else
55n/a#endif
56n/a#ifdef ProvideFast1024
57n/a if (state->rate == 1024)
58n/a KeccakAbsorb1024bits(state->state, state->dataQueue);
59n/a else
60n/a#endif
61n/a#ifdef ProvideFast1088
62n/a if (state->rate == 1088)
63n/a KeccakAbsorb1088bits(state->state, state->dataQueue);
64n/a else
65n/a#endif
66n/a#ifdef ProvideFast1152
67n/a if (state->rate == 1152)
68n/a KeccakAbsorb1152bits(state->state, state->dataQueue);
69n/a else
70n/a#endif
71n/a#ifdef ProvideFast1344
72n/a if (state->rate == 1344)
73n/a KeccakAbsorb1344bits(state->state, state->dataQueue);
74n/a else
75n/a#endif
76n/a KeccakAbsorb(state->state, state->dataQueue, state->rate/64);
77n/a state->bitsInQueue = 0;
78n/a}
79n/a
80n/astatic int Absorb(spongeState *state, const unsigned char *data, unsigned long long databitlen)
81n/a{
82n/a unsigned long long i, j, wholeBlocks;
83n/a unsigned int partialBlock, partialByte;
84n/a const unsigned char *curData;
85n/a
86n/a if ((state->bitsInQueue % 8) != 0)
87n/a return 1; /* Only the last call may contain a partial byte */
88n/a if (state->squeezing)
89n/a return 1; /* Too late for additional input */
90n/a
91n/a i = 0;
92n/a while(i < databitlen) {
93n/a if ((state->bitsInQueue == 0) && (databitlen >= state->rate) && (i <= (databitlen-state->rate))) {
94n/a wholeBlocks = (databitlen-i)/state->rate;
95n/a curData = data+i/8;
96n/a#ifdef ProvideFast576
97n/a if (state->rate == 576) {
98n/a for(j=0; j<wholeBlocks; j++, curData+=576/8) {
99n/a #ifdef KeccakReference
100n/a displayBytes(1, "Block to be absorbed", curData, state->rate/8);
101n/a #endif
102n/a KeccakAbsorb576bits(state->state, curData);
103n/a }
104n/a }
105n/a else
106n/a#endif
107n/a#ifdef ProvideFast832
108n/a if (state->rate == 832) {
109n/a for(j=0; j<wholeBlocks; j++, curData+=832/8) {
110n/a #ifdef KeccakReference
111n/a displayBytes(1, "Block to be absorbed", curData, state->rate/8);
112n/a #endif
113n/a KeccakAbsorb832bits(state->state, curData);
114n/a }
115n/a }
116n/a else
117n/a#endif
118n/a#ifdef ProvideFast1024
119n/a if (state->rate == 1024) {
120n/a for(j=0; j<wholeBlocks; j++, curData+=1024/8) {
121n/a #ifdef KeccakReference
122n/a displayBytes(1, "Block to be absorbed", curData, state->rate/8);
123n/a #endif
124n/a KeccakAbsorb1024bits(state->state, curData);
125n/a }
126n/a }
127n/a else
128n/a#endif
129n/a#ifdef ProvideFast1088
130n/a if (state->rate == 1088) {
131n/a for(j=0; j<wholeBlocks; j++, curData+=1088/8) {
132n/a #ifdef KeccakReference
133n/a displayBytes(1, "Block to be absorbed", curData, state->rate/8);
134n/a #endif
135n/a KeccakAbsorb1088bits(state->state, curData);
136n/a }
137n/a }
138n/a else
139n/a#endif
140n/a#ifdef ProvideFast1152
141n/a if (state->rate == 1152) {
142n/a for(j=0; j<wholeBlocks; j++, curData+=1152/8) {
143n/a #ifdef KeccakReference
144n/a displayBytes(1, "Block to be absorbed", curData, state->rate/8);
145n/a #endif
146n/a KeccakAbsorb1152bits(state->state, curData);
147n/a }
148n/a }
149n/a else
150n/a#endif
151n/a#ifdef ProvideFast1344
152n/a if (state->rate == 1344) {
153n/a for(j=0; j<wholeBlocks; j++, curData+=1344/8) {
154n/a #ifdef KeccakReference
155n/a displayBytes(1, "Block to be absorbed", curData, state->rate/8);
156n/a #endif
157n/a KeccakAbsorb1344bits(state->state, curData);
158n/a }
159n/a }
160n/a else
161n/a#endif
162n/a {
163n/a for(j=0; j<wholeBlocks; j++, curData+=state->rate/8) {
164n/a #ifdef KeccakReference
165n/a displayBytes(1, "Block to be absorbed", curData, state->rate/8);
166n/a #endif
167n/a KeccakAbsorb(state->state, curData, state->rate/64);
168n/a }
169n/a }
170n/a i += wholeBlocks*state->rate;
171n/a }
172n/a else {
173n/a partialBlock = (unsigned int)(databitlen - i);
174n/a if (partialBlock+state->bitsInQueue > state->rate)
175n/a partialBlock = state->rate-state->bitsInQueue;
176n/a partialByte = partialBlock % 8;
177n/a partialBlock -= partialByte;
178n/a memcpy(state->dataQueue+state->bitsInQueue/8, data+i/8, partialBlock/8);
179n/a state->bitsInQueue += partialBlock;
180n/a i += partialBlock;
181n/a if (state->bitsInQueue == state->rate)
182n/a AbsorbQueue(state);
183n/a if (partialByte > 0) {
184n/a unsigned char mask = (1 << partialByte)-1;
185n/a state->dataQueue[state->bitsInQueue/8] = data[i/8] & mask;
186n/a state->bitsInQueue += partialByte;
187n/a i += partialByte;
188n/a }
189n/a }
190n/a }
191n/a return 0;
192n/a}
193n/a
194n/astatic void PadAndSwitchToSqueezingPhase(spongeState *state)
195n/a{
196n/a /* Note: the bits are numbered from 0=LSB to 7=MSB */
197n/a if (state->bitsInQueue + 1 == state->rate) {
198n/a state->dataQueue[state->bitsInQueue/8 ] |= 1 << (state->bitsInQueue % 8);
199n/a AbsorbQueue(state);
200n/a memset(state->dataQueue, 0, state->rate/8);
201n/a }
202n/a else {
203n/a memset(state->dataQueue + (state->bitsInQueue+7)/8, 0, state->rate/8 - (state->bitsInQueue+7)/8);
204n/a state->dataQueue[state->bitsInQueue/8 ] |= 1 << (state->bitsInQueue % 8);
205n/a }
206n/a state->dataQueue[(state->rate-1)/8] |= 1 << ((state->rate-1) % 8);
207n/a AbsorbQueue(state);
208n/a
209n/a #ifdef KeccakReference
210n/a displayText(1, "--- Switching to squeezing phase ---");
211n/a #endif
212n/a#ifdef ProvideFast1024
213n/a if (state->rate == 1024) {
214n/a KeccakExtract1024bits(state->state, state->dataQueue);
215n/a state->bitsAvailableForSqueezing = 1024;
216n/a }
217n/a else
218n/a#endif
219n/a {
220n/a KeccakExtract(state->state, state->dataQueue, state->rate/64);
221n/a state->bitsAvailableForSqueezing = state->rate;
222n/a }
223n/a #ifdef KeccakReference
224n/a displayBytes(1, "Block available for squeezing", state->dataQueue, state->bitsAvailableForSqueezing/8);
225n/a #endif
226n/a state->squeezing = 1;
227n/a}
228n/a
229n/astatic int Squeeze(spongeState *state, unsigned char *output, unsigned long long outputLength)
230n/a{
231n/a unsigned long long i;
232n/a unsigned int partialBlock;
233n/a
234n/a if (!state->squeezing)
235n/a PadAndSwitchToSqueezingPhase(state);
236n/a if ((outputLength % 8) != 0)
237n/a return 1; /* Only multiple of 8 bits are allowed, truncation can be done at user level */
238n/a
239n/a i = 0;
240n/a while(i < outputLength) {
241n/a if (state->bitsAvailableForSqueezing == 0) {
242n/a KeccakPermutation(state->state);
243n/a#ifdef ProvideFast1024
244n/a if (state->rate == 1024) {
245n/a KeccakExtract1024bits(state->state, state->dataQueue);
246n/a state->bitsAvailableForSqueezing = 1024;
247n/a }
248n/a else
249n/a#endif
250n/a {
251n/a KeccakExtract(state->state, state->dataQueue, state->rate/64);
252n/a state->bitsAvailableForSqueezing = state->rate;
253n/a }
254n/a #ifdef KeccakReference
255n/a displayBytes(1, "Block available for squeezing", state->dataQueue, state->bitsAvailableForSqueezing/8);
256n/a #endif
257n/a }
258n/a partialBlock = state->bitsAvailableForSqueezing;
259n/a if ((unsigned long long)partialBlock > outputLength - i)
260n/a partialBlock = (unsigned int)(outputLength - i);
261n/a memcpy(output+i/8, state->dataQueue+(state->rate-state->bitsAvailableForSqueezing)/8, partialBlock/8);
262n/a state->bitsAvailableForSqueezing -= partialBlock;
263n/a i += partialBlock;
264n/a }
265n/a return 0;
266n/a}