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 20 changed files
... ...
@@ -1,2 +1,4 @@
1 1
 *.o
2 2
 re
3
+keccak/*.o
4
+keccak/*.a
... ...
@@ -1,15 +1,21 @@
1 1
 CC=gcc
2
-CFLAGS=-g -Wall -I/usr/include/SDL2
2
+CFLAGS=-g -Wall -Ideps -I/usr/include/SDL2
3 3
 LDFLAGS=-lSDL2 -lSDL2_image
4 4
 
5
+KECCAKOPTS=-Ikeccak -DKeccakP200_excluded -DKeccakP400_excluded -DKeccakP800_excluded -DKeccakOpt=32
6
+
5 7
 all: re
6 8
 
7 9
 recenteditor_data.o: recenteditor_data.c recenteditor_data.h
10
+	$(CC) $(CFLAGS) $(KECCAKOPTS) -c -o recenteditor_data.o recenteditor_data.c
8 11
 
9 12
 recenteditor.o: recenteditor.c recenteditor_data.h
10 13
 
11
-re: recenteditor.o recenteditor_data.o
12
-	$(CC) $(LDFLAGS) -o re recenteditor.o recenteditor_data.o
14
+keccak/keccak.a:
15
+	sh -c "cd keccak && make keccak.a"
16
+
17
+re: recenteditor.o recenteditor_data.o keccak/keccak.a
18
+	$(CC) $(LDFLAGS) -o re recenteditor.o recenteditor_data.o keccak/keccak.a
13 19
 
14 20
 clean:
15 21
 	rm -f recenteditor.o recenteditor_data.o re
16 22
new file mode 100644
... ...
@@ -0,0 +1,82 @@
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 "KeccakHash.h"
18
+
19
+/* ---------------------------------------------------------------- */
20
+
21
+HashReturn Keccak_HashInitialize(Keccak_HashInstance *instance, unsigned int rate, unsigned int capacity, unsigned int hashbitlen, unsigned char delimitedSuffix)
22
+{
23
+    HashReturn result;
24
+
25
+    if (delimitedSuffix == 0)
26
+        return FAIL;
27
+    result = (HashReturn)KeccakWidth1600_SpongeInitialize(&instance->sponge, rate, capacity);
28
+    if (result != SUCCESS)
29
+        return result;
30
+    instance->fixedOutputLength = hashbitlen;
31
+    instance->delimitedSuffix = delimitedSuffix;
32
+    return SUCCESS;
33
+}
34
+
35
+/* ---------------------------------------------------------------- */
36
+
37
+HashReturn Keccak_HashUpdate(Keccak_HashInstance *instance, const BitSequence *data, DataLength databitlen)
38
+{
39
+    if ((databitlen % 8) == 0)
40
+        return (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, data, databitlen/8);
41
+    else {
42
+        HashReturn ret = (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, data, databitlen/8);
43
+        if (ret == SUCCESS) {
44
+            /* The last partial byte is assumed to be aligned on the least significant bits */
45
+
46
+            unsigned char lastByte = data[databitlen/8];
47
+            /* Concatenate the last few bits provided here with those of the suffix */
48
+
49
+            unsigned short delimitedLastBytes = (unsigned short)((unsigned short)lastByte | ((unsigned short)instance->delimitedSuffix << (databitlen % 8)));
50
+            if ((delimitedLastBytes & 0xFF00) == 0x0000) {
51
+                instance->delimitedSuffix = delimitedLastBytes & 0xFF;
52
+            }
53
+            else {
54
+                unsigned char oneByte[1];
55
+                oneByte[0] = delimitedLastBytes & 0xFF;
56
+                ret = (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, oneByte, 1);
57
+                instance->delimitedSuffix = (delimitedLastBytes >> 8) & 0xFF;
58
+            }
59
+        }
60
+        return ret;
61
+    }
62
+}
63
+
64
+/* ---------------------------------------------------------------- */
65
+
66
+HashReturn Keccak_HashFinal(Keccak_HashInstance *instance, BitSequence *hashval)
67
+{
68
+    HashReturn ret = (HashReturn)KeccakWidth1600_SpongeAbsorbLastFewBits(&instance->sponge, instance->delimitedSuffix);
69
+    if (ret == SUCCESS)
70
+        return (HashReturn)KeccakWidth1600_SpongeSqueeze(&instance->sponge, hashval, instance->fixedOutputLength/8);
71
+    else
72
+        return ret;
73
+}
74
+
75
+/* ---------------------------------------------------------------- */
76
+
77
+HashReturn Keccak_HashSqueeze(Keccak_HashInstance *instance, BitSequence *data, DataLength databitlen)
78
+{
79
+    if ((databitlen % 8) != 0)
80
+        return FAIL;
81
+    return (HashReturn)KeccakWidth1600_SpongeSqueeze(&instance->sponge, data, databitlen/8);
82
+}
0 83
new file mode 100644
... ...
@@ -0,0 +1,114 @@
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
+#ifndef _KeccakHashInterface_h_
17
+#define _KeccakHashInterface_h_
18
+
19
+#ifndef KeccakP1600_excluded
20
+
21
+#include "KeccakSponge.h"
22
+#include <string.h>
23
+
24
+typedef unsigned char BitSequence;
25
+typedef size_t DataLength;
26
+typedef enum { SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2 } HashReturn;
27
+
28
+typedef struct {
29
+    KeccakWidth1600_SpongeInstance sponge;
30
+    unsigned int fixedOutputLength;
31
+    unsigned char delimitedSuffix;
32
+} Keccak_HashInstance;
33
+
34
+/**
35
+  * Function to initialize the Keccak[r, c] sponge function instance used in sequential hashing mode.
36
+  * @param  hashInstance    Pointer to the hash instance to be initialized.
37
+  * @param  rate        The value of the rate r.
38
+  * @param  capacity    The value of the capacity c.
39
+  * @param  hashbitlen  The desired number of output bits,
40
+  *                     or 0 for an arbitrarily-long output.
41
+  * @param  delimitedSuffix Bits that will be automatically appended to the end
42
+  *                         of the input message, as in domain separation.
43
+  *                         This is a byte containing from 0 to 7 bits
44
+  *                         formatted like the @a delimitedData parameter of
45
+  *                         the Keccak_SpongeAbsorbLastFewBits() function.
46
+  * @pre    One must have r+c=1600 and the rate a multiple of 8 bits in this implementation.
47
+  * @return SUCCESS if successful, FAIL otherwise.
48
+  */
49
+HashReturn Keccak_HashInitialize(Keccak_HashInstance *hashInstance, unsigned int rate, unsigned int capacity, unsigned int hashbitlen, unsigned char delimitedSuffix);
50
+
51
+/** Macro to initialize a SHAKE128 instance as specified in the FIPS 202 standard.
52
+  */
53
+#define Keccak_HashInitialize_SHAKE128(hashInstance)        Keccak_HashInitialize(hashInstance, 1344,  256,   0, 0x1F)
54
+
55
+/** Macro to initialize a SHAKE256 instance as specified in the FIPS 202 standard.
56
+  */
57
+#define Keccak_HashInitialize_SHAKE256(hashInstance)        Keccak_HashInitialize(hashInstance, 1088,  512,   0, 0x1F)
58
+
59
+/** Macro to initialize a SHA3-224 instance as specified in the FIPS 202 standard.
60
+  */
61
+#define Keccak_HashInitialize_SHA3_224(hashInstance)        Keccak_HashInitialize(hashInstance, 1152,  448, 224, 0x06)
62
+
63
+/** Macro to initialize a SHA3-256 instance as specified in the FIPS 202 standard.
64
+  */
65
+#define Keccak_HashInitialize_SHA3_256(hashInstance)        Keccak_HashInitialize(hashInstance, 1088,  512, 256, 0x06)
66
+
67
+/** Macro to initialize a SHA3-384 instance as specified in the FIPS 202 standard.
68
+  */
69
+#define Keccak_HashInitialize_SHA3_384(hashInstance)        Keccak_HashInitialize(hashInstance,  832,  768, 384, 0x06)
70
+
71
+/** Macro to initialize a SHA3-512 instance as specified in the FIPS 202 standard.
72
+  */
73
+#define Keccak_HashInitialize_SHA3_512(hashInstance)        Keccak_HashInitialize(hashInstance,  576, 1024, 512, 0x06)
74
+
75
+/**
76
+  * Function to give input data to be absorbed.
77
+  * @param  hashInstance    Pointer to the hash instance initialized by Keccak_HashInitialize().
78
+  * @param  data        Pointer to the input data.
79
+  *                     When @a databitLen is not a multiple of 8, the last bits of data must be
80
+  *                     in the least significant bits of the last byte (little-endian convention).
81
+  * @param  databitLen  The number of input bits provided in the input data.
82
+  * @pre    In the previous call to Keccak_HashUpdate(), databitlen was a multiple of 8.
83
+  * @return SUCCESS if successful, FAIL otherwise.
84
+  */
85
+HashReturn Keccak_HashUpdate(Keccak_HashInstance *hashInstance, const BitSequence *data, DataLength databitlen);
86
+
87
+/**
88
+  * Function to call after all input blocks have been input and to get
89
+  * output bits if the length was specified when calling Keccak_HashInitialize().
90
+  * @param  hashInstance    Pointer to the hash instance initialized by Keccak_HashInitialize().
91
+  * If @a hashbitlen was not 0 in the call to Keccak_HashInitialize(), the number of
92
+  *     output bits is equal to @a hashbitlen.
93
+  * If @a hashbitlen was 0 in the call to Keccak_HashInitialize(), the output bits
94
+  *     must be extracted using the Keccak_HashSqueeze() function.
95
+  * @param  state       Pointer to the state of the sponge function initialized by Init().
96
+  * @param  hashval     Pointer to the buffer where to store the output data.
97
+  * @return SUCCESS if successful, FAIL otherwise.
98
+  */
99
+HashReturn Keccak_HashFinal(Keccak_HashInstance *hashInstance, BitSequence *hashval);
100
+
101
+ /**
102
+  * Function to squeeze output data.
103
+  * @param  hashInstance    Pointer to the hash instance initialized by Keccak_HashInitialize().
104
+  * @param  data        Pointer to the buffer where to store the output data.
105
+  * @param  databitlen  The number of output bits desired (must be a multiple of 8).
106
+  * @pre    Keccak_HashFinal() must have been already called.
107
+  * @pre    @a databitlen is a multiple of 8.
108
+  * @return SUCCESS if successful, FAIL otherwise.
109
+  */
110
+HashReturn Keccak_HashSqueeze(Keccak_HashInstance *hashInstance, BitSequence *data, DataLength databitlen);
111
+
112
+#endif
113
+
114
+#endif
0 115
new file mode 100644
... ...
@@ -0,0 +1,37 @@
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
+#ifndef _KeccakP_1600_SnP_h_
17
+#define _KeccakP_1600_SnP_h_
18
+
19
+/** For the documentation, see SnP-documentation.h.
20
+ */
21
+
22
+#define KeccakP1600_implementation      "in-place 32-bit optimized implementation"
23
+#define KeccakP1600_stateSizeInBytes    200
24
+#define KeccakP1600_stateAlignment      8
25
+
26
+#define KeccakP1600_StaticInitialize()
27
+void KeccakP1600_Initialize(void *state);
28
+void KeccakP1600_AddByte(void *state, unsigned char data, unsigned int offset);
29
+void KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length);
30
+void KeccakP1600_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length);
31
+void KeccakP1600_OverwriteWithZeroes(void *state, unsigned int byteCount);
32
+void KeccakP1600_Permute_12rounds(void *state);
33
+void KeccakP1600_Permute_24rounds(void *state);
34
+void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length);
35
+void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length);
36
+
37
+#endif
0 38
new file mode 100644
... ...
@@ -0,0 +1,49 @@
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
+#ifndef _KeccakP_1600_SnP_h_
17
+#define _KeccakP_1600_SnP_h_
18
+
19
+/** For the documentation, see SnP-documentation.h.
20
+ */
21
+
22
+/* #include "brg_endian.h" */
23
+#include "KeccakP-1600-opt64-config.h"
24
+
25
+#define KeccakP1600_implementation      "generic 64-bit optimized implementation (" KeccakP1600_implementation_config ")"
26
+#define KeccakP1600_stateSizeInBytes    200
27
+#define KeccakP1600_stateAlignment      8
28
+#define KeccakF1600_FastLoop_supported
29
+
30
+#include <stddef.h>
31
+
32
+#define KeccakP1600_StaticInitialize()
33
+void KeccakP1600_Initialize(void *state);
34
+#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
35
+#define KeccakP1600_AddByte(state, byte, offset) \
36
+    ((unsigned char*)(state))[(offset)] ^= (byte)
37
+#else
38
+void KeccakP1600_AddByte(void *state, unsigned char data, unsigned int offset);
39
+#endif
40
+void KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length);
41
+void KeccakP1600_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length);
42
+void KeccakP1600_OverwriteWithZeroes(void *state, unsigned int byteCount);
43
+void KeccakP1600_Permute_12rounds(void *state);
44
+void KeccakP1600_Permute_24rounds(void *state);
45
+void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length);
46
+void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length);
47
+size_t KeccakF1600_FastLoop_Absorb(void *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen);
48
+
49
+#endif
0 50
new file mode 100644
... ...
@@ -0,0 +1,7 @@
1
+#if KeccakOpt == 64
2
+  #include "KeccakP-1600-SnP-opt64.h"
3
+#elif KeccakOpt == 32
4
+  #include "KeccakP-1600-SnP-opt32.h"
5
+#else
6
+  #error "No KeccakOpt"
7
+#endif
0 8
new file mode 100644
... ...
@@ -0,0 +1,1162 @@
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 "brg_endian.h" */
18
+#include "KeccakP-1600-SnP.h"
19
+#include "SnP-Relaned.h"
20
+
21
+typedef unsigned char UINT8;
22
+typedef unsigned int UINT32;
23
+/* WARNING: on 8-bit and 16-bit platforms, this should be replaced by: */
24
+
25
+/*typedef unsigned long       UINT32; */
26
+
27
+
28
+#define ROL32(a, offset) ((((UINT32)a) << (offset)) ^ (((UINT32)a) >> (32-(offset))))
29
+
30
+/* Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */
31
+
32
+#define prepareToBitInterleaving(low, high, temp, temp0, temp1) \
33
+        temp0 = (low); \
34
+        temp = (temp0 ^ (temp0 >>  1)) & 0x22222222UL;  temp0 = temp0 ^ temp ^ (temp <<  1); \
35
+        temp = (temp0 ^ (temp0 >>  2)) & 0x0C0C0C0CUL;  temp0 = temp0 ^ temp ^ (temp <<  2); \
36
+        temp = (temp0 ^ (temp0 >>  4)) & 0x00F000F0UL;  temp0 = temp0 ^ temp ^ (temp <<  4); \
37
+        temp = (temp0 ^ (temp0 >>  8)) & 0x0000FF00UL;  temp0 = temp0 ^ temp ^ (temp <<  8); \
38
+        temp1 = (high); \
39
+        temp = (temp1 ^ (temp1 >>  1)) & 0x22222222UL;  temp1 = temp1 ^ temp ^ (temp <<  1); \
40
+        temp = (temp1 ^ (temp1 >>  2)) & 0x0C0C0C0CUL;  temp1 = temp1 ^ temp ^ (temp <<  2); \
41
+        temp = (temp1 ^ (temp1 >>  4)) & 0x00F000F0UL;  temp1 = temp1 ^ temp ^ (temp <<  4); \
42
+        temp = (temp1 ^ (temp1 >>  8)) & 0x0000FF00UL;  temp1 = temp1 ^ temp ^ (temp <<  8);
43
+
44
+#define toBitInterleavingAndXOR(low, high, even, odd, temp, temp0, temp1) \
45
+        prepareToBitInterleaving(low, high, temp, temp0, temp1) \
46
+        even ^= (temp0 & 0x0000FFFF) | (temp1 << 16); \
47
+        odd ^= (temp0 >> 16) | (temp1 & 0xFFFF0000);
48
+
49
+#define toBitInterleavingAndAND(low, high, even, odd, temp, temp0, temp1) \
50
+        prepareToBitInterleaving(low, high, temp, temp0, temp1) \
51
+        even &= (temp0 & 0x0000FFFF) | (temp1 << 16); \
52
+        odd &= (temp0 >> 16) | (temp1 & 0xFFFF0000);
53
+
54
+#define toBitInterleavingAndSet(low, high, even, odd, temp, temp0, temp1) \
55
+        prepareToBitInterleaving(low, high, temp, temp0, temp1) \
56
+        even = (temp0 & 0x0000FFFF) | (temp1 << 16); \
57
+        odd = (temp0 >> 16) | (temp1 & 0xFFFF0000);
58
+
59
+/* Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */
60
+
61
+#define prepareFromBitInterleaving(even, odd, temp, temp0, temp1) \
62
+        temp0 = (even); \
63
+        temp1 = (odd); \
64
+        temp = (temp0 & 0x0000FFFF) | (temp1 << 16); \
65
+        temp1 = (temp0 >> 16) | (temp1 & 0xFFFF0000); \
66
+        temp0 = temp; \
67
+        temp = (temp0 ^ (temp0 >>  8)) & 0x0000FF00UL;  temp0 = temp0 ^ temp ^ (temp <<  8); \
68
+        temp = (temp0 ^ (temp0 >>  4)) & 0x00F000F0UL;  temp0 = temp0 ^ temp ^ (temp <<  4); \
69
+        temp = (temp0 ^ (temp0 >>  2)) & 0x0C0C0C0CUL;  temp0 = temp0 ^ temp ^ (temp <<  2); \
70
+        temp = (temp0 ^ (temp0 >>  1)) & 0x22222222UL;  temp0 = temp0 ^ temp ^ (temp <<  1); \
71
+        temp = (temp1 ^ (temp1 >>  8)) & 0x0000FF00UL;  temp1 = temp1 ^ temp ^ (temp <<  8); \
72
+        temp = (temp1 ^ (temp1 >>  4)) & 0x00F000F0UL;  temp1 = temp1 ^ temp ^ (temp <<  4); \
73
+        temp = (temp1 ^ (temp1 >>  2)) & 0x0C0C0C0CUL;  temp1 = temp1 ^ temp ^ (temp <<  2); \
74
+        temp = (temp1 ^ (temp1 >>  1)) & 0x22222222UL;  temp1 = temp1 ^ temp ^ (temp <<  1);
75
+
76
+#define fromBitInterleaving(even, odd, low, high, temp, temp0, temp1) \
77
+        prepareFromBitInterleaving(even, odd, temp, temp0, temp1) \
78
+        low = temp0; \
79
+        high = temp1;
80
+
81
+#define fromBitInterleavingAndXOR(even, odd, lowIn, highIn, lowOut, highOut, temp, temp0, temp1) \
82
+        prepareFromBitInterleaving(even, odd, temp, temp0, temp1) \
83
+        lowOut = lowIn ^ temp0; \
84
+        highOut = highIn ^ temp1;
85
+
86
+void KeccakP1600_SetBytesInLaneToZero(void *state, unsigned int lanePosition, unsigned int offset, unsigned int length)
87
+{
88
+    UINT8 laneAsBytes[8];
89
+    UINT32 low, high;
90
+    UINT32 temp, temp0, temp1;
91
+    UINT32 *stateAsHalfLanes = (UINT32*)state;
92
+
93
+    memset(laneAsBytes, 0xFF, offset);
94
+    memset(laneAsBytes+offset, 0x00, length);
95
+    memset(laneAsBytes+offset+length, 0xFF, 8-offset-length);
96
+#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
97
+    low = *((UINT32*)(laneAsBytes+0));
98
+    high = *((UINT32*)(laneAsBytes+4));
99
+#else
100
+    low = laneAsBytes[0]
101
+        | ((UINT32)(laneAsBytes[1]) << 8)
102
+        | ((UINT32)(laneAsBytes[2]) << 16)
103
+        | ((UINT32)(laneAsBytes[3]) << 24);
104
+    high = laneAsBytes[4]
105
+        | ((UINT32)(laneAsBytes[5]) << 8)
106
+        | ((UINT32)(laneAsBytes[6]) << 16)
107
+        | ((UINT32)(laneAsBytes[7]) << 24);
108
+#endif
109
+    toBitInterleavingAndAND(low, high, stateAsHalfLanes[lanePosition*2+0], stateAsHalfLanes[lanePosition*2+1], temp, temp0, temp1);
110
+}
111
+
112
+/* ---------------------------------------------------------------- */
113
+
114
+void KeccakP1600_Initialize(void *state)
115
+{
116
+    memset(state, 0, 200);
117
+}
118
+
119
+/* ---------------------------------------------------------------- */
120
+
121
+void KeccakP1600_AddByte(void *state, unsigned char byte, unsigned int offset)
122
+{
123
+    unsigned int lanePosition = offset/8;
124
+    unsigned int offsetInLane = offset%8;
125
+    UINT32 low, high;
126
+    UINT32 temp, temp0, temp1;
127
+    UINT32 *stateAsHalfLanes = (UINT32*)state;
128
+
129
+    if (offsetInLane < 4) {
130
+        low = (UINT32)byte << (offsetInLane*8);
131
+        high = 0;
132
+    }
133
+    else {
134
+        low = 0;
135
+        high = (UINT32)byte << ((offsetInLane-4)*8);
136
+    }
137
+    toBitInterleavingAndXOR(low, high, stateAsHalfLanes[lanePosition*2+0], stateAsHalfLanes[lanePosition*2+1], temp, temp0, temp1);
138
+}
139
+
140
+/* ---------------------------------------------------------------- */
141
+
142
+void KeccakP1600_AddBytesInLane(void *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length)
143
+{
144
+    UINT8 laneAsBytes[8];
145
+    UINT32 low, high;
146
+    UINT32 temp, temp0, temp1;
147
+    UINT32 *stateAsHalfLanes = (UINT32*)state;
148
+
149
+    memset(laneAsBytes, 0, 8);
150
+    memcpy(laneAsBytes+offset, data, length);
151
+#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
152
+    low = *((UINT32*)(laneAsBytes+0));
153
+    high = *((UINT32*)(laneAsBytes+4));
154
+#else
155
+    low = laneAsBytes[0]
156
+        | ((UINT32)(laneAsBytes[1]) << 8)
157
+        | ((UINT32)(laneAsBytes[2]) << 16)
158
+        | ((UINT32)(laneAsBytes[3]) << 24);
159
+    high = laneAsBytes[4]
160
+        | ((UINT32)(laneAsBytes[5]) << 8)
161
+        | ((UINT32)(laneAsBytes[6]) << 16)
162
+        | ((UINT32)(laneAsBytes[7]) << 24);
163
+#endif
164
+    toBitInterleavingAndXOR(low, high, stateAsHalfLanes[lanePosition*2+0], stateAsHalfLanes[lanePosition*2+1], temp, temp0, temp1);
165
+}
166
+
167
+/* ---------------------------------------------------------------- */
168
+
169
+void KeccakP1600_AddLanes(void *state, const unsigned char *data, unsigned int laneCount)
170
+{
171
+#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
172
+    const UINT32 * pI = (const UINT32 *)data;
173
+    UINT32 * pS = (UINT32*)state;
174
+    UINT32 t, x0, x1;
175
+    int i;
176
+    for (i = laneCount-1; i >= 0; --i) {
177
+#ifdef NO_MISALIGNED_ACCESSES
178
+        UINT32 low;
179
+        UINT32 high;
180
+        memcpy(&low, pI++, 4);
181
+        memcpy(&high, pI++, 4);
182
+        toBitInterleavingAndXOR(low, high, *(pS++), *(pS++), t, x0, x1);
183
+#else
184
+        toBitInterleavingAndXOR(*(pI++), *(pI++), *(pS++), *(pS++), t, x0, x1)
185
+#endif
186
+    }
187
+#else
188
+    unsigned int lanePosition;
189
+    for(lanePosition=0; lanePosition<laneCount; lanePosition++) {
190
+        UINT8 laneAsBytes[8];
191
+        UINT32 low, high, temp, temp0, temp1;
192
+        UINT32 *stateAsHalfLanes;
193
+        memcpy(laneAsBytes, data+lanePosition*8, 8);
194
+        low = laneAsBytes[0]
195
+            | ((UINT32)(laneAsBytes[1]) << 8)
196
+            | ((UINT32)(laneAsBytes[2]) << 16)
197
+            | ((UINT32)(laneAsBytes[3]) << 24);
198
+        high = laneAsBytes[4]
199
+            | ((UINT32)(laneAsBytes[5]) << 8)
200
+            | ((UINT32)(laneAsBytes[6]) << 16)
201
+            | ((UINT32)(laneAsBytes[7]) << 24);
202
+        stateAsHalfLanes = (UINT32*)state;
203
+        toBitInterleavingAndXOR(low, high, stateAsHalfLanes[lanePosition*2+0], stateAsHalfLanes[lanePosition*2+1], temp, temp0, temp1);
204
+    }
205
+#endif
206
+}
207
+
208
+/* ---------------------------------------------------------------- */
209
+
210
+void KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length)
211
+{
212
+    SnP_AddBytes(state, data, offset, length, KeccakP1600_AddLanes, KeccakP1600_AddBytesInLane, 8);
213
+}
214
+
215
+/* ---------------------------------------------------------------- */
216
+
217
+void KeccakP1600_OverwriteBytesInLane(void *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length)
218
+{
219
+    KeccakP1600_SetBytesInLaneToZero(state, lanePosition, offset, length);
220
+    KeccakP1600_AddBytesInLane(state, lanePosition, data, offset, length);
221
+}
222
+
223
+/* ---------------------------------------------------------------- */
224
+
225
+void KeccakP1600_OverwriteLanes(void *state, const unsigned char *data, unsigned int laneCount)
226
+{
227
+#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
228
+    const UINT32 * pI = (const UINT32 *)data;
229
+    UINT32 * pS = (UINT32 *)state;
230
+    UINT32 t, x0, x1;
231
+    int i;
232
+    for (i = laneCount-1; i >= 0; --i) {
233
+#ifdef NO_MISALIGNED_ACCESSES
234
+        UINT32 low;
235
+        UINT32 high;
236
+        memcpy(&low, pI++, 4);
237
+        memcpy(&high, pI++, 4);
238
+        toBitInterleavingAndSet(low, high, *(pS++), *(pS++), t, x0, x1);
239
+#else
240
+        toBitInterleavingAndSet(*(pI++), *(pI++), *(pS++), *(pS++), t, x0, x1)
241
+#endif
242
+    }
243
+#else
244
+    unsigned int lanePosition;
245
+    for(lanePosition=0; lanePosition<laneCount; lanePosition++) {
246
+        UINT8 laneAsBytes[8];
247
+        UINT32 low, high, temp, temp0, temp1;
248
+        UINT32 *stateAsHalfLanes;
249
+        memcpy(laneAsBytes, data+lanePosition*8, 8);
250
+        low = laneAsBytes[0]
251
+            | ((UINT32)(laneAsBytes[1]) << 8)
252
+            | ((UINT32)(laneAsBytes[2]) << 16)
253
+            | ((UINT32)(laneAsBytes[3]) << 24);
254
+        high = laneAsBytes[4]
255
+            | ((UINT32)(laneAsBytes[5]) << 8)
256
+            | ((UINT32)(laneAsBytes[6]) << 16)
257
+            | ((UINT32)(laneAsBytes[7]) << 24);
258
+        stateAsHalfLanes = (UINT32*)state;
259
+        toBitInterleavingAndSet(low, high, stateAsHalfLanes[lanePosition*2+0], stateAsHalfLanes[lanePosition*2+1], temp, temp0, temp1);
260
+    }
261
+#endif
262
+}
263
+
264
+/* ---------------------------------------------------------------- */
265
+
266
+void KeccakP1600_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length)
267
+{
268
+    SnP_OverwriteBytes(state, data, offset, length, KeccakP1600_OverwriteLanes, KeccakP1600_OverwriteBytesInLane, 8);
269
+}
270
+
271
+/* ---------------------------------------------------------------- */
272
+
273
+void KeccakP1600_OverwriteWithZeroes(void *state, unsigned int byteCount)
274
+{
275
+    UINT32 *stateAsHalfLanes = (UINT32*)state;
276
+    unsigned int i;
277
+
278
+    for(i=0; i<byteCount/8; i++) {
279
+        stateAsHalfLanes[i*2+0] = 0;
280
+        stateAsHalfLanes[i*2+1] = 0;
281
+    }
282
+    if (byteCount%8 != 0)
283
+        KeccakP1600_SetBytesInLaneToZero(state, byteCount/8, 0, byteCount%8);
284
+}
285
+
286
+/* ---------------------------------------------------------------- */
287
+
288
+void KeccakP1600_ExtractBytesInLane(const void *state, unsigned int lanePosition, unsigned char *data, unsigned int offset, unsigned int length)
289
+{
290
+    UINT32 *stateAsHalfLanes = (UINT32*)state;
291
+    UINT32 low, high, temp, temp0, temp1;
292
+    UINT8 laneAsBytes[8];
293
+
294
+    fromBitInterleaving(stateAsHalfLanes[lanePosition*2], stateAsHalfLanes[lanePosition*2+1], low, high, temp, temp0, temp1);
295
+#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
296
+    *((UINT32*)(laneAsBytes+0)) = low;
297
+    *((UINT32*)(laneAsBytes+4)) = high;
298
+#else
299
+    laneAsBytes[0] = low & 0xFF;
300
+    laneAsBytes[1] = (low >> 8) & 0xFF;
301
+    laneAsBytes[2] = (low >> 16) & 0xFF;
302
+    laneAsBytes[3] = (low >> 24) & 0xFF;
303
+    laneAsBytes[4] = high & 0xFF;
304
+    laneAsBytes[5] = (high >> 8) & 0xFF;
305
+    laneAsBytes[6] = (high >> 16) & 0xFF;
306
+    laneAsBytes[7] = (high >> 24) & 0xFF;
307
+#endif
308
+    memcpy(data, laneAsBytes+offset, length);
309
+}
310
+
311
+/* ---------------------------------------------------------------- */
312
+
313
+void KeccakP1600_ExtractLanes(const void *state, unsigned char *data, unsigned int laneCount)
314
+{
315
+#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
316
+    UINT32 * pI = (UINT32 *)data;
317
+    const UINT32 * pS = ( const UINT32 *)state;
318
+    UINT32 t, x0, x1;
319
+    int i;
320
+    for (i = laneCount-1; i >= 0; --i) {
321
+#ifdef NO_MISALIGNED_ACCESSES
322
+        UINT32 low;
323
+        UINT32 high;
324
+        fromBitInterleaving(*(pS++), *(pS++), low, high, t, x0, x1);
325
+        memcpy(pI++, &low, 4);
326
+        memcpy(pI++, &high, 4);
327
+#else
328
+        fromBitInterleaving(*(pS++), *(pS++), *(pI++), *(pI++), t, x0, x1)
329
+#endif
330
+    }
331
+#else
332
+    unsigned int lanePosition;
333
+    for(lanePosition=0; lanePosition<laneCount; lanePosition++) {
334
+        UINT32 *stateAsHalfLanes = (UINT32*)state;
335
+        UINT32 low, high, temp, temp0, temp1;
336
+        UINT8 laneAsBytes[8];
337
+        fromBitInterleaving(stateAsHalfLanes[lanePosition*2], stateAsHalfLanes[lanePosition*2+1], low, high, temp, temp0, temp1);
338
+        laneAsBytes[0] = low & 0xFF;
339
+        laneAsBytes[1] = (low >> 8) & 0xFF;
340
+        laneAsBytes[2] = (low >> 16) & 0xFF;
341
+        laneAsBytes[3] = (low >> 24) & 0xFF;
342
+        laneAsBytes[4] = high & 0xFF;
343
+        laneAsBytes[5] = (high >> 8) & 0xFF;
344
+        laneAsBytes[6] = (high >> 16) & 0xFF;
345
+        laneAsBytes[7] = (high >> 24) & 0xFF;
346
+        memcpy(data+lanePosition*8, laneAsBytes, 8);
347
+    }
348
+#endif
349
+}
350
+
351
+/* ---------------------------------------------------------------- */
352
+
353
+void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length)
354
+{
355
+    SnP_ExtractBytes(state, data, offset, length, KeccakP1600_ExtractLanes, KeccakP1600_ExtractBytesInLane, 8);
356
+}
357
+
358
+/* ---------------------------------------------------------------- */
359
+
360
+void KeccakP1600_ExtractAndAddBytesInLane(const void *state, unsigned int lanePosition, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length)
361
+{
362
+    UINT32 *stateAsHalfLanes = (UINT32*)state;
363
+    UINT32 low, high, temp, temp0, temp1;
364
+    UINT8 laneAsBytes[8];
365
+    unsigned int i;
366
+
367
+    fromBitInterleaving(stateAsHalfLanes[lanePosition*2], stateAsHalfLanes[lanePosition*2+1], low, high, temp, temp0, temp1);
368
+#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
369
+    *((UINT32*)(laneAsBytes+0)) = low;
370
+    *((UINT32*)(laneAsBytes+4)) = high;
371
+#else
372
+    laneAsBytes[0] = low & 0xFF;
373
+    laneAsBytes[1] = (low >> 8) & 0xFF;
374
+    laneAsBytes[2] = (low >> 16) & 0xFF;
375
+    laneAsBytes[3] = (low >> 24) & 0xFF;
376
+    laneAsBytes[4] = high & 0xFF;
377
+    laneAsBytes[5] = (high >> 8) & 0xFF;
378
+    laneAsBytes[6] = (high >> 16) & 0xFF;
379
+    laneAsBytes[7] = (high >> 24) & 0xFF;
380
+#endif
381
+    for(i=0; i<length; i++)
382
+        output[i] = input[i] ^ laneAsBytes[offset+i];
383
+}
384
+
385
+/* ---------------------------------------------------------------- */
386
+
387
+void KeccakP1600_ExtractAndAddLanes(const void *state, const unsigned char *input, unsigned char *output, unsigned int laneCount)
388
+{
389
+#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
390
+    const UINT32 * pI = (const UINT32 *)input;
391
+    UINT32 * pO = (UINT32 *)output;
392
+    const UINT32 * pS = (const UINT32 *)state;
393
+    UINT32 t, x0, x1;
394
+    int i;
395
+    for (i = laneCount-1; i >= 0; --i) {
396
+#ifdef NO_MISALIGNED_ACCESSES
397
+        UINT32 low;
398
+        UINT32 high;
399
+        fromBitInterleaving(*(pS++), *(pS++), low, high, t, x0, x1);
400
+        *(pO++) = *(pI++) ^ low;
401
+        *(pO++) = *(pI++) ^ high;
402
+#else
403
+        fromBitInterleavingAndXOR(*(pS++), *(pS++), *(pI++), *(pI++), *(pO++), *(pO++), t, x0, x1)
404
+#endif
405
+    }
406
+#else
407
+    unsigned int lanePosition;
408
+    for(lanePosition=0; lanePosition<laneCount; lanePosition++) {
409
+        UINT32 *stateAsHalfLanes = (UINT32*)state;
410
+        UINT32 low, high, temp, temp0, temp1;
411
+        UINT8 laneAsBytes[8];
412
+        fromBitInterleaving(stateAsHalfLanes[lanePosition*2], stateAsHalfLanes[lanePosition*2+1], low, high, temp, temp0, temp1);
413
+        laneAsBytes[0] = low & 0xFF;
414
+        laneAsBytes[1] = (low >> 8) & 0xFF;
415
+        laneAsBytes[2] = (low >> 16) & 0xFF;
416
+        laneAsBytes[3] = (low >> 24) & 0xFF;
417
+        laneAsBytes[4] = high & 0xFF;
418
+        laneAsBytes[5] = (high >> 8) & 0xFF;
419
+        laneAsBytes[6] = (high >> 16) & 0xFF;
420
+        laneAsBytes[7] = (high >> 24) & 0xFF;
421
+        ((UINT32*)(output+lanePosition*8))[0] = ((UINT32*)(input+lanePosition*8))[0] ^ (*(const UINT32*)(laneAsBytes+0));
422
+        ((UINT32*)(output+lanePosition*8))[1] = ((UINT32*)(input+lanePosition*8))[0] ^ (*(const UINT32*)(laneAsBytes+4));
423
+    }
424
+#endif
425
+}
426
+/* ---------------------------------------------------------------- */
427
+
428
+void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length)
429
+{
430
+    SnP_ExtractAndAddBytes(state, input, output, offset, length, KeccakP1600_ExtractAndAddLanes, KeccakP1600_ExtractAndAddBytesInLane, 8);
431
+}
432
+
433
+/* ---------------------------------------------------------------- */
434
+
435
+static const UINT32 KeccakF1600RoundConstants_int2[2*24+1] =
436
+{
437
+    0x00000001UL,    0x00000000UL,
438
+    0x00000000UL,    0x00000089UL,
439
+    0x00000000UL,    0x8000008bUL,
440
+    0x00000000UL,    0x80008080UL,
441
+    0x00000001UL,    0x0000008bUL,
442
+    0x00000001UL,    0x00008000UL,
443
+    0x00000001UL,    0x80008088UL,
444
+    0x00000001UL,    0x80000082UL,
445
+    0x00000000UL,    0x0000000bUL,
446
+    0x00000000UL,    0x0000000aUL,
447
+    0x00000001UL,    0x00008082UL,
448
+    0x00000000UL,    0x00008003UL,
449
+    0x00000001UL,    0x0000808bUL,
450
+    0x00000001UL,    0x8000000bUL,
451
+    0x00000001UL,    0x8000008aUL,
452
+    0x00000001UL,    0x80000081UL,
453
+    0x00000000UL,    0x80000081UL,
454
+    0x00000000UL,    0x80000008UL,
455
+    0x00000000UL,    0x00000083UL,
456
+    0x00000000UL,    0x80008003UL,
457
+    0x00000001UL,    0x80008088UL,
458
+    0x00000000UL,    0x80000088UL,
459
+    0x00000001UL,    0x00008000UL,
460
+    0x00000000UL,    0x80008082UL,
461
+    0x000000FFUL
462
+};
463
+
464
+#define KeccakAtoD_round0() \
465
+        Cx = Abu0^Agu0^Aku0^Amu0^Asu0; \
466
+        Du1 = Abe1^Age1^Ake1^Ame1^Ase1; \
467
+        Da0 = Cx^ROL32(Du1, 1); \
468
+        Cz = Abu1^Agu1^Aku1^Amu1^Asu1; \
469
+        Du0 = Abe0^Age0^Ake0^Ame0^Ase0; \
470
+        Da1 = Cz^Du0; \
471
+\
472
+        Cw = Abi0^Agi0^Aki0^Ami0^Asi0; \
473
+        Do0 = Cw^ROL32(Cz, 1); \
474
+        Cy = Abi1^Agi1^Aki1^Ami1^Asi1; \
475
+        Do1 = Cy^Cx; \
476
+\
477
+        Cx = Aba0^Aga0^Aka0^Ama0^Asa0; \
478
+        De0 = Cx^ROL32(Cy, 1); \
479
+        Cz = Aba1^Aga1^Aka1^Ama1^Asa1; \
480
+        De1 = Cz^Cw; \
481
+\
482
+        Cy = Abo1^Ago1^Ako1^Amo1^Aso1; \
483
+        Di0 = Du0^ROL32(Cy, 1); \
484
+        Cw = Abo0^Ago0^Ako0^Amo0^Aso0; \
485
+        Di1 = Du1^Cw; \
486
+\
487
+        Du0 = Cw^ROL32(Cz, 1); \
488
+        Du1 = Cy^Cx; \
489
+
490
+#define KeccakAtoD_round1() \
491
+        Cx = Asu0^Agu0^Amu0^Abu1^Aku1; \
492
+        Du1 = Age1^Ame0^Abe0^Ake1^Ase1; \
493
+        Da0 = Cx^ROL32(Du1, 1); \
494
+        Cz = Asu1^Agu1^Amu1^Abu0^Aku0; \
495
+        Du0 = Age0^Ame1^Abe1^Ake0^Ase0; \
496
+        Da1 = Cz^Du0; \
497
+\
498
+        Cw = Aki1^Asi1^Agi0^Ami1^Abi0; \
499
+        Do0 = Cw^ROL32(Cz, 1); \
500
+        Cy = Aki0^Asi0^Agi1^Ami0^Abi1; \
501
+        Do1 = Cy^Cx; \
502
+\
503
+        Cx = Aba0^Aka1^Asa0^Aga0^Ama1; \
504
+        De0 = Cx^ROL32(Cy, 1); \
505
+        Cz = Aba1^Aka0^Asa1^Aga1^Ama0; \
506
+        De1 = Cz^Cw; \
507
+\
508
+        Cy = Amo0^Abo1^Ako0^Aso1^Ago0; \
509
+        Di0 = Du0^ROL32(Cy, 1); \
510
+        Cw = Amo1^Abo0^Ako1^Aso0^Ago1; \
511
+        Di1 = Du1^Cw; \
512
+\
513
+        Du0 = Cw^ROL32(Cz, 1); \
514
+        Du1 = Cy^Cx; \
515
+
516
+#define KeccakAtoD_round2() \
517
+        Cx = Aku1^Agu0^Abu1^Asu1^Amu1; \
518
+        Du1 = Ame0^Ake0^Age0^Abe0^Ase1; \
519
+        Da0 = Cx^ROL32(Du1, 1); \
520
+        Cz = Aku0^Agu1^Abu0^Asu0^Amu0; \
521
+        Du0 = Ame1^Ake1^Age1^Abe1^Ase0; \
522
+        Da1 = Cz^Du0; \
523
+\
524
+        Cw = Agi1^Abi1^Asi1^Ami0^Aki1; \
525
+        Do0 = Cw^ROL32(Cz, 1); \
526
+        Cy = Agi0^Abi0^Asi0^Ami1^Aki0; \
527
+        Do1 = Cy^Cx; \
528
+\
529
+        Cx = Aba0^Asa1^Ama1^Aka1^Aga1; \
530
+        De0 = Cx^ROL32(Cy, 1); \
531
+        Cz = Aba1^Asa0^Ama0^Aka0^Aga0; \
532
+        De1 = Cz^Cw; \
533
+\
534
+        Cy = Aso0^Amo0^Ako1^Ago0^Abo0; \
535
+        Di0 = Du0^ROL32(Cy, 1); \
536
+        Cw = Aso1^Amo1^Ako0^Ago1^Abo1; \
537
+        Di1 = Du1^Cw; \
538
+\
539
+        Du0 = Cw^ROL32(Cz, 1); \
540
+        Du1 = Cy^Cx; \
541
+
542
+#define KeccakAtoD_round3() \
543
+        Cx = Amu1^Agu0^Asu1^Aku0^Abu0; \
544
+        Du1 = Ake0^Abe1^Ame1^Age0^Ase1; \
545
+        Da0 = Cx^ROL32(Du1, 1); \
546
+        Cz = Amu0^Agu1^Asu0^Aku1^Abu1; \
547
+        Du0 = Ake1^Abe0^Ame0^Age1^Ase0; \
548
+        Da1 = Cz^Du0; \
549
+\
550
+        Cw = Asi0^Aki0^Abi1^Ami1^Agi1; \
551
+        Do0 = Cw^ROL32(Cz, 1); \
552
+        Cy = Asi1^Aki1^Abi0^Ami0^Agi0; \
553
+        Do1 = Cy^Cx; \
554
+\
555
+        Cx = Aba0^Ama0^Aga1^Asa1^Aka0; \
556
+        De0 = Cx^ROL32(Cy, 1); \
557
+        Cz = Aba1^Ama1^Aga0^Asa0^Aka1; \
558
+        De1 = Cz^Cw; \
559
+\
560
+        Cy = Ago1^Aso0^Ako0^Abo0^Amo1; \
561
+        Di0 = Du0^ROL32(Cy, 1); \
562
+        Cw = Ago0^Aso1^Ako1^Abo1^Amo0; \
563
+        Di1 = Du1^Cw; \
564
+\
565
+        Du0 = Cw^ROL32(Cz, 1); \
566
+        Du1 = Cy^Cx; \
567
+
568
+void KeccakP1600_Permute_Nrounds(void *state, unsigned int nRounds)
569
+{
570
+    {
571
+        UINT32 Da0, De0, Di0, Do0, Du0;
572
+        UINT32 Da1, De1, Di1, Do1, Du1;
573
+        UINT32 Ca0, Ce0, Ci0, Co0, Cu0;
574
+        UINT32 Cx, Cy, Cz, Cw;
575
+        #define Ba Ca0
576
+        #define Be Ce0
577
+        #define Bi Ci0
578
+        #define Bo Co0
579
+        #define Bu Cu0
580
+        const UINT32 *pRoundConstants = KeccakF1600RoundConstants_int2+(24-nRounds)*2;
581
+        UINT32 *stateAsHalfLanes = (UINT32*)state;
582
+        #define Aba0 stateAsHalfLanes[ 0]
583
+        #define Aba1 stateAsHalfLanes[ 1]
584
+        #define Abe0 stateAsHalfLanes[ 2]
585
+        #define Abe1 stateAsHalfLanes[ 3]
586
+        #define Abi0 stateAsHalfLanes[ 4]
587
+        #define Abi1 stateAsHalfLanes[ 5]
588
+        #define Abo0 stateAsHalfLanes[ 6]
589
+        #define Abo1 stateAsHalfLanes[ 7]
590
+        #define Abu0 stateAsHalfLanes[ 8]
591
+        #define Abu1 stateAsHalfLanes[ 9]
592
+        #define Aga0 stateAsHalfLanes[10]
593
+        #define Aga1 stateAsHalfLanes[11]
594
+        #define Age0 stateAsHalfLanes[12]
595
+        #define Age1 stateAsHalfLanes[13]
596
+        #define Agi0 stateAsHalfLanes[14]
597
+        #define Agi1 stateAsHalfLanes[15]
598
+        #define Ago0 stateAsHalfLanes[16]
599
+        #define Ago1 stateAsHalfLanes[17]
600
+        #define Agu0 stateAsHalfLanes[18]
601
+        #define Agu1 stateAsHalfLanes[19]
602
+        #define Aka0 stateAsHalfLanes[20]
603
+        #define Aka1 stateAsHalfLanes[21]
604
+        #define Ake0 stateAsHalfLanes[22]
605
+        #define Ake1 stateAsHalfLanes[23]
606
+        #define Aki0 stateAsHalfLanes[24]
607
+        #define Aki1 stateAsHalfLanes[25]
608
+        #define Ako0 stateAsHalfLanes[26]
609
+        #define Ako1 stateAsHalfLanes[27]
610
+        #define Aku0 stateAsHalfLanes[28]
611
+        #define Aku1 stateAsHalfLanes[29]
612
+        #define Ama0 stateAsHalfLanes[30]
613
+        #define Ama1 stateAsHalfLanes[31]
614
+        #define Ame0 stateAsHalfLanes[32]
615
+        #define Ame1 stateAsHalfLanes[33]
616
+        #define Ami0 stateAsHalfLanes[34]
617
+        #define Ami1 stateAsHalfLanes[35]
618
+        #define Amo0 stateAsHalfLanes[36]
619
+        #define Amo1 stateAsHalfLanes[37]
620
+        #define Amu0 stateAsHalfLanes[38]
621
+        #define Amu1 stateAsHalfLanes[39]
622
+        #define Asa0 stateAsHalfLanes[40]
623
+        #define Asa1 stateAsHalfLanes[41]
624
+        #define Ase0 stateAsHalfLanes[42]
625
+        #define Ase1 stateAsHalfLanes[43]
626
+        #define Asi0 stateAsHalfLanes[44]
627
+        #define Asi1 stateAsHalfLanes[45]
628
+        #define Aso0 stateAsHalfLanes[46]
629
+        #define Aso1 stateAsHalfLanes[47]
630
+        #define Asu0 stateAsHalfLanes[48]
631
+        #define Asu1 stateAsHalfLanes[49]
632
+
633
+        do
634
+        {
635
+            /* --- Code for 4 rounds */
636
+
637
+            /* --- using factor 2 interleaving, 64-bit lanes mapped to 32-bit words */
638
+
639
+            KeccakAtoD_round0();
640
+
641
+            Ba = (Aba0^Da0);
642
+            Be = ROL32((Age0^De0), 22);
643
+            Bi = ROL32((Aki1^Di1), 22);
644
+            Bo = ROL32((Amo1^Do1), 11);
645
+            Bu = ROL32((Asu0^Du0), 7);
646
+            Aba0 =   Ba ^((~Be)&  Bi );
647
+            Aba0 ^= *(pRoundConstants++);
648
+            Age0 =   Be ^((~Bi)&  Bo );
649
+            Aki1 =   Bi ^((~Bo)&  Bu );
650
+            Amo1 =   Bo ^((~Bu)&  Ba );
651
+            Asu0 =   Bu ^((~Ba)&  Be );
652
+
653
+            Ba = (Aba1^Da1);
654
+            Be = ROL32((Age1^De1), 22);
655
+            Bi = ROL32((Aki0^Di0), 21);
656
+            Bo = ROL32((Amo0^Do0), 10);
657
+            Bu = ROL32((Asu1^Du1), 7);
658
+            Aba1 =   Ba ^((~Be)&  Bi );
659
+            Aba1 ^= *(pRoundConstants++);
660
+            Age1 =   Be ^((~Bi)&  Bo );
661
+            Aki0 =   Bi ^((~Bo)&  Bu );
662
+            Amo0 =   Bo ^((~Bu)&  Ba );
663
+            Asu1 =   Bu ^((~Ba)&  Be );
664
+
665
+            Bi = ROL32((Aka1^Da1), 2);
666
+            Bo = ROL32((Ame1^De1), 23);
667
+            Bu = ROL32((Asi1^Di1), 31);
668
+            Ba = ROL32((Abo0^Do0), 14);
669
+            Be = ROL32((Agu0^Du0), 10);
670
+            Aka1 =   Ba ^((~Be)&  Bi );
671
+            Ame1 =   Be ^((~Bi)&  Bo );
672
+            Asi1 =   Bi ^((~Bo)&  Bu );
673
+            Abo0 =   Bo ^((~Bu)&  Ba );
674
+            Agu0 =   Bu ^((~Ba)&  Be );
675
+
676
+            Bi = ROL32((Aka0^Da0), 1);
677
+            Bo = ROL32((Ame0^De0), 22);
678
+            Bu = ROL32((Asi0^Di0), 30);
679
+            Ba = ROL32((Abo1^Do1), 14);
680
+            Be = ROL32((Agu1^Du1), 10);
681
+            Aka0 =   Ba ^((~Be)&  Bi );
682
+            Ame0 =   Be ^((~Bi)&  Bo );
683
+            Asi0 =   Bi ^((~Bo)&  Bu );
684
+            Abo1 =   Bo ^((~Bu)&  Ba );
685
+            Agu1 =   Bu ^((~Ba)&  Be );
686
+
687
+            Bu = ROL32((Asa0^Da0), 9);
688
+            Ba = ROL32((Abe1^De1), 1);
689
+            Be = ROL32((Agi0^Di0), 3);
690
+            Bi = ROL32((Ako1^Do1), 13);
691
+            Bo = ROL32((Amu0^Du0), 4);
692
+            Asa0 =   Ba ^((~Be)&  Bi );
693
+            Abe1 =   Be ^((~Bi)&  Bo );
694
+            Agi0 =   Bi ^((~Bo)&  Bu );
695
+            Ako1 =   Bo ^((~Bu)&  Ba );
696
+            Amu0 =   Bu ^((~Ba)&  Be );
697
+
698
+            Bu = ROL32((Asa1^Da1), 9);
699
+            Ba = (Abe0^De0);
700
+            Be = ROL32((Agi1^Di1), 3);
701
+            Bi = ROL32((Ako0^Do0), 12);
702
+            Bo = ROL32((Amu1^Du1), 4);
703
+            Asa1 =   Ba ^((~Be)&  Bi );
704
+            Abe0 =   Be ^((~Bi)&  Bo );
705
+            Agi1 =   Bi ^((~Bo)&  Bu );
706
+            Ako0 =   Bo ^((~Bu)&  Ba );
707
+            Amu1 =   Bu ^((~Ba)&  Be );
708
+
709
+            Be = ROL32((Aga0^Da0), 18);
710
+            Bi = ROL32((Ake0^De0), 5);
711
+            Bo = ROL32((Ami1^Di1), 8);
712
+            Bu = ROL32((Aso0^Do0), 28);
713
+            Ba = ROL32((Abu1^Du1), 14);
714
+            Aga0 =   Ba ^((~Be)&  Bi );
715
+            Ake0 =   Be ^((~Bi)&  Bo );
716
+            Ami1 =   Bi ^((~Bo)&  Bu );
717
+            Aso0 =   Bo ^((~Bu)&  Ba );
718
+            Abu1 =   Bu ^((~Ba)&  Be );
719
+
720
+            Be = ROL32((Aga1^Da1), 18);
721
+            Bi = ROL32((Ake1^De1), 5);
722
+            Bo = ROL32((Ami0^Di0), 7);
723
+            Bu = ROL32((Aso1^Do1), 28);
724
+            Ba = ROL32((Abu0^Du0), 13);
725
+            Aga1 =   Ba ^((~Be)&  Bi );
726
+            Ake1 =   Be ^((~Bi)&  Bo );
727
+            Ami0 =   Bi ^((~Bo)&  Bu );
728
+            Aso1 =   Bo ^((~Bu)&  Ba );
729
+            Abu0 =   Bu ^((~Ba)&  Be );
730
+
731
+            Bo = ROL32((Ama1^Da1), 21);
732
+            Bu = ROL32((Ase0^De0), 1);
733
+            Ba = ROL32((Abi0^Di0), 31);
734
+            Be = ROL32((Ago1^Do1), 28);
735
+            Bi = ROL32((Aku1^Du1), 20);
736
+            Ama1 =   Ba ^((~Be)&  Bi );
737
+            Ase0 =   Be ^((~Bi)&  Bo );
738
+            Abi0 =   Bi ^((~Bo)&  Bu );
739
+            Ago1 =   Bo ^((~Bu)&  Ba );
740
+            Aku1 =   Bu ^((~Ba)&  Be );
741
+
742
+            Bo = ROL32((Ama0^Da0), 20);
743
+            Bu = ROL32((Ase1^De1), 1);
744
+            Ba = ROL32((Abi1^Di1), 31);
745
+            Be = ROL32((Ago0^Do0), 27);
746
+            Bi = ROL32((Aku0^Du0), 19);
747
+            Ama0 =   Ba ^((~Be)&  Bi );
748
+            Ase1 =   Be ^((~Bi)&  Bo );
749
+            Abi1 =   Bi ^((~Bo)&  Bu );
750
+            Ago0 =   Bo ^((~Bu)&  Ba );
751
+            Aku0 =   Bu ^((~Ba)&  Be );
752
+
753
+            KeccakAtoD_round1();
754
+
755
+            Ba = (Aba0^Da0);
756
+            Be = ROL32((Ame1^De0), 22);
757
+            Bi = ROL32((Agi1^Di1), 22);
758
+            Bo = ROL32((Aso1^Do1), 11);
759
+            Bu = ROL32((Aku1^Du0), 7);
760
+            Aba0 =   Ba ^((~Be)&  Bi );
761
+            Aba0 ^= *(pRoundConstants++);
762
+            Ame1 =   Be ^((~Bi)&  Bo );
763
+            Agi1 =   Bi ^((~Bo)&  Bu );
764
+            Aso1 =   Bo ^((~Bu)&  Ba );
765
+            Aku1 =   Bu ^((~Ba)&  Be );
766
+
767
+            Ba = (Aba1^Da1);
768
+            Be = ROL32((Ame0^De1), 22);
769
+            Bi = ROL32((Agi0^Di0), 21);
770
+            Bo = ROL32((Aso0^Do0), 10);
771
+            Bu = ROL32((Aku0^Du1), 7);
772
+            Aba1 =   Ba ^((~Be)&  Bi );
773
+            Aba1 ^= *(pRoundConstants++);
774
+            Ame0 =   Be ^((~Bi)&  Bo );
775
+            Agi0 =   Bi ^((~Bo)&  Bu );
776
+            Aso0 =   Bo ^((~Bu)&  Ba );
777
+            Aku0 =   Bu ^((~Ba)&  Be );
778
+
779
+            Bi = ROL32((Asa1^Da1), 2);
780
+            Bo = ROL32((Ake1^De1), 23);
781
+            Bu = ROL32((Abi1^Di1), 31);
782
+            Ba = ROL32((Amo1^Do0), 14);
783
+            Be = ROL32((Agu0^Du0), 10);
784
+            Asa1 =   Ba ^((~Be)&  Bi );
785
+            Ake1 =   Be ^((~Bi)&  Bo );
786
+            Abi1 =   Bi ^((~Bo)&  Bu );
787
+            Amo1 =   Bo ^((~Bu)&  Ba );
788
+            Agu0 =   Bu ^((~Ba)&  Be );
789
+
790
+            Bi = ROL32((Asa0^Da0), 1);
791
+            Bo = ROL32((Ake0^De0), 22);
792
+            Bu = ROL32((Abi0^Di0), 30);
793
+            Ba = ROL32((Amo0^Do1), 14);
794
+            Be = ROL32((Agu1^Du1), 10);
795
+            Asa0 =   Ba ^((~Be)&  Bi );
796
+            Ake0 =   Be ^((~Bi)&  Bo );
797
+            Abi0 =   Bi ^((~Bo)&  Bu );
798
+            Amo0 =   Bo ^((~Bu)&  Ba );
799
+            Agu1 =   Bu ^((~Ba)&  Be );
800
+
801
+            Bu = ROL32((Ama1^Da0), 9);
802
+            Ba = ROL32((Age1^De1), 1);
803
+            Be = ROL32((Asi1^Di0), 3);
804
+            Bi = ROL32((Ako0^Do1), 13);
805
+            Bo = ROL32((Abu1^Du0), 4);
806
+            Ama1 =   Ba ^((~Be)&  Bi );
807
+            Age1 =   Be ^((~Bi)&  Bo );
808
+            Asi1 =   Bi ^((~Bo)&  Bu );
809
+            Ako0 =   Bo ^((~Bu)&  Ba );
810
+            Abu1 =   Bu ^((~Ba)&  Be );
811
+
812
+            Bu = ROL32((Ama0^Da1), 9);
813
+            Ba = (Age0^De0);
814
+            Be = ROL32((Asi0^Di1), 3);
815
+            Bi = ROL32((Ako1^Do0), 12);
816
+            Bo = ROL32((Abu0^Du1), 4);
817
+            Ama0 =   Ba ^((~Be)&  Bi );
818
+            Age0 =   Be ^((~Bi)&  Bo );
819
+            Asi0 =   Bi ^((~Bo)&  Bu );
820
+            Ako1 =   Bo ^((~Bu)&  Ba );
821
+            Abu0 =   Bu ^((~Ba)&  Be );
822
+
823
+            Be = ROL32((Aka1^Da0), 18);
824
+            Bi = ROL32((Abe1^De0), 5);
825
+            Bo = ROL32((Ami0^Di1), 8);
826
+            Bu = ROL32((Ago1^Do0), 28);
827
+            Ba = ROL32((Asu1^Du1), 14);
828
+            Aka1 =   Ba ^((~Be)&  Bi );
829
+            Abe1 =   Be ^((~Bi)&  Bo );
830
+            Ami0 =   Bi ^((~Bo)&  Bu );
831
+            Ago1 =   Bo ^((~Bu)&  Ba );
832
+            Asu1 =   Bu ^((~Ba)&  Be );
833
+
834
+            Be = ROL32((Aka0^Da1), 18);
835
+            Bi = ROL32((Abe0^De1), 5);
836
+            Bo = ROL32((Ami1^Di0), 7);
837
+            Bu = ROL32((Ago0^Do1), 28);
838
+            Ba = ROL32((Asu0^Du0), 13);
839
+            Aka0 =   Ba ^((~Be)&  Bi );
840
+            Abe0 =   Be ^((~Bi)&  Bo );
841
+            Ami1 =   Bi ^((~Bo)&  Bu );
842
+            Ago0 =   Bo ^((~Bu)&  Ba );
843
+            Asu0 =   Bu ^((~Ba)&  Be );
844
+
845
+            Bo = ROL32((Aga1^Da1), 21);
846
+            Bu = ROL32((Ase0^De0), 1);
847
+            Ba = ROL32((Aki1^Di0), 31);
848
+            Be = ROL32((Abo1^Do1), 28);
849
+            Bi = ROL32((Amu1^Du1), 20);
850
+            Aga1 =   Ba ^((~Be)&  Bi );
851
+            Ase0 =   Be ^((~Bi)&  Bo );
852
+            Aki1 =   Bi ^((~Bo)&  Bu );
853
+            Abo1 =   Bo ^((~Bu)&  Ba );
854
+            Amu1 =   Bu ^((~Ba)&  Be );
855
+
856
+            Bo = ROL32((Aga0^Da0), 20);
857
+            Bu = ROL32((Ase1^De1), 1);
858
+            Ba = ROL32((Aki0^Di1), 31);
859
+            Be = ROL32((Abo0^Do0), 27);
860
+            Bi = ROL32((Amu0^Du0), 19);
861
+            Aga0 =   Ba ^((~Be)&  Bi );
862
+            Ase1 =   Be ^((~Bi)&  Bo );
863
+            Aki0 =   Bi ^((~Bo)&  Bu );
864
+            Abo0 =   Bo ^((~Bu)&  Ba );
865
+            Amu0 =   Bu ^((~Ba)&  Be );
866
+
867
+            KeccakAtoD_round2();
868
+
869
+            Ba = (Aba0^Da0);
870
+            Be = ROL32((Ake1^De0), 22);
871
+            Bi = ROL32((Asi0^Di1), 22);
872
+            Bo = ROL32((Ago0^Do1), 11);
873
+            Bu = ROL32((Amu1^Du0), 7);
874
+            Aba0 =   Ba ^((~Be)&  Bi );
875
+            Aba0 ^= *(pRoundConstants++);
876
+            Ake1 =   Be ^((~Bi)&  Bo );
877
+            Asi0 =   Bi ^((~Bo)&  Bu );
878
+            Ago0 =   Bo ^((~Bu)&  Ba );
879
+            Amu1 =   Bu ^((~Ba)&  Be );
880
+
881
+            Ba = (Aba1^Da1);
882
+            Be = ROL32((Ake0^De1), 22);
883
+            Bi = ROL32((Asi1^Di0), 21);
884
+            Bo = ROL32((Ago1^Do0), 10);
885
+            Bu = ROL32((Amu0^Du1), 7);
886
+            Aba1 =   Ba ^((~Be)&  Bi );
887
+            Aba1 ^= *(pRoundConstants++);
888
+            Ake0 =   Be ^((~Bi)&  Bo );
889
+            Asi1 =   Bi ^((~Bo)&  Bu );
890
+            Ago1 =   Bo ^((~Bu)&  Ba );
891
+            Amu0 =   Bu ^((~Ba)&  Be );
892
+
893
+            Bi = ROL32((Ama0^Da1), 2);
894
+            Bo = ROL32((Abe0^De1), 23);
895
+            Bu = ROL32((Aki0^Di1), 31);
896
+            Ba = ROL32((Aso1^Do0), 14);
897
+            Be = ROL32((Agu0^Du0), 10);
898
+            Ama0 =   Ba ^((~Be)&  Bi );
899
+            Abe0 =   Be ^((~Bi)&  Bo );
900
+            Aki0 =   Bi ^((~Bo)&  Bu );
901
+            Aso1 =   Bo ^((~Bu)&  Ba );
902
+            Agu0 =   Bu ^((~Ba)&  Be );
903
+
904
+            Bi = ROL32((Ama1^Da0), 1);
905
+            Bo = ROL32((Abe1^De0), 22);
906
+            Bu = ROL32((Aki1^Di0), 30);
907
+            Ba = ROL32((Aso0^Do1), 14);
908
+            Be = ROL32((Agu1^Du1), 10);
909
+            Ama1 =   Ba ^((~Be)&  Bi );
910
+            Abe1 =   Be ^((~Bi)&  Bo );
911
+            Aki1 =   Bi ^((~Bo)&  Bu );
912
+            Aso0 =   Bo ^((~Bu)&  Ba );
913
+            Agu1 =   Bu ^((~Ba)&  Be );
914
+
915
+            Bu = ROL32((Aga1^Da0), 9);
916
+            Ba = ROL32((Ame0^De1), 1);
917
+            Be = ROL32((Abi1^Di0), 3);
918
+            Bi = ROL32((Ako1^Do1), 13);
919
+            Bo = ROL32((Asu1^Du0), 4);
920
+            Aga1 =   Ba ^((~Be)&  Bi );
921
+            Ame0 =   Be ^((~Bi)&  Bo );
922
+            Abi1 =   Bi ^((~Bo)&  Bu );
923
+            Ako1 =   Bo ^((~Bu)&  Ba );
924
+            Asu1 =   Bu ^((~Ba)&  Be );
925
+
926
+            Bu = ROL32((Aga0^Da1), 9);
927
+            Ba = (Ame1^De0);
928
+            Be = ROL32((Abi0^Di1), 3);
929
+            Bi = ROL32((Ako0^Do0), 12);
930
+            Bo = ROL32((Asu0^Du1), 4);
931
+            Aga0 =   Ba ^((~Be)&  Bi );
932
+            Ame1 =   Be ^((~Bi)&  Bo );
933
+            Abi0 =   Bi ^((~Bo)&  Bu );
934
+            Ako0 =   Bo ^((~Bu)&  Ba );
935
+            Asu0 =   Bu ^((~Ba)&  Be );
936
+
937
+            Be = ROL32((Asa1^Da0), 18);
938
+            Bi = ROL32((Age1^De0), 5);
939
+            Bo = ROL32((Ami1^Di1), 8);
940
+            Bu = ROL32((Abo1^Do0), 28);
941
+            Ba = ROL32((Aku0^Du1), 14);
942
+            Asa1 =   Ba ^((~Be)&  Bi );
943
+            Age1 =   Be ^((~Bi)&  Bo );
944
+            Ami1 =   Bi ^((~Bo)&  Bu );
945
+            Abo1 =   Bo ^((~Bu)&  Ba );
946
+            Aku0 =   Bu ^((~Ba)&  Be );
947
+
948
+            Be = ROL32((Asa0^Da1), 18);
949
+            Bi = ROL32((Age0^De1), 5);
950
+            Bo = ROL32((Ami0^Di0), 7);
951
+            Bu = ROL32((Abo0^Do1), 28);
952
+            Ba = ROL32((Aku1^Du0), 13);
953
+            Asa0 =   Ba ^((~Be)&  Bi );
954
+            Age0 =   Be ^((~Bi)&  Bo );
955
+            Ami0 =   Bi ^((~Bo)&  Bu );
956
+            Abo0 =   Bo ^((~Bu)&  Ba );
957
+            Aku1 =   Bu ^((~Ba)&  Be );
958
+
959
+            Bo = ROL32((Aka0^Da1), 21);
960
+            Bu = ROL32((Ase0^De0), 1);
961
+            Ba = ROL32((Agi1^Di0), 31);
962
+            Be = ROL32((Amo0^Do1), 28);
963
+            Bi = ROL32((Abu0^Du1), 20);
964
+            Aka0 =   Ba ^((~Be)&  Bi );
965
+            Ase0 =   Be ^((~Bi)&  Bo );
966
+            Agi1 =   Bi ^((~Bo)&  Bu );
967
+            Amo0 =   Bo ^((~Bu)&  Ba );
968
+            Abu0 =   Bu ^((~Ba)&  Be );
969
+
970
+            Bo = ROL32((Aka1^Da0), 20);
971
+            Bu = ROL32((Ase1^De1), 1);
972
+            Ba = ROL32((Agi0^Di1), 31);
973
+            Be = ROL32((Amo1^Do0), 27);
974
+            Bi = ROL32((Abu1^Du0), 19);
975
+            Aka1 =   Ba ^((~Be)&  Bi );
976
+            Ase1 =   Be ^((~Bi)&  Bo );
977
+            Agi0 =   Bi ^((~Bo)&  Bu );
978
+            Amo1 =   Bo ^((~Bu)&  Ba );
979
+            Abu1 =   Bu ^((~Ba)&  Be );
980
+
981
+            KeccakAtoD_round3();
982
+
983
+            Ba = (Aba0^Da0);
984
+            Be = ROL32((Abe0^De0), 22);
985
+            Bi = ROL32((Abi0^Di1), 22);
986
+            Bo = ROL32((Abo0^Do1), 11);
987
+            Bu = ROL32((Abu0^Du0), 7);
988
+            Aba0 =   Ba ^((~Be)&  Bi );
989
+            Aba0 ^= *(pRoundConstants++);
990
+            Abe0 =   Be ^((~Bi)&  Bo );
991
+            Abi0 =   Bi ^((~Bo)&  Bu );
992
+            Abo0 =   Bo ^((~Bu)&  Ba );
993
+            Abu0 =   Bu ^((~Ba)&  Be );
994
+
995
+            Ba = (Aba1^Da1);
996
+            Be = ROL32((Abe1^De1), 22);
997
+            Bi = ROL32((Abi1^Di0), 21);
998
+            Bo = ROL32((Abo1^Do0), 10);
999
+            Bu = ROL32((Abu1^Du1), 7);
1000
+            Aba1 =   Ba ^((~Be)&  Bi );
1001
+            Aba1 ^= *(pRoundConstants++);
1002
+            Abe1 =   Be ^((~Bi)&  Bo );
1003
+            Abi1 =   Bi ^((~Bo)&  Bu );
1004
+            Abo1 =   Bo ^((~Bu)&  Ba );
1005
+            Abu1 =   Bu ^((~Ba)&  Be );
1006
+
1007
+            Bi = ROL32((Aga0^Da1), 2);
1008
+            Bo = ROL32((Age0^De1), 23);
1009
+            Bu = ROL32((Agi0^Di1), 31);
1010
+            Ba = ROL32((Ago0^Do0), 14);
1011
+            Be = ROL32((Agu0^Du0), 10);
1012
+            Aga0 =   Ba ^((~Be)&  Bi );
1013
+            Age0 =   Be ^((~Bi)&  Bo );
1014
+            Agi0 =   Bi ^((~Bo)&  Bu );
1015
+            Ago0 =   Bo ^((~Bu)&  Ba );
1016
+            Agu0 =   Bu ^((~Ba)&  Be );
1017
+
1018
+            Bi = ROL32((Aga1^Da0), 1);
1019
+            Bo = ROL32((Age1^De0), 22);
1020
+            Bu = ROL32((Agi1^Di0), 30);
1021
+            Ba = ROL32((Ago1^Do1), 14);
1022
+            Be = ROL32((Agu1^Du1), 10);
1023
+            Aga1 =   Ba ^((~Be)&  Bi );
1024
+            Age1 =   Be ^((~Bi)&  Bo );
1025
+            Agi1 =   Bi ^((~Bo)&  Bu );
1026
+            Ago1 =   Bo ^((~Bu)&  Ba );
1027
+            Agu1 =   Bu ^((~Ba)&  Be );
1028
+
1029
+            Bu = ROL32((Aka0^Da0), 9);
1030
+            Ba = ROL32((Ake0^De1), 1);
1031
+            Be = ROL32((Aki0^Di0), 3);
1032
+            Bi = ROL32((Ako0^Do1), 13);
1033
+            Bo = ROL32((Aku0^Du0), 4);
1034
+            Aka0 =   Ba ^((~Be)&  Bi );
1035
+            Ake0 =   Be ^((~Bi)&  Bo );
1036
+            Aki0 =   Bi ^((~Bo)&  Bu );
1037
+            Ako0 =   Bo ^((~Bu)&  Ba );
1038
+            Aku0 =   Bu ^((~Ba)&  Be );
1039
+
1040
+            Bu = ROL32((Aka1^Da1), 9);
1041
+            Ba = (Ake1^De0);
1042
+            Be = ROL32((Aki1^Di1), 3);
1043
+            Bi = ROL32((Ako1^Do0), 12);
1044
+            Bo = ROL32((Aku1^Du1), 4);
1045
+            Aka1 =   Ba ^((~Be)&  Bi );
1046
+            Ake1 =   Be ^((~Bi)&  Bo );
1047
+            Aki1 =   Bi ^((~Bo)&  Bu );
1048
+            Ako1 =   Bo ^((~Bu)&  Ba );
1049
+            Aku1 =   Bu ^((~Ba)&  Be );
1050
+
1051
+            Be = ROL32((Ama0^Da0), 18);
1052
+            Bi = ROL32((Ame0^De0), 5);
1053
+            Bo = ROL32((Ami0^Di1), 8);
1054
+            Bu = ROL32((Amo0^Do0), 28);
1055
+            Ba = ROL32((Amu0^Du1), 14);
1056
+            Ama0 =   Ba ^((~Be)&  Bi );
1057
+            Ame0 =   Be ^((~Bi)&  Bo );
1058
+            Ami0 =   Bi ^((~Bo)&  Bu );
1059
+            Amo0 =   Bo ^((~Bu)&  Ba );
1060
+            Amu0 =   Bu ^((~Ba)&  Be );
1061
+
1062
+            Be = ROL32((Ama1^Da1), 18);
1063
+            Bi = ROL32((Ame1^De1), 5);
1064
+            Bo = ROL32((Ami1^Di0), 7);
1065
+            Bu = ROL32((Amo1^Do1), 28);
1066
+            Ba = ROL32((Amu1^Du0), 13);
1067
+            Ama1 =   Ba ^((~Be)&  Bi );
1068
+            Ame1 =   Be ^((~Bi)&  Bo );
1069
+            Ami1 =   Bi ^((~Bo)&  Bu );
1070
+            Amo1 =   Bo ^((~Bu)&  Ba );
1071
+            Amu1 =   Bu ^((~Ba)&  Be );
1072
+
1073
+            Bo = ROL32((Asa0^Da1), 21);
1074
+            Bu = ROL32((Ase0^De0), 1);
1075
+            Ba = ROL32((Asi0^Di0), 31);
1076
+            Be = ROL32((Aso0^Do1), 28);
1077
+            Bi = ROL32((Asu0^Du1), 20);
1078
+            Asa0 =   Ba ^((~Be)&  Bi );
1079
+            Ase0 =   Be ^((~Bi)&  Bo );
1080
+            Asi0 =   Bi ^((~Bo)&  Bu );
1081
+            Aso0 =   Bo ^((~Bu)&  Ba );
1082
+            Asu0 =   Bu ^((~Ba)&  Be );
1083
+
1084
+            Bo = ROL32((Asa1^Da0), 20);
1085
+            Bu = ROL32((Ase1^De1), 1);
1086
+            Ba = ROL32((Asi1^Di1), 31);
1087
+            Be = ROL32((Aso1^Do0), 27);
1088
+            Bi = ROL32((Asu1^Du0), 19);
1089
+            Asa1 =   Ba ^((~Be)&  Bi );
1090
+            Ase1 =   Be ^((~Bi)&  Bo );
1091
+            Asi1 =   Bi ^((~Bo)&  Bu );
1092
+            Aso1 =   Bo ^((~Bu)&  Ba );
1093
+            Asu1 =   Bu ^((~Ba)&  Be );
1094
+        }
1095
+        while ( *pRoundConstants != 0xFF );
1096
+
1097
+        #undef Aba0
1098
+        #undef Aba1
1099
+        #undef Abe0
1100
+        #undef Abe1
1101
+        #undef Abi0
1102
+        #undef Abi1
1103
+        #undef Abo0
1104
+        #undef Abo1
1105
+        #undef Abu0
1106
+        #undef Abu1
1107
+        #undef Aga0
1108
+        #undef Aga1
1109
+        #undef Age0
1110
+        #undef Age1
1111
+        #undef Agi0
1112
+        #undef Agi1
1113
+        #undef Ago0
1114
+        #undef Ago1
1115
+        #undef Agu0
1116
+        #undef Agu1
1117
+        #undef Aka0
1118
+        #undef Aka1
1119
+        #undef Ake0
1120
+        #undef Ake1
1121
+        #undef Aki0
1122
+        #undef Aki1
1123
+        #undef Ako0
1124
+        #undef Ako1
1125
+        #undef Aku0
1126
+        #undef Aku1
1127
+        #undef Ama0
1128
+        #undef Ama1
1129
+        #undef Ame0
1130
+        #undef Ame1
1131
+        #undef Ami0
1132
+        #undef Ami1
1133
+        #undef Amo0
1134
+        #undef Amo1
1135
+        #undef Amu0
1136
+        #undef Amu1
1137
+        #undef Asa0
1138
+        #undef Asa1
1139
+        #undef Ase0
1140
+        #undef Ase1
1141
+        #undef Asi0
1142
+        #undef Asi1
1143
+        #undef Aso0
1144
+        #undef Aso1
1145
+        #undef Asu0
1146
+        #undef Asu1
1147
+    }
1148
+}
1149
+
1150
+/* ---------------------------------------------------------------- */
1151
+
1152
+void KeccakP1600_Permute_12rounds(void *state)
1153
+{
1154
+     KeccakP1600_Permute_Nrounds(state, 12);
1155
+}
1156
+
1157
+/* ---------------------------------------------------------------- */
1158
+
1159
+void KeccakP1600_Permute_24rounds(void *state)
1160
+{
1161
+     KeccakP1600_Permute_Nrounds(state, 24);
1162
+}
0 1163
new file mode 100644
... ...
@@ -0,0 +1,3 @@
1
+#define KeccakP1600_implementation_config "lane complementing, all rounds unrolled"
2
+#define KeccakP1600_fullUnrolling
3
+#define KeccakP1600_useLaneComplementing
0 4
new file mode 100644
... ...
@@ -0,0 +1,474 @@
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
+
21
+#if NOT_PYTHON
22
+typedef unsigned char UINT8;
23
+/* typedef unsigned long long int UINT64; */
24
+#endif
25
+
26
+#if defined(KeccakP1600_useLaneComplementing)
27
+#define UseBebigokimisa
28
+#endif
29
+
30
+#if defined(_MSC_VER)
31
+#define ROL64(a, offset) _rotl64(a, offset)
32
+#elif defined(KeccakP1600_useSHLD)
33
+    #define ROL64(x,N) ({ \
34
+    register UINT64 __out; \
35
+    register UINT64 __in = x; \
36
+    __asm__ ("shld %2,%0,%0" : "=r"(__out) : "0"(__in), "i"(N)); \
37
+    __out; \
38
+    })
39
+#else
40
+#define ROL64(a, offset) ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64-offset)))
41
+#endif
42
+
43
+#include "KeccakP-1600-64.macros"
44
+#ifdef KeccakP1600_fullUnrolling
45
+#define FullUnrolling
46
+#else
47
+#define Unrolling KeccakP1600_unrolling
48
+#endif
49
+#include "KeccakP-1600-unrolling.macros"
50
+#include "SnP-Relaned.h"
51
+
52
+static const UINT64 KeccakF1600RoundConstants[24] = {
53
+    0x0000000000000001ULL,
54
+    0x0000000000008082ULL,
55
+    0x800000000000808aULL,
56
+    0x8000000080008000ULL,
57
+    0x000000000000808bULL,
58
+    0x0000000080000001ULL,
59
+    0x8000000080008081ULL,
60
+    0x8000000000008009ULL,
61
+    0x000000000000008aULL,
62
+    0x0000000000000088ULL,
63
+    0x0000000080008009ULL,
64
+    0x000000008000000aULL,
65
+    0x000000008000808bULL,
66
+    0x800000000000008bULL,
67
+    0x8000000000008089ULL,
68
+    0x8000000000008003ULL,
69
+    0x8000000000008002ULL,
70
+    0x8000000000000080ULL,
71
+    0x000000000000800aULL,
72
+    0x800000008000000aULL,
73
+    0x8000000080008081ULL,
74
+    0x8000000000008080ULL,
75
+    0x0000000080000001ULL,
76
+    0x8000000080008008ULL };
77
+
78
+/* ---------------------------------------------------------------- */
79
+
80
+void KeccakP1600_Initialize(void *state)
81
+{
82
+    memset(state, 0, 200);
83
+#ifdef KeccakP1600_useLaneComplementing
84
+    ((UINT64*)state)[ 1] = ~(UINT64)0;
85
+    ((UINT64*)state)[ 2] = ~(UINT64)0;
86
+    ((UINT64*)state)[ 8] = ~(UINT64)0;
87
+    ((UINT64*)state)[12] = ~(UINT64)0;
88
+    ((UINT64*)state)[17] = ~(UINT64)0;
89
+    ((UINT64*)state)[20] = ~(UINT64)0;
90
+#endif
91
+}
92
+
93
+/* ---------------------------------------------------------------- */
94
+
95
+void KeccakP1600_AddBytesInLane(void *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length)
96
+{
97
+#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
98
+    UINT64 lane;
99
+    if (length == 0)
100
+        return;
101
+    if (length == 1)
102
+        lane = data[0];
103
+    else {
104
+        lane = 0;
105
+        memcpy(&lane, data, length);
106
+    }
107
+    lane <<= offset*8;
108
+#else
109
+    UINT64 lane = 0;
110
+    unsigned int i;
111
+    for(i=0; i<length; i++)
112
+        lane |= ((UINT64)data[i]) << ((i+offset)*8);
113
+#endif
114
+    ((UINT64*)state)[lanePosition] ^= lane;
115
+}
116
+
117
+/* ---------------------------------------------------------------- */
118
+
119
+void KeccakP1600_AddLanes(void *state, const unsigned char *data, unsigned int laneCount)
120
+{
121
+#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
122
+    unsigned int i = 0;
123
+#ifdef NO_MISALIGNED_ACCESSES
124
+    /* If either pointer is misaligned, fall back to byte-wise xor. */
125
+
126
+    if (((((uintptr_t)state) & 7) != 0) || ((((uintptr_t)data) & 7) != 0)) {
127
+      for (i = 0; i < laneCount * 8; i++) {
128
+        ((unsigned char*)state)[i] ^= data[i];
129
+      }
130
+    }
131
+    else
132
+#endif
133
+    {
134
+      /* Otherwise... */
135
+
136
+      for( ; (i+8)<=laneCount; i+=8) {
137
+          ((UINT64*)state)[i+0] ^= ((UINT64*)data)[i+0];
138
+          ((UINT64*)state)[i+1] ^= ((UINT64*)data)[i+1];
139
+          ((UINT64*)state)[i+2] ^= ((UINT64*)data)[i+2];
140
+          ((UINT64*)state)[i+3] ^= ((UINT64*)data)[i+3];
141
+          ((UINT64*)state)[i+4] ^= ((UINT64*)data)[i+4];
142
+          ((UINT64*)state)[i+5] ^= ((UINT64*)data)[i+5];
143
+          ((UINT64*)state)[i+6] ^= ((UINT64*)data)[i+6];
144
+          ((UINT64*)state)[i+7] ^= ((UINT64*)data)[i+7];
145
+      }
146
+      for( ; (i+4)<=laneCount; i+=4) {
147
+          ((UINT64*)state)[i+0] ^= ((UINT64*)data)[i+0];
148
+          ((UINT64*)state)[i+1] ^= ((UINT64*)data)[i+1];
149
+          ((UINT64*)state)[i+2] ^= ((UINT64*)data)[i+2];
150
+          ((UINT64*)state)[i+3] ^= ((UINT64*)data)[i+3];
151
+      }
152
+      for( ; (i+2)<=laneCount; i+=2) {
153
+          ((UINT64*)state)[i+0] ^= ((UINT64*)data)[i+0];
154
+          ((UINT64*)state)[i+1] ^= ((UINT64*)data)[i+1];
155
+      }
156
+      if (i<laneCount) {
157
+          ((UINT64*)state)[i+0] ^= ((UINT64*)data)[i+0];
158
+      }
159
+    }
160
+#else
161
+    unsigned int i;
162
+    UINT8 *curData = data;
163
+    for(i=0; i<laneCount; i++, curData+=8) {
164
+        UINT64 lane = (UINT64)curData[0]
165
+            | ((UINT64)curData[1] << 8)
166
+            | ((UINT64)curData[2] << 16)
167
+            | ((UINT64)curData[3] << 24)
168
+            | ((UINT64)curData[4] <<32)
169
+            | ((UINT64)curData[5] << 40)
170
+            | ((UINT64)curData[6] << 48)
171
+            | ((UINT64)curData[7] << 56);
172
+        ((UINT64*)state)[i] ^= lane;
173
+    }
174
+#endif
175
+}
176
+
177
+/* ---------------------------------------------------------------- */
178
+
179
+#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN)
180
+void KeccakP1600_AddByte(void *state, unsigned char byte, unsigned int offset)
181
+{
182
+    UINT64 lane = byte;
183
+    lane <<= (offset%8)*8;
184
+    ((UINT64*)state)[offset/8] ^= lane;
185
+}
186
+#endif
187
+
188
+/* ---------------------------------------------------------------- */
189
+
190
+void KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length)
191
+{
192
+    SnP_AddBytes(state, data, offset, length, KeccakP1600_AddLanes, KeccakP1600_AddBytesInLane, 8);
193
+}
194
+
195
+/* ---------------------------------------------------------------- */
196
+
197
+void KeccakP1600_OverwriteBytesInLane(void *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length)
198
+{
199
+#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
200
+#ifdef KeccakP1600_useLaneComplementing
201
+    if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20)) {
202
+        unsigned int i;
203
+        for(i=0; i<length; i++)
204
+            ((unsigned char*)state)[lanePosition*8+offset+i] = ~data[i];
205
+    }
206
+    else
207
+#endif
208
+    {
209
+        memcpy((unsigned char*)state+lanePosition*8+offset, data, length);
210
+    }
211
+#else
212
+#error "Not yet implemented"
213
+#endif
214
+}
215
+
216
+/* ---------------------------------------------------------------- */
217
+
218
+void KeccakP1600_OverwriteLanes(void *state, const unsigned char *data, unsigned int laneCount)
219
+{
220
+#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
221
+#ifdef KeccakP1600_useLaneComplementing
222
+    unsigned int lanePosition;
223
+
224
+    for(lanePosition=0; lanePosition<laneCount; lanePosition++)
225
+        if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20))
226
+            ((UINT64*)state)[lanePosition] = ~((const UINT64*)data)[lanePosition];
227
+        else
228
+            ((UINT64*)state)[lanePosition] = ((const UINT64*)data)[lanePosition];
229
+#else
230
+    memcpy(state, data, laneCount*8);
231
+#endif
232
+#else
233
+#error "Not yet implemented"
234
+#endif
235
+}
236
+
237
+/* ---------------------------------------------------------------- */
238
+
239
+void KeccakP1600_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length)
240
+{
241
+    SnP_OverwriteBytes(state, data, offset, length, KeccakP1600_OverwriteLanes, KeccakP1600_OverwriteBytesInLane, 8);
242
+}
243
+
244
+/* ---------------------------------------------------------------- */
245
+
246
+void KeccakP1600_OverwriteWithZeroes(void *state, unsigned int byteCount)
247
+{
248
+#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
249
+#ifdef KeccakP1600_useLaneComplementing
250
+    unsigned int lanePosition;
251
+
252
+    for(lanePosition=0; lanePosition<byteCount/8; lanePosition++)
253
+        if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20))
254
+            ((UINT64*)state)[lanePosition] = ~0;
255
+        else
256
+            ((UINT64*)state)[lanePosition] = 0;
257
+    if (byteCount%8 != 0) {
258
+        lanePosition = byteCount/8;
259
+        if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20))
260
+            memset((unsigned char*)state+lanePosition*8, 0xFF, byteCount%8);
261
+        else
262
+            memset((unsigned char*)state+lanePosition*8, 0, byteCount%8);
263
+    }
264
+#else
265
+    memset(state, 0, byteCount);
266
+#endif
267
+#else
268
+#error "Not yet implemented"
269
+#endif
270
+}
271
+
272
+/* ---------------------------------------------------------------- */
273
+
274
+void KeccakP1600_Permute_24rounds(void *state)
275
+{
276
+    declareABCDE
277
+    #ifndef KeccakP1600_fullUnrolling
278
+    unsigned int i;
279
+    #endif
280
+    UINT64 *stateAsLanes = (UINT64*)state;
281
+
282
+    copyFromState(A, stateAsLanes)
283
+    rounds24
284
+    copyToState(stateAsLanes, A)
285
+}
286
+
287
+/* ---------------------------------------------------------------- */
288
+
289
+void KeccakP1600_Permute_12rounds(void *state)
290
+{
291
+    declareABCDE
292
+    #ifndef KeccakP1600_fullUnrolling
293
+    unsigned int i;
294
+    #endif
295
+    UINT64 *stateAsLanes = (UINT64*)state;
296
+
297
+    copyFromState(A, stateAsLanes)
298
+    rounds12
299
+    copyToState(stateAsLanes, A)
300
+}
301
+
302
+/* ---------------------------------------------------------------- */
303
+
304
+void KeccakP1600_ExtractBytesInLane(const void *state, unsigned int lanePosition, unsigned char *data, unsigned int offset, unsigned int length)
305
+{
306
+    UINT64 lane = ((UINT64*)state)[lanePosition];
307
+#ifdef KeccakP1600_useLaneComplementing
308
+    if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20))
309
+        lane = ~lane;
310
+#endif
311
+#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
312
+    {
313
+        UINT64 lane1[1];
314
+        lane1[0] = lane;
315
+        memcpy(data, (UINT8*)lane1+offset, length);
316
+    }
317
+#else
318
+    unsigned int i;
319
+    lane >>= offset*8;
320
+    for(i=0; i<length; i++) {
321
+        data[i] = lane & 0xFF;
322
+        lane >>= 8;
323
+    }
324
+#endif
325
+}
326
+
327
+/* ---------------------------------------------------------------- */
328
+
329
+#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN)
330
+void fromWordToBytes(UINT8 *bytes, const UINT64 word)
331
+{
332
+    unsigned int i;
333
+
334
+    for(i=0; i<(64/8); i++)
335
+        bytes[i] = (word >> (8*i)) & 0xFF;
336
+}
337
+#endif
338
+
339
+void KeccakP1600_ExtractLanes(const void *state, unsigned char *data, unsigned int laneCount)
340
+{
341
+#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
342
+    memcpy(data, state, laneCount*8);
343
+#else
344
+    unsigned int i;
345
+
346
+    for(i=0; i<laneCount; i++)
347
+        fromWordToBytes(data+(i*8), ((const UINT64*)state)[i]);
348
+#endif
349
+#ifdef KeccakP1600_useLaneComplementing
350
+    if (laneCount > 1) {
351
+        ((UINT64*)data)[ 1] = ~((UINT64*)data)[ 1];
352
+        if (laneCount > 2) {
353
+            ((UINT64*)data)[ 2] = ~((UINT64*)data)[ 2];
354
+            if (laneCount > 8) {
355
+                ((UINT64*)data)[ 8] = ~((UINT64*)data)[ 8];
356
+                if (laneCount > 12) {
357
+                    ((UINT64*)data)[12] = ~((UINT64*)data)[12];
358
+                    if (laneCount > 17) {
359
+                        ((UINT64*)data)[17] = ~((UINT64*)data)[17];
360
+                        if (laneCount > 20) {
361
+                            ((UINT64*)data)[20] = ~((UINT64*)data)[20];
362
+                        }
363
+                    }
364
+                }
365
+            }
366
+        }
367
+    }
368
+#endif
369
+}
370
+
371
+/* ---------------------------------------------------------------- */
372
+
373
+void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length)
374
+{
375
+    SnP_ExtractBytes(state, data, offset, length, KeccakP1600_ExtractLanes, KeccakP1600_ExtractBytesInLane, 8);
376
+}
377
+
378
+/* ---------------------------------------------------------------- */
379
+
380
+void KeccakP1600_ExtractAndAddBytesInLane(const void *state, unsigned int lanePosition, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length)
381
+{
382
+    UINT64 lane = ((UINT64*)state)[lanePosition];
383
+#ifdef KeccakP1600_useLaneComplementing
384
+    if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20))
385
+        lane = ~lane;
386
+#endif
387
+#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
388
+    {
389
+        unsigned int i;
390
+        UINT64 lane1[1];
391
+        lane1[0] = lane;
392
+        for(i=0; i<length; i++)
393
+            output[i] = input[i] ^ ((UINT8*)lane1)[offset+i];
394
+    }
395
+#else
396
+    unsigned int i;
397
+    lane >>= offset*8;
398
+    for(i=0; i<length; i++) {
399
+        output[i] = input[i] ^ (lane & 0xFF);
400
+        lane >>= 8;
401
+    }
402
+#endif
403
+}
404
+
405
+/* ---------------------------------------------------------------- */
406
+
407
+void KeccakP1600_ExtractAndAddLanes(const void *state, const unsigned char *input, unsigned char *output, unsigned int laneCount)
408
+{
409
+    unsigned int i;
410
+#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN)
411
+    unsigned char temp[8];
412
+    unsigned int j;
413
+#endif
414
+
415
+    for(i=0; i<laneCount; i++) {
416
+#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
417
+        ((UINT64*)output)[i] = ((UINT64*)input)[i] ^ ((const UINT64*)state)[i];
418
+#else
419
+        fromWordToBytes(temp, ((const UINT64*)state)[i]);
420
+        for(j=0; j<8; j++)
421
+            output[i*8+j] = input[i*8+j] ^ temp[j];
422
+#endif
423
+    }
424
+#ifdef KeccakP1600_useLaneComplementing
425
+    if (laneCount > 1) {
426
+        ((UINT64*)output)[ 1] = ~((UINT64*)output)[ 1];
427
+        if (laneCount > 2) {
428
+            ((UINT64*)output)[ 2] = ~((UINT64*)output)[ 2];
429
+            if (laneCount > 8) {
430
+                ((UINT64*)output)[ 8] = ~((UINT64*)output)[ 8];
431
+                if (laneCount > 12) {
432
+                    ((UINT64*)output)[12] = ~((UINT64*)output)[12];
433
+                    if (laneCount > 17) {
434
+                        ((UINT64*)output)[17] = ~((UINT64*)output)[17];
435
+                        if (laneCount > 20) {
436
+                            ((UINT64*)output)[20] = ~((UINT64*)output)[20];
437
+                        }
438
+                    }
439
+                }
440
+            }
441
+        }
442
+    }
443
+#endif
444
+}
445
+
446
+/* ---------------------------------------------------------------- */
447
+
448
+void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length)
449
+{
450
+    SnP_ExtractAndAddBytes(state, input, output, offset, length, KeccakP1600_ExtractAndAddLanes, KeccakP1600_ExtractAndAddBytesInLane, 8);
451
+}
452
+
453
+/* ---------------------------------------------------------------- */
454
+
455
+size_t KeccakF1600_FastLoop_Absorb(void *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen)
456
+{
457
+    size_t originalDataByteLen = dataByteLen;
458
+    declareABCDE
459
+    #ifndef KeccakP1600_fullUnrolling
460
+    unsigned int i;
461
+    #endif
462
+    UINT64 *stateAsLanes = (UINT64*)state;
463
+    UINT64 *inDataAsLanes = (UINT64*)data;
464
+
465
+    copyFromState(A, stateAsLanes)
466
+    while(dataByteLen >= laneCount*8) {
467
+        addInput(A, inDataAsLanes, laneCount)
468
+        rounds24
469
+        inDataAsLanes += laneCount;
470
+        dataByteLen -= laneCount*8;
471
+    }
472
+    copyToState(stateAsLanes, A)
473
+    return originalDataByteLen - dataByteLen;
474
+}
0 475
new file mode 100644
... ...
@@ -0,0 +1,92 @@
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 "KeccakSponge.h"
17
+
18
+#ifdef KeccakReference
19
+    #include "displayIntermediateValues.h"
20
+#endif
21
+
22
+#ifndef KeccakP200_excluded
23
+    #include "KeccakP-200-SnP.h"
24
+
25
+    #define prefix KeccakWidth200
26
+    #define SnP KeccakP200
27
+    #define SnP_width 200
28
+    #define SnP_Permute KeccakP200_Permute_18rounds
29
+    #if defined(KeccakF200_FastLoop_supported)
30
+        #define SnP_FastLoop_Absorb KeccakF200_FastLoop_Absorb
31
+    #endif
32
+        #include "KeccakSponge.inc"
33
+    #undef prefix
34
+    #undef SnP
35
+    #undef SnP_width
36
+    #undef SnP_Permute
37
+    #undef SnP_FastLoop_Absorb
38
+#endif
39
+
40
+#ifndef KeccakP400_excluded
41
+    #include "KeccakP-400-SnP.h"
42
+
43
+    #define prefix KeccakWidth400
44
+    #define SnP KeccakP400
45
+    #define SnP_width 400
46
+    #define SnP_Permute KeccakP400_Permute_20rounds
47
+    #if defined(KeccakF400_FastLoop_supported)
48
+        #define SnP_FastLoop_Absorb KeccakF400_FastLoop_Absorb
49
+    #endif
50
+        #include "KeccakSponge.inc"
51
+    #undef prefix
52
+    #undef SnP
53
+    #undef SnP_width
54
+    #undef SnP_Permute
55
+    #undef SnP_FastLoop_Absorb
56
+#endif
57
+
58
+#ifndef KeccakP800_excluded
59
+    #include "KeccakP-800-SnP.h"
60
+
61
+    #define prefix KeccakWidth800
62
+    #define SnP KeccakP800
63
+    #define SnP_width 800
64
+    #define SnP_Permute KeccakP800_Permute_22rounds
65
+    #if defined(KeccakF800_FastLoop_supported)
66
+        #define SnP_FastLoop_Absorb KeccakF800_FastLoop_Absorb
67
+    #endif
68
+        #include "KeccakSponge.inc"
69
+    #undef prefix
70
+    #undef SnP
71
+    #undef SnP_width
72
+    #undef SnP_Permute
73
+    #undef SnP_FastLoop_Absorb
74
+#endif
75
+
76
+#ifndef KeccakP1600_excluded
77
+    #include "KeccakP-1600-SnP.h"
78
+
79
+    #define prefix KeccakWidth1600
80
+    #define SnP KeccakP1600
81
+    #define SnP_width 1600
82
+    #define SnP_Permute KeccakP1600_Permute_24rounds
83
+    #if defined(KeccakF1600_FastLoop_supported)
84
+        #define SnP_FastLoop_Absorb KeccakF1600_FastLoop_Absorb
85
+    #endif
86
+        #include "KeccakSponge.inc"
87
+    #undef prefix
88
+    #undef SnP
89
+    #undef SnP_width
90
+    #undef SnP_Permute
91
+    #undef SnP_FastLoop_Absorb
92
+#endif
0 93
new file mode 100644
... ...
@@ -0,0 +1,172 @@
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
+#ifndef _KeccakSponge_h_
17
+#define _KeccakSponge_h_
18
+
19
+/** General information
20
+  *
21
+  * The following type and functions are not actually implemented. Their
22
+  * documentation is generic, with the prefix Prefix replaced by
23
+  * - KeccakWidth200 for a sponge function based on Keccak-f[200]
24
+  * - KeccakWidth400 for a sponge function based on Keccak-f[400]
25
+  * - KeccakWidth800 for a sponge function based on Keccak-f[800]
26
+  * - KeccakWidth1600 for a sponge function based on Keccak-f[1600]
27
+  *
28
+  * In all these functions, the rate and capacity must sum to the width of the
29
+  * chosen permutation. For instance, to use the sponge function
30
+  * Keccak[r=1344, c=256], one must use KeccakWidth1600_Sponge() or a combination
31
+  * of KeccakWidth1600_SpongeInitialize(), KeccakWidth1600_SpongeAbsorb(),
32
+  * KeccakWidth1600_SpongeAbsorbLastFewBits() and
33
+  * KeccakWidth1600_SpongeSqueeze().
34
+  *
35
+  * The Prefix_SpongeInstance contains the sponge instance attributes for use
36
+  * with the Prefix_Sponge* functions.
37
+  * It gathers the state processed by the permutation as well as the rate,
38
+  * the position of input/output bytes in the state and the phase
39
+  * (absorbing or squeezing).
40
+  */
41
+
42
+#ifdef DontReallyInclude_DocumentationOnly
43
+/** Function to evaluate the sponge function Keccak[r, c] in a single call.
44
+  * @param  rate        The value of the rate r.
45
+  * @param  capacity    The value of the capacity c.
46
+  * @param  input           Pointer to the input message (before the suffix).
47
+  * @param  inputByteLen    The length of the input message in bytes.
48
+  * @param  suffix          Byte containing from 0 to 7 suffix bits
49
+  *                         that must be absorbed after @a input.
50
+  *                         These <i>n</i> bits must be in the least significant bit positions.
51
+  *                         These bits must be delimited with a bit 1 at position <i>n</i>
52
+  *                         (counting from 0=LSB to 7=MSB) and followed by bits 0
53
+  *                         from position <i>n</i>+1 to position 7.
54
+  *                         Some examples:
55
+  *                             - If no bits are to be absorbed, then @a suffix must be 0x01.
56
+  *                             - If the 2-bit sequence 0,0 is to be absorbed, @a suffix must be 0x04.
57
+  *                             - If the 5-bit sequence 0,1,0,0,1 is to be absorbed, @a suffix must be 0x32.
58
+  *                             - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a suffix must be 0x8B.
59
+  *                         .
60
+  * @param  output          Pointer to the output buffer.
61
+  * @param  outputByteLen   The desired number of output bytes.
62
+  * @pre    One must have r+c equal to the supported width of this implementation
63
+  *         and the rate a multiple of 8 bits (one byte) in this implementation.
64
+  * @pre    @a suffix ≠ 0x00
65
+  * @return Zero if successful, 1 otherwise.
66
+  */
67
+int Prefix_Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen);
68
+
69
+/**
70
+  * Function to initialize the state of the Keccak[r, c] sponge function.
71
+  * The phase of the sponge function is set to absorbing.
72
+  * @param  spongeInstance  Pointer to the sponge instance to be initialized.
73
+  * @param  rate        The value of the rate r.
74
+  * @param  capacity    The value of the capacity c.
75
+  * @pre    One must have r+c equal to the supported width of this implementation
76
+  *         and the rate a multiple of 8 bits (one byte) in this implementation.
77
+  * @return Zero if successful, 1 otherwise.
78
+  */
79
+int Prefix_SpongeInitialize(Prefix_SpongeInstance *spongeInstance, unsigned int rate, unsigned int capacity);
80
+
81
+/**
82
+  * Function to give input data bytes for the sponge function to absorb.
83
+  * @param  spongeInstance  Pointer to the sponge instance initialized by Prefix_SpongeInitialize().
84
+  * @param  data        Pointer to the input data.
85
+  * @param  dataByteLen  The number of input bytes provided in the input data.
86
+  * @pre    The sponge function must be in the absorbing phase,
87
+  *         i.e., Prefix_SpongeSqueeze() or Prefix_SpongeAbsorbLastFewBits()
88
+  *         must not have been called before.
89
+  * @return Zero if successful, 1 otherwise.
90
+  */
91
+int Prefix_SpongeAbsorb(Prefix_SpongeInstance *spongeInstance, const unsigned char *data, size_t dataByteLen);
92
+
93
+/**
94
+  * Function to give input data bits for the sponge function to absorb
95
+  * and then to switch to the squeezing phase.
96
+  * @param  spongeInstance  Pointer to the sponge instance initialized by Prefix_SpongeInitialize().
97
+  * @param  delimitedData   Byte containing from 0 to 7 trailing bits
98
+  *                     that must be absorbed.
99
+  *                     These <i>n</i> bits must be in the least significant bit positions.
100
+  *                     These bits must be delimited with a bit 1 at position <i>n</i>
101
+  *                     (counting from 0=LSB to 7=MSB) and followed by bits 0
102
+  *                     from position <i>n</i>+1 to position 7.
103
+  *                     Some examples:
104
+  *                         - If no bits are to be absorbed, then @a delimitedData must be 0x01.
105
+  *                         - If the 2-bit sequence 0,0 is to be absorbed, @a delimitedData must be 0x04.
106
+  *                         - If the 5-bit sequence 0,1,0,0,1 is to be absorbed, @a delimitedData must be 0x32.
107
+  *                         - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a delimitedData must be 0x8B.
108
+  *                     .
109
+  * @pre    The sponge function must be in the absorbing phase,
110
+  *         i.e., Prefix_SpongeSqueeze() or Prefix_SpongeAbsorbLastFewBits()
111
+  *         must not have been called before.
112
+  * @pre    @a delimitedData ≠ 0x00
113
+  * @return Zero if successful, 1 otherwise.
114
+  */
115
+int Prefix_SpongeAbsorbLastFewBits(Prefix_SpongeInstance *spongeInstance, unsigned char delimitedData);
116
+
117
+/**
118
+  * Function to squeeze output data from the sponge function.
119
+  * If the sponge function was in the absorbing phase, this function
120
+  * switches it to the squeezing phase
121
+  * as if Prefix_SpongeAbsorbLastFewBits(spongeInstance, 0x01) was called.
122
+  * @param  spongeInstance  Pointer to the sponge instance initialized by Prefix_SpongeInitialize().
123
+  * @param  data        Pointer to the buffer where to store the output data.
124
+  * @param  dataByteLen The number of output bytes desired.
125
+  * @return Zero if successful, 1 otherwise.
126
+  */
127
+int Prefix_SpongeSqueeze(Prefix_SpongeInstance *spongeInstance, unsigned char *data, size_t dataByteLen);
128
+#endif
129
+
130
+#include <string.h>
131
+#include "align.h"
132
+
133
+#define KCP_DeclareSpongeStructure(prefix, size, alignment) \
134
+    ALIGN(alignment) typedef struct prefix##_SpongeInstanceStruct { \
135
+        unsigned char state[size]; \
136
+        unsigned int rate; \
137
+        unsigned int byteIOIndex; \
138
+        int squeezing; \
139
+    } prefix##_SpongeInstance;
140
+
141
+#define KCP_DeclareSpongeFunctions(prefix) \
142
+    int prefix##_Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen); \
143
+    int prefix##_SpongeInitialize(prefix##_SpongeInstance *spongeInstance, unsigned int rate, unsigned int capacity); \
144
+    int prefix##_SpongeAbsorb(prefix##_SpongeInstance *spongeInstance, const unsigned char *data, size_t dataByteLen); \
145
+    int prefix##_SpongeAbsorbLastFewBits(prefix##_SpongeInstance *spongeInstance, unsigned char delimitedData); \
146
+    int prefix##_SpongeSqueeze(prefix##_SpongeInstance *spongeInstance, unsigned char *data, size_t dataByteLen);
147
+
148
+#ifndef KeccakP200_excluded
149
+    #include "KeccakP-200-SnP.h"
150
+    KCP_DeclareSpongeStructure(KeccakWidth200, KeccakP200_stateSizeInBytes, KeccakP200_stateAlignment)
151
+    KCP_DeclareSpongeFunctions(KeccakWidth200)
152
+#endif
153
+
154
+#ifndef KeccakP400_excluded
155
+    #include "KeccakP-400-SnP.h"
156
+    KCP_DeclareSpongeStructure(KeccakWidth400, KeccakP400_stateSizeInBytes, KeccakP400_stateAlignment)
157
+    KCP_DeclareSpongeFunctions(KeccakWidth400)
158
+#endif
159
+
160
+#ifndef KeccakP800_excluded
161
+    #include "KeccakP-800-SnP.h"
162
+    KCP_DeclareSpongeStructure(KeccakWidth800, KeccakP800_stateSizeInBytes, KeccakP800_stateAlignment)
163
+    KCP_DeclareSpongeFunctions(KeccakWidth800)
164
+#endif
165
+
166
+#ifndef KeccakP1600_excluded
167
+    #include "KeccakP-1600-SnP.h"
168
+    KCP_DeclareSpongeStructure(KeccakWidth1600, KeccakP1600_stateSizeInBytes, KeccakP1600_stateAlignment)
169
+    KCP_DeclareSpongeFunctions(KeccakWidth1600)
170
+#endif
171
+
172
+#endif
0 173
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
0 333
new file mode 100644
... ...
@@ -0,0 +1,17 @@
1
+CC=gcc
2
+CFLAGS=-g -Wall -DKeccakP200_excluded -DKeccakP400_excluded -DKeccakP800_excluded -DKeccakOpt=32
3
+LDFLAGS=
4
+
5
+all: keccak.a
6
+
7
+KeccakHash.o: KeccakHash.c KeccakHash.h
8
+
9
+KeccakSponge.o: KeccakSponge.c KeccakSponge.h
10
+
11
+KeccakP-1600-inplace32BI.o: KeccakP-1600-inplace32BI.c
12
+
13
+keccak.a: KeccakHash.o KeccakSponge.o KeccakP-1600-inplace32BI.o
14
+	ar q keccak.a KeccakHash.o KeccakSponge.o KeccakP-1600-inplace32BI.o
15
+
16
+clean:
17
+	rm -f keccak.a KeccakHash.o KeccakSponge.o KeccakP-1600-inplace32BI.o
0 18
new file mode 100644
... ...
@@ -0,0 +1,134 @@
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
+#ifndef _SnP_Relaned_h_
17
+#define _SnP_Relaned_h_
18
+
19
+#define SnP_AddBytes(state, data, offset, length, SnP_AddLanes, SnP_AddBytesInLane, SnP_laneLengthInBytes) \
20
+    { \
21
+        if ((offset) == 0) { \
22
+            SnP_AddLanes(state, data, (length)/SnP_laneLengthInBytes); \
23
+            SnP_AddBytesInLane(state, \
24
+                (length)/SnP_laneLengthInBytes, \
25
+                (data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \
26
+                0, \
27
+                (length)%SnP_laneLengthInBytes); \
28
+        } \
29
+        else { \
30
+            unsigned int _sizeLeft = (length); \
31
+            unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \
32
+            unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \
33
+            const unsigned char *_curData = (data); \
34
+            while(_sizeLeft > 0) { \
35
+                unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \
36
+                if (_bytesInLane > _sizeLeft) \
37
+                    _bytesInLane = _sizeLeft; \
38
+                SnP_AddBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \
39
+                _sizeLeft -= _bytesInLane; \
40
+                _lanePosition++; \
41
+                _offsetInLane = 0; \
42
+                _curData += _bytesInLane; \
43
+            } \
44
+        } \
45
+    }
46
+
47
+#define SnP_OverwriteBytes(state, data, offset, length, SnP_OverwriteLanes, SnP_OverwriteBytesInLane, SnP_laneLengthInBytes) \
48
+    { \
49
+        if ((offset) == 0) { \
50
+            SnP_OverwriteLanes(state, data, (length)/SnP_laneLengthInBytes); \
51
+            SnP_OverwriteBytesInLane(state, \
52
+                (length)/SnP_laneLengthInBytes, \
53
+                (data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \
54
+                0, \
55
+                (length)%SnP_laneLengthInBytes); \
56
+        } \
57
+        else { \
58
+            unsigned int _sizeLeft = (length); \
59
+            unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \
60
+            unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \
61
+            const unsigned char *_curData = (data); \
62
+            while(_sizeLeft > 0) { \
63
+                unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \
64
+                if (_bytesInLane > _sizeLeft) \
65
+                    _bytesInLane = _sizeLeft; \
66
+                SnP_OverwriteBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \
67
+                _sizeLeft -= _bytesInLane; \
68
+                _lanePosition++; \
69
+                _offsetInLane = 0; \
70
+                _curData += _bytesInLane; \
71
+            } \
72
+        } \
73
+    }
74
+
75
+#define SnP_ExtractBytes(state, data, offset, length, SnP_ExtractLanes, SnP_ExtractBytesInLane, SnP_laneLengthInBytes) \
76
+    { \
77
+        if ((offset) == 0) { \
78
+            SnP_ExtractLanes(state, data, (length)/SnP_laneLengthInBytes); \
79
+            SnP_ExtractBytesInLane(state, \
80
+                (length)/SnP_laneLengthInBytes, \
81
+                (data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \
82
+                0, \
83
+                (length)%SnP_laneLengthInBytes); \
84
+        } \
85
+        else { \
86
+            unsigned int _sizeLeft = (length); \
87
+            unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \
88
+            unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \
89
+            unsigned char *_curData = (data); \
90
+            while(_sizeLeft > 0) { \
91
+                unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \
92
+                if (_bytesInLane > _sizeLeft) \
93
+                    _bytesInLane = _sizeLeft; \
94
+                SnP_ExtractBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \
95
+                _sizeLeft -= _bytesInLane; \
96
+                _lanePosition++; \
97
+                _offsetInLane = 0; \
98
+                _curData += _bytesInLane; \
99
+            } \
100
+        } \
101
+    }
102
+
103
+#define SnP_ExtractAndAddBytes(state, input, output, offset, length, SnP_ExtractAndAddLanes, SnP_ExtractAndAddBytesInLane, SnP_laneLengthInBytes) \
104
+    { \
105
+        if ((offset) == 0) { \
106
+            SnP_ExtractAndAddLanes(state, input, output, (length)/SnP_laneLengthInBytes); \
107
+            SnP_ExtractAndAddBytesInLane(state, \
108
+                (length)/SnP_laneLengthInBytes, \
109
+                (input)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \
110
+                (output)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \
111
+                0, \
112
+                (length)%SnP_laneLengthInBytes); \
113
+        } \
114
+        else { \
115
+            unsigned int _sizeLeft = (length); \
116
+            unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \
117
+            unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \
118
+            const unsigned char *_curInput = (input); \
119
+            unsigned char *_curOutput = (output); \
120
+            while(_sizeLeft > 0) { \
121
+                unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \
122
+                if (_bytesInLane > _sizeLeft) \
123
+                    _bytesInLane = _sizeLeft; \
124
+                SnP_ExtractAndAddBytesInLane(state, _lanePosition, _curInput, _curOutput, _offsetInLane, _bytesInLane); \
125
+                _sizeLeft -= _bytesInLane; \
126
+                _lanePosition++; \
127
+                _offsetInLane = 0; \
128
+                _curInput += _bytesInLane; \
129
+                _curOutput += _bytesInLane; \
130
+            } \
131
+        } \
132
+    }
133
+
134
+#endif
0 135
new file mode 100644
... ...
@@ -0,0 +1,35 @@
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
+#ifndef _align_h_
17
+#define _align_h_
18
+
19
+/* on Mac OS-X and possibly others, ALIGN(x) is defined in param.h, and -Werror chokes on the redef. */
20
+
21
+#ifdef ALIGN
22
+#undef ALIGN
23
+#endif
24
+
25
+#if defined(__GNUC__)
26
+#define ALIGN(x) __attribute__ ((aligned(x)))
27
+#elif defined(_MSC_VER)
28
+#define ALIGN(x) __declspec(align(x))
29
+#elif defined(__ARMCC_VERSION)
30
+#define ALIGN(x) __align(x)
31
+#else
32
+#define ALIGN(x)
33
+#endif
34
+
35
+#endif
0 36
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+https://github.com/python/cpython/tree/master/Modules/_sha3
... ...
@@ -43,10 +43,16 @@ main(int argc, char *argv[])
43 43
                 re_free(re),re=NULL;
44 44
                 return(2);
45 45
         }
46
-        if((redata_load(re->redata,re->filename))!=0)
46
+        if((redata_load(re->redata,re->filename,0))!=0)
47 47
                 re->flag_newfile=1;
48 48
         else
49 49
                 re->flag_newfile=0;
50
+#warning TESTS
51
+        {
52
+                char buf[129];
53
+                redata_hash(re->redata,buf);
54
+                fprintf(stderr,"%s %s\n",buf,re->filename);
55
+        }
50 56
 #warning TODO
51 57
         re_free(re),re=NULL;
52 58
         return(0);
... ...
@@ -18,8 +18,11 @@
18 18
 #include <fcntl.h>
19 19
 
20 20
 #include "recenteditor_data.h"
21
+#include "keccak/KeccakHash.h"
21 22
 
22 23
 #define CHUNKSIZE 32768
24
+#define UNSAVEDPREFIX "."
25
+#define UNSAVEDPOSTFIX ".reu"
23 26
 
24 27
 
25 28
 redata_t *
... ...
@@ -29,10 +32,21 @@ redata_init(void)
29 32
         if((redata=malloc(sizeof(redata_t)))==NULL)
30 33
                 return(NULL); /* sanity check failed */
31 34
         memset(redata,0,sizeof(redata_t));
35
+        /* data */
32 36
         redata->sizechunks=0;
33 37
         redata->chunks=NULL;
34 38
         redata->chunkdatasize=CHUNKSIZE;
35 39
         redata->available=0;
40
+        /* undo */
41
+        redata->sizeundo=0;
42
+        redata->usedundo=0;
43
+        redata->curundo=0;
44
+        redata->undo=NULL;
45
+        redata->undobuf=NULL;
46
+        /* unsaved */
47
+        redata->unsavedfd=-1;
48
+        redata->flag_unsaveddata=0;
49
+        /* all done */
36 50
         return(redata);
37 51
 }
38 52
 
... ...
@@ -42,6 +56,7 @@ redata_free(redata_t *redata)
42 56
         int i;
43 57
         if(redata==NULL)
44 58
                 return; /* nothing to do */
59
+        /* data */
45 60
         for(i=0;i<redata->sizechunks;i++) {
46 61
                 if(redata->chunks[i]!=NULL)
47 62
                         free(redata->chunks[i]),redata->chunks[i]=NULL;
... ...
@@ -49,6 +64,22 @@ redata_free(redata_t *redata)
49 64
         redata->sizechunks=0;
50 65
         if(redata->chunks!=NULL)
51 66
                 free(redata->chunks),redata->chunks=NULL;
67
+        /* undo */
68
+        if(redata->undo!=NULL)
69
+                free(redata->undo),redata->undo=NULL;
70
+        if(redata->undobuf!=NULL)
71
+                free(redata->undobuf),redata->undobuf=NULL;
72
+        /* unsaved */
73
+        if(redata->unsavedfd!=-1)
74
+                close(redata->unsavedfd),redata->unsavedfd=-1;
75
+        if(redata->unsavedfilename!=NULL) {
76
+                if(redata->unsavedfilename[0]!='\0') {
77
+                        /* remove the file, if here, the user has validated exiting without saving */
78
+                        unlink(redata->unsavedfilename);
79
+                }
80
+                free(redata->unsavedfilename),redata->unsavedfilename=NULL;
81
+        }
82
+        /* free main struct */
52 83
         free(redata),redata=NULL;
53 84
         return;
54 85
 }
... ...
@@ -83,11 +114,24 @@ redata_wipe(redata_t *redata)
83 114
         int i;
84 115
         if(redata==NULL)
85 116
                 return(-1); /* sanity check failed */
117
+        /* data */
86 118
         for(i=0;i<redata->sizechunks;i++) {
87 119
                 redata->chunks[i]->useddata=0;
88 120
                 memset(&(redata->chunks[i]->whatin),0,sizeof(whatin_t));
89 121
         }
90 122
         redata->available=redata_getsize(redata);
123
+        /* unsaved */
124
+        if(redata->unsavedfd!=-1)
125
+                close(redata->unsavedfd),redata->unsavedfd=-1;
126
+        if(redata->unsavedfilename!=NULL) {
127
+                if(redata->unsavedfilename[0]!='\0') {
128
+                        /* remove the file, if here, the user has validated exiting without saving */
129
+                        unlink(redata->unsavedfilename);
130
+                }
131
+                free(redata->unsavedfilename),redata->unsavedfilename=NULL;
132
+        }
133
+        redata->flag_unsaveddata=0;
134
+        /* all done */
91 135
         return(0);
92 136
 }
93 137
 
... ...
@@ -98,7 +142,7 @@ redata_preallocate(redata_t *redata, int newsize)
98 142
         int nchunks;
99 143
         int i;
100 144
         int rechunksize;
101
-        rechunk_t *newchunks,*chunk;
145
+        rechunk_t **newchunks,*chunk;
102 146
         int oldsizechunks;
103 147
         if(redata==NULL || redata->chunkdatasize==0 || newsize<0)
104 148
                 return(-1); /* sanity check failed */
... ...
@@ -143,8 +187,9 @@ redata_fill_whatin(redata_t *redata, int chunkno)
143 187
 
144 188
 
145 189
 int
146
-redata_load(redata_t *redata, char *filename)
190
+redata_load(redata_t *redata, char *filename, int use_unsaved)
147 191
 {
192
+#warning TODO: use_unsaved
148 193
         int fd,nread,totalread;
149 194
         int chunkno, avail;
150 195
         struct stat statbuf;
... ...
@@ -155,20 +200,27 @@ redata_load(redata_t *redata, char *filename)
155 200
                         close(fd),fd=-1;
156 201
                 return(-1); /* file not found, couldn't query size or not regular file */
157 202
         }
158
-        if(redata_preallocate(redata,statbuf.st_size)) {
203
+        /* preallocate 10% more than needed */
204
+        if(redata_preallocate(redata,statbuf.st_size+(statbuf.st_size/10)+1 )) {
159 205
                 if(fd!=-1)
160 206
                         close(fd),fd=-1;
161 207
                 return(-1); /* insuf. mem. */
162 208
         }
163 209
         for(totalread=0,chunkno=0,nread=0;totalread<statbuf.st_size;totalread+=nread,nread=0) {
164 210
                 if(chunkno>=redata->sizechunks || redata->chunks[chunkno]==NULL) {
165
-                        if(fd!=-1)
166
-                                close(fd),fd=-1;
167
-                        fprintf(stderr,"redata_load: INTERNAL ERROR\n");
168
-                        return(-2); /* internal error */
211
+                        /* alloc another chunk */
212
+                        if(redata_preallocate(redata,(redata->sizechunks+1)*redata->chunkdatasize)==-1 ||
213
+                                chunkno>=redata->sizechunks || redata->chunks[chunkno]==NULL) {
214
+                                if(fd!=-1)
215
+                                        close(fd),fd=-1;
216
+                                fprintf(stderr,"redata_load: INTERNAL ERROR\n");
217
+                                return(-2); /* internal error */
218
+                        }
169 219
                 }
170 220
                 chunk=redata->chunks[chunkno];
171
-                avail=redata->chunkdatasize-chunk->useddata;
221
+                /* leave 10% free on each chunk */
222
+                avail=(redata->chunkdatasize-redata->chunkdatasize/10)-chunk->useddata;
223
+                avail=(avail<0)?0:avail;
172 224
                 avail=((totalread+avail)>statbuf.st_size)?statbuf.st_size-totalread:avail;
173 225
                 if(avail==0) {
174 226
                         chunkno++; /* full, try next */
... ...
@@ -183,6 +235,9 @@ redata_load(redata_t *redata, char *filename)
183 235
                 redata->available-=nread;
184 236
                 redata_fill_whatin(redata,chunkno);
185 237
         }
238
+        /* prepare unsaved */
239
+
240
+        /* all done */
186 241
         return(0);
187 242
 }
188 243
 
... ...
@@ -192,3 +247,51 @@ redata_save(redata_t *redata, char *filename)
192 247
 #warning TODO
193 248
         return(-1);
194 249
 }
250
+
251
+int
252
+redata_op_add(redata_t *redata, char *buf, int sizebuf, int pos)
253
+{
254
+}
255
+
256
+int
257
+redata_op_del(redata_t *redata, int pos, int size)
258
+{
259
+}
260
+
261
+int
262
+redata_op_move(redata_t *redata, int posorig, int size, int posdest)
263
+{
264
+}
265
+
266
+int
267
+redata_hash(redata_t *redata, char *resbuf129bytes)
268
+{
269
+        static char conv[]={"0123456789ABCDEF"};
270
+        Keccak_HashInstance hash;
271
+        int i,c;
272
+        if(resbuf129bytes!=NULL)
273
+                *resbuf129bytes='\0';
274
+        if(redata==NULL || resbuf129bytes==NULL) {
275
+                return(-1); /* sanity check failed */
276
+        }
277
+        if(Keccak_HashInitialize_SHA3_512(&hash)!=SUCCESS)
278
+                return(-1); /* init failed */
279
+        for(i=0;i<redata->sizechunks;i++) {
280
+                if(Keccak_HashUpdate(&hash, (void *) redata->chunks[i]->data,redata->chunks[i]->useddata)!=SUCCESS)
281
+                        return(-1); /* hash calc. error */
282
+        }
283
+        if(Keccak_HashFinal(&hash, (void *) resbuf129bytes)!=SUCCESS) {
284
+                *resbuf129bytes='\0';
285
+                return(-1); /* hash final calc. error */
286
+        }
287
+        resbuf129bytes[128]='\0';
288
+        for(i=63;i>=0;i--) {
289
+                c=((unsigned char *)resbuf129bytes)[i];
290
+                resbuf129bytes[i<<1]=conv[((c>>4)&0xf)];
291
+                resbuf129bytes[(i<<1)+1]=conv[(c&0xf)];
292
+        }
293
+#warning TODO: result is not as expected
294
+        return(0);
295
+}
296
+
297
+
... ...
@@ -11,7 +11,6 @@
11 11
  * This program is licensed under the terms of GNU GPL v2.1+
12 12
  */
13 13
 
14
-
15 14
 typedef struct whatin_t {
16 15
         int nlcount;
17 16
 } whatin_t;
... ...
@@ -22,13 +21,30 @@ typedef struct rechunk_t {
22 21
         unsigned char data[1];
23 22
 } rechunk_t;
24 23
 
24
+typedef struct undo_t {
25
+
26
+} undo_t;
27
+
25 28
 typedef struct redata_t {
29
+        /* data */
26 30
         int chunkdatasize;
27 31
         int sizechunks;
28 32
         rechunk_t **chunks;
29 33
         int available;
34
+        /* undo */
35
+        int sizeundo;
36
+        int usedundo;
37
+        int curundo;
38
+        undo_t *undo;
39
+        char *undobuf;
40
+        /* unsaved (for recovery when the program closes unexpectedly) */
41
+        char *unsavedfilename;
42
+        int unsavedfd;
43
+        int flag_unsaveddata;
30 44
 } redata_t;
31 45
 
46
+#warning TODO: undo operations log/buffer, add/remove/move text funtions
47
+
32 48
 redata_t *redata_init(void);
33 49
 void redata_free(redata_t *redata);
34 50
 
... ...
@@ -40,5 +56,15 @@ int redata_wipe(redata_t *redata);
40 56
 int redata_preallocate(redata_t *redata, int size);
41 57
 int redata_fill_whatin(redata_t *redata, int chunkno);
42 58
 
43
-int redata_load(redata_t *redata, char *filename);
59
+int redata_unsavedcheck(redata_t *redata, char *filename);
60
+int redata_load(redata_t *redata, char *filename, int use_unsaved);
44 61
 int redata_save(redata_t *redata, char *filename);
62
+
63
+int redata_op_add(redata_t *redata, char *buf, int sizebuf, int pos);
64
+int redata_op_del(redata_t *redata, int pos, int size);
65
+int redata_op_move(redata_t *redata, int posorig, int size, int posdest);
66
+int redata_op_undo(redata_t *redata);
67
+int redata_op_redor(redata_t *redata);
68
+
69
+int redata_hash(redata_t *redata, char *resbuf129bytes);
70
+