]>
Commit | Line | Data |
---|---|---|
1c8cc9e9 | 1 | /* sha3-permute.c |
90112edb NM |
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 | */ | |
1c8cc9e9 NM |
33 | |
34 | #if HAVE_CONFIG_H | |
35 | # include "config.h" | |
36 | #endif | |
37 | ||
38 | #include "sha3.h" | |
da81c86a | 39 | #include "sha3-internal.h" |
1c8cc9e9 NM |
40 | |
41 | #include "macros.h" | |
42 | ||
43 | #define SHA3_ROUNDS 24 | |
44 | ||
d5cb83ea NM |
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 | ||
1c8cc9e9 NM |
52 | void |
53 | sha3_permute (struct sha3_state *state) | |
54 | { | |
a7457dfa NM |
55 | static const uint64_t rc[SHA3_ROUNDS] = { |
56 | 0x0000000000000001ULL, 0X0000000000008082ULL, | |
57 | 0X800000000000808AULL, 0X8000000080008000ULL, | |
58 | 0X000000000000808BULL, 0X0000000080000001ULL, | |
59 | 0X8000000080008081ULL, 0X8000000000008009ULL, | |
60 | 0X000000000000008AULL, 0X0000000000000088ULL, | |
61 | 0X0000000080008009ULL, 0X000000008000000AULL, | |
62 | 0X000000008000808BULL, 0X800000000000008BULL, | |
63 | 0X8000000000008089ULL, 0X8000000000008003ULL, | |
64 | 0X8000000000008002ULL, 0X8000000000000080ULL, | |
65 | 0X000000000000800AULL, 0X800000008000000AULL, | |
66 | 0X8000000080008081ULL, 0X8000000000008080ULL, | |
67 | 0X0000000080000001ULL, 0X8000000080008008ULL, | |
68 | }; | |
69 | ||
5b7605e0 NM |
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 | ||
1c8cc9e9 NM |
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, | |
5b7605e0 NM |
85 | */ |
86 | ||
a7457dfa NM |
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 | uint64_t C[5], D[5], T, X; | |
118 | unsigned i, y; | |
c41fbeb7 | 119 | |
c41fbeb7 NM |
120 | #define A state->a |
121 | ||
5b7605e0 NM |
122 | C[0] = A[0] ^ A[5+0] ^ A[10+0] ^ A[15+0] ^ A[20+0]; |
123 | C[1] = A[1] ^ A[5+1] ^ A[10+1] ^ A[15+1] ^ A[20+1]; | |
124 | C[2] = A[2] ^ A[5+2] ^ A[10+2] ^ A[15+2] ^ A[20+2]; | |
125 | C[3] = A[3] ^ A[5+3] ^ A[10+3] ^ A[15+3] ^ A[20+3]; | |
126 | C[4] = A[4] ^ A[5+4] ^ A[10+4] ^ A[15+4] ^ A[20+4]; | |
127 | ||
1c8cc9e9 NM |
128 | for (i = 0; i < SHA3_ROUNDS; i++) |
129 | { | |
c41fbeb7 NM |
130 | D[0] = C[4] ^ ROTL64(1, C[1]); |
131 | D[1] = C[0] ^ ROTL64(1, C[2]); | |
132 | D[2] = C[1] ^ ROTL64(1, C[3]); | |
133 | D[3] = C[2] ^ ROTL64(1, C[4]); | |
134 | D[4] = C[3] ^ ROTL64(1, C[0]); | |
135 | ||
a7457dfa NM |
136 | A[0] ^= D[0]; |
137 | X = A[ 1] ^ D[1]; T = ROTL64(1, X); | |
138 | X = A[ 6] ^ D[1]; A[ 1] = ROTL64 (44, X); | |
139 | X = A[ 9] ^ D[4]; A[ 6] = ROTL64 (20, X); | |
140 | X = A[22] ^ D[2]; A[ 9] = ROTL64 (61, X); | |
141 | X = A[14] ^ D[4]; A[22] = ROTL64 (39, X); | |
142 | X = A[20] ^ D[0]; A[14] = ROTL64 (18, X); | |
143 | X = A[ 2] ^ D[2]; A[20] = ROTL64 (62, X); | |
144 | X = A[12] ^ D[2]; A[ 2] = ROTL64 (43, X); | |
145 | X = A[13] ^ D[3]; A[12] = ROTL64 (25, X); | |
146 | X = A[19] ^ D[4]; A[13] = ROTL64 ( 8, X); | |
147 | X = A[23] ^ D[3]; A[19] = ROTL64 (56, X); | |
148 | X = A[15] ^ D[0]; A[23] = ROTL64 (41, X); | |
149 | X = A[ 4] ^ D[4]; A[15] = ROTL64 (27, X); | |
150 | X = A[24] ^ D[4]; A[ 4] = ROTL64 (14, X); | |
151 | X = A[21] ^ D[1]; A[24] = ROTL64 ( 2, X); | |
152 | X = A[ 8] ^ D[3]; A[21] = ROTL64 (55, X); /* row 4 done */ | |
153 | X = A[16] ^ D[1]; A[ 8] = ROTL64 (45, X); | |
154 | X = A[ 5] ^ D[0]; A[16] = ROTL64 (36, X); | |
155 | X = A[ 3] ^ D[3]; A[ 5] = ROTL64 (28, X); | |
156 | X = A[18] ^ D[3]; A[ 3] = ROTL64 (21, X); /* row 0 done */ | |
157 | X = A[17] ^ D[2]; A[18] = ROTL64 (15, X); | |
158 | X = A[11] ^ D[1]; A[17] = ROTL64 (10, X); /* row 3 done */ | |
159 | X = A[ 7] ^ D[2]; A[11] = ROTL64 ( 6, X); /* row 1 done */ | |
160 | X = A[10] ^ D[0]; A[ 7] = ROTL64 ( 3, X); | |
161 | A[10] = T; /* row 2 done */ | |
162 | ||
163 | D[0] = ~A[1] & A[2]; | |
164 | D[1] = ~A[2] & A[3]; | |
165 | D[2] = ~A[3] & A[4]; | |
166 | D[3] = ~A[4] & A[0]; | |
167 | D[4] = ~A[0] & A[1]; | |
168 | ||
169 | A[0] ^= D[0] ^ rc[i]; C[0] = A[0]; | |
170 | A[1] ^= D[1]; C[1] = A[1]; | |
171 | A[2] ^= D[2]; C[2] = A[2]; | |
172 | A[3] ^= D[3]; C[3] = A[3]; | |
173 | A[4] ^= D[4]; C[4] = A[4]; | |
174 | ||
175 | for (y = 5; y < 25; y+= 5) | |
c41fbeb7 | 176 | { |
a7457dfa NM |
177 | D[0] = ~A[y+1] & A[y+2]; |
178 | D[1] = ~A[y+2] & A[y+3]; | |
179 | D[2] = ~A[y+3] & A[y+4]; | |
180 | D[3] = ~A[y+4] & A[y+0]; | |
181 | D[4] = ~A[y+0] & A[y+1]; | |
182 | ||
183 | A[y+0] ^= D[0]; C[0] ^= A[y+0]; | |
184 | A[y+1] ^= D[1]; C[1] ^= A[y+1]; | |
185 | A[y+2] ^= D[2]; C[2] ^= A[y+2]; | |
186 | A[y+3] ^= D[3]; C[3] ^= A[y+3]; | |
187 | A[y+4] ^= D[4]; C[4] ^= A[y+4]; | |
c41fbeb7 | 188 | } |
1c8cc9e9 | 189 | } |
c41fbeb7 | 190 | #undef A |
1c8cc9e9 | 191 | } |