Coverage Report

Created: 2026-02-09 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/nettle/sha512-compress.c
Line
Count
Source
1
/* sha512-compress.c
2
3
   The compression function of the sha512 hash function.
4
5
   Copyright (C) 2001, 2010 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
#ifndef SHA512_DEBUG
39
# define SHA512_DEBUG 0
40
#endif
41
42
#if SHA512_DEBUG
43
# include <stdio.h>
44
# define DEBUG(i) \
45
  fprintf(stderr, "%2d: %8lx %8lx %8lx %8lx\n    %8lx %8lx %8lx %8lx\n", \
46
    i, A, B, C, D ,E, F, G, H)
47
#else
48
# define DEBUG(i)
49
#endif
50
51
#include <assert.h>
52
#include <stdlib.h>
53
#include <string.h>
54
55
#include "sha2.h"
56
#include "sha2-internal.h"
57
58
#include "macros.h"
59
60
/* A block, treated as a sequence of 64-bit words. */
61
51.8M
#define SHA512_DATA_LENGTH 16
62
63
/* For fat builds */
64
#if HAVE_NATIVE_sha512_compress
65
void
66
_nettle_sha512_compress_c (uint64_t *state, const uint8_t *input, const uint64_t *k);
67
#define _nettle_sha512_compress _nettle_sha512_compress_c
68
#endif
69
70
/* The SHA512 functions. The Choice function is the same as the SHA1
71
   function f1, and the majority function is the same as the SHA1 f3
72
   function, and the same as for SHA256. */
73
74
243M
#define Choice(x,y,z)   ( (z) ^ ( (x) & ( (y) ^ (z) ) ) ) 
75
243M
#define Majority(x,y,z) ( ((x) & (y)) ^ ((z) & ((x) ^ (y))) )
76
77
243M
#define S0(x) (ROTL64(36,(x)) ^ ROTL64(30,(x)) ^ ROTL64(25,(x))) 
78
243M
#define S1(x) (ROTL64(50,(x)) ^ ROTL64(46,(x)) ^ ROTL64(23,(x)))
79
80
#define s0(x) (ROTL64(63,(x)) ^ ROTL64(56,(x)) ^ ((x) >> 7))
81
#define s1(x) (ROTL64(45,(x)) ^ ROTL64(3,(x)) ^ ((x) >> 6))
82
83
/* The initial expanding function. The hash function is defined over
84
   an 64-word expanded input array W, where the first 16 are copies of
85
   the input data, and the remaining 64 are defined by
86
87
        W[ t ] = s1(W[t-2]) + W[t-7] + s0(W[i-15]) + W[i-16]
88
89
   This implementation generates these values on the fly in a circular
90
   buffer.
91
*/
92
93
#define EXPAND(W,i) \
94
( W[(i) & 15 ] += (s1(W[((i)-2) & 15]) + W[((i)-7) & 15] + s0(W[((i)-15) & 15])) )
95
96
/* The prototype SHA sub-round.  The fundamental sub-round is:
97
98
        T1 = h + S1(e) + Choice(e,f,g) + K[t] + W[t]
99
  T2 = S0(a) + Majority(a,b,c)
100
  a' = T1+T2
101
  b' = a
102
  c' = b
103
  d' = c
104
  e' = d + T1
105
  f' = e
106
  g' = f
107
  h' = g
108
109
   but this is implemented by unrolling the loop 8 times and renaming
110
   the variables
111
   ( h, a, b, c, d, e, f, g ) = ( a, b, c, d, e, f, g, h ) each
112
   iteration. This code is then replicated 8, using the next 8 values
113
   from the W[] array each time */
114
115
/* It's crucial that DATA is only used once, as that argument will
116
 * have side effects. */
117
243M
#define ROUND(a,b,c,d,e,f,g,h,k,data) do { \
118
243M
  h += S1(e) + Choice(e,f,g) + k + data; \
119
243M
  d += h;         \
120
243M
  h += S0(a) + Majority(a,b,c);      \
121
243M
} while (0)
122
123
void
124
_nettle_sha512_compress(uint64_t *state, const uint8_t *input, const uint64_t *k)
125
3.04M
{
126
3.04M
  uint64_t data[SHA512_DATA_LENGTH];
127
3.04M
  uint64_t A, B, C, D, E, F, G, H;     /* Local vars */
128
3.04M
  unsigned i;
129
3.04M
  uint64_t *d;
130
131
51.8M
  for (i = 0; i < SHA512_DATA_LENGTH; i++, input += 8)
132
48.7M
    {
133
48.7M
      data[i] = READ_UINT64(input);
134
48.7M
    }
135
136
  /* Set up first buffer and local data buffer */
137
3.04M
  A = state[0];
138
3.04M
  B = state[1];
139
3.04M
  C = state[2];
140
3.04M
  D = state[3];
141
3.04M
  E = state[4];
142
3.04M
  F = state[5];
143
3.04M
  G = state[6];
144
3.04M
  H = state[7];
145
  
146
  /* Heavy mangling */
147
  /* First 16 subrounds that act on the original data */
148
149
3.04M
  DEBUG(-1);
150
9.14M
  for (i = 0, d = data; i<16; i+=8, k += 8, d+= 8)
151
6.09M
    {
152
6.09M
      ROUND(A, B, C, D, E, F, G, H, k[0], d[0]); DEBUG(i);
153
6.09M
      ROUND(H, A, B, C, D, E, F, G, k[1], d[1]); DEBUG(i+1);
154
6.09M
      ROUND(G, H, A, B, C, D, E, F, k[2], d[2]);
155
6.09M
      ROUND(F, G, H, A, B, C, D, E, k[3], d[3]);
156
6.09M
      ROUND(E, F, G, H, A, B, C, D, k[4], d[4]);
157
6.09M
      ROUND(D, E, F, G, H, A, B, C, k[5], d[5]);
158
6.09M
      ROUND(C, D, E, F, G, H, A, B, k[6], d[6]); DEBUG(i+6);
159
6.09M
      ROUND(B, C, D, E, F, G, H, A, k[7], d[7]); DEBUG(i+7);
160
6.09M
    }
161
  
162
15.2M
  for (; i<80; i += 16, k+= 16)
163
12.1M
    {
164
12.1M
      ROUND(A, B, C, D, E, F, G, H, k[ 0], EXPAND(data,  0)); DEBUG(i);
165
12.1M
      ROUND(H, A, B, C, D, E, F, G, k[ 1], EXPAND(data,  1)); DEBUG(i+1);
166
12.1M
      ROUND(G, H, A, B, C, D, E, F, k[ 2], EXPAND(data,  2)); DEBUG(i+2);
167
12.1M
      ROUND(F, G, H, A, B, C, D, E, k[ 3], EXPAND(data,  3));
168
12.1M
      ROUND(E, F, G, H, A, B, C, D, k[ 4], EXPAND(data,  4));
169
12.1M
      ROUND(D, E, F, G, H, A, B, C, k[ 5], EXPAND(data,  5));
170
12.1M
      ROUND(C, D, E, F, G, H, A, B, k[ 6], EXPAND(data,  6));
171
12.1M
      ROUND(B, C, D, E, F, G, H, A, k[ 7], EXPAND(data,  7));
172
12.1M
      ROUND(A, B, C, D, E, F, G, H, k[ 8], EXPAND(data,  8));
173
12.1M
      ROUND(H, A, B, C, D, E, F, G, k[ 9], EXPAND(data,  9));
174
12.1M
      ROUND(G, H, A, B, C, D, E, F, k[10], EXPAND(data, 10));
175
12.1M
      ROUND(F, G, H, A, B, C, D, E, k[11], EXPAND(data, 11));
176
12.1M
      ROUND(E, F, G, H, A, B, C, D, k[12], EXPAND(data, 12));
177
12.1M
      ROUND(D, E, F, G, H, A, B, C, k[13], EXPAND(data, 13));
178
12.1M
      ROUND(C, D, E, F, G, H, A, B, k[14], EXPAND(data, 14)); DEBUG(i+14);
179
12.1M
      ROUND(B, C, D, E, F, G, H, A, k[15], EXPAND(data, 15)); DEBUG(i+15);
180
12.1M
    }
181
182
  /* Update state */
183
3.04M
  state[0] += A;
184
3.04M
  state[1] += B;
185
3.04M
  state[2] += C;
186
3.04M
  state[3] += D;
187
3.04M
  state[4] += E;
188
3.04M
  state[5] += F;
189
3.04M
  state[6] += G;
190
3.04M
  state[7] += H;
191
#if SHA512_DEBUG
192
  fprintf(stderr, "99: %8lx %8lx %8lx %8lx\n    %8lx %8lx %8lx %8lx\n",
193
    state[0], state[1], state[2], state[3],
194
    state[4], state[5], state[6], state[7]);
195
#endif
196
3.04M
}