From 0665824f2a5d09915701abfcb964a86f8db4a08e Mon Sep 17 00:00:00 2001 From: BTChip Date: Tue, 9 Aug 2016 11:58:45 +0200 Subject: [PATCH] Re-add missing alternate SHA3, matching release version --- src_tmp/app_cx_sha3.c | 299 ++++++++++++++++++++++++++++++++++++++++++ src_tmp/app_cx_sha3.h | 45 +++++++ 2 files changed, 344 insertions(+) create mode 100644 src_tmp/app_cx_sha3.c create mode 100644 src_tmp/app_cx_sha3.h diff --git a/src_tmp/app_cx_sha3.c b/src_tmp/app_cx_sha3.c new file mode 100644 index 0000000..ed3c773 --- /dev/null +++ b/src_tmp/app_cx_sha3.c @@ -0,0 +1,299 @@ +/******************************************************************************* +* Ledger Blue +* (c) 2016 Ledger +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +********************************************************************************/ + +#include "os.h" +#include "cx.h" +#include "app_cx_sha3.h" + +#define S64(x, y) state[x + 5 * y] +#define ROTL64(x, n) (((x) << (n)) | ((x) >> ((64) - (n)))) +#define _64BITS(h, l) (h##ULL << 32) | (l##ULL) + +static void cx_sha3_theta(uint64bits_t state[]) { + uint64bits_t C[5]; + uint64bits_t D[5]; + C[0] = S64(0, 0) ^ S64(0, 1) ^ S64(0, 2) ^ S64(0, 3) ^ S64(0, 4); + C[1] = S64(1, 0) ^ S64(1, 1) ^ S64(1, 2) ^ S64(1, 3) ^ S64(1, 4); + C[2] = S64(2, 0) ^ S64(2, 1) ^ S64(2, 2) ^ S64(2, 3) ^ S64(2, 4); + C[3] = S64(3, 0) ^ S64(3, 1) ^ S64(3, 2) ^ S64(3, 3) ^ S64(3, 4); + C[4] = S64(4, 0) ^ S64(4, 1) ^ S64(4, 2) ^ S64(4, 3) ^ S64(4, 4); + + D[0] = C[4] ^ ROTL64(C[1], 1); + D[1] = C[0] ^ ROTL64(C[2], 1); + D[2] = C[1] ^ ROTL64(C[3], 1); + D[3] = C[2] ^ ROTL64(C[4], 1); + D[4] = C[3] ^ ROTL64(C[0], 1); + + S64(0, 0) = S64(0, 0) ^ D[0]; + S64(1, 0) = S64(1, 0) ^ D[1]; + S64(2, 0) = S64(2, 0) ^ D[2]; + S64(3, 0) = S64(3, 0) ^ D[3]; + S64(4, 0) = S64(4, 0) ^ D[4]; + + S64(0, 1) = S64(0, 1) ^ D[0]; + S64(1, 1) = S64(1, 1) ^ D[1]; + S64(2, 1) = S64(2, 1) ^ D[2]; + S64(3, 1) = S64(3, 1) ^ D[3]; + S64(4, 1) = S64(4, 1) ^ D[4]; + + S64(0, 2) = S64(0, 2) ^ D[0]; + S64(1, 2) = S64(1, 2) ^ D[1]; + S64(2, 2) = S64(2, 2) ^ D[2]; + S64(3, 2) = S64(3, 2) ^ D[3]; + S64(4, 2) = S64(4, 2) ^ D[4]; + + S64(0, 3) = S64(0, 3) ^ D[0]; + S64(1, 3) = S64(1, 3) ^ D[1]; + S64(2, 3) = S64(2, 3) ^ D[2]; + S64(3, 3) = S64(3, 3) ^ D[3]; + S64(4, 3) = S64(4, 3) ^ D[4]; + + S64(0, 4) = S64(0, 4) ^ D[0]; + S64(1, 4) = S64(1, 4) ^ D[1]; + S64(2, 4) = S64(2, 4) ^ D[2]; + S64(3, 4) = S64(3, 4) ^ D[3]; + S64(4, 4) = S64(4, 4) ^ D[4]; +} + +static void cx_sha3_rho(uint64bits_t state[]) { + // S64(0,0) = ROTL(S64(1,0), 0); + S64(0, 1) = ROTL64(S64(0, 1), 36); + S64(0, 2) = ROTL64(S64(0, 2), 3); + S64(0, 3) = ROTL64(S64(0, 3), 41); + S64(0, 4) = ROTL64(S64(0, 4), 18); + + S64(1, 0) = ROTL64(S64(1, 0), 1); + S64(1, 1) = ROTL64(S64(1, 1), 44); + S64(1, 2) = ROTL64(S64(1, 2), 10); + S64(1, 3) = ROTL64(S64(1, 3), 45); + S64(1, 4) = ROTL64(S64(1, 4), 2); + + S64(2, 0) = ROTL64(S64(2, 0), 62); + S64(2, 1) = ROTL64(S64(2, 1), 6); + S64(2, 2) = ROTL64(S64(2, 2), 43); + S64(2, 3) = ROTL64(S64(2, 3), 15); + S64(2, 4) = ROTL64(S64(2, 4), 61); + + S64(3, 0) = ROTL64(S64(3, 0), 28); + S64(3, 1) = ROTL64(S64(3, 1), 55); + S64(3, 2) = ROTL64(S64(3, 2), 25); + S64(3, 3) = ROTL64(S64(3, 3), 21); + S64(3, 4) = ROTL64(S64(3, 4), 56); + + S64(4, 0) = ROTL64(S64(4, 0), 27); + S64(4, 1) = ROTL64(S64(4, 1), 20); + S64(4, 2) = ROTL64(S64(4, 2), 39); + S64(4, 3) = ROTL64(S64(4, 3), 8); + S64(4, 4) = ROTL64(S64(4, 4), 14); +} + +static void cx_sha3_pi(uint64bits_t state[]) { + uint64bits_t s; + + s = S64(0, 1); + S64(0, 1) = S64(3, 0); + S64(3, 0) = S64(3, 3); + S64(3, 3) = S64(2, 3); + S64(2, 3) = S64(1, 2); + S64(1, 2) = S64(2, 1); + S64(2, 1) = S64(0, 2); + S64(0, 2) = S64(1, 0); + S64(1, 0) = S64(1, 1); + S64(1, 1) = S64(4, 1); + S64(4, 1) = S64(2, 4); + S64(2, 4) = S64(4, 2); + S64(4, 2) = S64(0, 4); + S64(0, 4) = S64(2, 0); + S64(2, 0) = S64(2, 2); + S64(2, 2) = S64(3, 2); + S64(3, 2) = S64(4, 3); + S64(4, 3) = S64(3, 4); + S64(3, 4) = S64(0, 3); + S64(0, 3) = S64(4, 0); + S64(4, 0) = S64(4, 4); + S64(4, 4) = S64(1, 4); + S64(1, 4) = S64(3, 1); + S64(3, 1) = S64(1, 3); + S64(1, 3) = s; +} + +static void cx_sha3_chi(uint64bits_t state[]) { + uint64bits_t S0y, S1y; + + S0y = S64(0, 0); + S1y = S64(1, 0); + S64(0, 0) ^= ~S64(1, 0) & S64(2, 0); + S64(1, 0) ^= ~S64(2, 0) & S64(3, 0); + S64(2, 0) ^= ~S64(3, 0) & S64(4, 0); + S64(3, 0) ^= ~S64(4, 0) & S0y; + S64(4, 0) ^= ~S0y & S1y; + + S0y = S64(0, 1); + S1y = S64(1, 1); + S64(0, 1) ^= ~S64(1, 1) & S64(2, 1); + S64(1, 1) ^= ~S64(2, 1) & S64(3, 1); + S64(2, 1) ^= ~S64(3, 1) & S64(4, 1); + S64(3, 1) ^= ~S64(4, 1) & S0y; + S64(4, 1) ^= ~S0y & S1y; + + S0y = S64(0, 2); + S1y = S64(1, 2); + S64(0, 2) ^= ~S64(1, 2) & S64(2, 2); + S64(1, 2) ^= ~S64(2, 2) & S64(3, 2); + S64(2, 2) ^= ~S64(3, 2) & S64(4, 2); + S64(3, 2) ^= ~S64(4, 2) & S0y; + S64(4, 2) ^= ~S0y & S1y; + + S0y = S64(0, 3); + S1y = S64(1, 3); + S64(0, 3) ^= ~S64(1, 3) & S64(2, 3); + S64(1, 3) ^= ~S64(2, 3) & S64(3, 3); + S64(2, 3) ^= ~S64(3, 3) & S64(4, 3); + S64(3, 3) ^= ~S64(4, 3) & S0y; + S64(4, 3) ^= ~S0y & S1y; + + S0y = S64(0, 4); + S1y = S64(1, 4); + S64(0, 4) ^= ~S64(1, 4) & S64(2, 4); + S64(1, 4) ^= ~S64(2, 4) & S64(3, 4); + S64(2, 4) ^= ~S64(3, 4) & S64(4, 4); + S64(3, 4) ^= ~S64(4, 4) & S0y; + S64(4, 4) ^= ~S0y & S1y; +} + +static const uint64bits_t WIDE C_cx_iota_RC[24] = { + _64BITS(0x00000000, 0x00000001), _64BITS(0x00000000, 0x00008082), + _64BITS(0x80000000, 0x0000808A), _64BITS(0x80000000, 0x80008000), + _64BITS(0x00000000, 0x0000808B), _64BITS(0x00000000, 0x80000001), + _64BITS(0x80000000, 0x80008081), _64BITS(0x80000000, 0x00008009), + _64BITS(0x00000000, 0x0000008A), _64BITS(0x00000000, 0x00000088), + _64BITS(0x00000000, 0x80008009), _64BITS(0x00000000, 0x8000000A), + _64BITS(0x00000000, 0x8000808B), _64BITS(0x80000000, 0x0000008B), + _64BITS(0x80000000, 0x00008089), _64BITS(0x80000000, 0x00008003), + _64BITS(0x80000000, 0x00008002), _64BITS(0x80000000, 0x00000080), + _64BITS(0x00000000, 0x0000800A), _64BITS(0x80000000, 0x8000000A), + _64BITS(0x80000000, 0x80008081), _64BITS(0x80000000, 0x00008080), + _64BITS(0x00000000, 0x80000001), _64BITS(0x80000000, 0x80008008)}; + +static void cx_sha3_iota(uint64bits_t state[], int round) { + S64(0, 0) ^= C_cx_iota_RC[round]; +} + +int app_cx_sha3_init(app_cx_sha3_t *hash, int size) { + os_memset(hash, 0, sizeof(app_cx_sha3_t)); + hash->output_size = size >> 3; + hash->block_size = (1600 - 2 * size) >> 3; + return 0; +} + +void app_cx_sha3_block(app_cx_sha3_t *hash) { + uint64bits_t *block; + uint64bits_t *acc; + int r; + + block = (uint64bits_t *)hash->block; + acc = (uint64bits_t *)hash->acc; + + acc[0] ^= block[0]; + acc[1] ^= block[1]; + acc[2] ^= block[2]; + acc[3] ^= block[3]; + acc[4] ^= block[4]; + acc[5] ^= block[5]; + acc[6] ^= block[6]; + acc[7] ^= block[7]; + acc[8] ^= block[8]; + if (hash->block_size > 72) { + acc[9] ^= block[9]; + acc[10] ^= block[10]; + acc[11] ^= block[11]; + acc[12] ^= block[12]; + if (hash->block_size > 104) { + acc[13] ^= block[13]; + acc[14] ^= block[14]; + acc[15] ^= block[15]; + acc[16] ^= block[16]; + if (hash->block_size > 136) { + acc[17] ^= block[17]; + } + } + } + + for (r = 0; r < 24; r++) { + cx_sha3_theta(acc); + cx_sha3_rho(acc); + cx_sha3_pi(acc); + cx_sha3_chi(acc); + cx_sha3_iota(acc, r); + } +} + +int app_cx_hash(cx_hash_t *hash, int mode, unsigned char WIDE *in, int len, + unsigned char *out) { + unsigned int r; + unsigned char block_size; + unsigned char *block; + int blen; + unsigned char *acc; + + // --- init locals --- + block_size = 0; + blen = 0; + block = NULL; + acc = NULL; + + block_size = ((app_cx_sha3_t *)hash)->block_size; + block = ((app_cx_sha3_t *)hash)->block; + blen = ((app_cx_sha3_t *)hash)->blen; + ((app_cx_sha3_t *)hash)->blen = 0; + acc = (unsigned char *)((app_cx_sha3_t *)hash)->acc; + + // --- append input data and process all blocks --- + if ((blen + len) >= block_size) { + r = block_size - blen; + do { + os_memmove(block + blen, in, r); + app_cx_sha3_block((app_cx_sha3_t *)hash); + blen = 0; + hash->counter++; + in += r; + len -= r; + r = block_size; + } while (len >= block_size); + } + + // --- remainder --- + os_memmove(block + blen, in, len); + blen += len; + ((app_cx_sha3_t *)hash)->blen = blen; + + // --- last block --- + if (mode & CX_LAST) { + os_memset(block + blen, 0, (200 - blen)); + block[blen] |= 0x01; + block[block_size - 1] |= 0x80; + app_cx_sha3_block((app_cx_sha3_t *)hash); + // provide result + len = ((app_cx_sha3_t *)hash)->output_size; + if (out) { + os_memmove(out, acc, len); + } + ((app_cx_sha3_t *)hash)->blen = 0; + } + + return len; +} diff --git a/src_tmp/app_cx_sha3.h b/src_tmp/app_cx_sha3.h new file mode 100644 index 0000000..af3dd75 --- /dev/null +++ b/src_tmp/app_cx_sha3.h @@ -0,0 +1,45 @@ +/******************************************************************************* +* Ledger Blue +* (c) 2016 Ledger +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +********************************************************************************/ + +#include "os.h" +#include "cx.h" + +#pragma once + +#ifndef uint64bits_t +typedef unsigned long long uint64bits_t; +#endif + +struct app_cx_sha3_s { + struct cx_hash_header_s header; + + // x bytes per input block, depends on sha3-xxx output size + unsigned int output_size; + unsigned char block_size; + // + int blen; + unsigned char block[200]; + // use 64bits type to ensure alignment + uint64bits_t acc[25]; + // unsigned char acc[200]; +}; +typedef struct app_cx_sha3_s app_cx_sha3_t; + +int app_cx_sha3_init(app_cx_sha3_t *hash, int size); +void app_cx_sha3_block(app_cx_sha3_t *hash); +int app_cx_hash(cx_hash_t *hash, int mode, unsigned char WIDE *in, int len, + unsigned char *out);