1/*
2Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni,
3Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby
4denoted as "the implementer".
5
6For more information, feedback or questions, please refer to our websites:
7http://keccak.noekeon.org/
8http://keyak.noekeon.org/
9http://ketje.noekeon.org/
10
11To the extent possible under law, the implementer has waived all copyright
12and related or neighboring rights to the source code in this file.
13http://creativecommons.org/publicdomain/zero/1.0/
14*/
15
16#if (defined(FullUnrolling))
17#define rounds24 \
18    prepareTheta \
19    thetaRhoPiChiIotaPrepareTheta( 0, A, E) \
20    thetaRhoPiChiIotaPrepareTheta( 1, E, A) \
21    thetaRhoPiChiIotaPrepareTheta( 2, A, E) \
22    thetaRhoPiChiIotaPrepareTheta( 3, E, A) \
23    thetaRhoPiChiIotaPrepareTheta( 4, A, E) \
24    thetaRhoPiChiIotaPrepareTheta( 5, E, A) \
25    thetaRhoPiChiIotaPrepareTheta( 6, A, E) \
26    thetaRhoPiChiIotaPrepareTheta( 7, E, A) \
27    thetaRhoPiChiIotaPrepareTheta( 8, A, E) \
28    thetaRhoPiChiIotaPrepareTheta( 9, E, A) \
29    thetaRhoPiChiIotaPrepareTheta(10, A, E) \
30    thetaRhoPiChiIotaPrepareTheta(11, E, A) \
31    thetaRhoPiChiIotaPrepareTheta(12, A, E) \
32    thetaRhoPiChiIotaPrepareTheta(13, E, A) \
33    thetaRhoPiChiIotaPrepareTheta(14, A, E) \
34    thetaRhoPiChiIotaPrepareTheta(15, E, A) \
35    thetaRhoPiChiIotaPrepareTheta(16, A, E) \
36    thetaRhoPiChiIotaPrepareTheta(17, E, A) \
37    thetaRhoPiChiIotaPrepareTheta(18, A, E) \
38    thetaRhoPiChiIotaPrepareTheta(19, E, A) \
39    thetaRhoPiChiIotaPrepareTheta(20, A, E) \
40    thetaRhoPiChiIotaPrepareTheta(21, E, A) \
41    thetaRhoPiChiIotaPrepareTheta(22, A, E) \
42    thetaRhoPiChiIota(23, E, A) \
43
44#define rounds12 \
45    prepareTheta \
46    thetaRhoPiChiIotaPrepareTheta(12, A, E) \
47    thetaRhoPiChiIotaPrepareTheta(13, E, A) \
48    thetaRhoPiChiIotaPrepareTheta(14, A, E) \
49    thetaRhoPiChiIotaPrepareTheta(15, E, A) \
50    thetaRhoPiChiIotaPrepareTheta(16, A, E) \
51    thetaRhoPiChiIotaPrepareTheta(17, E, A) \
52    thetaRhoPiChiIotaPrepareTheta(18, A, E) \
53    thetaRhoPiChiIotaPrepareTheta(19, E, A) \
54    thetaRhoPiChiIotaPrepareTheta(20, A, E) \
55    thetaRhoPiChiIotaPrepareTheta(21, E, A) \
56    thetaRhoPiChiIotaPrepareTheta(22, A, E) \
57    thetaRhoPiChiIota(23, E, A) \
58
59#elif (Unrolling == 12)
60#define rounds24 \
61    prepareTheta \
62    for(i=0; i<24; i+=12) { \
63        thetaRhoPiChiIotaPrepareTheta(i   , A, E) \
64        thetaRhoPiChiIotaPrepareTheta(i+ 1, E, A) \
65        thetaRhoPiChiIotaPrepareTheta(i+ 2, A, E) \
66        thetaRhoPiChiIotaPrepareTheta(i+ 3, E, A) \
67        thetaRhoPiChiIotaPrepareTheta(i+ 4, A, E) \
68        thetaRhoPiChiIotaPrepareTheta(i+ 5, E, A) \
69        thetaRhoPiChiIotaPrepareTheta(i+ 6, A, E) \
70        thetaRhoPiChiIotaPrepareTheta(i+ 7, E, A) \
71        thetaRhoPiChiIotaPrepareTheta(i+ 8, A, E) \
72        thetaRhoPiChiIotaPrepareTheta(i+ 9, E, A) \
73        thetaRhoPiChiIotaPrepareTheta(i+10, A, E) \
74        thetaRhoPiChiIotaPrepareTheta(i+11, E, A) \
75    } \
76
77#define rounds12 \
78    prepareTheta \
79    thetaRhoPiChiIotaPrepareTheta(12, A, E) \
80    thetaRhoPiChiIotaPrepareTheta(13, E, A) \
81    thetaRhoPiChiIotaPrepareTheta(14, A, E) \
82    thetaRhoPiChiIotaPrepareTheta(15, E, A) \
83    thetaRhoPiChiIotaPrepareTheta(16, A, E) \
84    thetaRhoPiChiIotaPrepareTheta(17, E, A) \
85    thetaRhoPiChiIotaPrepareTheta(18, A, E) \
86    thetaRhoPiChiIotaPrepareTheta(19, E, A) \
87    thetaRhoPiChiIotaPrepareTheta(20, A, E) \
88    thetaRhoPiChiIotaPrepareTheta(21, E, A) \
89    thetaRhoPiChiIotaPrepareTheta(22, A, E) \
90    thetaRhoPiChiIota(23, E, A) \
91
92#elif (Unrolling == 6)
93#define rounds24 \
94    prepareTheta \
95    for(i=0; i<24; i+=6) { \
96        thetaRhoPiChiIotaPrepareTheta(i  , A, E) \
97        thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \
98        thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \
99        thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \
100        thetaRhoPiChiIotaPrepareTheta(i+4, A, E) \
101        thetaRhoPiChiIotaPrepareTheta(i+5, E, A) \
102    } \
103
104#define rounds12 \
105    prepareTheta \
106    for(i=12; i<24; i+=6) { \
107        thetaRhoPiChiIotaPrepareTheta(i  , A, E) \
108        thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \
109        thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \
110        thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \
111        thetaRhoPiChiIotaPrepareTheta(i+4, A, E) \
112        thetaRhoPiChiIotaPrepareTheta(i+5, E, A) \
113    } \
114
115#elif (Unrolling == 4)
116#define rounds24 \
117    prepareTheta \
118    for(i=0; i<24; i+=4) { \
119        thetaRhoPiChiIotaPrepareTheta(i  , A, E) \
120        thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \
121        thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \
122        thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \
123    } \
124
125#define rounds12 \
126    prepareTheta \
127    for(i=12; i<24; i+=4) { \
128        thetaRhoPiChiIotaPrepareTheta(i  , A, E) \
129        thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \
130        thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \
131        thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \
132    } \
133
134#elif (Unrolling == 3)
135#define rounds24 \
136    prepareTheta \
137    for(i=0; i<24; i+=3) { \
138        thetaRhoPiChiIotaPrepareTheta(i  , A, E) \
139        thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \
140        thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \
141        copyStateVariables(A, E) \
142    } \
143
144#define rounds12 \
145    prepareTheta \
146    for(i=12; i<24; i+=3) { \
147        thetaRhoPiChiIotaPrepareTheta(i  , A, E) \
148        thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \
149        thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \
150        copyStateVariables(A, E) \
151    } \
152
153#elif (Unrolling == 2)
154#define rounds24 \
155    prepareTheta \
156    for(i=0; i<24; i+=2) { \
157        thetaRhoPiChiIotaPrepareTheta(i  , A, E) \
158        thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \
159    } \
160
161#define rounds12 \
162    prepareTheta \
163    for(i=12; i<24; i+=2) { \
164        thetaRhoPiChiIotaPrepareTheta(i  , A, E) \
165        thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \
166    } \
167
168#elif (Unrolling == 1)
169#define rounds24 \
170    prepareTheta \
171    for(i=0; i<24; i++) { \
172        thetaRhoPiChiIotaPrepareTheta(i  , A, E) \
173        copyStateVariables(A, E) \
174    } \
175
176#define rounds12 \
177    prepareTheta \
178    for(i=12; i<24; i++) { \
179        thetaRhoPiChiIotaPrepareTheta(i  , A, E) \
180        copyStateVariables(A, E) \
181    } \
182
183#else
184#error "Unrolling is not correctly specified!"
185#endif
186
187#define roundsN(__nrounds) \
188    prepareTheta \
189    i = 24 - (__nrounds); \
190    if ((i&1) != 0) { \
191        thetaRhoPiChiIotaPrepareTheta(i, A, E) \
192        copyStateVariables(A, E) \
193        ++i; \
194    } \
195    for( /* empty */; i<24; i+=2) { \
196        thetaRhoPiChiIotaPrepareTheta(i  , A, E) \
197        thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \
198    }
199