10 #define sha3_224_hash_size 28
11 #define sha3_256_hash_size 32
12 #define sha3_384_hash_size 48
13 #define sha3_512_hash_size 64
14 #define sha3_max_permutation_size 25
15 #define sha3_max_rate_in_qwords 24
18 * SHA3 Algorithm context.
20 typedef struct sha3_ctx
22 /* 1600 bits algorithm hashing state */
23 uint64_t hash[sha3_max_permutation_size];
24 /* 1536-bit buffer for leftovers */
25 uint64_t message[sha3_max_rate_in_qwords];
26 /* count of bytes in the message[] buffer */
28 /* size of a message block processed at once */
32 /* methods for calculating the hash function */
34 // void rhash_sha3_224_init(sha3_ctx *ctx);
35 // void rhash_sha3_256_init(sha3_ctx *ctx);
36 // void rhash_sha3_384_init(sha3_ctx *ctx);
37 // void rhash_sha3_512_init(sha3_ctx *ctx);
38 // void rhash_sha3_update(sha3_ctx *ctx, const unsigned char* msg, size_t size);
39 // void rhash_sha3_final(sha3_ctx *ctx, unsigned char* result);
42 #define rhash_keccak_224_init rhash_sha3_224_init
43 #define rhash_keccak_256_init rhash_sha3_256_init
44 #define rhash_keccak_384_init rhash_sha3_384_init
45 #define rhash_keccak_512_init rhash_sha3_512_init
46 #define rhash_keccak_update rhash_sha3_update
47 inline void rhash_keccak_final(sha3_ctx *ctx, unsigned char* result);
52 #endif /* __cplusplus */
56 // Adpated from sha3.c
57 /*--------------------------------------------------------------------------*/
58 /* sha3.c - an implementation of Secure Hash Algorithm 3 (Keccak).
60 * The Keccak SHA-3 submission. Submission to NIST (Round 3), 2011
61 * by Guido Bertoni, Joan Daemen, Michaƫl Peeters and Gilles Van Assche
63 * Copyright: 2013 Aleksey Kravchenko <rhash.admin@gmail.com>
65 * Permission is hereby granted, free of charge, to any person obtaining a
66 * copy of this software and associated documentation files (the "Software"),
67 * to deal in the Software without restriction, including without limitation
68 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
69 * and/or sell copies of the Software, and to permit persons to whom the
70 * Software is furnished to do so.
72 * This program is distributed in the hope that it will be useful, but
73 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
74 * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
79 #include "byte_order-allInOne.h"
82 #define NumberOfRounds 24
84 /* SHA3 (Keccak) constants for 24 rounds */
85 static uint64_t keccak_round_constants[NumberOfRounds] = {
86 I64(0x0000000000000001), I64(0x0000000000008082), I64(0x800000000000808A), I64(0x8000000080008000),
87 I64(0x000000000000808B), I64(0x0000000080000001), I64(0x8000000080008081), I64(0x8000000000008009),
88 I64(0x000000000000008A), I64(0x0000000000000088), I64(0x0000000080008009), I64(0x000000008000000A),
89 I64(0x000000008000808B), I64(0x800000000000008B), I64(0x8000000000008089), I64(0x8000000000008003),
90 I64(0x8000000000008002), I64(0x8000000000000080), I64(0x000000000000800A), I64(0x800000008000000A),
91 I64(0x8000000080008081), I64(0x8000000000008080), I64(0x0000000080000001), I64(0x8000000080008008)
94 /* Initializing a sha3 context for given number of output bits */
95 inline void rhash_keccak_init(sha3_ctx *ctx, unsigned bits)
97 /* NB: The Keccak capacity parameter = bits * 2 */
98 unsigned rate = 1600 - bits * 2;
100 memset(ctx, 0, sizeof(sha3_ctx));
101 ctx->block_size = rate / 8;
102 assert(rate <= 1600 && (rate % 64) == 0);
106 * Initialize context before calculating hash.
108 * @param ctx context to initialize
110 inline void rhash_sha3_224_init(sha3_ctx *ctx)
112 rhash_keccak_init(ctx, 224);
116 * Initialize context before calculating hash.
118 * @param ctx context to initialize
120 inline void rhash_sha3_256_init(sha3_ctx *ctx)
122 rhash_keccak_init(ctx, 256);
126 * Initialize context before calculating hash.
128 * @param ctx context to initialize
130 inline void rhash_sha3_384_init(sha3_ctx *ctx)
132 rhash_keccak_init(ctx, 384);
136 * Initialize context before calculating hash.
138 * @param ctx context to initialize
140 inline void rhash_sha3_512_init(sha3_ctx *ctx)
142 rhash_keccak_init(ctx, 512);
145 /* Keccak theta() transformation */
146 inline void keccak_theta(uint64_t *A)
151 for (x = 0; x < 5; x++) {
152 C[x] = A[x] ^ A[x + 5] ^ A[x + 10] ^ A[x + 15] ^ A[x + 20];
154 D[0] = ROTL64(C[1], 1) ^ C[4];
155 D[1] = ROTL64(C[2], 1) ^ C[0];
156 D[2] = ROTL64(C[3], 1) ^ C[1];
157 D[3] = ROTL64(C[4], 1) ^ C[2];
158 D[4] = ROTL64(C[0], 1) ^ C[3];
160 for (x = 0; x < 5; x++) {
169 /* Keccak pi() transformation */
170 inline void keccak_pi(uint64_t *A)
198 /* note: A[ 0] is left as is */
201 /* Keccak chi() transformation */
202 inline void keccak_chi(uint64_t *A)
205 for (i = 0; i < 25; i += 5) {
206 uint64_t A0 = A[0 + i], A1 = A[1 + i];
207 A[0 + i] ^= ~A1 & A[2 + i];
208 A[1 + i] ^= ~A[2 + i] & A[3 + i];
209 A[2 + i] ^= ~A[3 + i] & A[4 + i];
210 A[3 + i] ^= ~A[4 + i] & A0;
211 A[4 + i] ^= ~A0 & A1;
215 inline void rhash_sha3_permutation(uint64_t *state)
218 for (round = 0; round < NumberOfRounds; round++)
222 /* apply Keccak rho() transformation */
223 state[ 1] = ROTL64(state[ 1], 1);
224 state[ 2] = ROTL64(state[ 2], 62);
225 state[ 3] = ROTL64(state[ 3], 28);
226 state[ 4] = ROTL64(state[ 4], 27);
227 state[ 5] = ROTL64(state[ 5], 36);
228 state[ 6] = ROTL64(state[ 6], 44);
229 state[ 7] = ROTL64(state[ 7], 6);
230 state[ 8] = ROTL64(state[ 8], 55);
231 state[ 9] = ROTL64(state[ 9], 20);
232 state[10] = ROTL64(state[10], 3);
233 state[11] = ROTL64(state[11], 10);
234 state[12] = ROTL64(state[12], 43);
235 state[13] = ROTL64(state[13], 25);
236 state[14] = ROTL64(state[14], 39);
237 state[15] = ROTL64(state[15], 41);
238 state[16] = ROTL64(state[16], 45);
239 state[17] = ROTL64(state[17], 15);
240 state[18] = ROTL64(state[18], 21);
241 state[19] = ROTL64(state[19], 8);
242 state[20] = ROTL64(state[20], 18);
243 state[21] = ROTL64(state[21], 2);
244 state[22] = ROTL64(state[22], 61);
245 state[23] = ROTL64(state[23], 56);
246 state[24] = ROTL64(state[24], 14);
251 /* apply iota(state, round) */
252 *state ^= keccak_round_constants[round];
257 * The core transformation. Process the specified block of data.
259 * @param hash the algorithm state
260 * @param block the message block to process
261 * @param block_size the size of the processed block in bytes
263 inline void rhash_sha3_process_block(uint64_t hash[25], const uint64_t *block, size_t block_size)
266 hash[ 0] ^= le2me_64(block[ 0]);
267 hash[ 1] ^= le2me_64(block[ 1]);
268 hash[ 2] ^= le2me_64(block[ 2]);
269 hash[ 3] ^= le2me_64(block[ 3]);
270 hash[ 4] ^= le2me_64(block[ 4]);
271 hash[ 5] ^= le2me_64(block[ 5]);
272 hash[ 6] ^= le2me_64(block[ 6]);
273 hash[ 7] ^= le2me_64(block[ 7]);
274 hash[ 8] ^= le2me_64(block[ 8]);
275 /* if not sha3-512 */
276 if (block_size > 72) {
277 hash[ 9] ^= le2me_64(block[ 9]);
278 hash[10] ^= le2me_64(block[10]);
279 hash[11] ^= le2me_64(block[11]);
280 hash[12] ^= le2me_64(block[12]);
281 /* if not sha3-384 */
282 if (block_size > 104) {
283 hash[13] ^= le2me_64(block[13]);
284 hash[14] ^= le2me_64(block[14]);
285 hash[15] ^= le2me_64(block[15]);
286 hash[16] ^= le2me_64(block[16]);
287 /* if not sha3-256 */
288 if (block_size > 136) {
289 hash[17] ^= le2me_64(block[17]);
290 #ifdef FULL_SHA3_FAMILY_SUPPORT
291 /* if not sha3-224 */
292 if (block_size > 144) {
293 hash[18] ^= le2me_64(block[18]);
294 hash[19] ^= le2me_64(block[19]);
295 hash[20] ^= le2me_64(block[20]);
296 hash[21] ^= le2me_64(block[21]);
297 hash[22] ^= le2me_64(block[22]);
298 hash[23] ^= le2me_64(block[23]);
299 hash[24] ^= le2me_64(block[24]);
305 /* make a permutation of the hash */
306 rhash_sha3_permutation(hash);
309 #define SHA3_FINALIZED 0x80000000
312 * Calculate message hash.
313 * Can be called repeatedly with chunks of the message to be hashed.
315 * @param ctx the algorithm context containing current hashing state
316 * @param msg message chunk
317 * @param size length of the message chunk
319 inline void rhash_sha3_update(sha3_ctx *ctx, const unsigned char *msg, size_t size)
321 size_t index = (size_t)ctx->rest;
322 size_t block_size = (size_t)ctx->block_size;
324 if (ctx->rest & SHA3_FINALIZED) return; /* too late for additional input */
325 ctx->rest = (unsigned)((ctx->rest + size) % block_size);
327 /* fill partial block */
329 size_t left = block_size - index;
330 memcpy((char*)ctx->message + index, msg, (size < left ? size : left));
331 if (size < left) return;
333 /* process partial block */
334 rhash_sha3_process_block(ctx->hash, ctx->message, block_size);
338 while (size >= block_size) {
339 uint64_t* aligned_message_block;
340 if (IS_ALIGNED_64(msg)) {
341 /* the most common case is processing of an already aligned message
342 without copying it */
343 aligned_message_block = (uint64_t*)msg;
345 memcpy(ctx->message, msg, block_size);
346 aligned_message_block = ctx->message;
349 rhash_sha3_process_block(ctx->hash, aligned_message_block, block_size);
354 memcpy(ctx->message, msg, size); /* save leftovers */
359 * Store calculated hash into the given array.
361 * @param ctx the algorithm context containing current hashing state
362 * @param result calculated hash in binary form
364 inline void rhash_sha3_final(sha3_ctx *ctx, unsigned char* result)
366 size_t digest_length = 100 - ctx->block_size / 2;
367 const size_t block_size = ctx->block_size;
369 if (!(ctx->rest & SHA3_FINALIZED))
371 /* clear the rest of the data queue */
372 memset((char*)ctx->message + ctx->rest, 0, block_size - ctx->rest);
373 ((char*)ctx->message)[ctx->rest] |= 0x06;
374 ((char*)ctx->message)[block_size - 1] |= 0x80;
376 /* process final block */
377 rhash_sha3_process_block(ctx->hash, ctx->message, block_size);
378 ctx->rest = SHA3_FINALIZED; /* mark context as finalized */
381 assert(block_size > digest_length);
382 if (result) me64_to_le_str(result, ctx->hash, digest_length);
387 * Store calculated hash into the given array.
389 * @param ctx the algorithm context containing current hashing state
390 * @param result calculated hash in binary form
392 inline void rhash_keccak_final(sha3_ctx *ctx, unsigned char* result)
394 size_t digest_length = 100 - ctx->block_size / 2;
395 const size_t block_size = ctx->block_size;
397 if (!(ctx->rest & SHA3_FINALIZED))
399 /* clear the rest of the data queue */
400 memset((char*)ctx->message + ctx->rest, 0, block_size - ctx->rest);
401 ((char*)ctx->message)[ctx->rest] |= 0x01;
402 ((char*)ctx->message)[block_size - 1] |= 0x80;
404 /* process final block */
405 rhash_sha3_process_block(ctx->hash, ctx->message, block_size);
406 ctx->rest = SHA3_FINALIZED; /* mark context as finalized */
409 assert(block_size > digest_length);
410 if (result) me64_to_le_str(result, ctx->hash, digest_length);
412 #endif /* USE_KECCAK */
416 #endif /* RHASH_SHA3_H */