SHA256.cpp
Go to the documentation of this file.
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2  *
3  * LibTomCrypt is a library that provides various cryptographic
4  * algorithms in a highly modular and flexible manner.
5  *
6  * The library is free for all purposes without any express
7  * guarantee it works.
8  */
10 #include <cassert>
11 #include <cstring>
12 
19 #define LOAD32H(x, y) \
20  { \
21  x = ((ulong32)((y)[0] & 255) << 24) | ((ulong32)((y)[1] & 255) << 16) | \
22  ((ulong32)((y)[2] & 255) << 8) | ((ulong32)((y)[3] & 255)); \
23  }
24 
25 #define STORE32H(x, y) \
26  { \
27  (y)[0] = (ulong8)(((x) >> 24) & 255); \
28  (y)[1] = (ulong8)(((x) >> 16) & 255); \
29  (y)[2] = (ulong8)(((x) >> 8) & 255); \
30  (y)[3] = (ulong8)((x)&255); \
31  }
32 
33 #define STORE64H(x, y) \
34  { \
35  (y)[0] = (ulong8)(((x) >> 56) & 255); \
36  (y)[1] = (ulong8)(((x) >> 48) & 255); \
37  (y)[2] = (ulong8)(((x) >> 40) & 255); \
38  (y)[3] = (ulong8)(((x) >> 32) & 255); \
39  (y)[4] = (ulong8)(((x) >> 24) & 255); \
40  (y)[5] = (ulong8)(((x) >> 16) & 255); \
41  (y)[6] = (ulong8)(((x) >> 8) & 255); \
42  (y)[7] = (ulong8)((x)&255); \
43  }
44 
45 #define XMEMCPY memcpy
46 
47 #define XMEMCMP memcmp
48 
49 #ifndef MIN
50 # define MIN(x, y) (((x) < (y)) ? (x) : (y))
51 #endif
52 
53 
54 #define RORc(x, y) \
55  (((((ulong32)(x)&0xFFFFFFFFUL) >> (ulong32)((y)&31)) | \
56  ((ulong32)(x) << (ulong32)(32 - ((y)&31)))) & \
57  0xFFFFFFFFUL)
58 
59 /* Various logical functions */
60 #define Ch(x, y, z) (z ^ (x & (y ^ z)))
61 #define Maj(x, y, z) (((x | y) & z) | (x & y))
62 #define S(x, n) RORc((x), (n))
63 #define R(x, n) (((x)&0xFFFFFFFFUL) >> (n))
64 #define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
65 #define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
66 #define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
67 #define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
68 
69 static int sha256_compress(hash_state* md, const unsigned char* buf)
70 {
71  ulong32 S[8], W[64], t0, t1;
72  int i;
73 
74  /* copy state into S */
75  for (i = 0; i < 8; i++)
76  {
77  S[i] = md->sha256.state[i];
78  }
79 
80  /* copy the state into 512-bits into W[0..15] */
81  for (i = 0; i < 16; i++)
82  {
83  LOAD32H(W[i], buf + (4 * i));
84  }
85 
86  /* fill W[16..63] */
87  for (i = 16; i < 64; i++)
88  {
89  W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
90  }
91 
92  /* Compress */
93 #define RND(a, b, c, d, e, f, g, h, i, ki) \
94  t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \
95  t1 = Sigma0(a) + Maj(a, b, c); \
96  d += t0; \
97  h = t0 + t1;
98 
99  RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 0, 0x428a2f98);
100  RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 1, 0x71374491);
101  RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 2, 0xb5c0fbcf);
102  RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 3, 0xe9b5dba5);
103  RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 4, 0x3956c25b);
104  RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 5, 0x59f111f1);
105  RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 6, 0x923f82a4);
106  RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 7, 0xab1c5ed5);
107  RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 8, 0xd807aa98);
108  RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 9, 0x12835b01);
109  RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 10, 0x243185be);
110  RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 11, 0x550c7dc3);
111  RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 12, 0x72be5d74);
112  RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 13, 0x80deb1fe);
113  RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 14, 0x9bdc06a7);
114  RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 15, 0xc19bf174);
115  RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 16, 0xe49b69c1);
116  RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 17, 0xefbe4786);
117  RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 18, 0x0fc19dc6);
118  RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 19, 0x240ca1cc);
119  RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 20, 0x2de92c6f);
120  RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 21, 0x4a7484aa);
121  RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 22, 0x5cb0a9dc);
122  RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 23, 0x76f988da);
123  RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 24, 0x983e5152);
124  RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 25, 0xa831c66d);
125  RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 26, 0xb00327c8);
126  RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 27, 0xbf597fc7);
127  RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 28, 0xc6e00bf3);
128  RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 29, 0xd5a79147);
129  RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 30, 0x06ca6351);
130  RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 31, 0x14292967);
131  RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 32, 0x27b70a85);
132  RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 33, 0x2e1b2138);
133  RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 34, 0x4d2c6dfc);
134  RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 35, 0x53380d13);
135  RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 36, 0x650a7354);
136  RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 37, 0x766a0abb);
137  RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 38, 0x81c2c92e);
138  RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 39, 0x92722c85);
139  RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 40, 0xa2bfe8a1);
140  RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 41, 0xa81a664b);
141  RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 42, 0xc24b8b70);
142  RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 43, 0xc76c51a3);
143  RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 44, 0xd192e819);
144  RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 45, 0xd6990624);
145  RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 46, 0xf40e3585);
146  RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 47, 0x106aa070);
147  RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 48, 0x19a4c116);
148  RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 49, 0x1e376c08);
149  RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 50, 0x2748774c);
150  RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 51, 0x34b0bcb5);
151  RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 52, 0x391c0cb3);
152  RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 53, 0x4ed8aa4a);
153  RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 54, 0x5b9cca4f);
154  RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 55, 0x682e6ff3);
155  RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 56, 0x748f82ee);
156  RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 57, 0x78a5636f);
157  RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 58, 0x84c87814);
158  RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 59, 0x8cc70208);
159  RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 60, 0x90befffa);
160  RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 61, 0xa4506ceb);
161  RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 62, 0xbef9a3f7);
162  RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 63, 0xc67178f2);
163 
164 #undef RND
165 
166  /* feedback */
167  for (i = 0; i < 8; i++)
168  {
169  md->sha256.state[i] = md->sha256.state[i] + S[i];
170  }
171  return CRYPT_OK;
172 }
173 
174 
181 {
182  assert(md != NULL);
183 
184  md->sha256.curlen = 0;
185  md->sha256.length = 0;
186  md->sha256.state[0] = 0x6A09E667UL;
187  md->sha256.state[1] = 0xBB67AE85UL;
188  md->sha256.state[2] = 0x3C6EF372UL;
189  md->sha256.state[3] = 0xA54FF53AUL;
190  md->sha256.state[4] = 0x510E527FUL;
191  md->sha256.state[5] = 0x9B05688CUL;
192  md->sha256.state[6] = 0x1F83D9ABUL;
193  md->sha256.state[7] = 0x5BE0CD19UL;
194  return CRYPT_OK;
195 }
196 
212 int sha256_process(hash_state* md, const ulong8* in, ulong32 inlen)
213 {
214  ulong32 n;
215  int err;
216  if (NULL == in || NULL == md)
217  {
218  return CRYPT_INVALID_ARG;
219  }
220  if (md->sha256.curlen > sizeof(md->sha256.buf))
221  {
222  return CRYPT_INVALID_ARG;
223  }
224  if ((md->sha256.length + inlen) < md->sha256.length)
225  {
226  return CRYPT_HASH_OVERFLOW;
227  }
228  while (inlen > 0)
229  {
230  if (md->sha256.curlen == 0 && inlen >= 64)
231  {
232  if ((err = sha256_compress(md, (ulong8*)in)) != CRYPT_OK)
233  {
234  return err;
235  }
236  md->sha256.length += 64 * 8;
237  in += 64;
238  inlen -= 64;
239  }
240  else
241  {
242  n = MIN(inlen, (64 - md->sha256.curlen));
243  XMEMCPY(md->sha256.buf + md->sha256.curlen, in, (size_t)n);
244  md->sha256.curlen += n;
245  in += n;
246  inlen -= n;
247  if (md->sha256.curlen == 64)
248  {
249  if ((err = sha256_compress(md, md->sha256.buf)) != CRYPT_OK)
250  {
251  return err;
252  }
253  md->sha256.length += 8 * 64;
254  md->sha256.curlen = 0;
255  }
256  }
257  }
258  return CRYPT_OK;
259 }
266 int sha256_done(hash_state* md, unsigned char* out)
267 {
268  int i;
269 
270  assert(md != NULL);
271  assert(out != NULL);
272 
273  if (md->sha256.curlen >= sizeof(md->sha256.buf))
274  {
275  return CRYPT_INVALID_ARG;
276  }
277 
278 
279  /* increase the length of the message */
280  md->sha256.length += md->sha256.curlen * 8;
281 
282  /* append the '1' bit */
283  md->sha256.buf[md->sha256.curlen++] = (unsigned char)0x80;
284 
285  /* if the length is currently above 56 bytes we append zeros
286  * then compress. Then we can fall back to padding zeros and length
287  * encoding like normal.
288  */
289  if (md->sha256.curlen > 56)
290  {
291  while (md->sha256.curlen < 64)
292  {
293  md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
294  }
295  sha256_compress(md, md->sha256.buf);
296  md->sha256.curlen = 0;
297  }
298 
299  /* pad upto 56 bytes of zeroes */
300  while (md->sha256.curlen < 56)
301  {
302  md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
303  }
304 
305  /* store length */
306  STORE64H(md->sha256.length, md->sha256.buf + 56);
307  sha256_compress(md, md->sha256.buf);
308 
309  /* copy output */
310  for (i = 0; i < 8; i++)
311  {
312  STORE32H(md->sha256.state[i], out + (4 * i));
313  }
314  return CRYPT_OK;
315 }
CRYPT_OK
@ CRYPT_OK
Definition: SHA256.h:28
sha256_compress
static int sha256_compress(hash_state *md, const unsigned char *buf)
Definition: SHA256.cpp:69
Hash_state
Definition: SHA256.h:34
Gamma0
#define Gamma0(x)
Definition: SHA256.cpp:66
S
#define S(x, n)
Definition: SHA256.cpp:62
LOAD32H
#define LOAD32H(x, y)
Definition: SHA256.cpp:19
sha256_state::state
ulong32 state[8]
Definition: SHA256.h:21
CRYPT_INVALID_ARG
@ CRYPT_INVALID_ARG
Definition: SHA256.h:30
STORE64H
#define STORE64H(x, y)
Definition: SHA256.cpp:33
sha256_process
int sha256_process(hash_state *md, const ulong8 *in, ulong32 inlen)
Definition: SHA256.cpp:212
ulong32
uint32_t ulong32
Definition: SHA256.h:15
sha256_init
int sha256_init(hash_state *md)
Definition: SHA256.cpp:180
SHA256.h
XMEMCPY
#define XMEMCPY
Definition: SHA256.cpp:45
sha256_state::length
ulong64 length
Definition: SHA256.h:20
ulong8
uint8_t ulong8
Definition: SHA256.h:14
STORE32H
#define STORE32H(x, y)
Definition: SHA256.cpp:25
sha256_state::curlen
ulong32 curlen
Definition: SHA256.h:21
MIN
#define MIN(x, y)
Definition: SHA256.cpp:50
sha256_state::buf
unsigned char buf[64]
Definition: SHA256.h:22
Hash_state::sha256
struct sha256_state sha256
Definition: SHA256.h:36
CRYPT_HASH_OVERFLOW
@ CRYPT_HASH_OVERFLOW
Definition: SHA256.h:31
Gamma1
#define Gamma1(x)
Definition: SHA256.cpp:67
sha256_done
int sha256_done(hash_state *md, unsigned char *out)
Definition: SHA256.cpp:266
RND
#define RND(a, b, c, d, e, f, g, h, i, ki)


sick_safevisionary_base
Author(s):
autogenerated on Sat Oct 21 2023 02:24:26