Coverage Report

Created: 2025-07-23 06:43

/src/nettle/sha3-permute.c
Line
Count
Source
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
541k
#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
21.6k
{
55
21.6k
  static const uint64_t rc[SHA3_ROUNDS] = {
56
21.6k
    0x0000000000000001ULL, 0X0000000000008082ULL,
57
21.6k
    0X800000000000808AULL, 0X8000000080008000ULL,
58
21.6k
    0X000000000000808BULL, 0X0000000080000001ULL,
59
21.6k
    0X8000000080008081ULL, 0X8000000000008009ULL,
60
21.6k
    0X000000000000008AULL, 0X0000000000000088ULL,
61
21.6k
    0X0000000080008009ULL, 0X000000008000000AULL,
62
21.6k
    0X000000008000808BULL, 0X800000000000008BULL,
63
21.6k
    0X8000000000008089ULL, 0X8000000000008003ULL,
64
21.6k
    0X8000000000008002ULL, 0X8000000000000080ULL,
65
21.6k
    0X000000000000800AULL, 0X800000008000000AULL,
66
21.6k
    0X8000000080008081ULL, 0X8000000000008080ULL,
67
21.6k
    0X0000000080000001ULL, 0X8000000080008008ULL,
68
21.6k
  };
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
21.6k
  uint64_t C[5], D[5], T, X;
118
21.6k
  unsigned i, y;
119
120
78.0M
#define A state->a
121
122
21.6k
  C[0] = A[0] ^ A[5+0] ^ A[10+0] ^ A[15+0] ^ A[20+0];
123
21.6k
  C[1] = A[1] ^ A[5+1] ^ A[10+1] ^ A[15+1] ^ A[20+1];
124
21.6k
  C[2] = A[2] ^ A[5+2] ^ A[10+2] ^ A[15+2] ^ A[20+2];
125
21.6k
  C[3] = A[3] ^ A[5+3] ^ A[10+3] ^ A[15+3] ^ A[20+3];
126
21.6k
  C[4] = A[4] ^ A[5+4] ^ A[10+4] ^ A[15+4] ^ A[20+4];
127
128
541k
  for (i = 0; i < SHA3_ROUNDS; i++)
129
520k
    {
130
520k
      D[0] = C[4] ^ ROTL64(1, C[1]);
131
520k
      D[1] = C[0] ^ ROTL64(1, C[2]);
132
520k
      D[2] = C[1] ^ ROTL64(1, C[3]);
133
520k
      D[3] = C[2] ^ ROTL64(1, C[4]);
134
520k
      D[4] = C[3] ^ ROTL64(1, C[0]);
135
136
520k
      A[0] ^= D[0];
137
520k
      X = A[ 1] ^ D[1];     T = ROTL64(1, X);
138
520k
      X = A[ 6] ^ D[1]; A[ 1] = ROTL64 (44, X);
139
520k
      X = A[ 9] ^ D[4]; A[ 6] = ROTL64 (20, X);
140
520k
      X = A[22] ^ D[2]; A[ 9] = ROTL64 (61, X);
141
520k
      X = A[14] ^ D[4]; A[22] = ROTL64 (39, X);
142
520k
      X = A[20] ^ D[0]; A[14] = ROTL64 (18, X);
143
520k
      X = A[ 2] ^ D[2]; A[20] = ROTL64 (62, X);
144
520k
      X = A[12] ^ D[2]; A[ 2] = ROTL64 (43, X);
145
520k
      X = A[13] ^ D[3]; A[12] = ROTL64 (25, X);
146
520k
      X = A[19] ^ D[4]; A[13] = ROTL64 ( 8, X);
147
520k
      X = A[23] ^ D[3]; A[19] = ROTL64 (56, X);
148
520k
      X = A[15] ^ D[0]; A[23] = ROTL64 (41, X);
149
520k
      X = A[ 4] ^ D[4]; A[15] = ROTL64 (27, X);
150
520k
      X = A[24] ^ D[4]; A[ 4] = ROTL64 (14, X);
151
520k
      X = A[21] ^ D[1]; A[24] = ROTL64 ( 2, X);
152
520k
      X = A[ 8] ^ D[3]; A[21] = ROTL64 (55, X); /* row 4 done */
153
520k
      X = A[16] ^ D[1]; A[ 8] = ROTL64 (45, X);
154
520k
      X = A[ 5] ^ D[0]; A[16] = ROTL64 (36, X);
155
520k
      X = A[ 3] ^ D[3]; A[ 5] = ROTL64 (28, X);
156
520k
      X = A[18] ^ D[3]; A[ 3] = ROTL64 (21, X); /* row 0 done */
157
520k
      X = A[17] ^ D[2]; A[18] = ROTL64 (15, X);
158
520k
      X = A[11] ^ D[1]; A[17] = ROTL64 (10, X); /* row 3 done */
159
520k
      X = A[ 7] ^ D[2]; A[11] = ROTL64 ( 6, X); /* row 1 done */
160
520k
      X = A[10] ^ D[0]; A[ 7] = ROTL64 ( 3, X);
161
520k
      A[10] = T;       /* row 2 done */
162
163
520k
      D[0] = ~A[1] & A[2];
164
520k
      D[1] = ~A[2] & A[3];
165
520k
      D[2] = ~A[3] & A[4];
166
520k
      D[3] = ~A[4] & A[0];
167
520k
      D[4] = ~A[0] & A[1];
168
169
520k
      A[0] ^= D[0] ^ rc[i]; C[0] = A[0];
170
520k
      A[1] ^= D[1]; C[1] = A[1];
171
520k
      A[2] ^= D[2]; C[2] = A[2];
172
520k
      A[3] ^= D[3]; C[3] = A[3];
173
520k
      A[4] ^= D[4]; C[4] = A[4];
174
175
2.60M
      for (y = 5; y < 25; y+= 5)
176
2.08M
  {
177
2.08M
    D[0] = ~A[y+1] & A[y+2];
178
2.08M
    D[1] = ~A[y+2] & A[y+3];
179
2.08M
    D[2] = ~A[y+3] & A[y+4];
180
2.08M
    D[3] = ~A[y+4] & A[y+0];
181
2.08M
    D[4] = ~A[y+0] & A[y+1];
182
183
2.08M
    A[y+0] ^= D[0]; C[0] ^= A[y+0];
184
2.08M
    A[y+1] ^= D[1]; C[1] ^= A[y+1];
185
2.08M
    A[y+2] ^= D[2]; C[2] ^= A[y+2];
186
2.08M
    A[y+3] ^= D[3]; C[3] ^= A[y+3];
187
2.08M
    A[y+4] ^= D[4]; C[4] ^= A[y+4];
188
2.08M
  }
189
520k
    }
190
21.6k
#undef A
191
21.6k
}