/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 | } |