/src/php-src/ext/hash/sha3/generic64lc/KeccakP-1600-opt64.c
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 | | #include <string.h> |
17 | | #include <stdlib.h> |
18 | | #include "brg_endian.h" |
19 | | #include "KeccakP-1600-opt64-config.h" |
20 | | #ifdef __has_feature |
21 | | # if __has_feature(undefined_behavior_sanitizer) |
22 | | # define ALLOW_MISALIGNED_ACCESS __attribute__((no_sanitize("alignment"))) |
23 | | # endif |
24 | | #endif |
25 | | #ifndef ALLOW_MISALIGNED_ACCESS |
26 | | # define ALLOW_MISALIGNED_ACCESS |
27 | | #endif |
28 | | |
29 | | typedef unsigned char UINT8; |
30 | | typedef unsigned long long int UINT64; |
31 | | |
32 | | #if defined(KeccakP1600_useLaneComplementing) |
33 | | #define UseBebigokimisa |
34 | | #endif |
35 | | |
36 | | #if defined(_MSC_VER) |
37 | | #define ROL64(a, offset) _rotl64(a, offset) |
38 | | #elif defined(KeccakP1600_useSHLD) |
39 | | #define ROL64(x,N) ({ \ |
40 | | register UINT64 __out; \ |
41 | | register UINT64 __in = x; \ |
42 | | __asm__ ("shld %2,%0,%0" : "=r"(__out) : "0"(__in), "i"(N)); \ |
43 | | __out; \ |
44 | | }) |
45 | | #else |
46 | 17.2M | #define ROL64(a, offset) ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64-offset))) |
47 | | #endif |
48 | | |
49 | | #include "KeccakP-1600-64.macros" |
50 | | #ifdef KeccakP1600_fullUnrolling |
51 | | #define FullUnrolling |
52 | | #else |
53 | | #define Unrolling KeccakP1600_unrolling |
54 | | #endif |
55 | | #include "KeccakP-1600-unrolling.macros" |
56 | | #include "SnP-Relaned.h" |
57 | | |
58 | | static const UINT64 KeccakF1600RoundConstants[24] = { |
59 | | 0x0000000000000001ULL, |
60 | | 0x0000000000008082ULL, |
61 | | 0x800000000000808aULL, |
62 | | 0x8000000080008000ULL, |
63 | | 0x000000000000808bULL, |
64 | | 0x0000000080000001ULL, |
65 | | 0x8000000080008081ULL, |
66 | | 0x8000000000008009ULL, |
67 | | 0x000000000000008aULL, |
68 | | 0x0000000000000088ULL, |
69 | | 0x0000000080008009ULL, |
70 | | 0x000000008000000aULL, |
71 | | 0x000000008000808bULL, |
72 | | 0x800000000000008bULL, |
73 | | 0x8000000000008089ULL, |
74 | | 0x8000000000008003ULL, |
75 | | 0x8000000000008002ULL, |
76 | | 0x8000000000000080ULL, |
77 | | 0x000000000000800aULL, |
78 | | 0x800000008000000aULL, |
79 | | 0x8000000080008081ULL, |
80 | | 0x8000000000008080ULL, |
81 | | 0x0000000080000001ULL, |
82 | | 0x8000000080008008ULL }; |
83 | | |
84 | | /* ---------------------------------------------------------------- */ |
85 | | |
86 | | void KeccakP1600_Initialize(void *state) |
87 | 147 | { |
88 | 147 | memset(state, 0, 200); |
89 | 147 | #ifdef KeccakP1600_useLaneComplementing |
90 | 147 | ((UINT64*)state)[ 1] = ~(UINT64)0; |
91 | 147 | ((UINT64*)state)[ 2] = ~(UINT64)0; |
92 | 147 | ((UINT64*)state)[ 8] = ~(UINT64)0; |
93 | 147 | ((UINT64*)state)[12] = ~(UINT64)0; |
94 | 147 | ((UINT64*)state)[17] = ~(UINT64)0; |
95 | 147 | ((UINT64*)state)[20] = ~(UINT64)0; |
96 | 147 | #endif |
97 | 147 | } |
98 | | |
99 | | /* ---------------------------------------------------------------- */ |
100 | | |
101 | | void KeccakP1600_AddBytesInLane(void *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length) |
102 | 541 | { |
103 | 541 | #if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) |
104 | 541 | UINT64 lane; |
105 | 541 | if (length == 0) |
106 | 5 | return; |
107 | 536 | if (length == 1) |
108 | 41 | lane = data[0]; |
109 | 495 | else { |
110 | 495 | lane = 0; |
111 | 495 | memcpy(&lane, data, length); |
112 | 495 | } |
113 | 536 | lane <<= offset*8; |
114 | | #else |
115 | | UINT64 lane = 0; |
116 | | unsigned int i; |
117 | | for(i=0; i<length; i++) |
118 | | lane |= ((UINT64)data[i]) << ((i+offset)*8); |
119 | | #endif |
120 | 536 | ((UINT64*)state)[lanePosition] ^= lane; |
121 | 536 | } |
122 | | |
123 | | /* ---------------------------------------------------------------- */ |
124 | | |
125 | | ALLOW_MISALIGNED_ACCESS |
126 | | void KeccakP1600_AddLanes(void *state, const unsigned char *data, unsigned int laneCount) |
127 | 42 | { |
128 | 42 | #if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) |
129 | 42 | unsigned int i = 0; |
130 | | #ifdef NO_MISALIGNED_ACCESSES |
131 | | /* If either pointer is misaligned, fall back to byte-wise xor. */ |
132 | | if (((((uintptr_t)state) & 7) != 0) || ((((uintptr_t)data) & 7) != 0)) { |
133 | | for (i = 0; i < laneCount * 8; i++) { |
134 | | ((unsigned char*)state)[i] ^= data[i]; |
135 | | } |
136 | | } |
137 | | else |
138 | | #endif |
139 | 42 | { |
140 | | /* Otherwise... */ |
141 | 49 | for( ; (i+8)<=laneCount; i+=8) { |
142 | 7 | ((UINT64*)state)[i+0] ^= ((UINT64*)data)[i+0]; |
143 | 7 | ((UINT64*)state)[i+1] ^= ((UINT64*)data)[i+1]; |
144 | 7 | ((UINT64*)state)[i+2] ^= ((UINT64*)data)[i+2]; |
145 | 7 | ((UINT64*)state)[i+3] ^= ((UINT64*)data)[i+3]; |
146 | 7 | ((UINT64*)state)[i+4] ^= ((UINT64*)data)[i+4]; |
147 | 7 | ((UINT64*)state)[i+5] ^= ((UINT64*)data)[i+5]; |
148 | 7 | ((UINT64*)state)[i+6] ^= ((UINT64*)data)[i+6]; |
149 | 7 | ((UINT64*)state)[i+7] ^= ((UINT64*)data)[i+7]; |
150 | 7 | } |
151 | 54 | for( ; (i+4)<=laneCount; i+=4) { |
152 | 12 | ((UINT64*)state)[i+0] ^= ((UINT64*)data)[i+0]; |
153 | 12 | ((UINT64*)state)[i+1] ^= ((UINT64*)data)[i+1]; |
154 | 12 | ((UINT64*)state)[i+2] ^= ((UINT64*)data)[i+2]; |
155 | 12 | ((UINT64*)state)[i+3] ^= ((UINT64*)data)[i+3]; |
156 | 12 | } |
157 | 56 | for( ; (i+2)<=laneCount; i+=2) { |
158 | 14 | ((UINT64*)state)[i+0] ^= ((UINT64*)data)[i+0]; |
159 | 14 | ((UINT64*)state)[i+1] ^= ((UINT64*)data)[i+1]; |
160 | 14 | } |
161 | 42 | if (i<laneCount) { |
162 | 15 | ((UINT64*)state)[i+0] ^= ((UINT64*)data)[i+0]; |
163 | 15 | } |
164 | 42 | } |
165 | | #else |
166 | | unsigned int i; |
167 | | UINT8 *curData = data; |
168 | | for(i=0; i<laneCount; i++, curData+=8) { |
169 | | UINT64 lane = (UINT64)curData[0] |
170 | | | ((UINT64)curData[1] << 8) |
171 | | | ((UINT64)curData[2] << 16) |
172 | | | ((UINT64)curData[3] << 24) |
173 | | | ((UINT64)curData[4] <<32) |
174 | | | ((UINT64)curData[5] << 40) |
175 | | | ((UINT64)curData[6] << 48) |
176 | | | ((UINT64)curData[7] << 56); |
177 | | ((UINT64*)state)[i] ^= lane; |
178 | | } |
179 | | #endif |
180 | 42 | } |
181 | | |
182 | | /* ---------------------------------------------------------------- */ |
183 | | |
184 | | #if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) |
185 | | void KeccakP1600_AddByte(void *state, unsigned char byte, unsigned int offset) |
186 | | { |
187 | | UINT64 lane = byte; |
188 | | lane <<= (offset%8)*8; |
189 | | ((UINT64*)state)[offset/8] ^= lane; |
190 | | } |
191 | | #endif |
192 | | |
193 | | /* ---------------------------------------------------------------- */ |
194 | | |
195 | | void KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length) |
196 | 111 | { |
197 | 111 | SnP_AddBytes(state, data, offset, length, KeccakP1600_AddLanes, KeccakP1600_AddBytesInLane, 8); |
198 | 111 | } |
199 | | |
200 | | /* ---------------------------------------------------------------- */ |
201 | | |
202 | | void KeccakP1600_OverwriteBytesInLane(void *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length) |
203 | 0 | { |
204 | 0 | #if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) |
205 | 0 | #ifdef KeccakP1600_useLaneComplementing |
206 | 0 | if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20)) { |
207 | 0 | unsigned int i; |
208 | 0 | for(i=0; i<length; i++) |
209 | 0 | ((unsigned char*)state)[lanePosition*8+offset+i] = ~data[i]; |
210 | 0 | } |
211 | 0 | else |
212 | 0 | #endif |
213 | 0 | { |
214 | 0 | memcpy((unsigned char*)state+lanePosition*8+offset, data, length); |
215 | 0 | } |
216 | | #else |
217 | | #error "Not yet implemented" |
218 | | #endif |
219 | 0 | } |
220 | | |
221 | | /* ---------------------------------------------------------------- */ |
222 | | |
223 | | void KeccakP1600_OverwriteLanes(void *state, const unsigned char *data, unsigned int laneCount) |
224 | 0 | { |
225 | 0 | #if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) |
226 | 0 | #ifdef KeccakP1600_useLaneComplementing |
227 | 0 | unsigned int lanePosition; |
228 | |
|
229 | 0 | for(lanePosition=0; lanePosition<laneCount; lanePosition++) |
230 | 0 | if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20)) |
231 | 0 | ((UINT64*)state)[lanePosition] = ~((const UINT64*)data)[lanePosition]; |
232 | 0 | else |
233 | 0 | ((UINT64*)state)[lanePosition] = ((const UINT64*)data)[lanePosition]; |
234 | | #else |
235 | | memcpy(state, data, laneCount*8); |
236 | | #endif |
237 | | #else |
238 | | #error "Not yet implemented" |
239 | | #endif |
240 | 0 | } |
241 | | |
242 | | /* ---------------------------------------------------------------- */ |
243 | | |
244 | | void KeccakP1600_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length) |
245 | 0 | { |
246 | 0 | SnP_OverwriteBytes(state, data, offset, length, KeccakP1600_OverwriteLanes, KeccakP1600_OverwriteBytesInLane, 8); |
247 | 0 | } |
248 | | |
249 | | /* ---------------------------------------------------------------- */ |
250 | | |
251 | | void KeccakP1600_OverwriteWithZeroes(void *state, unsigned int byteCount) |
252 | 0 | { |
253 | 0 | #if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) |
254 | 0 | #ifdef KeccakP1600_useLaneComplementing |
255 | 0 | unsigned int lanePosition; |
256 | |
|
257 | 0 | for(lanePosition=0; lanePosition<byteCount/8; lanePosition++) |
258 | 0 | if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20)) |
259 | 0 | ((UINT64*)state)[lanePosition] = ~0; |
260 | 0 | else |
261 | 0 | ((UINT64*)state)[lanePosition] = 0; |
262 | 0 | if (byteCount%8 != 0) { |
263 | 0 | lanePosition = byteCount/8; |
264 | 0 | if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20)) |
265 | 0 | memset((unsigned char*)state+lanePosition*8, 0xFF, byteCount%8); |
266 | 0 | else |
267 | 0 | memset((unsigned char*)state+lanePosition*8, 0, byteCount%8); |
268 | 0 | } |
269 | | #else |
270 | | memset(state, 0, byteCount); |
271 | | #endif |
272 | | #else |
273 | | #error "Not yet implemented" |
274 | | #endif |
275 | 0 | } |
276 | | |
277 | | /* ---------------------------------------------------------------- */ |
278 | | |
279 | | void KeccakP1600_Permute_Nrounds(void *state, unsigned int nr) |
280 | 0 | { |
281 | 0 | declareABCDE |
282 | 0 | unsigned int i; |
283 | 0 | UINT64 *stateAsLanes = (UINT64*)state; |
284 | |
|
285 | 0 | copyFromState(A, stateAsLanes) |
286 | 0 | roundsN(nr) |
287 | 0 | copyToState(stateAsLanes, A) |
288 | |
|
289 | 0 | } |
290 | | |
291 | | /* ---------------------------------------------------------------- */ |
292 | | |
293 | | void KeccakP1600_Permute_24rounds(void *state) |
294 | 145 | { |
295 | 145 | declareABCDE |
296 | | #ifndef KeccakP1600_fullUnrolling |
297 | | unsigned int i; |
298 | | #endif |
299 | 145 | UINT64 *stateAsLanes = (UINT64*)state; |
300 | | |
301 | 145 | copyFromState(A, stateAsLanes) |
302 | 145 | rounds24 |
303 | 145 | copyToState(stateAsLanes, A) |
304 | 145 | } |
305 | | |
306 | | /* ---------------------------------------------------------------- */ |
307 | | |
308 | | void KeccakP1600_Permute_12rounds(void *state) |
309 | 0 | { |
310 | 0 | declareABCDE |
311 | | #ifndef KeccakP1600_fullUnrolling |
312 | | unsigned int i; |
313 | | #endif |
314 | 0 | UINT64 *stateAsLanes = (UINT64*)state; |
315 | |
|
316 | 0 | copyFromState(A, stateAsLanes) |
317 | 0 | rounds12 |
318 | 0 | copyToState(stateAsLanes, A) |
319 | 0 | } |
320 | | |
321 | | /* ---------------------------------------------------------------- */ |
322 | | |
323 | | void KeccakP1600_ExtractBytesInLane(const void *state, unsigned int lanePosition, unsigned char *data, unsigned int offset, unsigned int length) |
324 | 93 | { |
325 | 93 | UINT64 lane = ((UINT64*)state)[lanePosition]; |
326 | 93 | #ifdef KeccakP1600_useLaneComplementing |
327 | 93 | if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20)) |
328 | 31 | lane = ~lane; |
329 | 93 | #endif |
330 | 93 | #if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) |
331 | 93 | { |
332 | 93 | UINT64 lane1[1]; |
333 | 93 | lane1[0] = lane; |
334 | 93 | memcpy(data, (UINT8*)lane1+offset, length); |
335 | 93 | } |
336 | | #else |
337 | | unsigned int i; |
338 | | lane >>= offset*8; |
339 | | for(i=0; i<length; i++) { |
340 | | data[i] = lane & 0xFF; |
341 | | lane >>= 8; |
342 | | } |
343 | | #endif |
344 | 93 | } |
345 | | |
346 | | /* ---------------------------------------------------------------- */ |
347 | | |
348 | | #if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) |
349 | | void fromWordToBytes(UINT8 *bytes, const UINT64 word) |
350 | | { |
351 | | unsigned int i; |
352 | | |
353 | | for(i=0; i<(64/8); i++) |
354 | | bytes[i] = (word >> (8*i)) & 0xFF; |
355 | | } |
356 | | #endif |
357 | | |
358 | | void KeccakP1600_ExtractLanes(const void *state, unsigned char *data, unsigned int laneCount) |
359 | 93 | { |
360 | 93 | #if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) |
361 | 93 | memcpy(data, state, laneCount*8); |
362 | | #else |
363 | | unsigned int i; |
364 | | |
365 | | for(i=0; i<laneCount; i++) |
366 | | fromWordToBytes(data+(i*8), ((const UINT64*)state)[i]); |
367 | | #endif |
368 | 93 | #ifdef KeccakP1600_useLaneComplementing |
369 | 93 | if (laneCount > 1) { |
370 | 93 | ((UINT64*)data)[ 1] = ~((UINT64*)data)[ 1]; |
371 | 93 | if (laneCount > 2) { |
372 | 93 | ((UINT64*)data)[ 2] = ~((UINT64*)data)[ 2]; |
373 | 93 | if (laneCount > 8) { |
374 | 0 | ((UINT64*)data)[ 8] = ~((UINT64*)data)[ 8]; |
375 | 0 | if (laneCount > 12) { |
376 | 0 | ((UINT64*)data)[12] = ~((UINT64*)data)[12]; |
377 | 0 | if (laneCount > 17) { |
378 | 0 | ((UINT64*)data)[17] = ~((UINT64*)data)[17]; |
379 | 0 | if (laneCount > 20) { |
380 | 0 | ((UINT64*)data)[20] = ~((UINT64*)data)[20]; |
381 | 0 | } |
382 | 0 | } |
383 | 0 | } |
384 | 0 | } |
385 | 93 | } |
386 | 93 | } |
387 | 93 | #endif |
388 | 93 | } |
389 | | |
390 | | /* ---------------------------------------------------------------- */ |
391 | | |
392 | | void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length) |
393 | 93 | { |
394 | 93 | SnP_ExtractBytes(state, data, offset, length, KeccakP1600_ExtractLanes, KeccakP1600_ExtractBytesInLane, 8); |
395 | 93 | } |
396 | | |
397 | | /* ---------------------------------------------------------------- */ |
398 | | |
399 | | void KeccakP1600_ExtractAndAddBytesInLane(const void *state, unsigned int lanePosition, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) |
400 | 0 | { |
401 | 0 | UINT64 lane = ((UINT64*)state)[lanePosition]; |
402 | 0 | #ifdef KeccakP1600_useLaneComplementing |
403 | 0 | if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20)) |
404 | 0 | lane = ~lane; |
405 | 0 | #endif |
406 | 0 | #if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) |
407 | 0 | { |
408 | 0 | unsigned int i; |
409 | 0 | UINT64 lane1[1]; |
410 | 0 | lane1[0] = lane; |
411 | 0 | for(i=0; i<length; i++) |
412 | 0 | output[i] = input[i] ^ ((UINT8*)lane1)[offset+i]; |
413 | 0 | } |
414 | | #else |
415 | | unsigned int i; |
416 | | lane >>= offset*8; |
417 | | for(i=0; i<length; i++) { |
418 | | output[i] = input[i] ^ (lane & 0xFF); |
419 | | lane >>= 8; |
420 | | } |
421 | | #endif |
422 | 0 | } |
423 | | |
424 | | /* ---------------------------------------------------------------- */ |
425 | | |
426 | | void KeccakP1600_ExtractAndAddLanes(const void *state, const unsigned char *input, unsigned char *output, unsigned int laneCount) |
427 | 0 | { |
428 | 0 | unsigned int i; |
429 | | #if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) |
430 | | unsigned char temp[8]; |
431 | | unsigned int j; |
432 | | #endif |
433 | |
|
434 | 0 | for(i=0; i<laneCount; i++) { |
435 | 0 | #if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) |
436 | 0 | ((UINT64*)output)[i] = ((UINT64*)input)[i] ^ ((const UINT64*)state)[i]; |
437 | | #else |
438 | | fromWordToBytes(temp, ((const UINT64*)state)[i]); |
439 | | for(j=0; j<8; j++) |
440 | | output[i*8+j] = input[i*8+j] ^ temp[j]; |
441 | | #endif |
442 | 0 | } |
443 | 0 | #ifdef KeccakP1600_useLaneComplementing |
444 | 0 | if (laneCount > 1) { |
445 | 0 | ((UINT64*)output)[ 1] = ~((UINT64*)output)[ 1]; |
446 | 0 | if (laneCount > 2) { |
447 | 0 | ((UINT64*)output)[ 2] = ~((UINT64*)output)[ 2]; |
448 | 0 | if (laneCount > 8) { |
449 | 0 | ((UINT64*)output)[ 8] = ~((UINT64*)output)[ 8]; |
450 | 0 | if (laneCount > 12) { |
451 | 0 | ((UINT64*)output)[12] = ~((UINT64*)output)[12]; |
452 | 0 | if (laneCount > 17) { |
453 | 0 | ((UINT64*)output)[17] = ~((UINT64*)output)[17]; |
454 | 0 | if (laneCount > 20) { |
455 | 0 | ((UINT64*)output)[20] = ~((UINT64*)output)[20]; |
456 | 0 | } |
457 | 0 | } |
458 | 0 | } |
459 | 0 | } |
460 | 0 | } |
461 | 0 | } |
462 | 0 | #endif |
463 | 0 | } |
464 | | |
465 | | /* ---------------------------------------------------------------- */ |
466 | | |
467 | | void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) |
468 | 0 | { |
469 | 0 | SnP_ExtractAndAddBytes(state, input, output, offset, length, KeccakP1600_ExtractAndAddLanes, KeccakP1600_ExtractAndAddBytesInLane, 8); |
470 | 0 | } |
471 | | |
472 | | /* ---------------------------------------------------------------- */ |
473 | | |
474 | | ALLOW_MISALIGNED_ACCESS |
475 | | size_t KeccakF1600_FastLoop_Absorb(void *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen) |
476 | 66 | { |
477 | 66 | size_t originalDataByteLen = dataByteLen; |
478 | 66 | declareABCDE |
479 | | #ifndef KeccakP1600_fullUnrolling |
480 | | unsigned int i; |
481 | | #endif |
482 | 66 | UINT64 *stateAsLanes = (UINT64*)state; |
483 | 66 | UINT64 *inDataAsLanes = (UINT64*)data; |
484 | | |
485 | 66 | copyFromState(A, stateAsLanes) |
486 | 24.6k | while(dataByteLen >= laneCount*8) { |
487 | 24.5k | addInput(A, inDataAsLanes, laneCount) |
488 | 24.5k | rounds24 |
489 | 24.5k | inDataAsLanes += laneCount; |
490 | 24.5k | dataByteLen -= laneCount*8; |
491 | 24.5k | } |
492 | 66 | copyToState(stateAsLanes, A) |
493 | 66 | return originalDataByteLen - dataByteLen; |
494 | 66 | } |