22 #include "cx_errors.h"
28 #ifndef ARCH_LITTLE_ENDIAN
29 #error "Big endian architectures are not supported. Please abort your project"
33 #error sha3 require 64 bits support at compiler level (NATIVE_64BITS option)
36 const cx_hash_info_t cx_sha3_info
42 (cx_err_t(*)(cx_hash_t * ctx,
const uint8_t *data,
size_t len)) cx_sha3_update,
43 (cx_err_t(*)(cx_hash_t * ctx,
uint8_t *digest)) cx_sha3_final,
44 (cx_err_t(*)(cx_hash_t * ctx,
size_t output_size)) cx_sha3_init_no_throw,
45 (
size_t(*)(const cx_hash_t *ctx)) cx_sha3_get_output_size};
47 const cx_hash_info_t cx_keccak_info
53 (cx_err_t(*)(cx_hash_t * ctx,
const uint8_t *data,
size_t len)) cx_sha3_update,
54 (cx_err_t(*)(cx_hash_t * ctx,
uint8_t *digest)) cx_sha3_final,
55 (cx_err_t(*)(cx_hash_t * ctx,
size_t output_size)) cx_keccak_init_no_throw,
56 (
size_t(*)(const cx_hash_t *ctx)) cx_sha3_get_output_size};
58 const cx_hash_info_t cx_shake128_info
64 (cx_err_t(*)(cx_hash_t * ctx,
const uint8_t *data,
size_t len)) cx_sha3_update,
65 (cx_err_t(*)(cx_hash_t * ctx,
uint8_t *digest)) cx_sha3_final,
66 (cx_err_t(*)(cx_hash_t * ctx,
size_t output_size)) cx_shake128_init_no_throw,
67 (
size_t(*)(const cx_hash_t *ctx)) cx_sha3_get_output_size};
69 const cx_hash_info_t cx_shake256_info
75 (cx_err_t(*)(cx_hash_t * ctx,
const uint8_t *data,
size_t len)) cx_sha3_update,
76 (cx_err_t(*)(cx_hash_t * ctx,
uint8_t *digest)) cx_sha3_final,
77 (cx_err_t(*)(cx_hash_t * ctx,
size_t output_size)) cx_shake256_init_no_throw,
78 (
size_t(*)(const cx_hash_t *ctx)) cx_sha3_get_output_size};
81 #define S64(x, y) state[x + 5 * y]
82 #define ROTL64(x, n) cx_rotl64(x, n)
90 for (i = 0; i < 5; i++) {
91 C[i] = S64(i, 0) ^ S64(i, 1) ^ S64(i, 2) ^ S64(i, 3) ^ S64(i, 4);
93 for (i = 0; i < 5; i++) {
94 D[i] = C[(i + 4) % 5] ^ ROTL64(C[(i + 1) % 5], 1);
95 for (j = 0; j < 5; j++) {
101 static const uint8_t C_cx_pi_table[]
102 = {10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1};
104 static const uint8_t C_cx_rho_table[]
105 = {1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44};
114 for (i = 0; i < 24; i++) {
115 j = C_cx_pi_table[i];
117 state[j] = ROTL64(A, C_cx_rho_table[i]);
127 for (j = 0; j < 5; j++) {
128 for (i = 0; i < 5; i++) {
131 for (i = 0; i < 5; i++) {
132 S64(i, j) ^= (~C[(i + 1) % 5]) & C[(i + 2) % 5];
138 = {
_64BITS(0x00000000, 0x00000001),
_64BITS(0x00000000, 0x00008082),
149 _64BITS(0x00000000, 0x80000001),
_64BITS(0x80000000, 0x80008008)};
151 static void cx_sha3_iota(
uint64bits_t state[],
int round)
153 S64(0, 0) ^= C_cx_iota_RC[round];
156 static bool check_hash_out_size(
size_t size)
170 cx_err_t cx_sha3_init_no_throw(cx_sha3_t *hash PLENGTH(
sizeof(cx_sha3_t)),
size_t size)
172 if (!check_hash_out_size(size)) {
173 return CX_INVALID_PARAMETER;
175 memset(hash, 0,
sizeof(cx_sha3_t));
176 hash->header.info = &cx_sha3_info;
177 hash->output_size = size >> 3;
178 hash->block_size = (1600 - 2 * size) >> 3;
182 cx_err_t cx_keccak_init_no_throw(cx_sha3_t *hash PLENGTH(
sizeof(cx_sha3_t)),
size_t size)
184 if (!check_hash_out_size(size) || cx_sha3_init_no_throw(hash, size) != CX_OK) {
185 return CX_INVALID_PARAMETER;
187 hash->header.info = &cx_keccak_info;
191 cx_err_t cx_shake128_init_no_throw(cx_sha3_t *hash,
size_t size)
193 memset(hash, 0,
sizeof(cx_sha3_t));
195 return CX_INVALID_PARAMETER;
197 hash->header.info = &cx_shake128_info;
198 hash->output_size = size / 8;
199 hash->block_size = (1600 - 2 * 128) >> 3;
203 cx_err_t cx_shake256_init_no_throw(cx_sha3_t *hash,
size_t size)
205 memset(hash, 0,
sizeof(cx_sha3_t));
207 return CX_INVALID_PARAMETER;
209 hash->header.info = &cx_shake256_info;
210 hash->output_size = size / 8;
211 hash->block_size = (1600 - 2 * 256) >> 3;
215 cx_err_t cx_sha3_xof_init_no_throw(cx_sha3_t *hash PLENGTH(
sizeof(cx_sha3_t)),
219 if ((size != 128) && (size != 256)) {
220 return CX_INVALID_PARAMETER;
222 memset(hash, 0,
sizeof(cx_sha3_t));
224 hash->header.info = &cx_shake128_info;
227 hash->header.info = &cx_shake256_info;
229 hash->output_size = out_length;
230 hash->block_size = (1600 - 2 * size) >> 3;
234 void cx_sha3_block(cx_sha3_t *hash)
243 if (hash->block_size > 144) {
246 else if (hash->block_size > 136) {
249 else if (hash->block_size > 104) {
252 else if (hash->block_size > 72) {
258 for (i = 0; i < n; i++) {
262 for (r = 0; r < 24; r++) {
266 cx_sha3_iota(acc, r);
270 cx_err_t cx_sha3_update(cx_sha3_t *ctx,
const uint8_t *data,
size_t len)
278 return CX_INVALID_PARAMETER;
281 return len == 0 ? CX_OK : CX_INVALID_PARAMETER;
284 block_size = ctx->block_size;
285 if (block_size > 200) {
286 return CX_INVALID_PARAMETER;
293 if (blen >= block_size) {
294 return CX_INVALID_PARAMETER;
298 if ((blen + len) >= block_size) {
299 r = block_size - blen;
301 if (ctx->header.counter == CX_HASH_MAX_BLOCK_COUNT) {
302 return INVALID_PARAMETER;
304 memcpy(block + blen, data, r);
308 ctx->header.counter++;
312 }
while (len >= block_size);
316 memcpy(block + blen, data, len);
322 cx_err_t cx_sha3_final(cx_sha3_t *hash,
uint8_t *digest)
330 block_size = hash->block_size;
334 if (hash->header.info->md_type == CX_KECCAK || hash->header.info->md_type == CX_SHA3) {
336 memset(block + blen, 0, (200 - blen));
338 if (hash->header.info->md_type == CX_KECCAK) {
344 block[block_size - 1] |= 0x80;
348 len = (hash)->output_size;
349 memcpy(digest, hash->acc, len);
353 memset(block + blen, 0, (200 - blen));
355 block[block_size - 1] |= 0x80;
358 len = hash->output_size;
361 memset(block, 0, 200);
363 while (blen > block_size) {
364 memcpy(digest, hash->acc, block_size);
366 digest += block_size;
369 memcpy(digest, hash->acc, blen);
374 size_t cx_sha3_get_output_size(
const cx_sha3_t *ctx)
376 return ctx->output_size;
64-bit types, native or by-hands, depending on target and/or compiler support.