ReactOS  0.4.15-dev-2153-g62b4c61
sha3.c
Go to the documentation of this file.
1 /* @(#)sha3.c 1.4 15/12/27 2015 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5  "@(#)sha3.c 1.4 15/12/27 2015 J. Schilling";
6 #endif
7 /*
8  * SHA3 hash code taken from
9  * https://github.com/rhash/RHash/tree/master/librhash
10  *
11  * Portions Copyright (c) 2015 J. Schilling
12  */
13 
14 /*
15  * sha3.c - an implementation of Secure Hash Algorithm 3 (Keccak).
16  * based on the
17  * The Keccak SHA-3 submission. Submission to NIST (Round 3), 2011
18  * by Guido Bertoni, Joan Daemen, MichaĆ«l Peeters and Gilles Van Assche
19  *
20  * Copyright: 2013 Aleksey Kravchenko <rhash.admin@gmail.com>
21  *
22  * Permission is hereby granted, free of charge, to any person obtaining a
23  * copy of this software and associated documentation files (the "Software"),
24  * to deal in the Software without restriction, including without limitation
25  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
26  * and/or sell copies of the Software, and to permit persons to whom the
27  * Software is furnished to do so.
28  *
29  * This program is distributed in the hope that it will be useful, but
30  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
31  * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
32  */
33 
34 #include <schily/assert.h>
35 #include <schily/string.h>
36 #include "byte_order.h"
37 #include <schily/sha3.h>
38 
39 #ifdef HAVE_LONGLONG
40 
41 #if !defined(HAVE_MEMCPY) || !defined(HAVE_MEMSET)
42 #include <schily/schily.h>
43 #endif
44 #if !defined(HAVE_MEMCPY) && !defined(memcpy)
45 #define memcpy(s1, s2, n) movebytes(s2, s1, n)
46 #endif
47 #if !defined(HAVE_MEMSET) && !defined(memset)
48 #define memset(s, c, n) fillbytes(s, n, c)
49 #endif
50 
51 static void rhash_keccak_init __PR((sha3_ctx *ctx, unsigned bits));
52 static void keccak_theta __PR((UInt64_t *A));
53 static void keccak_pi __PR((UInt64_t *A));
54 static void keccak_chi __PR((UInt64_t *A));
55 static void rhash_sha3_permutation __PR((UInt64_t *state));
56 static void rhash_sha3_process_block __PR((UInt64_t hash[25],
57  const UInt64_t *block,
58  size_t block_size));
59 
60 /*
61  * The Cygwin compile environment incorrectly implements #pragma weak.
62  * The weak symbols are only defined as local symbols making it impossible
63  * to use them from outside the scope of this source file.
64  * A platform that allows linking with global symbols has HAVE_LINK_WEAK
65  * defined.
66  */
67 #if defined(HAVE_PRAGMA_WEAK) && defined(HAVE_LINK_WEAK)
68 #pragma weak SHA3_224_Init = rhash_sha3_224_init
69 #pragma weak SHA3_256_Init = rhash_sha3_256_init
70 #pragma weak SHA3_384_Init = rhash_sha3_384_init
71 #pragma weak SHA3_512_Init = rhash_sha3_512_init
72 #pragma weak SHA3_Update = rhash_sha3_update
73 #else
74 
75 void SHA3_224_Init __PR((SHA3_CTX *ctx));
76 void SHA3_256_Init __PR((SHA3_CTX *ctx));
77 void SHA3_384_Init __PR((SHA3_CTX *ctx));
78 void SHA3_512_Init __PR((SHA3_CTX *ctx));
79 void SHA3_Update __PR((SHA3_CTX *ctx,
80  const unsigned char *msg,
81  size_t size));
82 
83 void
84 SHA3_224_Init(ctx)
85  SHA3_CTX *ctx;
86 {
87  rhash_sha3_224_init(ctx);
88 }
89 
90 void
91 SHA3_256_Init(ctx)
92  SHA3_CTX *ctx;
93 {
94  rhash_sha3_256_init(ctx);
95 }
96 
97 void
98 SHA3_384_Init(ctx)
99  SHA3_CTX *ctx;
100 {
101  rhash_sha3_384_init(ctx);
102 }
103 
104 void
105 SHA3_512_Init(ctx)
106  SHA3_CTX *ctx;
107 {
108  rhash_sha3_512_init(ctx);
109 }
110 
111 void
112 SHA3_Update(ctx, msg, size)
113  SHA3_CTX *ctx;
114  const unsigned char *msg;
115  size_t size;
116 {
117  rhash_sha3_update(ctx, msg, size);
118 }
119 #endif /* defined(HAVE_PRAGMA_WEAK) && defined(HAVE_LINK_WEAK) */
120 
121 /* constants */
122 #define NumberOfRounds 24
123 
124 /* SHA3 (Keccak) constants for 24 rounds */
125 static UInt64_t keccak_round_constants[NumberOfRounds] = {
126  UI64(0x0000000000000001), UI64(0x0000000000008082),
127  UI64(0x800000000000808A), UI64(0x8000000080008000),
128  UI64(0x000000000000808B), UI64(0x0000000080000001),
129  UI64(0x8000000080008081), UI64(0x8000000000008009),
130  UI64(0x000000000000008A), UI64(0x0000000000000088),
131  UI64(0x0000000080008009), UI64(0x000000008000000A),
132  UI64(0x000000008000808B), UI64(0x800000000000008B),
133  UI64(0x8000000000008089), UI64(0x8000000000008003),
134  UI64(0x8000000000008002), UI64(0x8000000000000080),
135  UI64(0x000000000000800A), UI64(0x800000008000000A),
136  UI64(0x8000000080008081), UI64(0x8000000000008080),
137  UI64(0x0000000080000001), UI64(0x8000000080008008)
138 };
139 
140 /* Initializing a sha3 context for given number of output bits */
141 static void
142 rhash_keccak_init(ctx, bits)
143  sha3_ctx *ctx;
144  unsigned bits;
145 {
146  /* NB: The Keccak capacity parameter = bits * 2 */
147  unsigned rate = 1600 - bits * 2;
148 
149  memset(ctx, 0, sizeof (sha3_ctx));
150  ctx->block_size = rate / 8;
151  assert(rate <= 1600 && (rate % 64) == 0);
152 }
153 
154 /*
155  * Initialize context before calculating hash.
156  *
157  * @param ctx context to initialize
158  */
159 void
160 rhash_sha3_224_init(ctx)
161  sha3_ctx *ctx;
162 {
163  rhash_keccak_init(ctx, 224);
164 }
165 
166 /*
167  * Initialize context before calculating hash.
168  *
169  * @param ctx context to initialize
170  */
171 void
172 rhash_sha3_256_init(ctx)
173  sha3_ctx *ctx;
174 {
175  rhash_keccak_init(ctx, 256);
176 }
177 
178 /*
179  * Initialize context before calculating hash.
180  *
181  * @param ctx context to initialize
182  */
183 void
184 rhash_sha3_384_init(ctx)
185  sha3_ctx *ctx;
186 {
187  rhash_keccak_init(ctx, 384);
188 }
189 
190 /*
191  * Initialize context before calculating hash.
192  *
193  * @param ctx context to initialize
194  */
195 void
196 rhash_sha3_512_init(ctx)
197  sha3_ctx *ctx;
198 {
199  rhash_keccak_init(ctx, 512);
200 }
201 
202 /* Keccak theta() transformation */
203 static void
204 keccak_theta(A)
205  UInt64_t *A;
206 {
207  unsigned int x;
208  UInt64_t C[5], D[5];
209 
210  for (x = 0; x < 5; x++) {
211  C[x] = A[x] ^ A[x + 5] ^ A[x + 10] ^ A[x + 15] ^ A[x + 20];
212  }
213  D[0] = ROTL64(C[1], 1) ^ C[4];
214  D[1] = ROTL64(C[2], 1) ^ C[0];
215  D[2] = ROTL64(C[3], 1) ^ C[1];
216  D[3] = ROTL64(C[4], 1) ^ C[2];
217  D[4] = ROTL64(C[0], 1) ^ C[3];
218 
219  for (x = 0; x < 5; x++) {
220  A[x] ^= D[x];
221  A[x + 5] ^= D[x];
222  A[x + 10] ^= D[x];
223  A[x + 15] ^= D[x];
224  A[x + 20] ^= D[x];
225  }
226 }
227 
228 /* Keccak pi() transformation */
229 static void
230 keccak_pi(A)
231  UInt64_t *A;
232 {
233  UInt64_t A1;
234  A1 = A[1];
235  A[ 1] = A[ 6];
236  A[ 6] = A[ 9];
237  A[ 9] = A[22];
238  A[22] = A[14];
239  A[14] = A[20];
240  A[20] = A[ 2];
241  A[ 2] = A[12];
242  A[12] = A[13];
243  A[13] = A[19];
244  A[19] = A[23];
245  A[23] = A[15];
246  A[15] = A[ 4];
247  A[ 4] = A[24];
248  A[24] = A[21];
249  A[21] = A[ 8];
250  A[ 8] = A[16];
251  A[16] = A[ 5];
252  A[ 5] = A[ 3];
253  A[ 3] = A[18];
254  A[18] = A[17];
255  A[17] = A[11];
256  A[11] = A[ 7];
257  A[ 7] = A[10];
258  A[10] = A1;
259  /* note: A[ 0] is left as is */
260 }
261 
262 /* Keccak chi() transformation */
263 static void
264 keccak_chi(A)
265  UInt64_t *A;
266 {
267  int i;
268  for (i = 0; i < 25; i += 5) {
269  UInt64_t A0 = A[0 + i], A1 = A[1 + i];
270  A[0 + i] ^= ~A1 & A[2 + i];
271  A[1 + i] ^= ~A[2 + i] & A[3 + i];
272  A[2 + i] ^= ~A[3 + i] & A[4 + i];
273  A[3 + i] ^= ~A[4 + i] & A0;
274  A[4 + i] ^= ~A0 & A1;
275  }
276 }
277 
278 static void
279 rhash_sha3_permutation(state)
280  UInt64_t *state;
281 {
282  int round;
283  for (round = 0; round < NumberOfRounds; round++)
284  {
285  keccak_theta(state);
286 
287  /* apply Keccak rho() transformation */
288  state[ 1] = ROTL64(state[ 1], 1);
289  state[ 2] = ROTL64(state[ 2], 62);
290  state[ 3] = ROTL64(state[ 3], 28);
291  state[ 4] = ROTL64(state[ 4], 27);
292  state[ 5] = ROTL64(state[ 5], 36);
293  state[ 6] = ROTL64(state[ 6], 44);
294  state[ 7] = ROTL64(state[ 7], 6);
295  state[ 8] = ROTL64(state[ 8], 55);
296  state[ 9] = ROTL64(state[ 9], 20);
297  state[10] = ROTL64(state[10], 3);
298  state[11] = ROTL64(state[11], 10);
299  state[12] = ROTL64(state[12], 43);
300  state[13] = ROTL64(state[13], 25);
301  state[14] = ROTL64(state[14], 39);
302  state[15] = ROTL64(state[15], 41);
303  state[16] = ROTL64(state[16], 45);
304  state[17] = ROTL64(state[17], 15);
305  state[18] = ROTL64(state[18], 21);
306  state[19] = ROTL64(state[19], 8);
307  state[20] = ROTL64(state[20], 18);
308  state[21] = ROTL64(state[21], 2);
309  state[22] = ROTL64(state[22], 61);
310  state[23] = ROTL64(state[23], 56);
311  state[24] = ROTL64(state[24], 14);
312 
313  keccak_pi(state);
314  keccak_chi(state);
315 
316  /* apply iota(state, round) */
317  *state ^= keccak_round_constants[round];
318  }
319 }
320 
321 /*
322  * The core transformation. Process the specified block of data.
323  *
324  * @param hash the algorithm state
325  * @param block the message block to process
326  * @param block_size the size of the processed block in bytes
327  */
328 static void
329 rhash_sha3_process_block(hash, block, block_size)
330  UInt64_t hash[25];
331  const UInt64_t *block;
332  size_t block_size;
333 {
334  /* expanded loop */
335  hash[ 0] ^= le2me_64(block[ 0]);
336  hash[ 1] ^= le2me_64(block[ 1]);
337  hash[ 2] ^= le2me_64(block[ 2]);
338  hash[ 3] ^= le2me_64(block[ 3]);
339  hash[ 4] ^= le2me_64(block[ 4]);
340  hash[ 5] ^= le2me_64(block[ 5]);
341  hash[ 6] ^= le2me_64(block[ 6]);
342  hash[ 7] ^= le2me_64(block[ 7]);
343  hash[ 8] ^= le2me_64(block[ 8]);
344  /* if not sha3-512 */
345  if (block_size > 72) {
346  hash[ 9] ^= le2me_64(block[ 9]);
347  hash[10] ^= le2me_64(block[10]);
348  hash[11] ^= le2me_64(block[11]);
349  hash[12] ^= le2me_64(block[12]);
350  /* if not sha3-384 */
351  if (block_size > 104) {
352  hash[13] ^= le2me_64(block[13]);
353  hash[14] ^= le2me_64(block[14]);
354  hash[15] ^= le2me_64(block[15]);
355  hash[16] ^= le2me_64(block[16]);
356  /* if not sha3-256 */
357  if (block_size > 136) {
358  hash[17] ^= le2me_64(block[17]);
359 #ifdef FULL_SHA3_FAMILY_SUPPORT
360  /* if not sha3-224 */
361  if (block_size > 144) {
362  hash[18] ^= le2me_64(block[18]);
363  hash[19] ^= le2me_64(block[19]);
364  hash[20] ^= le2me_64(block[20]);
365  hash[21] ^= le2me_64(block[21]);
366  hash[22] ^= le2me_64(block[22]);
367  hash[23] ^= le2me_64(block[23]);
368  hash[24] ^= le2me_64(block[24]);
369  }
370 #endif
371  }
372  }
373  }
374  /* make a permutation of the hash */
375  rhash_sha3_permutation(hash);
376 }
377 
378 #define SHA3_FINALIZED 0x80000000
379 
380 /*
381  * Calculate message hash.
382  * Can be called repeatedly with chunks of the message to be hashed.
383  *
384  * @param ctx the algorithm context containing current hashing state
385  * @param msg message chunk
386  * @param size length of the message chunk
387  */
388 void
389 rhash_sha3_update(ctx, msg, size)
390  sha3_ctx *ctx;
391  const unsigned char *msg;
392  size_t size;
393 {
394  size_t idx = (size_t)ctx->rest;
395  size_t block_size = (size_t)ctx->block_size;
396 
397  if (ctx->rest & SHA3_FINALIZED)
398  return; /* too late for additional input */
399  ctx->rest = (unsigned)((ctx->rest + size) % block_size);
400 
401  /* fill partial block */
402  if (idx) {
403  size_t left = block_size - idx;
404  memcpy((char *)ctx->message + idx, msg,
405  (size < left ? size : left));
406  if (size < left)
407  return;
408 
409  /* process partial block */
410  rhash_sha3_process_block(ctx->hash, ctx->message, block_size);
411  msg += left;
412  size -= left;
413  }
414  while (size >= block_size) {
415  UInt64_t *aligned_message_block;
416  if (IS_ALIGNED_64(msg)) {
417  /*
418  * the most common case is processing of an already
419  * aligned message without copying it
420  */
421  aligned_message_block = (UInt64_t *)msg;
422  } else {
423  memcpy(ctx->message, msg, block_size);
424  aligned_message_block = ctx->message;
425  }
426 
427  rhash_sha3_process_block(ctx->hash, aligned_message_block,
428  block_size);
429  msg += block_size;
430  size -= block_size;
431  }
432  if (size) {
433  memcpy(ctx->message, msg, size); /* save leftovers */
434  }
435 }
436 
437 /*
438  * Store calculated hash into the given array.
439  *
440  * @param ctx the algorithm context containing current hashing state
441  * @param result calculated hash in binary form
442  */
443 void
444 rhash_sha3_final(ctx, result)
445  sha3_ctx *ctx;
446  unsigned char *result;
447 {
448  size_t digest_length = 100 - ctx->block_size / 2;
449  const size_t block_size = ctx->block_size;
450 
451  if (!(ctx->rest & SHA3_FINALIZED))
452  {
453  /* clear the rest of the data queue */
454  memset((char *)ctx->message + ctx->rest, 0,
455  block_size - ctx->rest);
456  ((char *)ctx->message)[ctx->rest] |= 0x06;
457  ((char *)ctx->message)[block_size - 1] |= 0x80;
458 
459  /* process final block */
460  rhash_sha3_process_block(ctx->hash, ctx->message, block_size);
461  ctx->rest = SHA3_FINALIZED; /* mark context as finalized */
462  }
463 
464  assert(block_size > digest_length);
465  if (result) me64_to_le_str(result, ctx->hash, digest_length);
466 }
467 
468 void
469 SHA3_Final(result, ctx)
470  UInt8_t *result;
471  SHA3_CTX *ctx;
472 {
473  rhash_sha3_final(ctx, result);
474 }
475 
476 #ifdef USE_KECCAK
477 /*
478  * Store calculated hash into the given array.
479  *
480  * @param ctx the algorithm context containing current hashing state
481  * @param result calculated hash in binary form
482  */
483 void
484 rhash_keccak_final(sha3_ctx *ctx, unsigned char *result)
485 {
486  size_t digest_length = 100 - ctx->block_size / 2;
487  const size_t block_size = ctx->block_size;
488 
489  if (!(ctx->rest & SHA3_FINALIZED)) {
490  /* clear the rest of the data queue */
491  memset((char *)ctx->message + ctx->rest, 0,
492  block_size - ctx->rest);
493  ((char *)ctx->message)[ctx->rest] |= 0x01;
494  ((char *)ctx->message)[block_size - 1] |= 0x80;
495 
496  /* process final block */
497  rhash_sha3_process_block(ctx->hash, ctx->message, block_size);
498  ctx->rest = SHA3_FINALIZED; /* mark context as finalized */
499  }
500 
501  assert(block_size > digest_length);
502  if (result)
503  me64_to_le_str(result, ctx->hash, digest_length);
504 }
505 #endif /* USE_KECCAK */
506 
507 #endif /* HAVE_LONGLONG */
static unsigned int block
Definition: xmlmemory.c:118
#define IS_ALIGNED_64(p)
Definition: byte_order.h:86
#define __PR(a)
Definition: prototyp.h:106
GLuint64EXT * result
Definition: glext.h:11304
#define me64_to_le_str(to, from, length)
Definition: byte_order.h:199
#define UConst
Definition: ccomdefs.h:72
#define assert(x)
Definition: debug.h:53
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
unsigned char UInt8_t
Definition: stdint.h:322
int rate
Definition: pcmconverter.c:97
Definition: terminate.cpp:23
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
Definition: ehthrow.cxx:92
static DWORD block_size(DWORD block)
Definition: jsutils.c:66
#define A(row, col)
unsigned int idx
Definition: utils.c:41
#define UI64(x)
Definition: byte_order.h:111
__kernel_size_t size_t
Definition: linux.h:237
GLsizeiptr size
Definition: glext.h:5919
#define D(d)
Definition: builtin.c:4557
#define round(x)
Definition: opentype.c:47
GLint left
Definition: glext.h:7726
#define le2me_64(x)
Definition: byte_order.h:192
static int state
Definition: maze.c:121
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ROTL64(qword, n)
Definition: byte_order.h:205
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define msg(x)
Definition: auth_time.c:54
#define A1
static UConst char sccsid[]
Definition: sha3.c:4
Definition: _hash_fun.h:40
#define memset(x, y, z)
Definition: compat.h:39
static unsigned(__cdecl *hash_bstr)(bstr_t s)