/src/nettle/sha3-permute.c
Line  | Count  | Source (jump to first uncovered line)  | 
1  |  | /* sha3-permute.c  | 
2  |  |  | 
3  |  |    The sha3 permutation function (aka Keccak).  | 
4  |  |  | 
5  |  |    Copyright (C) 2012 Niels Möller  | 
6  |  |  | 
7  |  |    This file is part of GNU Nettle.  | 
8  |  |  | 
9  |  |    GNU Nettle is free software: you can redistribute it and/or  | 
10  |  |    modify it under the terms of either:  | 
11  |  |  | 
12  |  |      * the GNU Lesser General Public License as published by the Free  | 
13  |  |        Software Foundation; either version 3 of the License, or (at your  | 
14  |  |        option) any later version.  | 
15  |  |  | 
16  |  |    or  | 
17  |  |  | 
18  |  |      * the GNU General Public License as published by the Free  | 
19  |  |        Software Foundation; either version 2 of the License, or (at your  | 
20  |  |        option) any later version.  | 
21  |  |  | 
22  |  |    or both in parallel, as here.  | 
23  |  |  | 
24  |  |    GNU Nettle is distributed in the hope that it will be useful,  | 
25  |  |    but WITHOUT ANY WARRANTY; without even the implied warranty of  | 
26  |  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  | 
27  |  |    General Public License for more details.  | 
28  |  |  | 
29  |  |    You should have received copies of the GNU General Public License and  | 
30  |  |    the GNU Lesser General Public License along with this program.  If  | 
31  |  |    not, see http://www.gnu.org/licenses/.  | 
32  |  | */  | 
33  |  |  | 
34  |  | #if HAVE_CONFIG_H  | 
35  |  | # include "config.h"  | 
36  |  | #endif  | 
37  |  |  | 
38  |  | #include "sha3.h"  | 
39  |  | #include "sha3-internal.h"  | 
40  |  |  | 
41  |  | #include "macros.h"  | 
42  |  |  | 
43  | 0  | #define SHA3_ROUNDS 24  | 
44  |  |  | 
45  |  | /* For fat builds */  | 
46  |  | #if HAVE_NATIVE_sha3_permute  | 
47  |  | void  | 
48  |  | _nettle_sha3_permute_c(struct sha3_state *state);  | 
49  |  | #define nettle_sha3_permute _nettle_sha3_permute_c  | 
50  |  | #endif  | 
51  |  |  | 
52  |  | void  | 
53  |  | sha3_permute (struct sha3_state *state)  | 
54  | 0  | { | 
55  | 0  |   static const uint64_t rc[SHA3_ROUNDS] = { | 
56  | 0  |     0x0000000000000001ULL, 0X0000000000008082ULL,  | 
57  | 0  |     0X800000000000808AULL, 0X8000000080008000ULL,  | 
58  | 0  |     0X000000000000808BULL, 0X0000000080000001ULL,  | 
59  | 0  |     0X8000000080008081ULL, 0X8000000000008009ULL,  | 
60  | 0  |     0X000000000000008AULL, 0X0000000000000088ULL,  | 
61  | 0  |     0X0000000080008009ULL, 0X000000008000000AULL,  | 
62  | 0  |     0X000000008000808BULL, 0X800000000000008BULL,  | 
63  | 0  |     0X8000000000008089ULL, 0X8000000000008003ULL,  | 
64  | 0  |     0X8000000000008002ULL, 0X8000000000000080ULL,  | 
65  | 0  |     0X000000000000800AULL, 0X800000008000000AULL,  | 
66  | 0  |     0X8000000080008081ULL, 0X8000000000008080ULL,  | 
67  | 0  |     0X0000000080000001ULL, 0X8000000080008008ULL,  | 
68  | 0  |   };  | 
69  |  |  | 
70  |  |   /* Original permutation:  | 
71  |  |        | 
72  |  |        0,10,20, 5,15,  | 
73  |  |       16, 1,11,21, 6,  | 
74  |  |        7,17, 2,12,22,  | 
75  |  |       23, 8,18, 3,13,  | 
76  |  |       14,24, 9,19, 4  | 
77  |  |  | 
78  |  |      Rotation counts:  | 
79  |  |  | 
80  |  |        0,  1, 62, 28, 27,  | 
81  |  |       36, 44,  6, 55, 20,  | 
82  |  |        3, 10, 43, 25, 39,  | 
83  |  |       41, 45, 15, 21,  8,  | 
84  |  |       18,  2, 61, 56, 14,  | 
85  |  |   */  | 
86  |  |  | 
87  |  |   /* In-place implementation. Permutation done as a long sequence of  | 
88  |  |      25 moves "following" the permutation.  | 
89  |  |  | 
90  |  |       T <--  1  | 
91  |  |       1 <--  6  | 
92  |  |       6 <--  9  | 
93  |  |       9 <-- 22  | 
94  |  |      22 <-- 14  | 
95  |  |      14 <-- 20  | 
96  |  |      20 <--  2  | 
97  |  |       2 <-- 12  | 
98  |  |      12 <-- 13  | 
99  |  |      13 <-- 19  | 
100  |  |      19 <-- 23  | 
101  |  |      23 <-- 15  | 
102  |  |      15 <--  4  | 
103  |  |       4 <-- 24  | 
104  |  |      24 <-- 21  | 
105  |  |      21 <--  8  | 
106  |  |       8 <-- 16  | 
107  |  |      16 <--  5  | 
108  |  |       5 <--  3  | 
109  |  |       3 <-- 18  | 
110  |  |      18 <-- 17  | 
111  |  |      17 <-- 11  | 
112  |  |      11 <--  7  | 
113  |  |       7 <-- 10  | 
114  |  |      10 <--  T  | 
115  |  |  | 
116  |  |   */  | 
117  | 0  |   uint64_t C[5], D[5], T, X;  | 
118  | 0  |   unsigned i, y;  | 
119  |  | 
  | 
120  | 0  | #define A state->a  | 
121  |  | 
  | 
122  | 0  |   C[0] = A[0] ^ A[5+0] ^ A[10+0] ^ A[15+0] ^ A[20+0];  | 
123  | 0  |   C[1] = A[1] ^ A[5+1] ^ A[10+1] ^ A[15+1] ^ A[20+1];  | 
124  | 0  |   C[2] = A[2] ^ A[5+2] ^ A[10+2] ^ A[15+2] ^ A[20+2];  | 
125  | 0  |   C[3] = A[3] ^ A[5+3] ^ A[10+3] ^ A[15+3] ^ A[20+3];  | 
126  | 0  |   C[4] = A[4] ^ A[5+4] ^ A[10+4] ^ A[15+4] ^ A[20+4];  | 
127  |  | 
  | 
128  | 0  |   for (i = 0; i < SHA3_ROUNDS; i++)  | 
129  | 0  |     { | 
130  | 0  |       D[0] = C[4] ^ ROTL64(1, C[1]);  | 
131  | 0  |       D[1] = C[0] ^ ROTL64(1, C[2]);  | 
132  | 0  |       D[2] = C[1] ^ ROTL64(1, C[3]);  | 
133  | 0  |       D[3] = C[2] ^ ROTL64(1, C[4]);  | 
134  | 0  |       D[4] = C[3] ^ ROTL64(1, C[0]);  | 
135  |  | 
  | 
136  | 0  |       A[0] ^= D[0];  | 
137  | 0  |       X = A[ 1] ^ D[1];     T = ROTL64(1, X);  | 
138  | 0  |       X = A[ 6] ^ D[1]; A[ 1] = ROTL64 (44, X);  | 
139  | 0  |       X = A[ 9] ^ D[4]; A[ 6] = ROTL64 (20, X);  | 
140  | 0  |       X = A[22] ^ D[2]; A[ 9] = ROTL64 (61, X);  | 
141  | 0  |       X = A[14] ^ D[4]; A[22] = ROTL64 (39, X);  | 
142  | 0  |       X = A[20] ^ D[0]; A[14] = ROTL64 (18, X);  | 
143  | 0  |       X = A[ 2] ^ D[2]; A[20] = ROTL64 (62, X);  | 
144  | 0  |       X = A[12] ^ D[2]; A[ 2] = ROTL64 (43, X);  | 
145  | 0  |       X = A[13] ^ D[3]; A[12] = ROTL64 (25, X);  | 
146  | 0  |       X = A[19] ^ D[4]; A[13] = ROTL64 ( 8, X);  | 
147  | 0  |       X = A[23] ^ D[3]; A[19] = ROTL64 (56, X);  | 
148  | 0  |       X = A[15] ^ D[0]; A[23] = ROTL64 (41, X);  | 
149  | 0  |       X = A[ 4] ^ D[4]; A[15] = ROTL64 (27, X);  | 
150  | 0  |       X = A[24] ^ D[4]; A[ 4] = ROTL64 (14, X);  | 
151  | 0  |       X = A[21] ^ D[1]; A[24] = ROTL64 ( 2, X);  | 
152  | 0  |       X = A[ 8] ^ D[3]; A[21] = ROTL64 (55, X); /* row 4 done */  | 
153  | 0  |       X = A[16] ^ D[1]; A[ 8] = ROTL64 (45, X);  | 
154  | 0  |       X = A[ 5] ^ D[0]; A[16] = ROTL64 (36, X);  | 
155  | 0  |       X = A[ 3] ^ D[3]; A[ 5] = ROTL64 (28, X);  | 
156  | 0  |       X = A[18] ^ D[3]; A[ 3] = ROTL64 (21, X); /* row 0 done */  | 
157  | 0  |       X = A[17] ^ D[2]; A[18] = ROTL64 (15, X);  | 
158  | 0  |       X = A[11] ^ D[1]; A[17] = ROTL64 (10, X); /* row 3 done */  | 
159  | 0  |       X = A[ 7] ^ D[2]; A[11] = ROTL64 ( 6, X); /* row 1 done */  | 
160  | 0  |       X = A[10] ^ D[0]; A[ 7] = ROTL64 ( 3, X);  | 
161  | 0  |       A[10] = T;       /* row 2 done */  | 
162  |  | 
  | 
163  | 0  |       D[0] = ~A[1] & A[2];  | 
164  | 0  |       D[1] = ~A[2] & A[3];  | 
165  | 0  |       D[2] = ~A[3] & A[4];  | 
166  | 0  |       D[3] = ~A[4] & A[0];  | 
167  | 0  |       D[4] = ~A[0] & A[1];  | 
168  |  | 
  | 
169  | 0  |       A[0] ^= D[0] ^ rc[i]; C[0] = A[0];  | 
170  | 0  |       A[1] ^= D[1]; C[1] = A[1];  | 
171  | 0  |       A[2] ^= D[2]; C[2] = A[2];  | 
172  | 0  |       A[3] ^= D[3]; C[3] = A[3];  | 
173  | 0  |       A[4] ^= D[4]; C[4] = A[4];  | 
174  |  | 
  | 
175  | 0  |       for (y = 5; y < 25; y+= 5)  | 
176  | 0  |   { | 
177  | 0  |     D[0] = ~A[y+1] & A[y+2];  | 
178  | 0  |     D[1] = ~A[y+2] & A[y+3];  | 
179  | 0  |     D[2] = ~A[y+3] & A[y+4];  | 
180  | 0  |     D[3] = ~A[y+4] & A[y+0];  | 
181  | 0  |     D[4] = ~A[y+0] & A[y+1];  | 
182  |  | 
  | 
183  | 0  |     A[y+0] ^= D[0]; C[0] ^= A[y+0];  | 
184  | 0  |     A[y+1] ^= D[1]; C[1] ^= A[y+1];  | 
185  | 0  |     A[y+2] ^= D[2]; C[2] ^= A[y+2];  | 
186  | 0  |     A[y+3] ^= D[3]; C[3] ^= A[y+3];  | 
187  | 0  |     A[y+4] ^= D[4]; C[4] ^= A[y+4];  | 
188  | 0  |   }  | 
189  | 0  |     }  | 
190  | 0  | #undef A  | 
191  | 0  | }  |