diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/benchmark-flags | 100 | ||||
-rw-r--r-- | src/benchmark.c | 172 | ||||
-rw-r--r-- | src/libkeccak.h | 24 | ||||
-rw-r--r-- | src/libkeccak/digest.c | 708 | ||||
-rw-r--r-- | src/libkeccak/digest.h | 40 | ||||
-rw-r--r-- | src/libkeccak/files.c | 87 | ||||
-rw-r--r-- | src/libkeccak/files.h | 73 | ||||
-rw-r--r-- | src/libkeccak/generalised-spec.c | 194 | ||||
-rw-r--r-- | src/libkeccak/generalised-spec.h | 114 | ||||
-rw-r--r-- | src/libkeccak/hex.c | 73 | ||||
-rw-r--r-- | src/libkeccak/hex.h | 28 | ||||
-rw-r--r-- | src/libkeccak/internal.h | 31 | ||||
-rw-r--r-- | src/libkeccak/mac/hmac.c | 622 | ||||
-rw-r--r-- | src/libkeccak/mac/hmac.h | 294 | ||||
-rw-r--r-- | src/libkeccak/spec.h | 145 | ||||
-rw-r--r-- | src/libkeccak/state.c | 185 | ||||
-rw-r--r-- | src/libkeccak/state.h | 247 | ||||
-rw-r--r-- | src/test.c | 1053 |
18 files changed, 1923 insertions, 2267 deletions
diff --git a/src/benchmark-flags b/src/benchmark-flags index 0143f40..1168ec0 100755 --- a/src/benchmark-flags +++ b/src/benchmark-flags @@ -1,32 +1,16 @@ #!/bin/sh -# libkeccak – Keccak-family hashing library -# -# Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) -# -# This library is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this library. If not, see <http://www.gnu.org/licenses/>. +# See LICENSE file for copyright and license details. set -e export LD_LIBRARY_PATH=bin -if [ "${TRIES}" = "" ]; then - TRIES=10 +if test "${TRIES}" = ""; then + TRIES=10 fi # List all flags that affect the object files -list_test_flags () -{ - cat <<EOF +list_test_flags() { + cat <<EOF -fdata-sections -fcrossjumping -fexpensive-optimizations -ffunction-sections -fkeep-inline-functions -fomit-frame-pointer -freorder-blocks-and-partition -ftree-ter -falign-functions=0 -fmerge-all-constants -fmerge-constants @@ -41,47 +25,47 @@ pass=1 exec 4>.benchmark.so.far while true; do - exec 3>.benchmarks - - for _try in $(seq ${TRIES}); do - for test_flag in "" ${test_flags}; do - flags="${test_flag} ${base_flags}" - make -B all COPTIMISE="${flags}" CPPFLAGS="${cppflags} $*" - make check - if [ "${test_flag}" = "" ]; then - test_flag=zzz - fi - echo "$(bin/benchmark || echo error) ${test_flag}" >&3 + exec 3>.benchmarks + + for _try in $(seq ${TRIES}); do + for test_flag in "" ${test_flags}; do + flags="${test_flag} ${base_flags}" + make -B all COPTIMISE="${flags}" CPPFLAGS="${cppflags} $*" + make check + if test "${test_flag}" = ""; then + test_flag=zzz + fi + echo "$(bin/benchmark || echo error) ${test_flag}" >&3 + done done - done - - exec 3<&- - - ! grep ^error .benchmarks >/dev/null 2>/dev/null - - good_flag="$(median < .benchmarks | sort -n | cut -d ' ' -f 2 | sed 1q)" - if [ "${good_flag}" = zzz ] || [ $pass = 2 ]; then - if [ $pass = 1 ]; then - pass=2 - base_flags="$(echo "${base_flags}" | sed -e 's/ -O0//')" - test_flags="-O0 -O1 -O2 -O3 -Ofast -Os" + + exec 3<&- + + ! grep ^error .benchmarks >/dev/null 2>/dev/null + + good_flag="$(median < .benchmarks | sort -n | cut -d ' ' -f 2 | sed 1q)" + if test "${good_flag}" = zzz || test $pass = 2; then + if test $pass = 1; then + pass=2 + base_flags="$(echo "${base_flags}" | sed -e 's/ -O0//')" + test_flags="-O0 -O1 -O2 -O3 -Ofast -Os" + else + if ! test "${good_flag}" = zzz; then + base_flags="${base_flags} ${good_flag}" + echo "${good_flag}" >&4 + fi + echo + echo + echo "Good flags:" + echo "${base_flags}" + exec 4<&- + exit 0 + fi else - if [ ! "${good_flag}" = zzz ]; then - base_flags="${base_flags} ${good_flag}" echo "${good_flag}" >&4 - fi - echo - echo - echo "Good flags:" - echo "${base_flags}" - exec 4<&- - exit 0 + base_flags="${base_flags} ${good_flag}" + test_flags="$(echo "${test_flags}" | sed -e "s/ ${good_flag} / /")" fi - else - echo "${good_flag}" >&4 - base_flags="${base_flags} ${good_flag}" - test_flags="$(echo "${test_flags}" | sed -e "s/ ${good_flag} / /")" - fi done # None of these GCC flags affect the object files. diff --git a/src/benchmark.c b/src/benchmark.c index 115fcc5..1ce7da9 100644 --- a/src/benchmark.c +++ b/src/benchmark.c @@ -1,28 +1,11 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #include <libkeccak.h> +#include <fcntl.h> #include <stdio.h> #include <string.h> -#include <fcntl.h> -#include <unistd.h> #include <time.h> +#include <unistd.h> #ifndef MESSAGE_FILE @@ -66,96 +49,91 @@ * * @return Zero on success, 1 on error */ -int main(void) +int +main(void) { - char message[MESSAGE_LEN]; - libkeccak_spec_t spec; - libkeccak_state_t state; - char hashsum[OUTPUT / 8]; + char message[MESSAGE_LEN]; + libkeccak_spec_t spec; + libkeccak_state_t state; + char hashsum[OUTPUT / 8]; #ifndef IGNORE_BEHEXING - char hexsum[OUTPUT / 8 * 2 + 1]; + char hexsum[OUTPUT / 8 * 2 + 1]; #endif - struct timespec start, end; - long i, r; - - /* Fill message with content from the file. */ - { - int fd; - ssize_t got; - size_t ptr; - if (fd = open(MESSAGE_FILE, O_RDONLY), fd < 0) - return perror("open"), 1; - for (ptr = 0; ptr < MESSAGE_LEN; ptr += (size_t)got) - if (got = read(fd, message, MESSAGE_LEN - ptr), got <= 0) - return perror("read"), close(fd), 1; - close(fd); - } - - /* Initialise state. */ - spec.bitrate = BITRATE; - spec.capacity = CAPACITY; - spec.output = OUTPUT; - if (libkeccak_state_initialise(&state, &spec)) - return perror("libkeccak_state_initialise"), 1; - - /* Get start-time. */ - if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start) < 0) - return perror("clock_gettime"), 1; - - /* Run benchmarking loop. */ - for (r = 0; r < RERUNS; r++) - { - /* Updates. */ + struct timespec start, end; + long i, r; + + /* Fill message with content from the file. */ + int fd; + ssize_t got; + size_t ptr; + if (fd = open(MESSAGE_FILE, O_RDONLY), fd < 0) + return perror("open"), 1; + for (ptr = 0; ptr < MESSAGE_LEN; ptr += (size_t)got) + if (got = read(fd, message, MESSAGE_LEN - ptr), got <= 0) + return perror("read"), close(fd), 1; + close(fd); + + /* Initialise state. */ + spec.bitrate = BITRATE; + spec.capacity = CAPACITY; + spec.output = OUTPUT; + if (libkeccak_state_initialise(&state, &spec)) + return perror("libkeccak_state_initialise"), 1; + + /* Get start-time. */ + if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start) < 0) + return perror("clock_gettime"), 1; + + /* Run benchmarking loop. */ + for (r = 0; r < RERUNS; r++) { + /* Updates. */ #if UPDATE_RUNS > 0 - for (i = 0; i < UPDATE_RUNS; i++) - if (libkeccak_fast_update(&state, message, MESSAGE_LEN) < 0) - return perror("libkeccak_update"), 1; + for (i = 0; i < UPDATE_RUNS; i++) + if (libkeccak_fast_update(&state, message, MESSAGE_LEN) < 0) + return perror("libkeccak_update"), 1; #endif - - /* Digest. */ - if (libkeccak_fast_digest(&state, NULL, 0, 0, NULL, hashsum) < 0) - return perror("libkeccak_digest"), 1; + + /* Digest. */ + if (libkeccak_fast_digest(&state, NULL, 0, 0, NULL, hashsum) < 0) + return perror("libkeccak_digest"), 1; #ifndef IGNORE_BEHEXING - libkeccak_behex_lower(hexsum, hashsum, OUTPUT / 8); + libkeccak_behex_lower(hexsum, hashsum, OUTPUT / 8); #endif - - /* Fast squeezes. */ + + /* Fast squeezes. */ #if FAST_SQUEEZE_RUNS > 0 - libkeccak_fast_squeeze(&state, FAST_SQUEEZE_RUNS); + libkeccak_fast_squeeze(&state, FAST_SQUEEZE_RUNS); #endif - - /* Slow squeezes. */ + + /* Slow squeezes. */ #if SLOW_SQUEEZE_RUNS > 0 - for (i = 0; i < SLOW_SQUEEZE_RUNS; i++) - { - libkeccak_squeeze(&state, hashsum); + for (i = 0; i < SLOW_SQUEEZE_RUNS; i++) { + libkeccak_squeeze(&state, hashsum); # ifndef IGNORE_BEHEXING - libkeccak_behex_lower(hexsum, hashsum, OUTPUT / 8); + libkeccak_behex_lower(hexsum, hashsum, OUTPUT / 8); # endif - } + } #endif - } - - /* Get end-time. */ - if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end) < 0) - return perror("clock_gettime"), -1; - - /* Print execution-time. */ - end.tv_sec -= start.tv_sec; - end.tv_nsec -= start.tv_nsec; - if (end.tv_nsec < 0) - { - end.tv_sec--; - end.tv_nsec += 1000000000L; - } - printf("%03li%09li\n", (long)(end.tv_sec), end.tv_nsec); - - /* Release resources and exit. */ - libkeccak_state_fast_destroy(&state); - return 0; - + } + + /* Get end-time. */ + if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end) < 0) + return perror("clock_gettime"), -1; + + /* Print execution-time. */ + end.tv_sec -= start.tv_sec; + end.tv_nsec -= start.tv_nsec; + if (end.tv_nsec < 0) { + end.tv_sec--; + end.tv_nsec += 1000000000L; + } + printf("%03li%09li\n", (long)(end.tv_sec), end.tv_nsec); + + /* Release resources and exit. */ + libkeccak_state_fast_destroy(&state); + return 0; + #if (UPDATE_RUNS == 0) && (SLOW_SQUEEZE_RUNS == 0) - (void) i; + (void) i; #endif } - diff --git a/src/libkeccak.h b/src/libkeccak.h index c53bcd1..7c71801 100644 --- a/src/libkeccak.h +++ b/src/libkeccak.h @@ -1,24 +1,6 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #ifndef LIBKECCAK_H -#define LIBKECCAK_H 1 - +#define LIBKECCAK_H 1 #include "libkeccak/spec.h" #include "libkeccak/generalised-spec.h" @@ -28,6 +10,4 @@ #include "libkeccak/files.h" #include "libkeccak/mac/hmac.h" - #endif - diff --git a/src/libkeccak/digest.c b/src/libkeccak/digest.c index 6168f33..5f7a32c 100644 --- a/src/libkeccak/digest.c +++ b/src/libkeccak/digest.c @@ -1,21 +1,4 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #include "digest.h" #include "state.h" @@ -25,27 +8,27 @@ /** * X-macro-enabled listing of all intergers in [0, 4] */ -#define LIST_5 X(0) X(1) X(2) X(3) X(4) +#define LIST_5 X(0) X(1) X(2) X(3) X(4) /** * X-macro-enabled listing of all intergers in [0, 7] */ -#define LIST_8 LIST_5 X(5) X(6) X(7) +#define LIST_8 LIST_5 X(5) X(6) X(7) /** * X-macro-enabled listing of all intergers in [0, 23] */ -#define LIST_24 LIST_8 X(8) X(9) X(10) X(11) X(12) X(13) X(14) X(15) \ - X(16) X(17) X(18) X(19) X(20) X(21) X(22) X(23) +#define LIST_24 LIST_8 X(8) X(9) X(10) X(11) X(12) X(13) X(14) X(15)\ + X(16) X(17) X(18) X(19) X(20) X(21) X(22) X(23) /** * X-macro-enabled listing of all intergers in [0, 24] */ -#define LIST_25 LIST_24 X(24) +#define LIST_25 LIST_24 X(24) -#define X(N) (N % 5) * 5 + N / 5, +#define X(N) (N % 5) * 5 + N / 5, /** * The order the lanes should be read when absorbing or squeezing, * it transposes the lanes in the sponge @@ -58,15 +41,14 @@ static const long LANE_TRANSPOSE_MAP[] = { LIST_25 }; /** * Keccak-f round constants */ -static const uint_fast64_t RC[] = - { - 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808AULL, 0x8000000080008000ULL, - 0x000000000000808BULL, 0x0000000080000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL, - 0x000000000000008AULL, 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000AULL, - 0x000000008000808BULL, 0x800000000000008BULL, 0x8000000000008089ULL, 0x8000000000008003ULL, - 0x8000000000008002ULL, 0x8000000000000080ULL, 0x000000000000800AULL, 0x800000008000000AULL, - 0x8000000080008081ULL, 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL - }; +static const uint_fast64_t RC[] = { + 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808AULL, 0x8000000080008000ULL, + 0x000000000000808BULL, 0x0000000080000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL, + 0x000000000000008AULL, 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000AULL, + 0x000000008000808BULL, 0x800000000000008BULL, 0x8000000000008089ULL, 0x8000000000008003ULL, + 0x8000000000008002ULL, 0x8000000000000080ULL, 0x000000000000800AULL, 0x800000008000000AULL, + 0x8000000080008081ULL, 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL +}; /** @@ -78,7 +60,7 @@ static const uint_fast64_t RC[] = * @param wmod:int_fast64_t `state->wmod` * @return :int_fast64_t The value rotated */ -#define rotate(x, n, w, wmod) ((((x) >> ((w) - ((n) % (w)))) | ((x) << ((n) % (w)))) & (wmod)) +#define rotate(x, n, w, wmod) ((((x) >> ((w) - ((n) % (w)))) | ((x) << ((n) % (w)))) & (wmod)) /** @@ -88,7 +70,7 @@ static const uint_fast64_t RC[] = * @param n:long Rotation steps, may not be zero * @return :int_fast64_t The value rotated */ -#define rotate64(x, n) ((int_fast64_t)(((uint64_t)(x) >> (64L - (n))) | ((uint64_t)(x) << (n)))) +#define rotate64(x, n) ((int_fast64_t)(((uint64_t)(x) >> (64L - (n))) | ((uint64_t)(x) << (n)))) /** @@ -97,44 +79,44 @@ static const uint_fast64_t RC[] = * @param state The hashing state * @param rc The round contant for this round */ -static __attribute__((nonnull, nothrow, hot)) -void libkeccak_f_round(register libkeccak_state_t* restrict state, register int_fast64_t rc) +static __attribute__((nonnull, nothrow, hot)) void +libkeccak_f_round(register libkeccak_state_t *restrict state, register int_fast64_t rc) { - int_fast64_t* restrict A = state->S; - int_fast64_t B[25]; - int_fast64_t C[5]; - int_fast64_t da, db, dc, dd, de; - int_fast64_t wmod = state->wmod; - long w = state->w; - - /* θ step (step 1 of 3). */ -#define X(N) C[N] = A[N * 5] ^ A[N * 5 + 1] ^ A[N * 5 + 2] ^ A[N * 5 + 3] ^ A[N * 5 + 4]; - LIST_5 + int_fast64_t *restrict A = state->S; + int_fast64_t B[25]; + int_fast64_t C[5]; + int_fast64_t da, db, dc, dd, de; + int_fast64_t wmod = state->wmod; + long w = state->w; + + /* θ step (step 1 of 3). */ +#define X(N) C[N] = A[N * 5] ^ A[N * 5 + 1] ^ A[N * 5 + 2] ^ A[N * 5 + 3] ^ A[N * 5 + 4]; + LIST_5; #undef X - - /* θ step (step 2 of 3). */ - da = C[4] ^ rotate(C[1], 1, w, wmod); - dd = C[2] ^ rotate(C[4], 1, w, wmod); - db = C[0] ^ rotate(C[2], 1, w, wmod); - de = C[3] ^ rotate(C[0], 1, w, wmod); - dc = C[1] ^ rotate(C[3], 1, w, wmod); - - /* ρ and π steps, with last two part of θ. */ -#define X(bi, ai, dv, r) B[bi] = rotate(A[ai] ^ dv, r, w, wmod) - B[0] = A[0] ^ da; X( 1, 15, dd, 28); X( 2, 5, db, 1); X( 3, 20, de, 27); X( 4, 10, dc, 62); - X( 5, 6, db, 44); X( 6, 21, de, 20); X( 7, 11, dc, 6); X( 8, 1, da, 36); X( 9, 16, dd, 55); - X(10, 12, dc, 43); X(11, 2, da, 3); X(12, 17, dd, 25); X(13, 7, db, 10); X(14, 22, de, 39); - X(15, 18, dd, 21); X(16, 8, db, 45); X(17, 23, de, 8); X(18, 13, dc, 15); X(19, 3, da, 41); - X(20, 24, de, 14); X(21, 14, dc, 61); X(22, 4, da, 18); X(23, 19, dd, 56); X(24, 9, db, 2); + + /* θ step (step 2 of 3). */ + da = C[4] ^ rotate(C[1], 1, w, wmod); + dd = C[2] ^ rotate(C[4], 1, w, wmod); + db = C[0] ^ rotate(C[2], 1, w, wmod); + de = C[3] ^ rotate(C[0], 1, w, wmod); + dc = C[1] ^ rotate(C[3], 1, w, wmod); + + /* ρ and π steps, with last two part of θ. */ +#define X(bi, ai, dv, r) B[bi] = rotate(A[ai] ^ dv, r, w, wmod) + B[0] = A[0] ^ da; X( 1, 15, dd, 28); X( 2, 5, db, 1); X( 3, 20, de, 27); X( 4, 10, dc, 62); + X( 5, 6, db, 44); X( 6, 21, de, 20); X( 7, 11, dc, 6); X( 8, 1, da, 36); X( 9, 16, dd, 55); + X(10, 12, dc, 43); X(11, 2, da, 3); X(12, 17, dd, 25); X(13, 7, db, 10); X(14, 22, de, 39); + X(15, 18, dd, 21); X(16, 8, db, 45); X(17, 23, de, 8); X(18, 13, dc, 15); X(19, 3, da, 41); + X(20, 24, de, 14); X(21, 14, dc, 61); X(22, 4, da, 18); X(23, 19, dd, 56); X(24, 9, db, 2); #undef X - - /* ξ step. */ -#define X(N) A[N] = B[N] ^ ((~(B[(N + 5) % 25])) & B[(N + 10) % 25]); - LIST_25 + + /* ξ step. */ +#define X(N) A[N] = B[N] ^ ((~(B[(N + 5) % 25])) & B[(N + 10) % 25]); + LIST_25; #undef X - - /* ι step. */ - A[0] ^= rc; + + /* ι step. */ + A[0] ^= rc; } @@ -144,42 +126,42 @@ void libkeccak_f_round(register libkeccak_state_t* restrict state, register int_ * @param state The hashing state * @param rc The round contant for this round */ -static __attribute__((nonnull, nothrow, hot)) -void libkeccak_f_round64(register libkeccak_state_t* restrict state, register int_fast64_t rc) +static __attribute__((nonnull, nothrow, hot)) void +libkeccak_f_round64(register libkeccak_state_t *restrict state, register int_fast64_t rc) { - int_fast64_t* restrict A = state->S; - int_fast64_t B[25]; - int_fast64_t C[5]; - int_fast64_t da, db, dc, dd, de; - - /* θ step (step 1 of 3). */ -#define X(N) C[N] = A[N * 5] ^ A[N * 5 + 1] ^ A[N * 5 + 2] ^ A[N * 5 + 3] ^ A[N * 5 + 4]; - LIST_5 + int_fast64_t *restrict A = state->S; + int_fast64_t B[25]; + int_fast64_t C[5]; + int_fast64_t da, db, dc, dd, de; + + /* θ step (step 1 of 3). */ +#define X(N) C[N] = A[N * 5] ^ A[N * 5 + 1] ^ A[N * 5 + 2] ^ A[N * 5 + 3] ^ A[N * 5 + 4]; + LIST_5; #undef X - - /* θ step (step 2 of 3). */ - da = C[4] ^ rotate64(C[1], 1); - dd = C[2] ^ rotate64(C[4], 1); - db = C[0] ^ rotate64(C[2], 1); - de = C[3] ^ rotate64(C[0], 1); - dc = C[1] ^ rotate64(C[3], 1); - - /* ρ and π steps, with last two part of θ. */ -#define X(bi, ai, dv, r) B[bi] = rotate64(A[ai] ^ dv, r) - B[0] = A[0] ^ da; X( 1, 15, dd, 28); X( 2, 5, db, 1); X( 3, 20, de, 27); X( 4, 10, dc, 62); - X( 5, 6, db, 44); X( 6, 21, de, 20); X( 7, 11, dc, 6); X( 8, 1, da, 36); X( 9, 16, dd, 55); - X(10, 12, dc, 43); X(11, 2, da, 3); X(12, 17, dd, 25); X(13, 7, db, 10); X(14, 22, de, 39); - X(15, 18, dd, 21); X(16, 8, db, 45); X(17, 23, de, 8); X(18, 13, dc, 15); X(19, 3, da, 41); - X(20, 24, de, 14); X(21, 14, dc, 61); X(22, 4, da, 18); X(23, 19, dd, 56); X(24, 9, db, 2); + + /* θ step (step 2 of 3). */ + da = C[4] ^ rotate64(C[1], 1); + dd = C[2] ^ rotate64(C[4], 1); + db = C[0] ^ rotate64(C[2], 1); + de = C[3] ^ rotate64(C[0], 1); + dc = C[1] ^ rotate64(C[3], 1); + + /* ρ and π steps, with last two part of θ. */ +#define X(bi, ai, dv, r) B[bi] = rotate64(A[ai] ^ dv, r) + B[0] = A[0] ^ da; X( 1, 15, dd, 28); X( 2, 5, db, 1); X( 3, 20, de, 27); X( 4, 10, dc, 62); + X( 5, 6, db, 44); X( 6, 21, de, 20); X( 7, 11, dc, 6); X( 8, 1, da, 36); X( 9, 16, dd, 55); + X(10, 12, dc, 43); X(11, 2, da, 3); X(12, 17, dd, 25); X(13, 7, db, 10); X(14, 22, de, 39); + X(15, 18, dd, 21); X(16, 8, db, 45); X(17, 23, de, 8); X(18, 13, dc, 15); X(19, 3, da, 41); + X(20, 24, de, 14); X(21, 14, dc, 61); X(22, 4, da, 18); X(23, 19, dd, 56); X(24, 9, db, 2); #undef X - - /* ξ step. */ -#define X(N) A[N] = B[N] ^ ((~(B[(N + 5) % 25])) & B[(N + 10) % 25]); - LIST_25 + + /* ξ step. */ +#define X(N) A[N] = B[N] ^ ((~(B[(N + 5) % 25])) & B[(N + 10) % 25]); + LIST_25; #undef X - - /* ι step. */ - A[0] ^= rc; + + /* ι step. */ + A[0] ^= rc; } @@ -188,18 +170,19 @@ void libkeccak_f_round64(register libkeccak_state_t* restrict state, register in * * @param state The hashing state */ -static inline __attribute__((nonnull, nothrow, gnu_inline)) -void libkeccak_f(register libkeccak_state_t* restrict state) +static inline __attribute__((nonnull, nothrow, gnu_inline)) void +libkeccak_f(register libkeccak_state_t *restrict state) { - register long i = 0; - register long nr = state->nr; - register long wmod = state->wmod; - if (nr == 24) - for (; i < nr; i++) - libkeccak_f_round64(state, (int_fast64_t)(RC[i])); - else - for (; i < nr; i++) - libkeccak_f_round(state, (int_fast64_t)(RC[i] & wmod)); + register long i = 0; + register long nr = state->nr; + register long wmod = state->wmod; + if (nr == 24) { + for (; i < nr; i++) + libkeccak_f_round64(state, (int_fast64_t)(RC[i])); + } else { + for (; i < nr; i++) + libkeccak_f_round(state, (int_fast64_t)(RC[i] & wmod)); + } } @@ -213,19 +196,18 @@ void libkeccak_f(register libkeccak_state_t* restrict state) * @param off The offset in the message * @return The lane */ -static inline __attribute__((nonnull, nothrow, pure, warn_unused_result, gnu_inline)) -int_fast64_t libkeccak_to_lane(register const char* restrict message, register size_t msglen, - register long rr, register long ww, size_t off) +static inline __attribute__((nonnull, nothrow, pure, warn_unused_result, gnu_inline)) int_fast64_t +libkeccak_to_lane(register const char *restrict message, register size_t msglen, + register long rr, register long ww, size_t off) { - register long n = (long)((msglen < (size_t)rr ? msglen : (size_t)rr) - off); - int_fast64_t rc = 0; - message += off; - while (ww--) - { - rc <<= 8; - rc |= __builtin_expect(ww < n, 1) ? (int_fast64_t)(unsigned char)(message[ww]) : 0L; - } - return rc; + register long n = (long)((msglen < (size_t)rr ? msglen : (size_t)rr) - off); + int_fast64_t rc = 0; + message += off; + while (ww--) { + rc <<= 8; + rc |= __builtin_expect(ww < n, 1) ? (int_fast64_t)(unsigned char)(message[ww]) : 0L; + } + return rc; } @@ -238,18 +220,18 @@ int_fast64_t libkeccak_to_lane(register const char* restrict message, register s * @param off The offset in the message * @return The lane */ -static inline __attribute__((nonnull, nothrow, pure, hot, warn_unused_result, gnu_inline)) -int_fast64_t libkeccak_to_lane64(register const char* restrict message, register size_t msglen, - register long rr, size_t off) +static inline __attribute__((nonnull, nothrow, pure, hot, warn_unused_result, gnu_inline)) int_fast64_t +libkeccak_to_lane64(register const char* restrict message, register size_t msglen, + register long rr, size_t off) { - register long n = (long)((msglen < (size_t)rr ? msglen : (size_t)rr) - off); - int_fast64_t rc = 0; - message += off; -#define X(N) if (__builtin_expect(N < n, 1)) rc |= (int_fast64_t)(unsigned char)(message[N]) << (N * 8); \ - else return rc; - LIST_8 + register long n = (long)((msglen < (size_t)rr ? msglen : (size_t)rr) - off); + int_fast64_t rc = 0; + message += off; +#define X(N) if (__builtin_expect(N < n, 1)) rc |= (int_fast64_t)(unsigned char)(message[N]) << (N * 8);\ + else return rc; + LIST_8; #undef X - return rc; + return rc; } @@ -260,30 +242,27 @@ int_fast64_t libkeccak_to_lane64(register const char* restrict message, register * `state->M` should have `state->r / 8` bytes left over at the end * @param bits The number of bits in the end of the message that does not make a whole byte */ -static inline __attribute__((nonnull, nothrow, gnu_inline)) -void libkeccak_pad10star1(register libkeccak_state_t* restrict state, register size_t bits) +static inline __attribute__((nonnull, nothrow, gnu_inline)) void +libkeccak_pad10star1(register libkeccak_state_t *restrict state, register size_t bits) { - register size_t r = (size_t)(state->r); - register size_t nrf = state->mptr - !!bits; - register size_t len = (nrf << 3) | bits; - register size_t ll = len % r; - register char b = (char)(bits ? (state->M[nrf] | (1 << bits)) : 1); - - if ((r - 8 <= ll) && (ll <= r - 2)) - { - state->M[nrf] = (char)(b ^ 0x80); - state->mptr = nrf + 1; - } - else - { - len = ++nrf << 3; - len = (len - (len % r) + (r - 8)) >> 3; - state->mptr = len + 1; - - state->M[nrf - 1] = b; - __builtin_memset(state->M + nrf, 0, (len - nrf) * sizeof(char)); - state->M[len] = (char)0x80; - } + register size_t r = (size_t)(state->r); + register size_t nrf = state->mptr - !!bits; + register size_t len = (nrf << 3) | bits; + register size_t ll = len % r; + register char b = (char)(bits ? (state->M[nrf] | (1 << bits)) : 1); + + if (r - 8 <= ll && ll <= r - 2) { + state->M[nrf] = (char)(b ^ 0x80); + state->mptr = nrf + 1; + } else { + len = ++nrf << 3; + len = (len - (len % r) + (r - 8)) >> 3; + state->mptr = len + 1; + + state->M[nrf - 1] = b; + __builtin_memset(state->M + nrf, 0, (len - nrf) * sizeof(char)); + state->M[len] = (char)0x80; + } } @@ -293,33 +272,32 @@ void libkeccak_pad10star1(register libkeccak_state_t* restrict state, register s * @param state The hashing state * @param len The number of bytes from `state->M` to absorb */ -static __attribute__((nonnull, nothrow)) -void libkeccak_absorption_phase(register libkeccak_state_t* restrict state, register size_t len) +static __attribute__((nonnull, nothrow)) void +libkeccak_absorption_phase(register libkeccak_state_t *restrict state, register size_t len) { - register long rr = state->r >> 3; - register long ww = state->w >> 3; - register long n = (long)len / rr; - register const char* restrict message = state->M; - if (__builtin_expect(ww >= 8, 1)) /* ww > 8 is impossible, it is just for optimisation possibilities. */ - while (n--) - { -#define X(N) state->S[N] ^= libkeccak_to_lane64(message, len, rr, (size_t)(LANE_TRANSPOSE_MAP[N] * 8)); - LIST_25 + register long rr = state->r >> 3; + register long ww = state->w >> 3; + register long n = (long)len / rr; + register const char* restrict message = state->M; + if (__builtin_expect(ww >= 8, 1)) { /* ww > 8 is impossible, it is just for optimisation possibilities. */ + while (n--) { +#define X(N) state->S[N] ^= libkeccak_to_lane64(message, len, rr, (size_t)(LANE_TRANSPOSE_MAP[N] * 8)); + LIST_25; #undef X - libkeccak_f(state); - message += (size_t)rr; - len -= (size_t)rr; - } - else - while (n--) - { -#define X(N) state->S[N] ^= libkeccak_to_lane(message, len, rr, ww, (size_t)(LANE_TRANSPOSE_MAP[N] * ww)); - LIST_25 + libkeccak_f(state); + message += (size_t)rr; + len -= (size_t)rr; + } + } else { + while (n--) { +#define X(N) state->S[N] ^= libkeccak_to_lane(message, len, rr, ww, (size_t)(LANE_TRANSPOSE_MAP[N] * ww)); + LIST_25; #undef X - libkeccak_f(state); - message += (size_t)rr; - len -= (size_t)rr; - } + libkeccak_f(state); + message += (size_t)rr; + len -= (size_t)rr; + } + } } @@ -332,28 +310,26 @@ void libkeccak_absorption_phase(register libkeccak_state_t* restrict state, regi * @param ww The word size in bytes * @param hashsum Output parameter for the hashsum */ -static __attribute__((nonnull, nothrow, hot)) -void libkeccak_squeezing_phase(register libkeccak_state_t* restrict state, long rr, - long nn, long ww, register char* restrict hashsum) +static __attribute__((nonnull, nothrow, hot)) void +libkeccak_squeezing_phase(register libkeccak_state_t *restrict state, long rr, + long nn, long ww, register char *restrict hashsum) { - register int_fast64_t v; - register long ni = rr / ww; - auto long olen = state->n; - auto long i, j = 0; - register long k; - while (olen > 0) - { - for (i = 0; (i < ni) && (j < nn); i++) - { - v = state->S[LANE_TRANSPOSE_MAP[i]]; - for (k = 0; (k++ < ww) && (j++ < nn); v >>= 8) - *hashsum++ = (char)v; + register int_fast64_t v; + register long ni = rr / ww; + auto long olen = state->n; + auto long i, j = 0; + register long k; + while (olen > 0) { + for (i = 0; i < ni && j < nn; i++) { + v = state->S[LANE_TRANSPOSE_MAP[i]]; + for (k = 0; k++ < ww && j++ < nn; v >>= 8) + *hashsum++ = (char)v; + } + if (olen -= state->r, olen > 0) + libkeccak_f(state); } - if (olen -= state->r, olen > 0) - libkeccak_f(state); - } - if (state->n & 7) - hashsum[-1] &= (char)((1 << (state->n & 7)) - 1); + if (state->n & 7) + hashsum[-1] &= (char)((1 << (state->n & 7)) - 1); } @@ -366,30 +342,30 @@ void libkeccak_squeezing_phase(register libkeccak_state_t* restrict state, long * @param msglen The length of the partial message * @return Zero on success, -1 on error */ -int libkeccak_fast_update(libkeccak_state_t* restrict state, const char* restrict msg, size_t msglen) +int +libkeccak_fast_update(libkeccak_state_t *restrict state, const char *restrict msg, size_t msglen) { - size_t len; - auto char* restrict new; - - if (__builtin_expect(state->mptr + msglen > state->mlen, 0)) - { - state->mlen += msglen; - new = realloc(state->M, state->mlen * sizeof(char)); - if (new == NULL) - return state->mlen -= msglen, -1; - state->M = new; - } - - __builtin_memcpy(state->M + state->mptr, msg, msglen * sizeof(char)); - state->mptr += msglen; - len = state->mptr; - len -= state->mptr % (size_t)((state->r * state->b) >> 3); - state->mptr -= len; - - libkeccak_absorption_phase(state, len); - __builtin_memmove(state->M, state->M + len, state->mptr * sizeof(char)); - - return 0; + size_t len; + auto char *restrict new; + + if (__builtin_expect(state->mptr + msglen > state->mlen, 0)) { + state->mlen += msglen; + new = realloc(state->M, state->mlen * sizeof(char)); + if (!new) + return state->mlen -= msglen, -1; + state->M = new; + } + + __builtin_memcpy(state->M + state->mptr, msg, msglen * sizeof(char)); + state->mptr += msglen; + len = state->mptr; + len -= state->mptr % (size_t)((state->r * state->b) >> 3); + state->mptr -= len; + + libkeccak_absorption_phase(state, len); + __builtin_memmove(state->M, state->M + len, state->mptr * sizeof(char)); + + return 0; } @@ -402,32 +378,32 @@ int libkeccak_fast_update(libkeccak_state_t* restrict state, const char* restric * @param msglen The length of the partial message * @return Zero on success, -1 on error */ -int libkeccak_update(libkeccak_state_t* restrict state, const char* restrict msg, size_t msglen) +int +libkeccak_update(libkeccak_state_t *restrict state, const char *restrict msg, size_t msglen) { - size_t len; - auto char* restrict new; - - if (__builtin_expect(state->mptr + msglen > state->mlen, 0)) - { - state->mlen += msglen; - new = malloc(state->mlen * sizeof(char)); - if (new == NULL) - return state->mlen -= msglen, -1; - libkeccak_state_wipe_message(state); - free(state->M); - state->M = new; - } - - __builtin_memcpy(state->M + state->mptr, msg, msglen * sizeof(char)); - state->mptr += msglen; - len = state->mptr; - len -= state->mptr % (size_t)((state->r * state->b) >> 3); - state->mptr -= len; - - libkeccak_absorption_phase(state, len); - __builtin_memmove(state->M, state->M + len, state->mptr * sizeof(char)); - - return 0; + size_t len; + auto char *restrict new; + + if (__builtin_expect(state->mptr + msglen > state->mlen, 0)) { + state->mlen += msglen; + new = malloc(state->mlen * sizeof(char)); + if (new == NULL) + return state->mlen -= msglen, -1; + libkeccak_state_wipe_message(state); + free(state->M); + state->M = new; + } + + __builtin_memcpy(state->M + state->mptr, msg, msglen * sizeof(char)); + state->mptr += msglen; + len = state->mptr; + len -= state->mptr % (size_t)((state->r * state->b) >> 3); + state->mptr -= len; + + libkeccak_absorption_phase(state, len); + __builtin_memmove(state->M, state->M + len, state->mptr * sizeof(char)); + + return 0; } @@ -443,60 +419,59 @@ int libkeccak_update(libkeccak_state_t* restrict state, const char* restrict msg * @param hashsum Output parameter for the hashsum, may be `NULL` * @return Zero on success, -1 on error */ -int libkeccak_fast_digest(libkeccak_state_t* restrict state, const char* restrict msg, size_t msglen, - size_t bits, const char* restrict suffix, char* restrict hashsum) +int +libkeccak_fast_digest(libkeccak_state_t *restrict state, const char *restrict msg, size_t msglen, + size_t bits, const char *restrict suffix, char *restrict hashsum) { - auto char* restrict new; - register long rr = state->r >> 3; - auto size_t suffix_len = suffix ? __builtin_strlen(suffix) : 0; - register size_t ext; - register long i; - - if (msg == NULL) - msglen = bits = 0; - else - msglen += bits >> 3, bits &= 7; - - ext = msglen + ((bits + suffix_len + 7) >> 3) + (size_t)rr; - if (__builtin_expect(state->mptr + ext > state->mlen, 0)) - { - state->mlen += ext; - new = realloc(state->M, state->mlen * sizeof(char)); - if (new == NULL) - return state->mlen -= ext, -1; - state->M = new; - } - - if (msglen) - __builtin_memcpy(state->M + state->mptr, msg, msglen * sizeof(char)); - state->mptr += msglen; - - if (bits) - state->M[state->mptr] = msg[msglen] & (char)((1 << bits) - 1); - if (__builtin_expect(!!suffix_len, 1)) - { - if (bits == 0) - state->M[state->mptr] = 0; - while (suffix_len--) - { - state->M[state->mptr] |= (char)((*suffix++ & 1) << bits++); - if (bits == 8) - bits = 0, state->M[++(state->mptr)] = 0; + auto char *restrict new; + register long rr = state->r >> 3; + auto size_t suffix_len = suffix ? __builtin_strlen(suffix) : 0; + register size_t ext; + register long i; + + if (msg == NULL) + msglen = bits = 0; + else + msglen += bits >> 3, bits &= 7; + + ext = msglen + ((bits + suffix_len + 7) >> 3) + (size_t)rr; + if (__builtin_expect(state->mptr + ext > state->mlen, 0)) { + state->mlen += ext; + new = realloc(state->M, state->mlen * sizeof(char)); + if (!new) + return state->mlen -= ext, -1; + state->M = new; + } + + if (msglen) + __builtin_memcpy(state->M + state->mptr, msg, msglen * sizeof(char)); + state->mptr += msglen; + + if (bits) + state->M[state->mptr] = msg[msglen] & (char)((1 << bits) - 1); + if (__builtin_expect(!!suffix_len, 1)) { + if (bits == 0) + state->M[state->mptr] = 0; + while (suffix_len--) { + state->M[state->mptr] |= (char)((*suffix++ & 1) << bits++); + if (bits == 8) + bits = 0, state->M[++(state->mptr)] = 0; + } + } + if (bits) + state->mptr++; + + libkeccak_pad10star1(state, bits); + libkeccak_absorption_phase(state, state->mptr); + + if (hashsum) { + libkeccak_squeezing_phase(state, rr, (state->n + 7) >> 3, state->w >> 3, hashsum); + } else { + for (i = (state->n - 1) / state->r; i--;) + libkeccak_f(state); } - } - if (bits) - state->mptr++; - - libkeccak_pad10star1(state, bits); - libkeccak_absorption_phase(state, state->mptr); - - if (hashsum != NULL) - libkeccak_squeezing_phase(state, rr, (state->n + 7) >> 3, state->w >> 3, hashsum); - else - for (i = (state->n - 1) / state->r; i--;) - libkeccak_f(state); - - return 0; + + return 0; } @@ -512,62 +487,61 @@ int libkeccak_fast_digest(libkeccak_state_t* restrict state, const char* restric * @param hashsum Output parameter for the hashsum, may be `NULL` * @return Zero on success, -1 on error */ -int libkeccak_digest(libkeccak_state_t* restrict state, const char* restrict msg, size_t msglen, - size_t bits, const char* restrict suffix, char* restrict hashsum) +int +libkeccak_digest(libkeccak_state_t *restrict state, const char *restrict msg, size_t msglen, + size_t bits, const char *restrict suffix, char *restrict hashsum) { - auto char* restrict new; - register long rr = state->r >> 3; - auto size_t suffix_len = suffix ? __builtin_strlen(suffix) : 0; - register size_t ext; - register long i; - - if (msg == NULL) - msglen = bits = 0; - else - msglen += bits >> 3, bits &= 7; - - ext = msglen + ((bits + suffix_len + 7) >> 3) + (size_t)rr; - if (__builtin_expect(state->mptr + ext > state->mlen, 0)) - { - state->mlen += ext; - new = malloc(state->mlen * sizeof(char)); - if (new == NULL) - return state->mlen -= ext, -1; - libkeccak_state_wipe_message(state); - free(state->M); - state->M = new; - } - - if (msglen) - __builtin_memcpy(state->M + state->mptr, msg, msglen * sizeof(char)); - state->mptr += msglen; - - if (bits) - state->M[state->mptr] = msg[msglen] & (char)((1 << bits) - 1); - if (__builtin_expect(!!suffix_len, 1)) - { - if (bits == 0) - state->M[state->mptr] = 0; - while (suffix_len--) - { - state->M[state->mptr] |= (char)((*suffix++ & 1) << bits++); - if (bits == 8) - bits = 0, state->M[++(state->mptr)] = 0; + auto char *restrict new; + register long rr = state->r >> 3; + auto size_t suffix_len = suffix ? __builtin_strlen(suffix) : 0; + register size_t ext; + register long i; + + if (msg == NULL) + msglen = bits = 0; + else + msglen += bits >> 3, bits &= 7; + + ext = msglen + ((bits + suffix_len + 7) >> 3) + (size_t)rr; + if (__builtin_expect(state->mptr + ext > state->mlen, 0)) { + state->mlen += ext; + new = malloc(state->mlen * sizeof(char)); + if (!new) + return state->mlen -= ext, -1; + libkeccak_state_wipe_message(state); + free(state->M); + state->M = new; + } + + if (msglen) + __builtin_memcpy(state->M + state->mptr, msg, msglen * sizeof(char)); + state->mptr += msglen; + + if (bits) + state->M[state->mptr] = msg[msglen] & (char)((1 << bits) - 1); + if (__builtin_expect(!!suffix_len, 1)) { + if (bits == 0) + state->M[state->mptr] = 0; + while (suffix_len--) { + state->M[state->mptr] |= (char)((*suffix++ & 1) << bits++); + if (bits == 8) + bits = 0, state->M[++(state->mptr)] = 0; + } + } + if (bits) + state->mptr++; + + libkeccak_pad10star1(state, bits); + libkeccak_absorption_phase(state, state->mptr); + + if (hashsum) { + libkeccak_squeezing_phase(state, rr, (state->n + 7) >> 3, state->w >> 3, hashsum); + } else { + for (i = (state->n - 1) / state->r; i--;) + libkeccak_f(state); } - } - if (bits) - state->mptr++; - - libkeccak_pad10star1(state, bits); - libkeccak_absorption_phase(state, state->mptr); - - if (hashsum != NULL) - libkeccak_squeezing_phase(state, rr, (state->n + 7) >> 3, state->w >> 3, hashsum); - else - for (i = (state->n - 1) / state->r; i--;) - libkeccak_f(state); - - return 0; + + return 0; } @@ -577,10 +551,11 @@ int libkeccak_digest(libkeccak_state_t* restrict state, const char* restrict msg * @param state The hashing state * @param times The number of rounds */ -void libkeccak_simple_squeeze(register libkeccak_state_t* restrict state, register long times) +void +libkeccak_simple_squeeze(register libkeccak_state_t *restrict state, register long times) { - while (times--) - libkeccak_f(state); + while (times--) + libkeccak_f(state); } @@ -590,11 +565,12 @@ void libkeccak_simple_squeeze(register libkeccak_state_t* restrict state, regist * @param state The hashing state * @param times The number of digests */ -void libkeccak_fast_squeeze(register libkeccak_state_t* restrict state, register long times) +void +libkeccak_fast_squeeze(register libkeccak_state_t *restrict state, register long times) { - times *= (state->n - 1) / state->r + 1; - while (times--) - libkeccak_f(state); + times *= (state->n - 1) / state->r + 1; + while (times--) + libkeccak_f(state); } @@ -604,9 +580,9 @@ void libkeccak_fast_squeeze(register libkeccak_state_t* restrict state, register * @param state The hashing state * @param hashsum Output parameter for the hashsum */ -void libkeccak_squeeze(register libkeccak_state_t* restrict state, register char* restrict hashsum) +void +libkeccak_squeeze(register libkeccak_state_t *restrict state, register char* restrict hashsum) { - libkeccak_f(state); - libkeccak_squeezing_phase(state, state->r >> 3, (state->n + 7) >> 3, state->w >> 3, hashsum); + libkeccak_f(state); + libkeccak_squeezing_phase(state, state->r >> 3, (state->n + 7) >> 3, state->w >> 3, hashsum); } - diff --git a/src/libkeccak/digest.h b/src/libkeccak/digest.h index 2dadd70..832f0c0 100644 --- a/src/libkeccak/digest.h +++ b/src/libkeccak/digest.h @@ -1,24 +1,6 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #ifndef LIBKECCAK_DIGEST_H -#define LIBKECCAK_DIGEST_H 1 - +#define LIBKECCAK_DIGEST_H 1 #include "state.h" #include "internal.h" @@ -34,7 +16,7 @@ * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull))) -int libkeccak_fast_update(libkeccak_state_t* restrict state, const char* restrict msg, size_t msglen); +int libkeccak_fast_update(libkeccak_state_t *restrict state, const char* restrict msg, size_t msglen); /** @@ -47,7 +29,7 @@ int libkeccak_fast_update(libkeccak_state_t* restrict state, const char* restric * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull))) -int libkeccak_update(libkeccak_state_t* restrict state, const char* restrict msg, size_t msglen); +int libkeccak_update(libkeccak_state_t *restrict state, const char *restrict msg, size_t msglen); /** @@ -63,8 +45,8 @@ int libkeccak_update(libkeccak_state_t* restrict state, const char* restrict msg * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(1)))) -int libkeccak_fast_digest(libkeccak_state_t* restrict state, const char* restrict msg, size_t msglen, - size_t bits, const char* restrict suffix, char* restrict hashsum); +int libkeccak_fast_digest(libkeccak_state_t *restrict state, const char *restrict msg, size_t msglen, + size_t bits, const char *restrict suffix, char *restrict hashsum); /** @@ -80,8 +62,8 @@ int libkeccak_fast_digest(libkeccak_state_t* restrict state, const char* restric * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(1)))) -int libkeccak_digest(libkeccak_state_t* restrict state, const char* restrict msg, size_t msglen, - size_t bits, const char* restrict suffix, char* restrict hashsum); +int libkeccak_digest(libkeccak_state_t *restrict state, const char *restrict msg, size_t msglen, + size_t bits, const char *restrict suffix, char *restrict hashsum); /** @@ -91,7 +73,7 @@ int libkeccak_digest(libkeccak_state_t* restrict state, const char* restrict msg * @param times The number of rounds */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow))) -void libkeccak_simple_squeeze(register libkeccak_state_t* restrict state, register long times); +void libkeccak_simple_squeeze(register libkeccak_state_t *restrict state, register long times); /** @@ -101,7 +83,7 @@ void libkeccak_simple_squeeze(register libkeccak_state_t* restrict state, regist * @param times The number of digests */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow))) -void libkeccak_fast_squeeze(register libkeccak_state_t* restrict state, register long times); +void libkeccak_fast_squeeze(register libkeccak_state_t *restrict state, register long times); /** @@ -111,7 +93,7 @@ void libkeccak_fast_squeeze(register libkeccak_state_t* restrict state, register * @param hashsum Output parameter for the hashsum */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow))) -void libkeccak_squeeze(register libkeccak_state_t* restrict state, register char* restrict hashsum); +void libkeccak_squeeze(register libkeccak_state_t *restrict state, register char* restrict hashsum); #endif diff --git a/src/libkeccak/files.c b/src/libkeccak/files.c index 07c2383..22d12f3 100644 --- a/src/libkeccak/files.c +++ b/src/libkeccak/files.c @@ -1,29 +1,12 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #include "files.h" - -#include <stddef.h> -#include <unistd.h> #include <sys/stat.h> #include <alloca.h> #include <errno.h> +#include <stddef.h> +#include <unistd.h> + /** @@ -38,39 +21,37 @@ * at least `((spec->output + 7) / 8) * sizeof(char)`, may be `NULL` * @return Zero on success, -1 on error */ -int libkeccak_generalised_sum_fd(int fd, libkeccak_state_t* restrict state, - const libkeccak_spec_t* restrict spec, - const char* restrict suffix, char* restrict hashsum) +int +libkeccak_generalised_sum_fd(int fd, libkeccak_state_t *restrict state, + const libkeccak_spec_t *restrict spec, + const char *restrict suffix, char *restrict hashsum) { - ssize_t got; - struct stat attr; - size_t blksize = 4096; - char* restrict chunk; - - if (libkeccak_state_initialise(state, spec) < 0) - return -1; - - if (fstat(fd, &attr) == 0) - if (attr.st_blksize > 0) - blksize = (size_t)(attr.st_blksize); - - chunk = alloca(blksize); + ssize_t got; + struct stat attr; + size_t blksize = 4096; + char *restrict chunk; + + if (libkeccak_state_initialise(state, spec) < 0) + return -1; + + if (fstat(fd, &attr) == 0) + if (attr.st_blksize > 0) + blksize = (size_t)(attr.st_blksize); - for (;;) - { - got = read(fd, chunk, blksize); - if (got < 0) - { - if (errno == EINTR) - continue; - return -1; + chunk = alloca(blksize); + + for (;;) { + got = read(fd, chunk, blksize); + if (got < 0) { + if (errno == EINTR) + continue; + return -1; + } + if (got == 0) + break; + if (libkeccak_fast_update(state, chunk, (size_t)got) < 0) + return -1; } - if (got == 0) - break; - if (libkeccak_fast_update(state, chunk, (size_t)got) < 0) - return -1; - } - - return libkeccak_fast_digest(state, NULL, 0, 0, suffix, hashsum); -} + return libkeccak_fast_digest(state, NULL, 0, 0, suffix, hashsum); +} diff --git a/src/libkeccak/files.h b/src/libkeccak/files.h index d694bbc..92038fb 100644 --- a/src/libkeccak/files.h +++ b/src/libkeccak/files.h @@ -1,24 +1,6 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #ifndef LIBKECCAK_FILES_H -#define LIBKECCAK_FILES_H 1 - +#define LIBKECCAK_FILES_H 1 #include "../libkeccak.h" #include "internal.h" @@ -37,9 +19,9 @@ * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(2, 3)))) -int libkeccak_generalised_sum_fd(int fd, libkeccak_state_t* restrict state, - const libkeccak_spec_t* restrict spec, - const char* restrict suffix, char* restrict hashsum); +int libkeccak_generalised_sum_fd(int fd, libkeccak_state_t *restrict state, + const libkeccak_spec_t *restrict spec, + const char *restrict suffix, char *restrict hashsum); /** @@ -54,11 +36,11 @@ int libkeccak_generalised_sum_fd(int fd, libkeccak_state_t* restrict state, * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(2, 3), artificial, gnu_inline))) -static inline -int libkeccak_keccaksum_fd(int fd, libkeccak_state_t* restrict state, - const libkeccak_spec_t* restrict spec, char* restrict hashsum) +static inline int +libkeccak_keccaksum_fd(int fd, libkeccak_state_t *restrict state, + const libkeccak_spec_t *restrict spec, char *restrict hashsum) { - return libkeccak_generalised_sum_fd(fd, state, spec, NULL, hashsum); + return libkeccak_generalised_sum_fd(fd, state, spec, NULL, hashsum); } @@ -74,13 +56,13 @@ int libkeccak_keccaksum_fd(int fd, libkeccak_state_t* restrict state, * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(2), artificial, gnu_inline))) -static inline -int libkeccak_sha3sum_fd(int fd, libkeccak_state_t* restrict state, - long output, char* restrict hashsum) +static inline int +libkeccak_sha3sum_fd(int fd, libkeccak_state_t *restrict state, + long output, char *restrict hashsum) { - libkeccak_spec_t spec; - libkeccak_spec_sha3(&spec, output); - return libkeccak_generalised_sum_fd(fd, state, &spec, LIBKECCAK_SHA3_SUFFIX, hashsum); + libkeccak_spec_t spec; + libkeccak_spec_sha3(&spec, output); + return libkeccak_generalised_sum_fd(fd, state, &spec, LIBKECCAK_SHA3_SUFFIX, hashsum); } @@ -97,13 +79,13 @@ int libkeccak_sha3sum_fd(int fd, libkeccak_state_t* restrict state, * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(2), artificial, gnu_inline))) -static inline -int libkeccak_rawshakesum_fd(int fd, libkeccak_state_t* restrict state, - long semicapacity, long output, char* restrict hashsum) +static inline int +libkeccak_rawshakesum_fd(int fd, libkeccak_state_t *restrict state, + long semicapacity, long output, char *restrict hashsum) { - libkeccak_spec_t spec; - libkeccak_spec_rawshake(&spec, semicapacity, output); - return libkeccak_generalised_sum_fd(fd, state, &spec, LIBKECCAK_RAWSHAKE_SUFFIX, hashsum); + libkeccak_spec_t spec; + libkeccak_spec_rawshake(&spec, semicapacity, output); + return libkeccak_generalised_sum_fd(fd, state, &spec, LIBKECCAK_RAWSHAKE_SUFFIX, hashsum); } @@ -120,15 +102,14 @@ int libkeccak_rawshakesum_fd(int fd, libkeccak_state_t* restrict state, * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(2), artificial, gnu_inline))) -static inline -int libkeccak_shakesum_fd(int fd, libkeccak_state_t* restrict state, - long semicapacity, long output, char* restrict hashsum) +static inline int +libkeccak_shakesum_fd(int fd, libkeccak_state_t *restrict state, + long semicapacity, long output, char *restrict hashsum) { - libkeccak_spec_t spec; - libkeccak_spec_shake(&spec, semicapacity, output); - return libkeccak_generalised_sum_fd(fd, state, &spec, LIBKECCAK_SHAKE_SUFFIX, hashsum); + libkeccak_spec_t spec; + libkeccak_spec_shake(&spec, semicapacity, output); + return libkeccak_generalised_sum_fd(fd, state, &spec, LIBKECCAK_SHAKE_SUFFIX, hashsum); } #endif - diff --git a/src/libkeccak/generalised-spec.c b/src/libkeccak/generalised-spec.c index 79d673b..9dfa918 100644 --- a/src/libkeccak/generalised-spec.c +++ b/src/libkeccak/generalised-spec.c @@ -1,32 +1,15 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #include "generalised-spec.h" - #ifdef __GNUC__ # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif -#define have(v) (spec->v != LIBKECCAK_GENERALISED_SPEC_AUTOMATIC) -#define copy(v) (v = spec->v) -#define deft(v, dv) (have_##v ? v : (dv)) +#define have(v) (spec->v != LIBKECCAK_GENERALISED_SPEC_AUTOMATIC) +#define copy(v) (v = spec->v) +#define deft(v, dv) (have_##v ? v : (dv)) + /** @@ -39,97 +22,83 @@ * @param output_spec The specification datastructure to fill in * @return Zero if `spec` is valid, a `LIBKECCAK_GENERALISED_SPEC_ERROR_*` if an error was found */ -int libkeccak_degeneralise_spec(libkeccak_generalised_spec_t* restrict spec, - libkeccak_spec_t* restrict output_spec) +int +libkeccak_degeneralise_spec(libkeccak_generalised_spec_t *restrict spec, + libkeccak_spec_t *restrict output_spec) { - long state_size, word_size, capacity, bitrate, output; - const int have_state_size = have(state_size); - const int have_word_size = have(word_size); - const int have_capacity = have(capacity); - const int have_bitrate = have(bitrate); - const int have_output = have(output); - - - if (have_state_size) - { - copy(state_size); - if (state_size <= 0) return LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_NONPOSITIVE; - if (state_size > 1600) return LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_TOO_LARGE; - if (state_size % 25) return LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_MOD_25; - } - - if (have_word_size) - { - copy(word_size); - if (word_size <= 0) return LIBKECCAK_GENERALISED_SPEC_ERROR_WORD_NONPOSITIVE; - if (word_size > 64) return LIBKECCAK_GENERALISED_SPEC_ERROR_WORD_TOO_LARGE; - if (have_state_size && (state_size != word_size * 25)) - return LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_WORD_INCOHERENCY; - else if (!have_state_size) - spec->state_size = 1, state_size = word_size * 25; - } - - if (have_capacity) - { - copy(capacity); - if (capacity <= 0) return LIBKECCAK_GENERALISED_SPEC_ERROR_CAPACITY_NONPOSITIVE; - if (capacity & 7) return LIBKECCAK_GENERALISED_SPEC_ERROR_CAPACITY_MOD_8; - } - - if (have_bitrate) - { - copy(bitrate); - if (bitrate <= 0) return LIBKECCAK_GENERALISED_SPEC_ERROR_BITRATE_NONPOSITIVE; - if (bitrate & 7) return LIBKECCAK_GENERALISED_SPEC_ERROR_BITRATE_MOD_8; - } - - if (have_output) - { - copy(output); - if (output <= 0) return LIBKECCAK_GENERALISED_SPEC_ERROR_OUTPUT_NONPOSITIVE; - } - - - if (!have_bitrate && !have_capacity && !have_output) - { - state_size = deft(state_size, 1600L); - output = ((state_size << 5) / 100L + 7L) & ~0x07L; - bitrate = output << 1; - capacity = state_size - bitrate; - output = output >= 8 ? output : 8; - } - else if (!have_bitrate && !have_capacity) - { - bitrate = 1024; - capacity = 1600 - 1024; - state_size = deft(state_size, bitrate + capacity); - } - else if (!have_bitrate) - { - state_size = deft(state_size, 1600L); - bitrate = state_size - capacity; - output = deft(output, capacity == 8 ? 8 : (capacity << 1)); - } - else if (!have_capacity) - { - state_size = deft(state_size, 1600L); - capacity = state_size - bitrate; - output = deft(output, capacity == 8 ? 8 : (capacity << 1)); - } - else - { - state_size = deft(state_size, bitrate + capacity); - output = deft(output, capacity == 8 ? 8 : (capacity << 1)); - } - - - spec->capacity = output_spec->capacity = capacity; - spec->bitrate = output_spec->bitrate = bitrate; - spec->output = output_spec->output = output; - spec->state_size = state_size; - spec->word_size = state_size / 25; - - return 0; + long state_size, word_size, capacity, bitrate, output; + const int have_state_size = have(state_size); + const int have_word_size = have(word_size); + const int have_capacity = have(capacity); + const int have_bitrate = have(bitrate); + const int have_output = have(output); + + + if (have_state_size) { + copy(state_size); + if (state_size <= 0) return LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_NONPOSITIVE; + if (state_size > 1600) return LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_TOO_LARGE; + if (state_size % 25) return LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_MOD_25; + } + + if (have_word_size) { + copy(word_size); + if (word_size <= 0) return LIBKECCAK_GENERALISED_SPEC_ERROR_WORD_NONPOSITIVE; + if (word_size > 64) return LIBKECCAK_GENERALISED_SPEC_ERROR_WORD_TOO_LARGE; + if (have_state_size && state_size != word_size * 25) + return LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_WORD_INCOHERENCY; + else if (!have_state_size) + spec->state_size = 1, state_size = word_size * 25; + } + + if (have_capacity) { + copy(capacity); + if (capacity <= 0) return LIBKECCAK_GENERALISED_SPEC_ERROR_CAPACITY_NONPOSITIVE; + if (capacity & 7) return LIBKECCAK_GENERALISED_SPEC_ERROR_CAPACITY_MOD_8; + } + + if (have_bitrate) { + copy(bitrate); + if (bitrate <= 0) return LIBKECCAK_GENERALISED_SPEC_ERROR_BITRATE_NONPOSITIVE; + if (bitrate & 7) return LIBKECCAK_GENERALISED_SPEC_ERROR_BITRATE_MOD_8; + } + + if (have_output) { + copy(output); + if (output <= 0) return LIBKECCAK_GENERALISED_SPEC_ERROR_OUTPUT_NONPOSITIVE; + } + + + if (!have_bitrate && !have_capacity && !have_output) { + state_size = deft(state_size, 1600L); + output = ((state_size << 5) / 100L + 7L) & ~0x07L; + bitrate = output << 1; + capacity = state_size - bitrate; + output = output >= 8 ? output : 8; + } else if (!have_bitrate && !have_capacity) { + bitrate = 1024; + capacity = 1600 - 1024; + state_size = deft(state_size, bitrate + capacity); + } else if (!have_bitrate) { + state_size = deft(state_size, 1600L); + bitrate = state_size - capacity; + output = deft(output, capacity == 8 ? 8 : (capacity << 1)); + } else if (!have_capacity) { + state_size = deft(state_size, 1600L); + capacity = state_size - bitrate; + output = deft(output, capacity == 8 ? 8 : (capacity << 1)); + } else { + state_size = deft(state_size, bitrate + capacity); + output = deft(output, capacity == 8 ? 8 : (capacity << 1)); + } + + spec->capacity = output_spec->capacity = capacity; + spec->bitrate = output_spec->bitrate = bitrate; + spec->output = output_spec->output = output; + spec->state_size = state_size; + spec->word_size = state_size / 25; + + return 0; } @@ -140,4 +109,3 @@ int libkeccak_degeneralise_spec(libkeccak_generalised_spec_t* restrict spec, #ifdef __GNUC__ # pragma GCC diagnostic pop #endif - diff --git a/src/libkeccak/generalised-spec.h b/src/libkeccak/generalised-spec.h index 6bd091e..2725961 100644 --- a/src/libkeccak/generalised-spec.h +++ b/src/libkeccak/generalised-spec.h @@ -1,24 +1,6 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #ifndef LIBKECCAK_GENERALISED_SPEC_H -#define LIBKECCAK_GENERALISED_SPEC_H 1 - +#define LIBKECCAK_GENERALISED_SPEC_H 1 #include "spec.h" #include "internal.h" @@ -31,64 +13,64 @@ * Value for `libkeccak_generalised_spec_t` member that * is used to automatically select the value */ -#define LIBKECCAK_GENERALISED_SPEC_AUTOMATIC (-65536L) +#define LIBKECCAK_GENERALISED_SPEC_AUTOMATIC (-65536L) /** * Invalid `libkeccak_generalised_spec_t.state_size`: non-positive */ -#define LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_NONPOSITIVE 1 +#define LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_NONPOSITIVE 1 /** * Invalid `libkeccak_generalised_spec_t.state_size`: larger than 1600 */ -#define LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_TOO_LARGE 2 +#define LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_TOO_LARGE 2 /** * Invalid `libkeccak_generalised_spec_t.state_size`: not a multiple of 25 */ -#define LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_MOD_25 3 +#define LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_MOD_25 3 /** * Invalid `libkeccak_generalised_spec_t.word_size`: non-positive */ -#define LIBKECCAK_GENERALISED_SPEC_ERROR_WORD_NONPOSITIVE 4 +#define LIBKECCAK_GENERALISED_SPEC_ERROR_WORD_NONPOSITIVE 4 /** * Invalid `libkeccak_generalised_spec_t.word_size`: larger than 1600 / 25 */ -#define LIBKECCAK_GENERALISED_SPEC_ERROR_WORD_TOO_LARGE 5 +#define LIBKECCAK_GENERALISED_SPEC_ERROR_WORD_TOO_LARGE 5 /** * Invalid `libkeccak_generalised_spec_t.word_size` and * `libkeccak_generalised_spec_t.state_size`: `.word_size * 25 != .state_size` */ -#define LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_WORD_INCOHERENCY 6 +#define LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_WORD_INCOHERENCY 6 /** * Invalid `libkeccak_generalised_spec_t.capacity`: non-positive */ -#define LIBKECCAK_GENERALISED_SPEC_ERROR_CAPACITY_NONPOSITIVE 7 +#define LIBKECCAK_GENERALISED_SPEC_ERROR_CAPACITY_NONPOSITIVE 7 /** * Invalid `libkeccak_generalised_spec_t.capacity`: not a multiple of 8 */ -#define LIBKECCAK_GENERALISED_SPEC_ERROR_CAPACITY_MOD_8 8 +#define LIBKECCAK_GENERALISED_SPEC_ERROR_CAPACITY_MOD_8 8 /** * Invalid `libkeccak_generalised_spec_t.bitrate`: non-positive */ -#define LIBKECCAK_GENERALISED_SPEC_ERROR_BITRATE_NONPOSITIVE 9 +#define LIBKECCAK_GENERALISED_SPEC_ERROR_BITRATE_NONPOSITIVE 9 /** * Invalid `libkeccak_generalised_spec_t.bitrate`: not a multiple of 8 */ -#define LIBKECCAK_GENERALISED_SPEC_ERROR_BITRATE_MOD_8 10 +#define LIBKECCAK_GENERALISED_SPEC_ERROR_BITRATE_MOD_8 10 /** * Invalid `libkeccak_generalised_spec_t.output`: non-positive */ -#define LIBKECCAK_GENERALISED_SPEC_ERROR_OUTPUT_NONPOSITIVE 11 +#define LIBKECCAK_GENERALISED_SPEC_ERROR_OUTPUT_NONPOSITIVE 11 @@ -98,31 +80,31 @@ */ typedef struct libkeccak_generalised_spec { - /** - * The bitrate - */ - long bitrate; - - /** - * The capacity - */ - long capacity; - - /** - * The output size - */ - long output; - - /** - * The state size - */ - long state_size; - - /** - * The word size - */ - long word_size; - + /** + * The bitrate + */ + long bitrate; + + /** + * The capacity + */ + long capacity; + + /** + * The output size + */ + long output; + + /** + * The state size + */ + long state_size; + + /** + * The word size + */ + long word_size; + } libkeccak_generalised_spec_t; @@ -133,14 +115,14 @@ typedef struct libkeccak_generalised_spec * @param spec The specification datastructure to fill in */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow, unused))) -static inline -void libkeccak_generalised_spec_initialise(libkeccak_generalised_spec_t* restrict spec) +static inline void +libkeccak_generalised_spec_initialise(libkeccak_generalised_spec_t *restrict spec) { - spec->bitrate = LIBKECCAK_GENERALISED_SPEC_AUTOMATIC; - spec->capacity = LIBKECCAK_GENERALISED_SPEC_AUTOMATIC; - spec->output = LIBKECCAK_GENERALISED_SPEC_AUTOMATIC; - spec->state_size = LIBKECCAK_GENERALISED_SPEC_AUTOMATIC; - spec->word_size = LIBKECCAK_GENERALISED_SPEC_AUTOMATIC; + spec->bitrate = LIBKECCAK_GENERALISED_SPEC_AUTOMATIC; + spec->capacity = LIBKECCAK_GENERALISED_SPEC_AUTOMATIC; + spec->output = LIBKECCAK_GENERALISED_SPEC_AUTOMATIC; + spec->state_size = LIBKECCAK_GENERALISED_SPEC_AUTOMATIC; + spec->word_size = LIBKECCAK_GENERALISED_SPEC_AUTOMATIC; } @@ -152,8 +134,8 @@ void libkeccak_generalised_spec_initialise(libkeccak_generalised_spec_t* restric * @return Zero if `spec` is valid, a `LIBKECCAK_GENERALISED_SPEC_ERROR_*` if an error was found */ LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull, nothrow))) -int libkeccak_degeneralise_spec(libkeccak_generalised_spec_t* restrict spec, - libkeccak_spec_t* restrict output_spec); +int libkeccak_degeneralise_spec(libkeccak_generalised_spec_t *restrict spec, + libkeccak_spec_t *restrict output_spec); #endif diff --git a/src/libkeccak/hex.c b/src/libkeccak/hex.c index 54f4006..7531223 100644 --- a/src/libkeccak/hex.c +++ b/src/libkeccak/hex.c @@ -1,21 +1,4 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #include "hex.h" #include <string.h> @@ -29,14 +12,14 @@ * @param hashsum The hashsum to convert * @param n The size of `hashsum` */ -void libkeccak_behex_lower(char* restrict output, const char* restrict hashsum, size_t n) +void +libkeccak_behex_lower(char *restrict output, const char *restrict hashsum, size_t n) { - output[2 * n] = '\0'; - while (n--) - { - output[2 * n + 0] = "0123456789abcdef"[(hashsum[n] >> 4) & 15]; - output[2 * n + 1] = "0123456789abcdef"[(hashsum[n] >> 0) & 15]; - } + output[2 * n] = '\0'; + while (n--) { + output[2 * n + 0] = "0123456789abcdef"[(hashsum[n] >> 4) & 15]; + output[2 * n + 1] = "0123456789abcdef"[(hashsum[n] >> 0) & 15]; + } } @@ -47,14 +30,14 @@ void libkeccak_behex_lower(char* restrict output, const char* restrict hashsum, * @param hashsum The hashsum to convert * @param n The size of `hashsum` */ -void libkeccak_behex_upper(char* restrict output, const char* restrict hashsum, size_t n) +void +libkeccak_behex_upper(char *restrict output, const char *restrict hashsum, size_t n) { - output[2 * n] = '\0'; - while (n--) - { - output[2 * n + 0] = "0123456789ABCDEF"[(hashsum[n] >> 4) & 15]; - output[2 * n + 1] = "0123456789ABCDEF"[(hashsum[n] >> 0) & 15]; - } + output[2 * n] = '\0'; + while (n--) { + output[2 * n + 0] = "0123456789ABCDEF"[(hashsum[n] >> 4) & 15]; + output[2 * n + 1] = "0123456789ABCDEF"[(hashsum[n] >> 0) & 15]; + } } @@ -65,18 +48,18 @@ void libkeccak_behex_upper(char* restrict output, const char* restrict hashsum, * @param output Output array, should have an allocation size of at least `strlen(hashsum) / 2` * @param hashsum The hashsum to convert */ -void libkeccak_unhex(char* restrict output, const char* restrict hashsum) +void +libkeccak_unhex(char *restrict output, const char *restrict hashsum) { - size_t n = strlen(hashsum) / 2; - while (n--) - { - char a = hashsum[2 * n + 0]; - char b = hashsum[2 * n + 1]; - - a = (char)((a & 15) + (a > '9' ? 9 : 0)); - b = (char)((b & 15) + (b > '9' ? 9 : 0)); - - output[n] = (char)((a << 4) | b); - } -} + size_t n = strlen(hashsum) / 2; + char a, b; + while (n--) { + a = hashsum[2 * n + 0]; + b = hashsum[2 * n + 1]; + a = (char)((a & 15) + (a > '9' ? 9 : 0)); + b = (char)((b & 15) + (b > '9' ? 9 : 0)); + + output[n] = (char)((a << 4) | b); + } +} diff --git a/src/libkeccak/hex.h b/src/libkeccak/hex.h index ce2a948..25375d5 100644 --- a/src/libkeccak/hex.h +++ b/src/libkeccak/hex.h @@ -1,24 +1,6 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #ifndef LIBKECCAK_HEX_H -#define LIBKECCAK_HEX_H 1 - +#define LIBKECCAK_HEX_H 1 #include "internal.h" @@ -33,7 +15,7 @@ * @param n The size of `hashsum` */ LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull, nothrow))) -void libkeccak_behex_lower(char* restrict output, const char* restrict hashsum, size_t n); +void libkeccak_behex_lower(char *restrict output, const char *restrict hashsum, size_t n); /** @@ -44,7 +26,7 @@ void libkeccak_behex_lower(char* restrict output, const char* restrict hashsum, * @param n The size of `hashsum` */ LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull, nothrow))) -void libkeccak_behex_upper(char* restrict output, const char* restrict hashsum, size_t n); +void libkeccak_behex_upper(char *restrict output, const char *restrict hashsum, size_t n); /** @@ -55,7 +37,7 @@ void libkeccak_behex_upper(char* restrict output, const char* restrict hashsum, * @param hashsum The hashsum to convert */ LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull, nothrow))) -void libkeccak_unhex(char* restrict output, const char* restrict hashsum); +void libkeccak_unhex(char *restrict output, const char *restrict hashsum); #endif diff --git a/src/libkeccak/internal.h b/src/libkeccak/internal.h index 5c8432e..466abf9 100644 --- a/src/libkeccak/internal.h +++ b/src/libkeccak/internal.h @@ -1,23 +1,6 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #ifndef LIBKECCAK_INTERNAL_H -#define LIBKECCAK_INTERNAL_H 1 +#define LIBKECCAK_INTERNAL_H 1 /** @@ -25,11 +8,19 @@ * if compiling with GCC. */ #ifdef __GNUC__ -# define LIBKECCAK_GCC_ONLY(x) x +# define LIBKECCAK_GCC_ONLY(x) x #else # define LIBKECCAK_GCC_ONLY(x) #endif +/* Use built in functions and branching optimisation if available */ +#ifndef __GNUC__ +# define __builtin_expect(expression, expect) expression +# define __builtin_memset(dest, c, n) memset(dest, c, n) +# define __builtin_memcpy(dest, src, n) memcpy(dest, src, n) +# define __builtin_memmove(dest, src, n) memmove(dest, src, n) #endif + +#endif diff --git a/src/libkeccak/mac/hmac.c b/src/libkeccak/mac/hmac.c index 3ecf539..ee3bc6a 100644 --- a/src/libkeccak/mac/hmac.c +++ b/src/libkeccak/mac/hmac.c @@ -1,21 +1,4 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #include "hmac.h" #include "../digest.h" @@ -25,20 +8,20 @@ /** * The outer pad pattern */ -#define OUTER_PAD 0x5C +#define OUTER_PAD 0x5C /** * The inner pad pattern */ -#define INNER_PAD 0x36 +#define INNER_PAD 0x36 -static void* (*volatile my_explicit_memset)(void*, int, size_t) = memset; -static __attribute__((optimize("-O0"))) -void my_explicit_bzero(void* ptr, size_t size) +static void *(*volatile my_explicit_memset)(void *, int, size_t) = memset; +static __attribute__((optimize("-O0"))) void +my_explicit_bzero(void *ptr, size_t size) { - (*my_explicit_memset)(ptr, 0, size); + (*my_explicit_memset)(ptr, 0, size); } @@ -50,38 +33,39 @@ void my_explicit_bzero(void* ptr, size_t size) * @param key_length The length of key, in bits * @return Zero on success, -1 on error */ -int libkeccak_hmac_set_key(libkeccak_hmac_state_t* restrict state, const char* restrict key, size_t key_length) +int +libkeccak_hmac_set_key(libkeccak_hmac_state_t *restrict state, const char *restrict key, size_t key_length) { - size_t i, size, new_key_length, key_bytes; - char* old; - - size = (size_t)(state->sponge.r) > key_length ? (size_t)(state->sponge.r) : key_length; - new_key_length = size; - size = (size + 7) >> 3; - key_bytes = (key_length + 7) >> 3; - - if (size != key_bytes) - { - state->key_opad = realloc(old = state->key_opad, 2 * size); - if (state->key_opad == NULL) - return state->key_opad = old, -1; - state->key_ipad = state->key_opad + size / sizeof(char); - } - - memcpy(state->key_opad, key, key_bytes); - if (key_length & 7) - state->key_opad[(key_bytes >> 3) - 1] &= (1 << (key_length & 7)) - 1; - - if ((size_t)(state->sponge.r) > key_length) - __builtin_memset(state->key_opad + key_bytes / sizeof(char), 0, size - key_bytes); - - for (i = 0; i < size; i++) - state->key_ipad[i] = state->key_opad[i] ^ INNER_PAD, - state->key_opad[i] ^= OUTER_PAD; - - state->key_length = new_key_length; - - return 0; + size_t i, size, new_key_length, key_bytes; + char *old; + + size = (size_t)(state->sponge.r) > key_length ? (size_t)(state->sponge.r) : key_length; + new_key_length = size; + size = (size + 7) >> 3; + key_bytes = (key_length + 7) >> 3; + + if (size != key_bytes) { + state->key_opad = realloc(old = state->key_opad, 2 * size); + if (!state->key_opad) + return state->key_opad = old, -1; + state->key_ipad = state->key_opad + size / sizeof(char); + } + + memcpy(state->key_opad, key, key_bytes); + if (key_length & 7) + state->key_opad[(key_bytes >> 3) - 1] &= (1 << (key_length & 7)) - 1; + + if ((size_t)(state->sponge.r) > key_length) + __builtin_memset(state->key_opad + key_bytes / sizeof(char), 0, size - key_bytes); + + for (i = 0; i < size; i++) { + state->key_ipad[i] = state->key_opad[i] ^ INNER_PAD; + state->key_opad[i] ^= OUTER_PAD; + } + + state->key_length = new_key_length; + + return 0; } @@ -90,17 +74,18 @@ int libkeccak_hmac_set_key(libkeccak_hmac_state_t* restrict state, const char* r * * @param state The state that should be wipe */ -void libkeccak_hmac_wipe(volatile libkeccak_hmac_state_t* restrict state) +void +libkeccak_hmac_wipe(volatile libkeccak_hmac_state_t *restrict state) { - volatile char* restrict key_pads; - size_t i, size; - key_pads = state->key_opad; - size = 2 * ((state->key_length + 7) >> 3); - libkeccak_state_wipe(&(state->sponge)); - for (i = 0; i < size; i++) - key_pads[i] = 0; - state->leftover = 0; - __builtin_memset(state->buffer, 0, state->buffer_size); + volatile char *restrict key_pads; + size_t i, size; + key_pads = state->key_opad; + size = 2 * ((state->key_length + 7) >> 3); + libkeccak_state_wipe(&state->sponge); + for (i = 0; i < size; i++) + key_pads[i] = 0; + state->leftover = 0; + __builtin_memset(state->buffer, 0, state->buffer_size); } @@ -111,30 +96,30 @@ void libkeccak_hmac_wipe(volatile libkeccak_hmac_state_t* restrict state) * @param src The state to duplicate * @return Zero on success, -1 on error */ -int libkeccak_hmac_copy(libkeccak_hmac_state_t* restrict dest, const libkeccak_hmac_state_t* restrict src) +int +libkeccak_hmac_copy(libkeccak_hmac_state_t *restrict dest, const libkeccak_hmac_state_t *restrict src) { - int saved_errno; - size_t size; - - dest->key_opad = NULL; - dest->key_ipad = NULL; - - if (libkeccak_state_copy(&(dest->sponge), &(src->sponge)) < 0) - return -1; - - dest->key_length = src->key_length; - dest->leftover = src->leftover; - - size = (src->key_length + 7) >> 3; - dest->key_opad = malloc(2 * size); - if (dest->key_opad == NULL) - return saved_errno = errno, libkeccak_state_destroy(&(dest->sponge)), errno = saved_errno, -1; - dest->key_ipad = dest->key_opad + size / sizeof(char); - - memcpy(dest->key_opad, src->key_opad, size); - memcpy(dest->key_ipad, src->key_ipad, size); - - return 0; + size_t size; + + dest->key_opad = NULL; + dest->key_ipad = NULL; + + if (libkeccak_state_copy(&dest->sponge, &src->sponge) < 0) + return -1; + + dest->key_length = src->key_length; + dest->leftover = src->leftover; + + size = (src->key_length + 7) >> 3; + dest->key_opad = malloc(2 * size); + if (dest->key_opad == NULL) + return libkeccak_state_destroy(&dest->sponge), -1; + dest->key_ipad = dest->key_opad + size / sizeof(char); + + memcpy(dest->key_opad, src->key_opad, size); + memcpy(dest->key_ipad, src->key_ipad, size); + + return 0; } @@ -145,42 +130,41 @@ int libkeccak_hmac_copy(libkeccak_hmac_state_t* restrict dest, const libkeccak_h * @param data The input buffer * @return The number of bytes read from `data`, 0 on error */ -size_t libkeccak_hmac_unmarshal(libkeccak_hmac_state_t* restrict state, const char* restrict data) +size_t +libkeccak_hmac_unmarshal(libkeccak_hmac_state_t *restrict state, const char *restrict data) { - size_t parsed, size, i; - int saved_errno; - - state->key_opad = NULL; - state->key_ipad = NULL; - - parsed = libkeccak_state_unmarshal(&(state->sponge), data); - if (parsed == 0) - return 0; - - data += parsed / sizeof(char); - state->key_length = *(const size_t*)data; - data += sizeof(size_t) / sizeof(char); - size = (state->key_length + 7) >> 3; - - state->key_opad = malloc(2 * size); - if (state->key_opad == NULL) - return saved_errno = errno, libkeccak_state_destroy(&(state->sponge)), errno = saved_errno, -1; - memcpy(state->key_opad, data, size); - data += size / sizeof(char); - - if (data[0]) - { - state->key_ipad = state->key_opad + size / sizeof(char); - memcpy(state->key_ipad, state->key_opad, size); - for (i = 0; i < size / sizeof(char); i++) - state->key_ipad[i] ^= (char)(OUTER_PAD ^ INNER_PAD); - } - - state->leftover = data[1]; - state->buffer = NULL; - state->buffer_size = 0; - - return parsed + sizeof(size_t) + size + 2 * sizeof(char); + size_t parsed, size, i; + + state->key_opad = NULL; + state->key_ipad = NULL; + + parsed = libkeccak_state_unmarshal(&state->sponge, data); + if (parsed == 0) + return 0; + + data += parsed / sizeof(char); + state->key_length = *(const size_t *)data; + data += sizeof(size_t) / sizeof(char); + size = (state->key_length + 7) >> 3; + + state->key_opad = malloc(2 * size); + if (state->key_opad == NULL) + return libkeccak_state_destroy(&state->sponge), -1; + memcpy(state->key_opad, data, size); + data += size / sizeof(char); + + if (data[0]) { + state->key_ipad = state->key_opad + size / sizeof(char); + memcpy(state->key_ipad, state->key_opad, size); + for (i = 0; i < size / sizeof(char); i++) + state->key_ipad[i] ^= (char)(OUTER_PAD ^ INNER_PAD); + } + + state->leftover = data[1]; + state->buffer = NULL; + state->buffer_size = 0; + + return parsed + sizeof(size_t) + size + 2 * sizeof(char); } @@ -193,42 +177,42 @@ size_t libkeccak_hmac_unmarshal(libkeccak_hmac_state_t* restrict state, const ch * @param msglen The length of the partial message, in bytes * @return Zero on success, -1 on error */ -int libkeccak_hmac_fast_update(libkeccak_hmac_state_t* restrict state, const char* restrict msg, size_t msglen) +int +libkeccak_hmac_fast_update(libkeccak_hmac_state_t *restrict state, const char *restrict msg, size_t msglen) { - char* old; - size_t i; - int n, cn; - - if (state->key_ipad != NULL) - { - if (libkeccak_fast_update(&(state->sponge), state->key_ipad, state->key_length >> 3) < 0) - return -1; - if (state->key_length & 7) - state->leftover = state->key_ipad[(state->key_length >> 3)]; - state->key_ipad = NULL; - } - - if ((msg == NULL) || (msglen == 0)) - return 0; - - if (!(state->key_length & 7)) - return libkeccak_fast_update(&(state->sponge), msg, msglen); - - if (msglen != state->buffer_size) - { - state->buffer = realloc(old = state->buffer, state->buffer_size = msglen); - if (state->buffer == NULL) - return state->buffer = old, -1; - } - - n = (int)(state->key_length & 7); - cn = 8 - n; - for (i = 1; i < msglen; i++) - state->buffer[i] = (((unsigned char)(msg[i - 1])) >> cn) | (msg[i] << n); - state->buffer[0] = (state->leftover & ((1 << n) - 1)) | (msg[0] << n); - state->leftover = ((unsigned char)(msg[msglen - 1])) >> cn; - - return libkeccak_fast_update(&(state->sponge), state->buffer, msglen); + char *old; + size_t i; + int n, cn; + + if (state->key_ipad) { + if (libkeccak_fast_update(&state->sponge, state->key_ipad, state->key_length >> 3) < 0) + return -1; + if (state->key_length & 7) + state->leftover = state->key_ipad[state->key_length >> 3]; + state->key_ipad = NULL; + } + + if (!msg || !msglen) + return 0; + + if (!(state->key_length & 7)) + return libkeccak_fast_update(&state->sponge, msg, msglen); + + if (msglen != state->buffer_size) { + state->buffer = realloc(old = state->buffer, msglen); + if (!state->buffer) + return state->buffer = old, -1; + state->buffer_size = msglen; + } + + n = (int)(state->key_length & 7); + cn = 8 - n; + for (i = 1; i < msglen; i++) + state->buffer[i] = (((unsigned char)(msg[i - 1])) >> cn) | (msg[i] << n); + state->buffer[0] = (state->leftover & ((1 << n) - 1)) | (msg[0] << n); + state->leftover = ((unsigned char)(msg[msglen - 1])) >> cn; + + return libkeccak_fast_update(&state->sponge, state->buffer, msglen); } @@ -241,46 +225,43 @@ int libkeccak_hmac_fast_update(libkeccak_hmac_state_t* restrict state, const cha * @param msglen The length of the partial message, in bytes * @return Zero on success, -1 on error */ -int libkeccak_hmac_update(libkeccak_hmac_state_t* restrict state, const char* restrict msg, size_t msglen) +int +libkeccak_hmac_update(libkeccak_hmac_state_t *restrict state, const char *restrict msg, size_t msglen) { - size_t i; - int n, cn, r, saved_errno; - - if (state->key_ipad != NULL) - { - if (libkeccak_update(&(state->sponge), state->key_ipad, state->key_length >> 3) < 0) - return -1; - if (state->key_length & 7) - state->leftover = state->key_ipad[(state->key_length >> 3)]; - state->key_ipad = NULL; - } - - if ((msg == NULL) || (msglen == 0)) - return 0; - - if (!(state->key_length & 7)) - return libkeccak_update(&(state->sponge), msg, msglen); - - if (msglen != state->buffer_size) - { - free(state->buffer); - state->buffer = malloc(state->buffer_size = msglen); - if (state->buffer == NULL) - return -1; - } - - n = (int)(state->key_length & 7); - cn = 8 - n; - for (i = 1; i < msglen; i++) - state->buffer[i] = (((unsigned char)(msg[i - 1])) >> cn) | (msg[i] << n); - state->buffer[0] = (state->leftover & ((1 << n) - 1)) | (msg[0] << n); - state->leftover = ((unsigned char)(msg[msglen - 1])) >> cn; - - r = libkeccak_update(&(state->sponge), state->buffer, msglen); - saved_errno = errno; - my_explicit_bzero(state->buffer, msglen); - errno = saved_errno; - return r; + size_t i; + int n, cn, r; + + if (state->key_ipad) { + if (libkeccak_update(&state->sponge, state->key_ipad, state->key_length >> 3) < 0) + return -1; + if (state->key_length & 7) + state->leftover = state->key_ipad[state->key_length >> 3]; + state->key_ipad = NULL; + } + + if (!msg || !msglen) + return 0; + + if (!(state->key_length & 7)) + return libkeccak_update(&state->sponge, msg, msglen); + + if (msglen != state->buffer_size) { + free(state->buffer); + state->buffer = malloc(state->buffer_size = msglen); + if (!state->buffer) + return -1; + } + + n = (int)(state->key_length & 7); + cn = 8 - n; + for (i = 1; i < msglen; i++) + state->buffer[i] = (((unsigned char)(msg[i - 1])) >> cn) | (msg[i] << n); + state->buffer[0] = (state->leftover & ((1 << n) - 1)) | (msg[0] << n); + state->leftover = ((unsigned char)(msg[msglen - 1])) >> cn; + + r = libkeccak_update(&state->sponge, state->buffer, msglen); + my_explicit_bzero(state->buffer, msglen); + return r; } @@ -288,7 +269,7 @@ int libkeccak_hmac_update(libkeccak_hmac_state_t* restrict state, const char* re * Absorb the last part of the message and fetch the hash * without wiping sensitive data when possible * - * You may use `&(state->sponge)` for continued squeezing + * You may use `&state->sponge` for continued squeezing * * @param state The hashing state * @param msg The rest of the message, may be `NULL`, may be modified @@ -298,71 +279,64 @@ int libkeccak_hmac_update(libkeccak_hmac_state_t* restrict state, const char* re * @param hashsum Output parameter for the hashsum, may be `NULL` * @return Zero on success, -1 on error */ -int libkeccak_hmac_fast_digest(libkeccak_hmac_state_t* restrict state, const char* restrict msg, size_t msglen, - size_t bits, const char* restrict suffix, char* restrict hashsum) +int +libkeccak_hmac_fast_digest(libkeccak_hmac_state_t *restrict state, const char *restrict msg, size_t msglen, + size_t bits, const char *restrict suffix, char *restrict hashsum) { - size_t hashsize = state->sponge.n >> 3; - char* tmp = malloc(((state->sponge.n + 7) >> 3) * sizeof(char)); - char leftover[2]; - size_t newlen; - int saved_errno; - - if (tmp == NULL) - return -1; - - if (!(state->key_length & 7)) - { - if (libkeccak_fast_digest(&(state->sponge), msg, msglen, bits, suffix, tmp) < 0) - goto fail; - goto stage_2; - } - - if (libkeccak_hmac_fast_update(state, msg, msglen) < 0) - goto fail; - leftover[0] = state->leftover; - if (bits) - { - leftover[0] |= msg[msglen] >> (state->key_length & 7); - leftover[1] = ((unsigned char)(msg[msglen])) << (8 - (state->key_length & 7)); - } - newlen = (state->key_length & 7) + bits; - if (libkeccak_fast_digest(&(state->sponge), leftover, newlen >> 3, newlen & 7, suffix, tmp) < 0) - goto fail; - - stage_2: - - bits = state->sponge.n & 7; - state->key_ipad = state->key_opad; - if (libkeccak_hmac_fast_update(state, NULL, 0) < 0) - goto fail; - - if (!(state->key_length & 7)) - { - if (libkeccak_fast_digest(&(state->sponge), tmp, hashsize, bits, suffix, hashsum) < 0) - goto fail; - goto stage_3; - } - - if (libkeccak_hmac_fast_update(state, tmp, hashsize) < 0) - goto fail; - leftover[0] = state->leftover; - if (bits) - { - leftover[0] |= tmp[hashsize] >> (state->key_length & 7); - leftover[1] = ((unsigned char)(tmp[hashsize])) << (8 - (state->key_length & 7)); - } - newlen = (state->key_length & 7) + bits; - if (libkeccak_fast_digest(&(state->sponge), leftover, newlen >> 3, newlen & 7, suffix, tmp) < 0) - goto fail; - - stage_3: - - free(tmp); - return 0; - fail: - saved_errno = errno; - free(tmp); - return errno = saved_errno, -1; + size_t hashsize = state->sponge.n >> 3; + char *tmp = malloc(((state->sponge.n + 7) >> 3) * sizeof(char)); + char leftover[2]; + size_t newlen; + + if (!tmp) + return -1; + + if (!(state->key_length & 7)) { + if (libkeccak_fast_digest(&state->sponge, msg, msglen, bits, suffix, tmp) < 0) + goto fail; + goto stage_2; + } + + if (libkeccak_hmac_fast_update(state, msg, msglen) < 0) + goto fail; + leftover[0] = state->leftover; + if (bits) { + leftover[0] |= msg[msglen] >> (state->key_length & 7); + leftover[1] = ((unsigned char)(msg[msglen])) << (8 - (state->key_length & 7)); + } + newlen = (state->key_length & 7) + bits; + if (libkeccak_fast_digest(&state->sponge, leftover, newlen >> 3, newlen & 7, suffix, tmp) < 0) + goto fail; + +stage_2: + bits = state->sponge.n & 7; + state->key_ipad = state->key_opad; + if (libkeccak_hmac_fast_update(state, NULL, 0) < 0) + goto fail; + + if (!(state->key_length & 7)) { + if (libkeccak_fast_digest(&state->sponge, tmp, hashsize, bits, suffix, hashsum) < 0) + goto fail; + goto stage_3; + } + + if (libkeccak_hmac_fast_update(state, tmp, hashsize) < 0) + goto fail; + leftover[0] = state->leftover; + if (bits) { + leftover[0] |= tmp[hashsize] >> (state->key_length & 7); + leftover[1] = ((unsigned char)(tmp[hashsize])) << (8 - (state->key_length & 7)); + } + newlen = (state->key_length & 7) + bits; + if (libkeccak_fast_digest(&state->sponge, leftover, newlen >> 3, newlen & 7, suffix, tmp) < 0) + goto fail; + +stage_3: + free(tmp); + return 0; +fail: + free(tmp); + return -1; } @@ -370,7 +344,7 @@ int libkeccak_hmac_fast_digest(libkeccak_hmac_state_t* restrict state, const cha * Absorb the last part of the message and fetch the hash * and wipe sensitive data when possible * - * You may use `&(state->sponge)` for continued squeezing + * You may use `&state->sponge` for continued squeezing * * @param state The hashing state * @param msg The rest of the message, may be `NULL`, may be modified @@ -380,71 +354,65 @@ int libkeccak_hmac_fast_digest(libkeccak_hmac_state_t* restrict state, const cha * @param hashsum Output parameter for the hashsum, may be `NULL` * @return Zero on success, -1 on error */ -int libkeccak_hmac_digest(libkeccak_hmac_state_t* restrict state, const char* restrict msg, size_t msglen, - size_t bits, const char* restrict suffix, char* restrict hashsum) +int +libkeccak_hmac_digest(libkeccak_hmac_state_t *restrict state, const char *restrict msg, size_t msglen, + size_t bits, const char *restrict suffix, char *restrict hashsum) { - size_t hashsize = state->sponge.n >> 3; - char* tmp = malloc(((state->sponge.n + 7) >> 3) * sizeof(char)); - char leftover[2]; - size_t newlen; - int saved_errno; - - if (tmp == NULL) - return -1; - - if (!(state->key_length & 7)) - { - if (libkeccak_digest(&(state->sponge), msg, msglen, bits, suffix, tmp) < 0) - goto fail; - goto stage_2; - } - - if (libkeccak_hmac_update(state, msg, msglen) < 0) - goto fail; - leftover[0] = state->leftover; - if (bits) - { - leftover[0] |= msg[msglen] >> (state->key_length & 7); - leftover[1] = ((unsigned char)(msg[msglen])) << (8 - (state->key_length & 7)); - } - newlen = (state->key_length & 7) + bits; - if (libkeccak_digest(&(state->sponge), leftover, newlen >> 3, newlen & 7, suffix, tmp) < 0) - goto fail; - - stage_2: - - bits = state->sponge.n & 7; - state->key_ipad = state->key_opad; - if (libkeccak_hmac_update(state, NULL, 0) < 0) - goto fail; - - if (!(state->key_length & 7)) - { - if (libkeccak_digest(&(state->sponge), tmp, hashsize, bits, suffix, hashsum) < 0) - goto fail; - goto stage_3; - } - - if (libkeccak_hmac_update(state, tmp, hashsize) < 0) - goto fail; - leftover[0] = state->leftover; - if (bits) - { - leftover[0] |= tmp[hashsize] >> (state->key_length & 7); - leftover[1] = ((unsigned char)(tmp[hashsize])) << (8 - (state->key_length & 7)); - } - newlen = (state->key_length & 7) + bits; - if (libkeccak_digest(&(state->sponge), leftover, newlen >> 3, newlen & 7, suffix, tmp) < 0) - goto fail; - - stage_3: - my_explicit_bzero(tmp, ((state->sponge.n + 7) >> 3) * sizeof(char)); - free(tmp); - return 0; + size_t hashsize = state->sponge.n >> 3; + char *tmp = malloc(((state->sponge.n + 7) >> 3) * sizeof(char)); + char leftover[2]; + size_t newlen; + + if (!tmp) + return -1; + + if (!(state->key_length & 7)) { + if (libkeccak_digest(&state->sponge, msg, msglen, bits, suffix, tmp) < 0) + goto fail; + goto stage_2; + } + + if (libkeccak_hmac_update(state, msg, msglen) < 0) + goto fail; + leftover[0] = state->leftover; + if (bits) { + leftover[0] |= msg[msglen] >> (state->key_length & 7); + leftover[1] = ((unsigned char)(msg[msglen])) << (8 - (state->key_length & 7)); + } + newlen = (state->key_length & 7) + bits; + if (libkeccak_digest(&state->sponge, leftover, newlen >> 3, newlen & 7, suffix, tmp) < 0) + goto fail; + +stage_2: + bits = state->sponge.n & 7; + state->key_ipad = state->key_opad; + if (libkeccak_hmac_update(state, NULL, 0) < 0) + goto fail; + + if (!(state->key_length & 7)) { + if (libkeccak_digest(&state->sponge, tmp, hashsize, bits, suffix, hashsum) < 0) + goto fail; + goto stage_3; + } + + if (libkeccak_hmac_update(state, tmp, hashsize) < 0) + goto fail; + leftover[0] = state->leftover; + if (bits) { + leftover[0] |= tmp[hashsize] >> (state->key_length & 7); + leftover[1] = ((unsigned char)(tmp[hashsize])) << (8 - (state->key_length & 7)); + } + newlen = (state->key_length & 7) + bits; + if (libkeccak_digest(&state->sponge, leftover, newlen >> 3, newlen & 7, suffix, tmp) < 0) + goto fail; + +stage_3: + my_explicit_bzero(tmp, ((state->sponge.n + 7) >> 3) * sizeof(char)); + free(tmp); + return 0; fail: - saved_errno = errno; - my_explicit_bzero(tmp, ((state->sponge.n + 7) >> 3) * sizeof(char)); - free(tmp); - return errno = saved_errno, -1; + my_explicit_bzero(tmp, ((state->sponge.n + 7) >> 3) * sizeof(char)); + free(tmp); + return -1; } diff --git a/src/libkeccak/mac/hmac.h b/src/libkeccak/mac/hmac.h index 0b3a29c..2681e61 100644 --- a/src/libkeccak/mac/hmac.h +++ b/src/libkeccak/mac/hmac.h @@ -1,31 +1,13 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #ifndef LIBKECCAK_MAC_HMAC_H -#define LIBKECCAK_MAC_HMAC_H 1 - +#define LIBKECCAK_MAC_HMAC_H 1 -/* The Keccak hash-function, that was selected by NIST as the SHA-3 competition winner, +/* + * The Keccak hash-function, that was selected by NIST as the SHA-3 competition winner, * doesn't need this nested approach and can be used to generate a MAC by simply prepending * the key to the message. [http://keccak.noekeon.org] */ - #include "../spec.h" #include "../state.h" #include "../internal.h" @@ -43,46 +25,46 @@ */ typedef struct libkeccak_hmac_state { - /** - * The key right-padded and XOR:ed with the outer pad - */ - char* restrict key_opad; - - /** - * The key right-padded and XOR:ed with the inner pad - */ - char* restrict key_ipad; - /* Not marshalled, implicitly unmarshalled using `key_opad`. */ - /* Shares allocation with `key_opad`, do not `free`. */ - - /** - * The length of key, but at least the input block size, in bits - */ - size_t key_length; - - /** - * The state of the underlaying hash-algorithm - */ - libkeccak_state_t sponge; - - /** - * Buffer used to temporarily store bit shift message if - * `.key_length` is not zero modulus 8 - */ - char* restrict buffer; - - /** - * The allocation size of `.buffer` - */ - size_t buffer_size; - - /** - * Part of feed key, message or digest that have not been passed yet - */ - char leftover; - - char __pad[sizeof(void*) / sizeof(char) - 1]; - + /** + * The key right-padded and XOR:ed with the outer pad + */ + char *restrict key_opad; + + /** + * The key right-padded and XOR:ed with the inner pad + */ + char *restrict key_ipad; + /* Not marshalled, implicitly unmarshalled using `key_opad`. */ + /* Shares allocation with `key_opad`, do not `free`. */ + + /** + * The length of key, but at least the input block size, in bits + */ + size_t key_length; + + /** + * The state of the underlaying hash-algorithm + */ + libkeccak_state_t sponge; + + /** + * Buffer used to temporarily store bit shift message if + * `.key_length` is not zero modulus 8 + */ + char *restrict buffer; + + /** + * The allocation size of `.buffer` + */ + size_t buffer_size; + + /** + * Part of feed key, message or digest that have not been passed yet + */ + char leftover; + + char __pad[sizeof(void*) / sizeof(char) - 1]; + } libkeccak_hmac_state_t; @@ -96,7 +78,7 @@ typedef struct libkeccak_hmac_state * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(1), unused))) -int libkeccak_hmac_set_key(libkeccak_hmac_state_t* restrict state, const char* restrict key, size_t key_length); +int libkeccak_hmac_set_key(libkeccak_hmac_state_t *restrict state, const char *restrict key, size_t key_length); /** @@ -109,19 +91,18 @@ int libkeccak_hmac_set_key(libkeccak_hmac_state_t* restrict state, const char* r * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull))) -static inline -int libkeccak_hmac_initialise(libkeccak_hmac_state_t* restrict state, const libkeccak_spec_t* restrict spec, - const char* restrict key, size_t key_length) +static inline int +libkeccak_hmac_initialise(libkeccak_hmac_state_t *restrict state, const libkeccak_spec_t *restrict spec, + const char *restrict key, size_t key_length) { - int saved_errno; - if (libkeccak_state_initialise(&(state->sponge), spec) < 0) - return -1; - if (libkeccak_hmac_set_key(state, key, key_length) < 0) - return saved_errno = errno, libkeccak_state_destroy(&(state->sponge)), errno = saved_errno, -1; - state->leftover = 0; - state->buffer = NULL; - state->buffer_size = 0; - return 0; + if (libkeccak_state_initialise(&state->sponge, spec) < 0) + return -1; + if (libkeccak_hmac_set_key(state, key, key_length) < 0) + return libkeccak_state_destroy(&state->sponge), -1; + state->leftover = 0; + state->buffer = NULL; + state->buffer_size = 0; + return 0; } @@ -134,15 +115,14 @@ int libkeccak_hmac_initialise(libkeccak_hmac_state_t* restrict state, const libk * @return The state, `NULL` on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, unused, warn_unused_result, malloc))) -static inline -libkeccak_hmac_state_t* libkeccak_hmac_create(const libkeccak_spec_t* restrict spec, - const char* restrict key, size_t key_length) +static inline libkeccak_hmac_state_t * +libkeccak_hmac_create(const libkeccak_spec_t *restrict spec, + const char *restrict key, size_t key_length) { - libkeccak_hmac_state_t* restrict state = malloc(sizeof(libkeccak_hmac_state_t)); - int saved_errno; - if ((state == NULL) || libkeccak_hmac_initialise(state, spec, key, key_length)) - return saved_errno = errno, free(state), errno = saved_errno, NULL; - return state; + libkeccak_hmac_state_t *restrict state = malloc(sizeof(libkeccak_hmac_state_t)); + if (!state || libkeccak_hmac_initialise(state, spec, key, key_length)) + return free(state), NULL; + return state; } @@ -156,11 +136,11 @@ libkeccak_hmac_state_t* libkeccak_hmac_create(const libkeccak_spec_t* restrict s * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(1), unused))) -static inline -int libkeccak_hmac_reset(libkeccak_hmac_state_t* restrict state, const char* restrict key, size_t key_length) +static inline int +libkeccak_hmac_reset(libkeccak_hmac_state_t *restrict state, const char *restrict key, size_t key_length) { - libkeccak_state_reset(&(state->sponge)); - return key != NULL ? libkeccak_hmac_set_key(state, key, key_length) : 0; + libkeccak_state_reset(&state->sponge); + return key ? libkeccak_hmac_set_key(state, key, key_length) : 0; } @@ -170,7 +150,7 @@ int libkeccak_hmac_reset(libkeccak_hmac_state_t* restrict state, const char* res * @param state The state that should be wipe */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow, optimize("-O0")))) -void libkeccak_hmac_wipe(volatile libkeccak_hmac_state_t* restrict state); +void libkeccak_hmac_wipe(volatile libkeccak_hmac_state_t *restrict state); /** @@ -178,18 +158,18 @@ void libkeccak_hmac_wipe(volatile libkeccak_hmac_state_t* restrict state); * * @param state The state that should be destroyed */ -static inline -void libkeccak_hmac_fast_destroy(libkeccak_hmac_state_t* restrict state) +static inline void +libkeccak_hmac_fast_destroy(libkeccak_hmac_state_t *restrict state) { - if (state == NULL) - return; - free(state->key_opad); - state->key_opad = NULL; - state->key_ipad = NULL; - state->key_length = 0; - free(state->buffer); - state->buffer = NULL; - state->buffer_size = 0; + if (!state) + return; + free(state->key_opad); + state->key_opad = NULL; + state->key_ipad = NULL; + state->key_length = 0; + free(state->buffer); + state->buffer = NULL; + state->buffer_size = 0; } @@ -199,20 +179,20 @@ void libkeccak_hmac_fast_destroy(libkeccak_hmac_state_t* restrict state) * @param state The state that should be destroyed */ LIBKECCAK_GCC_ONLY(__attribute__((unused, optimize("-O0")))) -static inline -void libkeccak_hmac_destroy(volatile libkeccak_hmac_state_t* restrict state) +static inline void +libkeccak_hmac_destroy(volatile libkeccak_hmac_state_t *restrict state) { - if (state == NULL) - return; - libkeccak_hmac_wipe(state); - free(state->key_opad); - state->key_opad = NULL; - state->key_ipad = NULL; - state->key_length = 0; - state->leftover = 0; - free(state->buffer); - state->buffer = NULL; - state->buffer_size = 0; + if (!state) + return; + libkeccak_hmac_wipe(state); + free(state->key_opad); + state->key_opad = NULL; + state->key_ipad = NULL; + state->key_length = 0; + state->leftover = 0; + free(state->buffer); + state->buffer = NULL; + state->buffer_size = 0; } @@ -222,11 +202,11 @@ void libkeccak_hmac_destroy(volatile libkeccak_hmac_state_t* restrict state) * @param state The state that should be freed */ LIBKECCAK_GCC_ONLY(__attribute__((unused))) -static inline -void libkeccak_hmac_fast_free(libkeccak_hmac_state_t* restrict state) +static inline void +libkeccak_hmac_fast_free(libkeccak_hmac_state_t *restrict state) { - libkeccak_hmac_fast_destroy(state); - free(state); + libkeccak_hmac_fast_destroy(state); + free(state); } @@ -236,15 +216,15 @@ void libkeccak_hmac_fast_free(libkeccak_hmac_state_t* restrict state) * @param state The state that should be freed */ LIBKECCAK_GCC_ONLY(__attribute__((unused, optimize("-O0")))) -static inline -void libkeccak_hmac_free(volatile libkeccak_hmac_state_t* restrict state) +static inline void +libkeccak_hmac_free(volatile libkeccak_hmac_state_t *restrict state) { #ifdef __GNUC__ # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wcast-qual" #endif - libkeccak_hmac_destroy(state); - free((libkeccak_hmac_state_t*)state); + libkeccak_hmac_destroy(state); + free((libkeccak_hmac_state_t*)state); #ifdef __GNUC__ # pragma GCC diagnostic pop #endif @@ -259,7 +239,7 @@ void libkeccak_hmac_free(volatile libkeccak_hmac_state_t* restrict state) * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull))) -int libkeccak_hmac_copy(libkeccak_hmac_state_t* restrict dest, const libkeccak_hmac_state_t* restrict src); +int libkeccak_hmac_copy(libkeccak_hmac_state_t *restrict dest, const libkeccak_hmac_state_t *restrict src); /** @@ -269,14 +249,13 @@ int libkeccak_hmac_copy(libkeccak_hmac_state_t* restrict dest, const libkeccak_h * @return The duplicate, `NULL` on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, unused, warn_unused_result, malloc))) -static inline -libkeccak_hmac_state_t* libkeccak_hmac_duplicate(const libkeccak_hmac_state_t* restrict src) +static inline libkeccak_hmac_state_t * +libkeccak_hmac_duplicate(const libkeccak_hmac_state_t *restrict src) { - libkeccak_hmac_state_t* restrict dest = malloc(sizeof(libkeccak_hmac_state_t)); - int saved_errno; - if ((dest == NULL) || libkeccak_hmac_copy(dest, src)) - return saved_errno = errno, libkeccak_hmac_free(dest), errno = saved_errno, NULL; - return dest; + libkeccak_hmac_state_t* restrict dest = malloc(sizeof(libkeccak_hmac_state_t)); + if (!dest || libkeccak_hmac_copy(dest, src)) + return libkeccak_hmac_free(dest), NULL; + return dest; } @@ -288,11 +267,11 @@ libkeccak_hmac_state_t* libkeccak_hmac_duplicate(const libkeccak_hmac_state_t* r * @return The allocation size needed for the buffer to which the state will be marshalled */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow, unused, warn_unused_result, pure))) -static inline -size_t libkeccak_hmac_marshal_size(const libkeccak_hmac_state_t* restrict state) +static inline size_t +libkeccak_hmac_marshal_size(const libkeccak_hmac_state_t *restrict state) { - return libkeccak_state_marshal_size(&(state->sponge)) + sizeof(size_t) + - ((state->key_length + 7) >> 3) + 2 * sizeof(char); + return libkeccak_state_marshal_size(&state->sponge) + sizeof(size_t) + + ((state->key_length + 7) >> 3) + 2 * sizeof(char); } @@ -304,18 +283,18 @@ size_t libkeccak_hmac_marshal_size(const libkeccak_hmac_state_t* restrict state) * @return The number of bytes stored to `data` */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow))) -static inline -size_t libkeccak_hmac_marshal(const libkeccak_hmac_state_t* restrict state, char* restrict data) +static inline size_t +libkeccak_hmac_marshal(const libkeccak_hmac_state_t *restrict state, char *restrict data) { - size_t written = libkeccak_state_marshal(&(state->sponge), data); - data += written / sizeof(char); - *(size_t*)data = state->key_length; - data += sizeof(size_t) / sizeof(char); - memcpy(data, state->key_opad, (state->key_length + 7) >> 3); - data += ((state->key_length + 7) >> 3) / sizeof(char); - data[0] = (char)(state->key_ipad != NULL); - data[1] = state->leftover; - return written + sizeof(size_t) + ((state->key_length + 7) >> 3) + 2 * sizeof(char); + size_t written = libkeccak_state_marshal(&state->sponge, data); + data += written / sizeof(char); + *(size_t *)data = state->key_length; + data += sizeof(size_t) / sizeof(char); + memcpy(data, state->key_opad, (state->key_length + 7) >> 3); + data += ((state->key_length + 7) >> 3) / sizeof(char); + data[0] = (char)!!state->key_ipad; + data[1] = state->leftover; + return written + sizeof(size_t) + ((state->key_length + 7) >> 3) + 2 * sizeof(char); } @@ -327,7 +306,7 @@ size_t libkeccak_hmac_marshal(const libkeccak_hmac_state_t* restrict state, char * @return The number of bytes read from `data`, 0 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull))) -size_t libkeccak_hmac_unmarshal(libkeccak_hmac_state_t* restrict state, const char* restrict data); +size_t libkeccak_hmac_unmarshal(libkeccak_hmac_state_t *restrict state, const char *restrict data); /** @@ -338,12 +317,12 @@ size_t libkeccak_hmac_unmarshal(libkeccak_hmac_state_t* restrict state, const ch * @return The byte size of the stored state */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow, warn_unused_result, pure))) -static inline -size_t libkeccak_hmac_unmarshal_skip(const char* restrict data) +static inline size_t +libkeccak_hmac_unmarshal_skip(const char *restrict data) { - size_t skip = libkeccak_state_unmarshal_skip(data); - data += skip / sizeof(char); - return skip + sizeof(size_t) + *(const size_t*)data + 2 * sizeof(char); + size_t skip = libkeccak_state_unmarshal_skip(data); + data += skip / sizeof(char); + return skip + sizeof(size_t) + *(const size_t *)data + 2 * sizeof(char); } @@ -357,7 +336,7 @@ size_t libkeccak_hmac_unmarshal_skip(const char* restrict data) * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(1)))) -int libkeccak_hmac_fast_update(libkeccak_hmac_state_t* restrict state, const char* restrict msg, size_t msglen); +int libkeccak_hmac_fast_update(libkeccak_hmac_state_t *restrict state, const char *restrict msg, size_t msglen); /** @@ -370,14 +349,14 @@ int libkeccak_hmac_fast_update(libkeccak_hmac_state_t* restrict state, const cha * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(1)))) -int libkeccak_hmac_update(libkeccak_hmac_state_t* restrict state, const char* restrict msg, size_t msglen); +int libkeccak_hmac_update(libkeccak_hmac_state_t *restrict state, const char *restrict msg, size_t msglen); /** * Absorb the last part of the message and fetch the hash * without wiping sensitive data when possible * - * You may use `&(state->sponge)` for continued squeezing + * You may use `&state->sponge` for continued squeezing * * @param state The hashing state * @param msg The rest of the message, may be `NULL`, may be modified @@ -388,15 +367,15 @@ int libkeccak_hmac_update(libkeccak_hmac_state_t* restrict state, const char* re * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(1)))) -int libkeccak_hmac_fast_digest(libkeccak_hmac_state_t* restrict state, const char* restrict msg, size_t msglen, - size_t bits, const char* restrict suffix, char* restrict hashsum); +int libkeccak_hmac_fast_digest(libkeccak_hmac_state_t *restrict state, const char *restrict msg, size_t msglen, + size_t bits, const char *restrict suffix, char *restrict hashsum); /** * Absorb the last part of the message and fetch the hash * and wipe sensitive data when possible * - * You may use `&(state->sponge)` for continued squeezing + * You may use `&state->sponge` for continued squeezing * * @param state The hashing state * @param msg The rest of the message, may be `NULL`, may be modified @@ -407,9 +386,8 @@ int libkeccak_hmac_fast_digest(libkeccak_hmac_state_t* restrict state, const cha * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull(1)))) -int libkeccak_hmac_digest(libkeccak_hmac_state_t* restrict state, const char* restrict msg, size_t msglen, - size_t bits, const char* restrict suffix, char* restrict hashsum); +int libkeccak_hmac_digest(libkeccak_hmac_state_t *restrict state, const char *restrict msg, size_t msglen, + size_t bits, const char *restrict suffix, char *restrict hashsum); #endif - diff --git a/src/libkeccak/spec.h b/src/libkeccak/spec.h index 2f0b21b..8d73c52 100644 --- a/src/libkeccak/spec.h +++ b/src/libkeccak/spec.h @@ -1,24 +1,6 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #ifndef LIBKECCAK_SPEC_H -#define LIBKECCAK_SPEC_H 1 - +#define LIBKECCAK_SPEC_H 1 #include "internal.h" @@ -29,68 +11,68 @@ /** * Message suffix for SHA3 hashing */ -#define LIBKECCAK_SHA3_SUFFIX "01" +#define LIBKECCAK_SHA3_SUFFIX "01" /** * Message suffix for RawSHAKE hashing */ -#define LIBKECCAK_RAWSHAKE_SUFFIX "11" +#define LIBKECCAK_RAWSHAKE_SUFFIX "11" /** * Message suffix for SHAKE hashing */ -#define LIBKECCAK_SHAKE_SUFFIX "1111" +#define LIBKECCAK_SHAKE_SUFFIX "1111" /** * Invalid `libkeccak_spec_t.bitrate`: non-positive */ -#define LIBKECCAK_SPEC_ERROR_BITRATE_NONPOSITIVE 1 +#define LIBKECCAK_SPEC_ERROR_BITRATE_NONPOSITIVE 1 /** * Invalid `libkeccak_spec_t.bitrate`: not a multiple of 8 */ -#define LIBKECCAK_SPEC_ERROR_BITRATE_MOD_8 2 +#define LIBKECCAK_SPEC_ERROR_BITRATE_MOD_8 2 /** * Invalid `libkeccak_spec_t.capacity`: non-positive */ -#define LIBKECCAK_SPEC_ERROR_CAPACITY_NONPOSITIVE 3 +#define LIBKECCAK_SPEC_ERROR_CAPACITY_NONPOSITIVE 3 /** * Invalid `libkeccak_spec_t.capacity`: not a multiple of 8 */ -#define LIBKECCAK_SPEC_ERROR_CAPACITY_MOD_8 4 +#define LIBKECCAK_SPEC_ERROR_CAPACITY_MOD_8 4 /** * Invalid `libkeccak_spec_t.output`: non-positive */ -#define LIBKECCAK_SPEC_ERROR_OUTPUT_NONPOSITIVE 5 +#define LIBKECCAK_SPEC_ERROR_OUTPUT_NONPOSITIVE 5 /** * Invalid `libkeccak_spec_t` values: `.bitrate + `.capacity` * is greater 1600 which is the largest supported state size */ -#define LIBKECCAK_SPEC_ERROR_STATE_TOO_LARGE 6 +#define LIBKECCAK_SPEC_ERROR_STATE_TOO_LARGE 6 /** * Invalid `libkeccak_spec_t` values: * `.bitrate + `.capacity` is not a multiple of 25 */ -#define LIBKECCAK_SPEC_ERROR_STATE_MOD_25 7 +#define LIBKECCAK_SPEC_ERROR_STATE_MOD_25 7 /** * Invalid `libkeccak_spec_t` values: `.bitrate + `.capacity` * is a not a 2-potent multiple of 25 */ -#define LIBKECCAK_SPEC_ERROR_WORD_NON_2_POTENT 8 +#define LIBKECCAK_SPEC_ERROR_WORD_NON_2_POTENT 8 /** * Invalid `libkeccak_spec_t` values: `.bitrate + `.capacity` * is a not multiple of 100, and thus the word size is not * a multiple of 8 */ -#define LIBKECCAK_SPEC_ERROR_WORD_MOD_8 9 +#define LIBKECCAK_SPEC_ERROR_WORD_MOD_8 9 @@ -98,23 +80,22 @@ * Datastructure that describes the parameters * that should be used when hashing */ -typedef struct libkeccak_spec -{ - /** - * The bitrate - */ - long bitrate; - - /** - * The capacity - */ - long capacity; - - /** - * The output size - */ - long output; - +typedef struct libkeccak_spec { + /** + * The bitrate + */ + long bitrate; + + /** + * The capacity + */ + long capacity; + + /** + * The output size + */ + long output; + } libkeccak_spec_t; @@ -126,12 +107,12 @@ typedef struct libkeccak_spec * @param x The value of x in `SHA3-x`, the output size */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow))) -static inline -void libkeccak_spec_sha3(libkeccak_spec_t* restrict spec, long x) +static inline void +libkeccak_spec_sha3(libkeccak_spec_t *restrict spec, long x) { - spec->bitrate = 1600 - 2 * x; - spec->capacity = 2 * x; - spec->output = x; + spec->bitrate = 1600 - 2 * x; + spec->capacity = 2 * x; + spec->output = x; } @@ -143,12 +124,12 @@ void libkeccak_spec_sha3(libkeccak_spec_t* restrict spec, long x) * @param d The output size */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow))) -static inline -void libkeccak_spec_rawshake(libkeccak_spec_t* restrict spec, long x, long d) +static inline void +libkeccak_spec_rawshake(libkeccak_spec_t *restrict spec, long x, long d) { - spec->bitrate = 1600 - 2 * x; - spec->capacity = 2 * x; - spec->output = d; + spec->bitrate = 1600 - 2 * x; + spec->capacity = 2 * x; + spec->output = d; } @@ -159,7 +140,7 @@ void libkeccak_spec_rawshake(libkeccak_spec_t* restrict spec, long x, long d) * @param x:long The value of x in `SHAKEx`, half the capacity * @param d:long The output size */ -#define libkeccak_spec_shake libkeccak_spec_rawshake +#define libkeccak_spec_shake libkeccak_spec_rawshake /** @@ -169,30 +150,28 @@ void libkeccak_spec_rawshake(libkeccak_spec_t* restrict spec, long x, long d) * @return Zero if error free, a `LIBKECCAK_SPEC_ERROR_*` if an error was found */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow, unused, warn_unused_result, pure))) -static inline -int libkeccak_spec_check(const libkeccak_spec_t* restrict spec) +static inline int +libkeccak_spec_check(const libkeccak_spec_t *restrict spec) { - long state_size = spec->capacity + spec->bitrate; - int32_t word_size = (int32_t)(state_size / 25); - if (spec->bitrate <= 0) return LIBKECCAK_SPEC_ERROR_BITRATE_NONPOSITIVE; - if (spec->bitrate % 8) return LIBKECCAK_SPEC_ERROR_BITRATE_MOD_8; - if (spec->capacity <= 0) return LIBKECCAK_SPEC_ERROR_CAPACITY_NONPOSITIVE; - if (spec->capacity % 8) return LIBKECCAK_SPEC_ERROR_CAPACITY_MOD_8; - if (spec->output <= 0) return LIBKECCAK_SPEC_ERROR_OUTPUT_NONPOSITIVE; - if (state_size > 1600) return LIBKECCAK_SPEC_ERROR_STATE_TOO_LARGE; - if (state_size % 25) return LIBKECCAK_SPEC_ERROR_STATE_MOD_25; - if (word_size % 8) return LIBKECCAK_SPEC_ERROR_WORD_MOD_8; - - /* `(x & -x) != x` assumes two's complement, which of course is always - * satisfied by GCC, however C99 guarantees that `int32_t` exists, - * and it is basically the same thing as `long int`; with one important - * difference: it is guaranteed to use two's complement. */ - if ((word_size & -word_size) != word_size) - return LIBKECCAK_SPEC_ERROR_WORD_NON_2_POTENT; - - return 0; + long state_size = spec->capacity + spec->bitrate; + int32_t word_size = (int32_t)(state_size / 25); + if (spec->bitrate <= 0) return LIBKECCAK_SPEC_ERROR_BITRATE_NONPOSITIVE; + if (spec->bitrate % 8) return LIBKECCAK_SPEC_ERROR_BITRATE_MOD_8; + if (spec->capacity <= 0) return LIBKECCAK_SPEC_ERROR_CAPACITY_NONPOSITIVE; + if (spec->capacity % 8) return LIBKECCAK_SPEC_ERROR_CAPACITY_MOD_8; + if (spec->output <= 0) return LIBKECCAK_SPEC_ERROR_OUTPUT_NONPOSITIVE; + if (state_size > 1600) return LIBKECCAK_SPEC_ERROR_STATE_TOO_LARGE; + if (state_size % 25) return LIBKECCAK_SPEC_ERROR_STATE_MOD_25; + if (word_size % 8) return LIBKECCAK_SPEC_ERROR_WORD_MOD_8; + + /* `(x & -x) != x` assumes two's complement, which of course is always + * satisfied by GCC, however C99 guarantees that `int32_t` exists, + * and it is basically the same thing as `long int`; with one important + * difference: it is guaranteed to use two's complement. */ + if ((word_size & -word_size) != word_size) + return LIBKECCAK_SPEC_ERROR_WORD_NON_2_POTENT; + + return 0; } - #endif - diff --git a/src/libkeccak/state.c b/src/libkeccak/state.c index 5eec52c..c6360b7 100644 --- a/src/libkeccak/state.c +++ b/src/libkeccak/state.c @@ -1,21 +1,4 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #include "state.h" #include <string.h> @@ -29,26 +12,27 @@ * @param spec The specifications for the state * @return Zero on success, -1 on error */ -int libkeccak_state_initialise(libkeccak_state_t* restrict state, const libkeccak_spec_t* restrict spec) +int +libkeccak_state_initialise(libkeccak_state_t *restrict state, const libkeccak_spec_t *restrict spec) { - long x; - state->r = spec->bitrate; - state->n = spec->output; - state->c = spec->capacity; - state->b = state->r + state->c; - state->w = x = state->b / 25; - state->l = 0; - if (x & 0xF0L) state->l |= 4, x >>= 4; - if (x & 0x0CL) state->l |= 2, x >>= 2; - if (x & 0x02L) state->l |= 1; - state->nr = 12 + (state->l << 1); - state->wmod = (state->w == 64) ? ~0LL : (int64_t)((1ULL << state->w) - 1); - for (x = 0; x < 25; x++) - state->S[x] = 0; - state->mptr = 0; - state->mlen = (size_t)(state->r * state->b) >> 2; - state->M = malloc(state->mlen * sizeof(char)); - return state->M == NULL ? -1 : 0; + long x; + state->r = spec->bitrate; + state->n = spec->output; + state->c = spec->capacity; + state->b = state->r + state->c; + state->w = x = state->b / 25; + state->l = 0; + if (x & 0xF0L) state->l |= 4, x >>= 4; + if (x & 0x0CL) state->l |= 2, x >>= 2; + if (x & 0x02L) state->l |= 1; + state->nr = 12 + (state->l << 1); + state->wmod = (state->w == 64) ? ~0LL : (int64_t)((1ULL << state->w) - 1); + for (x = 0; x < 25; x++) + state->S[x] = 0; + state->mptr = 0; + state->mlen = (size_t)(state->r * state->b) >> 2; + state->M = malloc(state->mlen * sizeof(char)); + return state->M == NULL ? -1 : 0; } @@ -57,12 +41,13 @@ int libkeccak_state_initialise(libkeccak_state_t* restrict state, const libkecca * * @param state The state that should be wipe */ -void libkeccak_state_wipe_message(volatile libkeccak_state_t* restrict state) +void +libkeccak_state_wipe_message(volatile libkeccak_state_t *restrict state) { - volatile char* restrict M = state->M; - size_t i; - for (i = 0; i < state->mptr; i++) - M[i] = 0; + volatile char *restrict M = state->M; + size_t i; + for (i = 0; i < state->mptr; i++) + M[i] = 0; } /** @@ -70,12 +55,13 @@ void libkeccak_state_wipe_message(volatile libkeccak_state_t* restrict state) * * @param state The state that should be wipe */ -void libkeccak_state_wipe_sponge(volatile libkeccak_state_t* restrict state) +void +libkeccak_state_wipe_sponge(volatile libkeccak_state_t *restrict state) { - volatile int64_t* restrict S = state->S; - size_t i; - for (i = 0; i < 25; i++) - S[i] = 0; + volatile int64_t *restrict S = state->S; + size_t i; + for (i = 0; i < 25; i++) + S[i] = 0; } /** @@ -83,10 +69,11 @@ void libkeccak_state_wipe_sponge(volatile libkeccak_state_t* restrict state) * * @param state The state that should be wipe */ -void libkeccak_state_wipe(volatile libkeccak_state_t* restrict state) +void +libkeccak_state_wipe(volatile libkeccak_state_t *restrict state) { - libkeccak_state_wipe_message(state); - libkeccak_state_wipe_sponge(state); + libkeccak_state_wipe_message(state); + libkeccak_state_wipe_sponge(state); } @@ -97,14 +84,15 @@ void libkeccak_state_wipe(volatile libkeccak_state_t* restrict state) * @param src The state to duplicate * @return Zero on success, -1 on error */ -int libkeccak_state_copy(libkeccak_state_t* restrict dest, const libkeccak_state_t* restrict src) +int +libkeccak_state_copy(libkeccak_state_t *restrict dest, const libkeccak_state_t *restrict src) { - memcpy(dest, src, sizeof(libkeccak_state_t)); - dest->M = malloc(src->mlen * sizeof(char)); - if (dest->M == NULL) - return -1; - memcpy(dest->M, src->M, src->mptr * sizeof(char)); - return 0; + memcpy(dest, src, sizeof(libkeccak_state_t)); + dest->M = malloc(src->mlen * sizeof(char)); + if (!dest->M) + return -1; + memcpy(dest->M, src->M, src->mptr * sizeof(char)); + return 0; } @@ -115,24 +103,25 @@ int libkeccak_state_copy(libkeccak_state_t* restrict dest, const libkeccak_state * @param data The output buffer * @return The number of bytes stored to `data` */ -size_t libkeccak_state_marshal(const libkeccak_state_t* restrict state, char* restrict data) +size_t +libkeccak_state_marshal(const libkeccak_state_t *restrict state, char *restrict data) { -#define set(type, var) *((type*)data) = state->var, data += sizeof(type) / sizeof(char) - set(long, r); - set(long, c); - set(long, n); - set(long, b); - set(long, w); - set(int64_t, wmod); - set(long, l); - set(long, nr); - memcpy(data, state->S, sizeof(state->S)); - data += sizeof(state->S) / sizeof(char); - set(size_t, mptr); - set(size_t, mlen); - memcpy(data, state->M, state->mptr * sizeof(char)); - data += state->mptr; - return sizeof(libkeccak_state_t) - sizeof(char*) + state->mptr * sizeof(char); +#define set(type, var) *((type *)data) = state->var, data += sizeof(type) / sizeof(char) + set(long, r); + set(long, c); + set(long, n); + set(long, b); + set(long, w); + set(int64_t, wmod); + set(long, l); + set(long, nr); + memcpy(data, state->S, sizeof(state->S)); + data += sizeof(state->S) / sizeof(char); + set(size_t, mptr); + set(size_t, mlen); + memcpy(data, state->M, state->mptr * sizeof(char)); + data += state->mptr; + return sizeof(libkeccak_state_t) - sizeof(char *) + state->mptr * sizeof(char); #undef set } @@ -144,27 +133,28 @@ size_t libkeccak_state_marshal(const libkeccak_state_t* restrict state, char* re * @param data The input buffer * @return The number of bytes read from `data`, 0 on error */ -size_t libkeccak_state_unmarshal(libkeccak_state_t* restrict state, const char* restrict data) +size_t +libkeccak_state_unmarshal(libkeccak_state_t *restrict state, const char *restrict data) { -#define get(type, var) state->var = *((const type*)data), data += sizeof(type) / sizeof(char) - get(long, r); - get(long, c); - get(long, n); - get(long, b); - get(long, w); - get(int64_t, wmod); - get(long, l); - get(long, nr); - memcpy(state->S, data, sizeof(state->S)); - data += sizeof(state->S) / sizeof(char); - get(size_t, mptr); - get(size_t, mlen); - state->M = malloc(state->mptr * sizeof(char)); - if (state->M == NULL) - return 0; - memcpy(state->M, data, state->mptr * sizeof(char)); - data += state->mptr; - return sizeof(libkeccak_state_t) - sizeof(char*) + state->mptr * sizeof(char); +#define get(type, var) state->var = *((const type *)data), data += sizeof(type) / sizeof(char) + get(long, r); + get(long, c); + get(long, n); + get(long, b); + get(long, w); + get(int64_t, wmod); + get(long, l); + get(long, nr); + memcpy(state->S, data, sizeof(state->S)); + data += sizeof(state->S) / sizeof(char); + get(size_t, mptr); + get(size_t, mlen); + state->M = malloc(state->mptr * sizeof(char)); + if (!state->M) + return 0; + memcpy(state->M, data, state->mptr * sizeof(char)); + data += state->mptr; + return sizeof(libkeccak_state_t) - sizeof(char *) + state->mptr * sizeof(char); #undef get } @@ -176,9 +166,10 @@ size_t libkeccak_state_unmarshal(libkeccak_state_t* restrict state, const char* * @param data The data buffer * @return The byte size of the stored state */ -size_t libkeccak_state_unmarshal_skip(const char* restrict data) +size_t +libkeccak_state_unmarshal_skip(const char *restrict data) { - data += (7 * sizeof(long) + 26 * sizeof(int64_t)) / sizeof(char); - return sizeof(libkeccak_state_t) - sizeof(char*) + *(const size_t*)data * sizeof(char); + data += (7 * sizeof(long) + 26 * sizeof(int64_t)) / sizeof(char); + return sizeof(libkeccak_state_t) - sizeof(char *) + *(const size_t *)data * sizeof(char); } diff --git a/src/libkeccak/state.h b/src/libkeccak/state.h index f030664..1c4b24e 100644 --- a/src/libkeccak/state.h +++ b/src/libkeccak/state.h @@ -1,32 +1,14 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015, 2017 Mattias Andrée (maandree@kth.se) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #ifndef LIBKECCAK_STATE_H -#define LIBKECCAK_STATE_H 1 - +#define LIBKECCAK_STATE_H 1 #include "spec.h" #include "internal.h" +#include <errno.h> #include <stddef.h> #include <stdint.h> #include <stdlib.h> -#include <errno.h> #include <string.h> @@ -36,68 +18,67 @@ * * The `char`-size of the output hashsum is calculated by `(.n + 7) / 8` */ -typedef struct libkeccak_state -{ - /** - * The lanes (state/sponge) - */ - int64_t S[25]; - - /** - * The bitrate - */ - long r; - - /** - * The capacity - */ - long c; - - /** - * The output size - */ - long n; - - /** - * The state size - */ - long b; - - /** - * The word size - */ - long w; - - /** - * The word mask - */ - int64_t wmod; - - /** - * ℓ, the binary logarithm of the word size - */ - long l; - - /** - * 12 + 2ℓ, the number of rounds - */ - long nr; - - /** - * Pointer for `M` - */ - size_t mptr; - - /** - * Size of `M` - */ - size_t mlen; - - /** - * Left over water to fill the sponge with at next update - */ - char* M; - +typedef struct libkeccak_state { + /** + * The lanes (state/sponge) + */ + int64_t S[25]; + + /** + * The bitrate + */ + long r; + + /** + * The capacity + */ + long c; + + /** + * The output size + */ + long n; + + /** + * The state size + */ + long b; + + /** + * The word size + */ + long w; + + /** + * The word mask + */ + int64_t wmod; + + /** + * ℓ, the binary logarithm of the word size + */ + long l; + + /** + * 12 + 2ℓ, the number of rounds + */ + long nr; + + /** + * Pointer for `M` + */ + size_t mptr; + + /** + * Size of `M` + */ + size_t mlen; + + /** + * Left over water to fill the sponge with at next update + */ + char *M; + } libkeccak_state_t; @@ -110,7 +91,7 @@ typedef struct libkeccak_state * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull))) -int libkeccak_state_initialise(libkeccak_state_t* restrict state, const libkeccak_spec_t* restrict spec); +int libkeccak_state_initialise(libkeccak_state_t *restrict state, const libkeccak_spec_t *restrict spec); /** @@ -119,11 +100,11 @@ int libkeccak_state_initialise(libkeccak_state_t* restrict state, const libkecca * @param state The state that should be reset */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow, unused))) -static inline -void libkeccak_state_reset(libkeccak_state_t* restrict state) +static inline void +libkeccak_state_reset(libkeccak_state_t *restrict state) { - state->mptr = 0; - memset(state->S, 0, sizeof(state->S)); + state->mptr = 0; + memset(state->S, 0, sizeof(state->S)); } @@ -132,13 +113,13 @@ void libkeccak_state_reset(libkeccak_state_t* restrict state) * * @param state The state that should be destroyed */ -static inline -void libkeccak_state_fast_destroy(libkeccak_state_t* restrict state) +static inline void +libkeccak_state_fast_destroy(libkeccak_state_t *restrict state) { - if (state == NULL) - return; - free(state->M); - state->M = NULL; + if (state == NULL) + return; + free(state->M); + state->M = NULL; } @@ -148,7 +129,7 @@ void libkeccak_state_fast_destroy(libkeccak_state_t* restrict state) * @param state The state that should be wipe */ LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull, nothrow, optimize("-O0")))) -void libkeccak_state_wipe_message(volatile libkeccak_state_t* restrict state); +void libkeccak_state_wipe_message(volatile libkeccak_state_t *restrict state); /** * Wipe data in the state's sponge wihout freeing any data @@ -156,7 +137,7 @@ void libkeccak_state_wipe_message(volatile libkeccak_state_t* restrict state); * @param state The state that should be wipe */ LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull, nothrow, optimize("-O0")))) -void libkeccak_state_wipe_sponge(volatile libkeccak_state_t* restrict state); +void libkeccak_state_wipe_sponge(volatile libkeccak_state_t *restrict state); /** * Wipe sensitive data wihout freeing any data @@ -164,7 +145,7 @@ void libkeccak_state_wipe_sponge(volatile libkeccak_state_t* restrict state); * @param state The state that should be wipe */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow, optimize("-O0")))) -void libkeccak_state_wipe(volatile libkeccak_state_t* restrict state); +void libkeccak_state_wipe(volatile libkeccak_state_t *restrict state); /** @@ -173,14 +154,14 @@ void libkeccak_state_wipe(volatile libkeccak_state_t* restrict state); * @param state The state that should be destroyed */ LIBKECCAK_GCC_ONLY(__attribute__((unused, optimize("-O0")))) -static inline -void libkeccak_state_destroy(volatile libkeccak_state_t* restrict state) +static inline void +libkeccak_state_destroy(volatile libkeccak_state_t *restrict state) { - if (state == NULL) - return; - libkeccak_state_wipe(state); - free(state->M); - state->M = NULL; + if (!state) + return; + libkeccak_state_wipe(state); + free(state->M); + state->M = NULL; } @@ -191,14 +172,13 @@ void libkeccak_state_destroy(volatile libkeccak_state_t* restrict state) * @return The state, `NULL` on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, unused, warn_unused_result, malloc))) -static inline -libkeccak_state_t* libkeccak_state_create(const libkeccak_spec_t* restrict spec) +static inline libkeccak_state_t * +libkeccak_state_create(const libkeccak_spec_t *restrict spec) { - libkeccak_state_t* restrict state = malloc(sizeof(libkeccak_state_t)); - int saved_errno; - if ((state == NULL) || libkeccak_state_initialise(state, spec)) - return saved_errno = errno, free(state), errno = saved_errno, NULL; - return state; + libkeccak_state_t *restrict state = malloc(sizeof(libkeccak_state_t)); + if (!state || libkeccak_state_initialise(state, spec)) + return free(state), NULL; + return state; } @@ -208,11 +188,11 @@ libkeccak_state_t* libkeccak_state_create(const libkeccak_spec_t* restrict spec) * @param state The state that should be freed */ LIBKECCAK_GCC_ONLY(__attribute__((unused))) -static inline -void libkeccak_state_fast_free(libkeccak_state_t* restrict state) +static inline void +libkeccak_state_fast_free(libkeccak_state_t *restrict state) { - libkeccak_state_fast_destroy(state); - free(state); + libkeccak_state_fast_destroy(state); + free(state); } @@ -222,15 +202,15 @@ void libkeccak_state_fast_free(libkeccak_state_t* restrict state) * @param state The state that should be freed */ LIBKECCAK_GCC_ONLY(__attribute__((unused, optimize("-O0")))) -static inline -void libkeccak_state_free(volatile libkeccak_state_t* restrict state) +static inline void +libkeccak_state_free(volatile libkeccak_state_t *restrict state) { #ifdef __GNUC__ # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wcast-qual" #endif - libkeccak_state_destroy(state); - free((libkeccak_state_t*)state); + libkeccak_state_destroy(state); + free((libkeccak_state_t *)state); #ifdef __GNUC__ # pragma GCC diagnostic pop #endif @@ -245,7 +225,7 @@ void libkeccak_state_free(volatile libkeccak_state_t* restrict state) * @return Zero on success, -1 on error */ LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull))) -int libkeccak_state_copy(libkeccak_state_t* restrict dest, const libkeccak_state_t* restrict src); +int libkeccak_state_copy(libkeccak_state_t *restrict dest, const libkeccak_state_t *restrict src); /** @@ -255,14 +235,13 @@ int libkeccak_state_copy(libkeccak_state_t* restrict dest, const libkeccak_state * @return The duplicate, `NULL` on error */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, unused, warn_unused_result, malloc))) -static inline -libkeccak_state_t* libkeccak_state_duplicate(const libkeccak_state_t* restrict src) +static inline libkeccak_state_t * +libkeccak_state_duplicate(const libkeccak_state_t *restrict src) { - libkeccak_state_t* restrict dest = malloc(sizeof(libkeccak_state_t)); - int saved_errno; - if ((dest == NULL) || libkeccak_state_copy(dest, src)) - return saved_errno = errno, libkeccak_state_free(dest), errno = saved_errno, NULL; - return dest; + libkeccak_state_t *restrict dest = malloc(sizeof(libkeccak_state_t)); + if (!dest || libkeccak_state_copy(dest, src)) + return libkeccak_state_free(dest), NULL; + return dest; } @@ -274,10 +253,10 @@ libkeccak_state_t* libkeccak_state_duplicate(const libkeccak_state_t* restrict s * @return The allocation size needed for the buffer to which the state will be marshalled */ LIBKECCAK_GCC_ONLY(__attribute__((nonnull, nothrow, unused, warn_unused_result, pure))) -static inline -size_t libkeccak_state_marshal_size(const libkeccak_state_t* restrict state) +static inline size_t +libkeccak_state_marshal_size(const libkeccak_state_t *restrict state) { - return sizeof(libkeccak_state_t) - sizeof(char*) + state->mptr * sizeof(char); + return sizeof(libkeccak_state_t) - sizeof(char*) + state->mptr * sizeof(char); } @@ -289,7 +268,7 @@ size_t libkeccak_state_marshal_size(const libkeccak_state_t* restrict state) * @return The number of bytes stored to `data` */ LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull, nothrow))) -size_t libkeccak_state_marshal(const libkeccak_state_t* restrict state, char* restrict data); +size_t libkeccak_state_marshal(const libkeccak_state_t *restrict state, char *restrict data); /** @@ -300,7 +279,7 @@ size_t libkeccak_state_marshal(const libkeccak_state_t* restrict state, char* re * @return The number of bytes read from `data`, 0 on error */ LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull))) -size_t libkeccak_state_unmarshal(libkeccak_state_t* restrict state, const char* restrict data); +size_t libkeccak_state_unmarshal(libkeccak_state_t *restrict state, const char *restrict data); /** @@ -311,8 +290,6 @@ size_t libkeccak_state_unmarshal(libkeccak_state_t* restrict state, const char* * @return The byte size of the stored state */ LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull, nothrow, warn_unused_result, pure))) -size_t libkeccak_state_unmarshal_skip(const char* restrict data); - +size_t libkeccak_state_unmarshal_skip(const char *restrict data); #endif - @@ -1,26 +1,9 @@ -/** - * libkeccak – Keccak-family hashing library - * - * Copyright © 2014, 2015 Mattias Andrée (maandree@member.fsf.org) - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ +/* See LICENSE file for copyright and license details. */ #include <libkeccak.h> +#include <fcntl.h> #include <stdio.h> #include <string.h> -#include <fcntl.h> #include <unistd.h> @@ -29,43 +12,44 @@ * * @return Zero on success, -1 on error */ -static int test_hex(void) +static int +test_hex(void) { - const unsigned char bindata[] = {0x04, 0x2F, 0x12, 0x83, 0xFF, 0x80, 0xA3, 0x00}; - const char hexdata_upper[] = "042F1283FF80A300"; - const char hexdata_lower[] = "042f1283ff80a300"; - char hextest[2 * 8 + 1]; - - printf("Testing libkeccak_behex_lower: "); - libkeccak_behex_lower(hextest, (const char*)bindata, 8); - if (!strcmp(hextest, hexdata_lower)) - printf("OK\n"); - else - return printf("Fail\n"), -1; - - printf("Testing libkeccak_behex_upper: "); - libkeccak_behex_upper(hextest, (const char*)bindata, 8); - if (!strcmp(hextest, hexdata_upper)) - printf("OK\n"); - else - return printf("Fail\n"), -1; - - printf("Testing libkeccak_unhex on uppercase: "); - libkeccak_unhex(hextest, hexdata_upper); - if (!memcmp(bindata, hextest, 8 * sizeof(char))) - printf("OK\n"); - else - return printf("Fail\n"), -1; - - printf("Testing libkeccak_unhex on lowercase: "); - libkeccak_unhex(hextest, hexdata_lower); - if (!memcmp(bindata, hextest, 8 * sizeof(char))) - printf("OK\n"); - else - return printf("Fail\n"), -1; - - printf("\n"); - return 0; + const unsigned char bindata[] = {0x04, 0x2F, 0x12, 0x83, 0xFF, 0x80, 0xA3, 0x00}; + const char hexdata_upper[] = "042F1283FF80A300"; + const char hexdata_lower[] = "042f1283ff80a300"; + char hextest[2 * 8 + 1]; + + printf("Testing libkeccak_behex_lower: "); + libkeccak_behex_lower(hextest, (const char*)bindata, 8); + if (!strcmp(hextest, hexdata_lower)) + printf("OK\n"); + else + return printf("Fail\n"), -1; + + printf("Testing libkeccak_behex_upper: "); + libkeccak_behex_upper(hextest, (const char*)bindata, 8); + if (!strcmp(hextest, hexdata_upper)) + printf("OK\n"); + else + return printf("Fail\n"), -1; + + printf("Testing libkeccak_unhex on uppercase: "); + libkeccak_unhex(hextest, hexdata_upper); + if (!memcmp(bindata, hextest, 8 * sizeof(char))) + printf("OK\n"); + else + return printf("Fail\n"), -1; + + printf("Testing libkeccak_unhex on lowercase: "); + libkeccak_unhex(hextest, hexdata_lower); + if (!memcmp(bindata, hextest, 8 * sizeof(char))) + printf("OK\n"); + else + return printf("Fail\n"), -1; + + printf("\n"); + return 0; } @@ -75,54 +59,55 @@ static int test_hex(void) * @param spec The specifications for the state * @return Zero on success, -1 on error */ -static int test_state(libkeccak_spec_t* restrict spec) +static int +test_state(libkeccak_spec_t *restrict spec) { - libkeccak_state_t* restrict state; - libkeccak_state_t* restrict state2; - size_t marshal_size, marshalled_size, i, n; - char* restrict marshalled_data; - - if (state = libkeccak_state_create(spec), state == NULL) - return perror("libkeccak_state_initialise"), -1; - - n = state->mlen / 2; - for (i = 0; i < n; i++) - state->M[state->mptr++] = (char)(i & 255); - - if (state2 = libkeccak_state_duplicate(state), state2 == NULL) - return perror("libkeccak_state_duplicate"), -1; - - if (state->M[state->mptr - 1] != state2->M[state2->mptr - 1]) - return printf("Inconsistency found between original state and duplicate state.\n"), -1; - - marshal_size = libkeccak_state_marshal_size(state2); - if (marshalled_data = malloc(marshal_size), marshalled_data == NULL) - return perror("malloc"), -1; - - marshalled_size = libkeccak_state_marshal(state2, marshalled_data); - if (marshalled_size != marshal_size) - return printf("libkeccak_state_marshal returned an unexpected value.\n"), -1; - - libkeccak_state_free(state); - - if (state = malloc(sizeof(libkeccak_state_t)), state == NULL) - return perror("malloc"), -1; - marshalled_size = libkeccak_state_unmarshal(state, marshalled_data); - if (marshalled_size == 0) - return perror("libkeccak_state_unmarshal"), -1; - if (marshalled_size != marshal_size) - return printf("libkeccak_state_unmarshal returned an unexpected value.\n"), -1; - - if (libkeccak_state_unmarshal_skip(marshalled_data) != marshal_size) - return printf("libkeccak_state_unmarshal_skip returned an unexpected value.\n"), -1; - - if (state->M[state->mptr - 1] != state2->M[state2->mptr - 1]) - return printf("Inconsistency found between original state and unmarshalled state.\n"), -1; + libkeccak_state_t *restrict state; + libkeccak_state_t *restrict state2; + size_t marshal_size, marshalled_size, i, n; + char *restrict marshalled_data; + + if (state = libkeccak_state_create(spec), state == NULL) + return perror("libkeccak_state_initialise"), -1; + + n = state->mlen / 2; + for (i = 0; i < n; i++) + state->M[state->mptr++] = (char)(i & 255); - free(marshalled_data); - libkeccak_state_free(state); - libkeccak_state_free(state2); - return 0; + if (state2 = libkeccak_state_duplicate(state), state2 == NULL) + return perror("libkeccak_state_duplicate"), -1; + + if (state->M[state->mptr - 1] != state2->M[state2->mptr - 1]) + return printf("Inconsistency found between original state and duplicate state.\n"), -1; + + marshal_size = libkeccak_state_marshal_size(state2); + if (marshalled_data = malloc(marshal_size), marshalled_data == NULL) + return perror("malloc"), -1; + + marshalled_size = libkeccak_state_marshal(state2, marshalled_data); + if (marshalled_size != marshal_size) + return printf("libkeccak_state_marshal returned an unexpected value.\n"), -1; + + libkeccak_state_free(state); + + if (state = malloc(sizeof(libkeccak_state_t)), state == NULL) + return perror("malloc"), -1; + marshalled_size = libkeccak_state_unmarshal(state, marshalled_data); + if (marshalled_size == 0) + return perror("libkeccak_state_unmarshal"), -1; + if (marshalled_size != marshal_size) + return printf("libkeccak_state_unmarshal returned an unexpected value.\n"), -1; + + if (libkeccak_state_unmarshal_skip(marshalled_data) != marshal_size) + return printf("libkeccak_state_unmarshal_skip returned an unexpected value.\n"), -1; + + if (state->M[state->mptr - 1] != state2->M[state2->mptr - 1]) + return printf("Inconsistency found between original state and unmarshalled state.\n"), -1; + + free(marshalled_data); + libkeccak_state_free(state); + libkeccak_state_free(state2); + return 0; } @@ -136,35 +121,36 @@ static int test_state(libkeccak_spec_t* restrict spec) * @param expected_answer The expected answer, must be lowercase * @return Zero on success, -1 on error */ -static int test_digest_case(const libkeccak_spec_t* restrict spec, const char* restrict suffix, - const char* restrict msg, long bits, const char* restrict expected_answer) +static int +test_digest_case(const libkeccak_spec_t *restrict spec, const char *restrict suffix, + const char *restrict msg, long bits, const char *restrict expected_answer) { - libkeccak_state_t state; - char* restrict hashsum; - char* restrict hexsum; - int ok; - - if (libkeccak_state_initialise(&state, spec)) - return perror("libkeccak_state_initialise"), -1; - if (hashsum = malloc((spec->output + 7) / 8), hashsum == NULL) - return perror("malloc"), -1; - if (hexsum = malloc((spec->output + 7) / 8 * 2 + 1), hexsum == NULL) - return perror("malloc"), -1; - - if (libkeccak_digest(&state, msg, strlen(msg) - !!bits, bits, suffix, hashsum)) - return perror("libkeccak_digest"), -1; - libkeccak_state_fast_destroy(&state); - - libkeccak_behex_lower(hexsum, hashsum, (spec->output + 7) / 8); - ok = !strcmp(hexsum, expected_answer); - printf("%s%s\n", ok ? "OK" : "Fail: ", ok ? "" : hexsum); - if (!ok) - printf(" r, c, n = %li, %li, %li\n", spec->bitrate, spec->capacity, spec->output); - - free(hashsum); - free(hexsum); - - return ok - 1; + libkeccak_state_t state; + char *restrict hashsum; + char *restrict hexsum; + int ok; + + if (libkeccak_state_initialise(&state, spec)) + return perror("libkeccak_state_initialise"), -1; + if (hashsum = malloc((spec->output + 7) / 8), hashsum == NULL) + return perror("malloc"), -1; + if (hexsum = malloc((spec->output + 7) / 8 * 2 + 1), hexsum == NULL) + return perror("malloc"), -1; + + if (libkeccak_digest(&state, msg, strlen(msg) - !!bits, bits, suffix, hashsum)) + return perror("libkeccak_digest"), -1; + libkeccak_state_fast_destroy(&state); + + libkeccak_behex_lower(hexsum, hashsum, (spec->output + 7) / 8); + ok = !strcmp(hexsum, expected_answer); + printf("%s%s\n", ok ? "OK" : "Fail: ", ok ? "" : hexsum); + if (!ok) + printf(" r, c, n = %li, %li, %li\n", spec->bitrate, spec->capacity, spec->output); + + free(hashsum); + free(hexsum); + + return ok - 1; } @@ -175,192 +161,198 @@ static int test_digest_case(const libkeccak_spec_t* restrict spec, const char* r */ static int test_digest(void) { -#define sha3(output, message) \ - (printf(" Testing SHA3-"#output"(%s): ", #message), \ - libkeccak_spec_sha3(&spec, output), \ - test_digest_case(&spec, LIBKECCAK_SHA3_SUFFIX, message, 0, answer)) -#define keccak(output, message) \ - (printf(" Testing Keccak-"#output"(%s): ", #message), \ - libkeccak_spec_sha3(&spec, output) /* sic! */, \ - test_digest_case(&spec, "", message, 0, answer)) -#define keccak_bits(output, message, bits) \ - (printf(" Testing Keccak-"#output"(%s-%i): ", #message, bits), \ - libkeccak_spec_sha3(&spec, output) /* sic! */, \ - test_digest_case(&spec, "", message, bits, answer)) -#define rawshake(semicapacity, output, message) \ - (printf(" Testing RawSHAKE-"#semicapacity"(%s, %i): ", #message, output), \ - libkeccak_spec_rawshake(&spec, semicapacity, output), \ - test_digest_case(&spec, LIBKECCAK_RAWSHAKE_SUFFIX, message, 0, answer)) -#define rawshake_bits(semicapacity, output, message, bits) \ - (printf(" Testing RawSHAKE-"#semicapacity"(%s-%i, %i): ", #message, bits, output), \ - libkeccak_spec_rawshake(&spec, semicapacity, output), \ - test_digest_case(&spec, LIBKECCAK_RAWSHAKE_SUFFIX, message, bits, answer)) -#define shake(semicapacity, output, message) \ - (printf(" Testing SHAKE-"#semicapacity"(%s, %i): ", #message, output), \ - libkeccak_spec_shake(&spec, semicapacity, output), \ - test_digest_case(&spec, LIBKECCAK_SHAKE_SUFFIX, message, 0, answer)) -#define keccak_g(b, c, o, message) \ - (printf(" Testing Keccak[%i,%i,%i](%s): ", b, c, o, #message), \ - spec.bitrate = b, spec.capacity = c, spec.output = o, \ - test_digest_case(&spec, "", message, 0, answer)) - - - libkeccak_spec_t spec; - const char* answer; - - printf("Testing libkeccak_digest:\n"); - - - answer = "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7"; - if (sha3(224, "")) return -1; - - answer = "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"; - if (sha3(256, "")) return -1; - - answer = "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004"; - if (sha3(384, "")) return -1; - - answer = "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a6" - "15b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26"; - if (sha3(512, "")) return -1; - - - answer = "f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd"; - if (keccak(224, "")) return -1; - - answer = "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"; - if (keccak(256, "")) return -1; - - answer = "2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff"; - if (keccak(384, "")) return -1; - - answer = "0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304" - "c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e"; - if (keccak(512, "")) return -1; - - - answer = "22c8017ac8bcf65f59d1b7e92c9d4c6739d25e34ce5cb608b24ff096"; - if (sha3(224, "withdrew hypothesis snakebird qmc2")) return -1; - - answer = "43808dde2662143dc4eed5dac5e98c74b06711829f02a3b121bd74f3"; - if (sha3(224, "intensifierat sturdiness perl-image-exiftool vingla")) return -1; - - answer = "d32b4ac86065774dee5eb5cdd2f67b4e86501086d7373884e8b20a36"; - if (sha3(224, "timjan avogadro uppdriven lib32-llvm-amdgpu-snapshot")) return -1; - - answer = "efbd76d45bfa952485148f8ad46143897f17c27ffdc8eb7287f9353b"; - if (sha3(224, "grilo-plugins auditorium tull dissimilarity's")) return -1; - - answer = "6705aa36ecf58f333e0e6364ac1d0b7931d402e13282127cfd6f876c"; - if (sha3(224, "royalty tt yellowstone deficiencies")) return -1; - - answer = "803a0ff09dda0df306e483a9f91b20a3dbbf9c2ebb8d0a3b28f3b9e0"; - if (sha3(224, "kdegames-kdiamond tunisisk occurrence's outtalad")) return -1; - - answer = "a64779aca943a6aef1d2e7c9a0f4e997f4dabd1f77112a22121d3ed5"; - if (sha3(224, "chevalier slat's spindel representations")) return -1; - - answer = "f0a3e0587af7723f0aa4719059d3f5107115a5b3667cd5209cc4d867"; - if (sha3(224, "archery lexicographical equine veered")) return -1; - - answer = "312e7e3c6403ab1a086155fb9a52b22a3d0d257876afd2b93fb7272e"; - if (sha3(224, "splay washbasin opposing there")) return -1; - - answer = "270ba05b764221ff5b5d94adfb4fdb1f36f07fe7c438904a5f3df071"; - if (sha3(224, "faktum desist thundered klen")) return -1; - - - answer = "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"; - if (keccak_bits(256, "\x02", 2)) return -1; - - answer = "3a1108d4a90a31b85a10bdce77f4bfbdcc5b1d70dd405686f8bbde834aa1a410"; - if (keccak_bits(256, "\x03", 2)) return -1; - - answer = "46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f"; - if (keccak_bits(256, "\x0F", 4)) return -1; - - - answer = "3a1108d4a90a31b85a10bdce77f4bfbd"; - if (rawshake(256, 128, "")) return -1; - - answer = "46b9dd2b0ba88d13233b3feb743eeb24"; - if (rawshake_bits(256, 128, "\x03", 2)) return -1; - - answer = "46b9dd2b0ba88d13233b3feb743eeb24"; - if (shake(256, 128, "")) return -1; - - - answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de92253515713cce8" - "d2098be1c82df40b40e375549c0eeb655f92d718f01f147ba1c7c67844c7ba8b11492cd6"; - if (keccak_g(1024, 1600 - 1024, 576, "capitol's kvistfri broadly raping")) return -1; - - answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de92253515713cce8" - "d2098be1c82df40b40e375549c0eeb655f92d718f01f147ba1c7c67844c7ba8b11492cd6" - "143466958504c110522f772fe746573b1dc905f943ed1ec6ecf858575798596beeca4eb6" - "bb7bea635bcea6331315728fb57866370bf1ad5d"; - if (keccak_g(1024, 1600 - 1024, 1024, "capitol's kvistfri broadly raping")) return -1; - - answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de92253515713cce8" - "d2098be1c82df40b40e375549c0eeb655f92d718f01f147ba1c7c67844c7ba8b11492cd6" - "143466958504c110522f772fe746573b1dc905f943ed1ec6ecf858575798596beeca4eb6" - "bb7bea635bcea6331315728fb57866370bf1ad5decbc56d28d47ce53f18376d9f5531551" - "7a976d52dd3f98b7025e0b3c513c6d17d40462cddb5406d693bbe859a136af5375b5dd6e" - "3478934b00aa6cd44aa7ae2cd0271d83fbab699b"; - if (keccak_g(1024, 1600 - 1024, 1600, "capitol's kvistfri broadly raping")) return -1; - - answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de92253515713cce8" - "d2098be1c82df40b40e375549c0eeb655f92d718f01f147ba1c7c67844c7ba8b11492cd6" - "143466958504c110522f772fe746573b1dc905f943ed1ec6ecf858575798596beeca4eb6" - "bb7bea635bcea6331315728fb57866370bf1ad5decbc56d28d47ce53f18376d9f5531551" - "7a976d52dd3f98b7025e0b3c513c6d17d40462cddb5406d693bbe859a136af5375b5dd6e" - "3478934b00aa6cd44aa7ae2cd0271d83fbab699b9c"; - if (keccak_g(1024, 1600 - 1024, 1608, "capitol's kvistfri broadly raping")) return -1; - - answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de92253515713cce8" - "d2098be1c82df40b40e375549c0eeb655f92d718f01f147ba1c7c67844c7ba8b11492cd6" - "143466958504c110522f772fe746573b1dc905f943ed1ec6ecf858575798596beeca4eb6" - "bb7bea635bcea6331315728fb57866370bf1ad5decbc56d28d47ce53f18376d9f5531551" - "7a976d52dd3f98b7025e0b3c513c6d17d40462cddb5406d693bbe859a136af5375b5dd6e" - "3478934b00aa6cd44aa7ae2cd0271d83fbab699b9c58351bf7d26586b9c32282f1ac6356" - "1981b79791d7ab2b6e01f5b8e6cf0cab8b2076fd82bd99df015a602cdda5684162fea982" - "0f5a441c4620f549fbaf4e818201f292dbf4f6c9f82af8aa80b4124984da6f65b2874e0e" - "f01d042c08e9aedbb6ce4c10526e38c1a4e8b108c4f14b066f9d42640687b55124b081da" - "a9f9ae4232f313740b4fb787545dc19e7778f7082b3fa5824d2400c012be1a6c5ade7149" - "e452d310752fa9ebb964ab36fde0c8f46f47a0e2c9b20f24e3cca904bbedaa7ea176f662" - "33cd2d95"; - if (keccak_g(1024, 1600 - 1024, 3200, "capitol's kvistfri broadly raping")) return -1; - - answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de9225351"; - if (keccak_g(1024, 1600 - 1024, 256, "capitol's kvistfri broadly raping")) return -1; - - answer = "e6f86ebc15b962f73f36f36fc8a84c3ae84b1c1023bfd4c5f1829389135aecc3"; - if (keccak_g(512, 1600 - 512, 256, "capitol's kvistfri broadly raping")) return -1; - - answer = "420b97fc88962c87ec2adaa8f48d74d9ff4ea7ae7d691f9c33b8713ca1d3d573"; - if (keccak_g(256, 1600 - 256, 256, "capitol's kvistfri broadly raping")) return -1; - - answer = "524790afbe4706d938b6f753e14104f556890e2a415e211b0564d60499db0333"; - if (keccak_g(512, 800 - 512, 256, "capitol's kvistfri broadly raping")) return -1; - - answer = "04a6b4ad08b3018eefba0fb756272d949ac0f71c26f836d31dd13b28b884aa0f"; - if (keccak_g(256, 800 - 256, 256, "capitol's kvistfri broadly raping")) return -1; - - answer = "d56f547791225e54460e6274ed31e57b7085820c11d65f1f322a16a3352c85ed"; - if (keccak_g(256, 400 - 256, 256, "capitol's kvistfri broadly raping")) return -1; - - answer = "ceec066a57b9b31a5a0661df7bafec4183a26d0ed81e50bc958471f84fa347a7"; - if (keccak_g(128, 400 - 128, 256, "capitol's kvistfri broadly raping")) return -1; - - answer = "b18f679c7105a72a993f70fa5adb3f17ef7ccffaffb4dc0f6fed74aa2f565194"; - if (keccak_g(128, 200 - 128, 256, "capitol's kvistfri broadly raping")) return -1; - - answer = "9b845c1ecc2b1b3a48ba42ef29ccc4b348da8ab15074a870d8e799ca33c15e4b"; - if (keccak_g(64, 200 - 64, 256, "capitol's kvistfri broadly raping")) return -1; - - - printf("\n"); - return 0; - +#define sha3(output, message)\ + (printf(" Testing SHA3-"#output"(%s): ", #message),\ + libkeccak_spec_sha3(&spec, output),\ + test_digest_case(&spec, LIBKECCAK_SHA3_SUFFIX, message, 0, answer)) + +#define keccak(output, message)\ + (printf(" Testing Keccak-"#output"(%s): ", #message),\ + libkeccak_spec_sha3(&spec, output) /* sic! */,\ + test_digest_case(&spec, "", message, 0, answer)) + +#define keccak_bits(output, message, bits)\ + (printf(" Testing Keccak-"#output"(%s-%i): ", #message, bits),\ + libkeccak_spec_sha3(&spec, output) /* sic! */,\ + test_digest_case(&spec, "", message, bits, answer)) + +#define rawshake(semicapacity, output, message)\ + (printf(" Testing RawSHAKE-"#semicapacity"(%s, %i): ", #message, output),\ + libkeccak_spec_rawshake(&spec, semicapacity, output),\ + test_digest_case(&spec, LIBKECCAK_RAWSHAKE_SUFFIX, message, 0, answer)) + +#define rawshake_bits(semicapacity, output, message, bits)\ + (printf(" Testing RawSHAKE-"#semicapacity"(%s-%i, %i): ", #message, bits, output),\ + libkeccak_spec_rawshake(&spec, semicapacity, output),\ + test_digest_case(&spec, LIBKECCAK_RAWSHAKE_SUFFIX, message, bits, answer)) + +#define shake(semicapacity, output, message)\ + (printf(" Testing SHAKE-"#semicapacity"(%s, %i): ", #message, output),\ + libkeccak_spec_shake(&spec, semicapacity, output),\ + test_digest_case(&spec, LIBKECCAK_SHAKE_SUFFIX, message, 0, answer)) + +#define keccak_g(b, c, o, message)\ + (printf(" Testing Keccak[%i,%i,%i](%s): ", b, c, o, #message),\ + spec.bitrate = b, spec.capacity = c, spec.output = o,\ + test_digest_case(&spec, "", message, 0, answer)) + + + libkeccak_spec_t spec; + const char *answer; + + printf("Testing libkeccak_digest:\n"); + + + answer = "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7"; + if (sha3(224, "")) return -1; + + answer = "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"; + if (sha3(256, "")) return -1; + + answer = "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004"; + if (sha3(384, "")) return -1; + + answer = "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a6" + "15b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26"; + if (sha3(512, "")) return -1; + + + answer = "f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd"; + if (keccak(224, "")) return -1; + + answer = "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"; + if (keccak(256, "")) return -1; + + answer = "2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff"; + if (keccak(384, "")) return -1; + + answer = "0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304" + "c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e"; + if (keccak(512, "")) return -1; + + + answer = "22c8017ac8bcf65f59d1b7e92c9d4c6739d25e34ce5cb608b24ff096"; + if (sha3(224, "withdrew hypothesis snakebird qmc2")) return -1; + + answer = "43808dde2662143dc4eed5dac5e98c74b06711829f02a3b121bd74f3"; + if (sha3(224, "intensifierat sturdiness perl-image-exiftool vingla")) return -1; + + answer = "d32b4ac86065774dee5eb5cdd2f67b4e86501086d7373884e8b20a36"; + if (sha3(224, "timjan avogadro uppdriven lib32-llvm-amdgpu-snapshot")) return -1; + + answer = "efbd76d45bfa952485148f8ad46143897f17c27ffdc8eb7287f9353b"; + if (sha3(224, "grilo-plugins auditorium tull dissimilarity's")) return -1; + + answer = "6705aa36ecf58f333e0e6364ac1d0b7931d402e13282127cfd6f876c"; + if (sha3(224, "royalty tt yellowstone deficiencies")) return -1; + + answer = "803a0ff09dda0df306e483a9f91b20a3dbbf9c2ebb8d0a3b28f3b9e0"; + if (sha3(224, "kdegames-kdiamond tunisisk occurrence's outtalad")) return -1; + + answer = "a64779aca943a6aef1d2e7c9a0f4e997f4dabd1f77112a22121d3ed5"; + if (sha3(224, "chevalier slat's spindel representations")) return -1; + + answer = "f0a3e0587af7723f0aa4719059d3f5107115a5b3667cd5209cc4d867"; + if (sha3(224, "archery lexicographical equine veered")) return -1; + + answer = "312e7e3c6403ab1a086155fb9a52b22a3d0d257876afd2b93fb7272e"; + if (sha3(224, "splay washbasin opposing there")) return -1; + + answer = "270ba05b764221ff5b5d94adfb4fdb1f36f07fe7c438904a5f3df071"; + if (sha3(224, "faktum desist thundered klen")) return -1; + + + answer = "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"; + if (keccak_bits(256, "\x02", 2)) return -1; + + answer = "3a1108d4a90a31b85a10bdce77f4bfbdcc5b1d70dd405686f8bbde834aa1a410"; + if (keccak_bits(256, "\x03", 2)) return -1; + + answer = "46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f"; + if (keccak_bits(256, "\x0F", 4)) return -1; + + + answer = "3a1108d4a90a31b85a10bdce77f4bfbd"; + if (rawshake(256, 128, "")) return -1; + + answer = "46b9dd2b0ba88d13233b3feb743eeb24"; + if (rawshake_bits(256, 128, "\x03", 2)) return -1; + + answer = "46b9dd2b0ba88d13233b3feb743eeb24"; + if (shake(256, 128, "")) return -1; + + + answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de92253515713cce8" + "d2098be1c82df40b40e375549c0eeb655f92d718f01f147ba1c7c67844c7ba8b11492cd6"; + if (keccak_g(1024, 1600 - 1024, 576, "capitol's kvistfri broadly raping")) return -1; + + answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de92253515713cce8" + "d2098be1c82df40b40e375549c0eeb655f92d718f01f147ba1c7c67844c7ba8b11492cd6" + "143466958504c110522f772fe746573b1dc905f943ed1ec6ecf858575798596beeca4eb6" + "bb7bea635bcea6331315728fb57866370bf1ad5d"; + if (keccak_g(1024, 1600 - 1024, 1024, "capitol's kvistfri broadly raping")) return -1; + + answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de92253515713cce8" + "d2098be1c82df40b40e375549c0eeb655f92d718f01f147ba1c7c67844c7ba8b11492cd6" + "143466958504c110522f772fe746573b1dc905f943ed1ec6ecf858575798596beeca4eb6" + "bb7bea635bcea6331315728fb57866370bf1ad5decbc56d28d47ce53f18376d9f5531551" + "7a976d52dd3f98b7025e0b3c513c6d17d40462cddb5406d693bbe859a136af5375b5dd6e" + "3478934b00aa6cd44aa7ae2cd0271d83fbab699b"; + if (keccak_g(1024, 1600 - 1024, 1600, "capitol's kvistfri broadly raping")) return -1; + + answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de92253515713cce8" + "d2098be1c82df40b40e375549c0eeb655f92d718f01f147ba1c7c67844c7ba8b11492cd6" + "143466958504c110522f772fe746573b1dc905f943ed1ec6ecf858575798596beeca4eb6" + "bb7bea635bcea6331315728fb57866370bf1ad5decbc56d28d47ce53f18376d9f5531551" + "7a976d52dd3f98b7025e0b3c513c6d17d40462cddb5406d693bbe859a136af5375b5dd6e" + "3478934b00aa6cd44aa7ae2cd0271d83fbab699b9c"; + if (keccak_g(1024, 1600 - 1024, 1608, "capitol's kvistfri broadly raping")) return -1; + + answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de92253515713cce8" + "d2098be1c82df40b40e375549c0eeb655f92d718f01f147ba1c7c67844c7ba8b11492cd6" + "143466958504c110522f772fe746573b1dc905f943ed1ec6ecf858575798596beeca4eb6" + "bb7bea635bcea6331315728fb57866370bf1ad5decbc56d28d47ce53f18376d9f5531551" + "7a976d52dd3f98b7025e0b3c513c6d17d40462cddb5406d693bbe859a136af5375b5dd6e" + "3478934b00aa6cd44aa7ae2cd0271d83fbab699b9c58351bf7d26586b9c32282f1ac6356" + "1981b79791d7ab2b6e01f5b8e6cf0cab8b2076fd82bd99df015a602cdda5684162fea982" + "0f5a441c4620f549fbaf4e818201f292dbf4f6c9f82af8aa80b4124984da6f65b2874e0e" + "f01d042c08e9aedbb6ce4c10526e38c1a4e8b108c4f14b066f9d42640687b55124b081da" + "a9f9ae4232f313740b4fb787545dc19e7778f7082b3fa5824d2400c012be1a6c5ade7149" + "e452d310752fa9ebb964ab36fde0c8f46f47a0e2c9b20f24e3cca904bbedaa7ea176f662" + "33cd2d95"; + if (keccak_g(1024, 1600 - 1024, 3200, "capitol's kvistfri broadly raping")) return -1; + + answer = "65070cdd6f91c0aadcfc470895a2606c828bce7ce3fa723418c9013de9225351"; + if (keccak_g(1024, 1600 - 1024, 256, "capitol's kvistfri broadly raping")) return -1; + + answer = "e6f86ebc15b962f73f36f36fc8a84c3ae84b1c1023bfd4c5f1829389135aecc3"; + if (keccak_g(512, 1600 - 512, 256, "capitol's kvistfri broadly raping")) return -1; + + answer = "420b97fc88962c87ec2adaa8f48d74d9ff4ea7ae7d691f9c33b8713ca1d3d573"; + if (keccak_g(256, 1600 - 256, 256, "capitol's kvistfri broadly raping")) return -1; + + answer = "524790afbe4706d938b6f753e14104f556890e2a415e211b0564d60499db0333"; + if (keccak_g(512, 800 - 512, 256, "capitol's kvistfri broadly raping")) return -1; + + answer = "04a6b4ad08b3018eefba0fb756272d949ac0f71c26f836d31dd13b28b884aa0f"; + if (keccak_g(256, 800 - 256, 256, "capitol's kvistfri broadly raping")) return -1; + + answer = "d56f547791225e54460e6274ed31e57b7085820c11d65f1f322a16a3352c85ed"; + if (keccak_g(256, 400 - 256, 256, "capitol's kvistfri broadly raping")) return -1; + + answer = "ceec066a57b9b31a5a0661df7bafec4183a26d0ed81e50bc958471f84fa347a7"; + if (keccak_g(128, 400 - 128, 256, "capitol's kvistfri broadly raping")) return -1; + + answer = "b18f679c7105a72a993f70fa5adb3f17ef7ccffaffb4dc0f6fed74aa2f565194"; + if (keccak_g(128, 200 - 128, 256, "capitol's kvistfri broadly raping")) return -1; + + answer = "9b845c1ecc2b1b3a48ba42ef29ccc4b348da8ab15074a870d8e799ca33c15e4b"; + if (keccak_g(64, 200 - 64, 256, "capitol's kvistfri broadly raping")) return -1; + + + printf("\n"); + return 0; + #undef keccak_g #undef shake #undef rawshake_bits @@ -380,37 +372,38 @@ static int test_digest(void) * @param expected_answer The expected answer, must be lowercase * @return Zero on success, -1 on error */ -static int test_update_case(const libkeccak_spec_t* restrict spec, const char* restrict suffix, - const char* restrict msg, const char* restrict expected_answer) +static int +test_update_case(const libkeccak_spec_t *restrict spec, const char *restrict suffix, + const char *restrict msg, const char *restrict expected_answer) { - libkeccak_state_t state; - char* restrict hashsum; - char* restrict hexsum; - int ok; - - if (libkeccak_state_initialise(&state, spec)) - return perror("libkeccak_state_initialise"), -1; - if (hashsum = malloc((spec->output + 7) / 8), hashsum == NULL) - return perror("malloc"), -1; - if (hexsum = malloc((spec->output + 7) / 8 * 2 + 1), hexsum == NULL) - return perror("malloc"), -1; - - if (libkeccak_update(&state, msg, strlen(msg))) - return perror("libkeccak_update"), -1; - if (libkeccak_digest(&state, NULL, 0, 0, suffix, hashsum)) - return perror("libkeccak_digest"), -1; - libkeccak_state_fast_destroy(&state); - - libkeccak_behex_lower(hexsum, hashsum, (spec->output + 7) / 8); - ok = !strcmp(hexsum, expected_answer); - printf("%s%s\n", ok ? "OK" : "Fail: ", ok ? "" : hexsum); - if (!ok) - printf(" r, c, n = %li, %li, %li\n", spec->bitrate, spec->capacity, spec->output); - - free(hashsum); - free(hexsum); - - return ok - 1; + libkeccak_state_t state; + char *restrict hashsum; + char *restrict hexsum; + int ok; + + if (libkeccak_state_initialise(&state, spec)) + return perror("libkeccak_state_initialise"), -1; + if (hashsum = malloc((spec->output + 7) / 8), hashsum == NULL) + return perror("malloc"), -1; + if (hexsum = malloc((spec->output + 7) / 8 * 2 + 1), hexsum == NULL) + return perror("malloc"), -1; + + if (libkeccak_update(&state, msg, strlen(msg))) + return perror("libkeccak_update"), -1; + if (libkeccak_digest(&state, NULL, 0, 0, suffix, hashsum)) + return perror("libkeccak_digest"), -1; + libkeccak_state_fast_destroy(&state); + + libkeccak_behex_lower(hexsum, hashsum, (spec->output + 7) / 8); + ok = !strcmp(hexsum, expected_answer); + printf("%s%s\n", ok ? "OK" : "Fail: ", ok ? "" : hexsum); + if (!ok) + printf(" r, c, n = %li, %li, %li\n", spec->bitrate, spec->capacity, spec->output); + + free(hashsum); + free(hexsum); + + return ok - 1; } @@ -421,51 +414,51 @@ static int test_update_case(const libkeccak_spec_t* restrict spec, const char* r */ static int test_update(void) { -#define sha3(output, message) \ - (printf(" Testing SHA3-"#output"(%s): ", #message), \ - libkeccak_spec_sha3(&spec, output), \ - test_update_case(&spec, LIBKECCAK_SHA3_SUFFIX, message, answer)) - - libkeccak_spec_t spec; - const char* answer; - - printf("Testing libkeccak_update:\n"); - - - answer = "22c8017ac8bcf65f59d1b7e92c9d4c6739d25e34ce5cb608b24ff096"; - if (sha3(224, "withdrew hypothesis snakebird qmc2")) return -1; - - answer = "43808dde2662143dc4eed5dac5e98c74b06711829f02a3b121bd74f3"; - if (sha3(224, "intensifierat sturdiness perl-image-exiftool vingla")) return -1; - - answer = "d32b4ac86065774dee5eb5cdd2f67b4e86501086d7373884e8b20a36"; - if (sha3(224, "timjan avogadro uppdriven lib32-llvm-amdgpu-snapshot")) return -1; - - answer = "efbd76d45bfa952485148f8ad46143897f17c27ffdc8eb7287f9353b"; - if (sha3(224, "grilo-plugins auditorium tull dissimilarity's")) return -1; - - answer = "6705aa36ecf58f333e0e6364ac1d0b7931d402e13282127cfd6f876c"; - if (sha3(224, "royalty tt yellowstone deficiencies")) return -1; - - answer = "803a0ff09dda0df306e483a9f91b20a3dbbf9c2ebb8d0a3b28f3b9e0"; - if (sha3(224, "kdegames-kdiamond tunisisk occurrence's outtalad")) return -1; - - answer = "a64779aca943a6aef1d2e7c9a0f4e997f4dabd1f77112a22121d3ed5"; - if (sha3(224, "chevalier slat's spindel representations")) return -1; - - answer = "f0a3e0587af7723f0aa4719059d3f5107115a5b3667cd5209cc4d867"; - if (sha3(224, "archery lexicographical equine veered")) return -1; - - answer = "312e7e3c6403ab1a086155fb9a52b22a3d0d257876afd2b93fb7272e"; - if (sha3(224, "splay washbasin opposing there")) return -1; - - answer = "270ba05b764221ff5b5d94adfb4fdb1f36f07fe7c438904a5f3df071"; - if (sha3(224, "faktum desist thundered klen")) return -1; - - - printf("\n"); - return 0; - +#define sha3(output, message)\ + (printf(" Testing SHA3-"#output"(%s): ", #message),\ + libkeccak_spec_sha3(&spec, output),\ + test_update_case(&spec, LIBKECCAK_SHA3_SUFFIX, message, answer)) + + libkeccak_spec_t spec; + const char* answer; + + printf("Testing libkeccak_update:\n"); + + + answer = "22c8017ac8bcf65f59d1b7e92c9d4c6739d25e34ce5cb608b24ff096"; + if (sha3(224, "withdrew hypothesis snakebird qmc2")) return -1; + + answer = "43808dde2662143dc4eed5dac5e98c74b06711829f02a3b121bd74f3"; + if (sha3(224, "intensifierat sturdiness perl-image-exiftool vingla")) return -1; + + answer = "d32b4ac86065774dee5eb5cdd2f67b4e86501086d7373884e8b20a36"; + if (sha3(224, "timjan avogadro uppdriven lib32-llvm-amdgpu-snapshot")) return -1; + + answer = "efbd76d45bfa952485148f8ad46143897f17c27ffdc8eb7287f9353b"; + if (sha3(224, "grilo-plugins auditorium tull dissimilarity's")) return -1; + + answer = "6705aa36ecf58f333e0e6364ac1d0b7931d402e13282127cfd6f876c"; + if (sha3(224, "royalty tt yellowstone deficiencies")) return -1; + + answer = "803a0ff09dda0df306e483a9f91b20a3dbbf9c2ebb8d0a3b28f3b9e0"; + if (sha3(224, "kdegames-kdiamond tunisisk occurrence's outtalad")) return -1; + + answer = "a64779aca943a6aef1d2e7c9a0f4e997f4dabd1f77112a22121d3ed5"; + if (sha3(224, "chevalier slat's spindel representations")) return -1; + + answer = "f0a3e0587af7723f0aa4719059d3f5107115a5b3667cd5209cc4d867"; + if (sha3(224, "archery lexicographical equine veered")) return -1; + + answer = "312e7e3c6403ab1a086155fb9a52b22a3d0d257876afd2b93fb7272e"; + if (sha3(224, "splay washbasin opposing there")) return -1; + + answer = "270ba05b764221ff5b5d94adfb4fdb1f36f07fe7c438904a5f3df071"; + if (sha3(224, "faktum desist thundered klen")) return -1; + + + printf("\n"); + return 0; + #undef sha3 } @@ -483,29 +476,29 @@ static int test_update(void) * @param expected_answer The hashum we expect, must be in lowercase hexadecimal * @return Zero on success, -1 on error */ -static int test_squeeze_case(libkeccak_state_t* restrict state, const libkeccak_spec_t* restrict spec, - long fast_squeezes, long squeezes, int fast_digest, char* restrict hashsum, - char* restrict hexsum, const char* restrict expected_answer) +static int test_squeeze_case(libkeccak_state_t *restrict state, const libkeccak_spec_t *restrict spec, + long fast_squeezes, long squeezes, int fast_digest, char* restrict hashsum, + char *restrict hexsum, const char *restrict expected_answer) { -#define message "withdrew hypothesis snakebird qmc2" - long i; - int ok; - - libkeccak_state_reset(state); - if (libkeccak_digest(state, message, strlen(message), 0, LIBKECCAK_SHA3_SUFFIX, fast_digest ? NULL : hashsum)) - return perror("libkeccak_digest"), -1; - - libkeccak_fast_squeeze(state, fast_squeezes); - for (i = fast_squeezes; i < squeezes; i++) - libkeccak_squeeze(state, hashsum); - - libkeccak_behex_lower(hexsum, hashsum, (spec->output + 7) / 8); - ok = !strcmp(hexsum, expected_answer); - printf("%s%s\n", ok ? "OK" : "Fail: ", ok ? "" : hexsum); - if (!ok) - printf(" r, c, n = %li, %li, %li\n", spec->bitrate, spec->capacity, spec->output); - - return ok - 1; +#define message "withdrew hypothesis snakebird qmc2" + long i; + int ok; + + libkeccak_state_reset(state); + if (libkeccak_digest(state, message, strlen(message), 0, LIBKECCAK_SHA3_SUFFIX, fast_digest ? NULL : hashsum)) + return perror("libkeccak_digest"), -1; + + libkeccak_fast_squeeze(state, fast_squeezes); + for (i = fast_squeezes; i < squeezes; i++) + libkeccak_squeeze(state, hashsum); + + libkeccak_behex_lower(hexsum, hashsum, (spec->output + 7) / 8); + ok = !strcmp(hexsum, expected_answer); + printf("%s%s\n", ok ? "OK" : "Fail: ", ok ? "" : hexsum); + if (!ok) + printf(" r, c, n = %li, %li, %li\n", spec->bitrate, spec->capacity, spec->output); + + return ok - 1; #undef message } @@ -515,60 +508,61 @@ static int test_squeeze_case(libkeccak_state_t* restrict state, const libkeccak_ * * @return Zero on success, -1 on error */ -static int test_squeeze(void) +static int +test_squeeze(void) { -#define answer1 "03fe12b4b51d56d96377d927e5cd498fc4bc3aee389b2f2ff8393aa5" -#define answer2 "0b8fb64ee5d8836956f49cbe4577afbc638c855c1d553452fc1eceb8" -#define answer3 "1e03b4cd9eef3892a7b5e865fce393c4bc90120d9aea84d0a0dff3b8" -#define answer4 "aac92fbfd22ce62e83ddaf2e61bd7bf696326e46d1327defa4530e20" - -#define run_test(fast_squeezes, squeezes, fast_digest) \ - test_squeeze_case(&state, &spec, fast_squeezes, squeezes, fast_digest, hashsum, hexsum, answer##squeezes) - - libkeccak_spec_t spec; - libkeccak_state_t state; - char* restrict hashsum; - char* restrict hexsum; - - libkeccak_spec_sha3(&spec, 224); - if (hashsum = malloc((spec.output + 7) / 8), hashsum == NULL) - return perror("malloc"), -1; - if (hexsum = malloc((spec.output + 7) / 8 * 2 + 1), hexsum == NULL) - return perror("malloc"), -1; - if (libkeccak_state_initialise(&state, &spec)) - return perror("libkeccak_state_initialise"), -1; - - printf("Testing squeeze functions with slow initial digest:\n"); - printf(" 1 extra squeeze, including 0 fast squeezes: "), run_test(0, 1, 0); - printf(" 2 extra squeezes, including 0 fast squeezes: "), run_test(0, 2, 0); - printf(" 2 extra squeezes, including 1 fast squeeze: "), run_test(1, 2, 0); - printf(" 3 extra squeezes, including 0 fast squeezes: "), run_test(0, 3, 0); - printf(" 3 extra squeezes, including 1 fast squeeze: "), run_test(1, 3, 0); - printf(" 3 extra squeezes, including 2 fast squeezes: "), run_test(2, 3, 0); - printf(" 4 extra squeezes, including 0 fast squeezes: "), run_test(0, 4, 0); - printf(" 4 extra squeezes, including 1 fast squeeze: "), run_test(1, 4, 0); - printf(" 4 extra squeezes, including 2 fast squeezes: "), run_test(2, 4, 0); - printf(" 4 extra squeezes, including 3 fast squeezes: "), run_test(3, 4, 0); - printf("\n"); - - printf("Testing squeeze functions with fast initial digest:\n"); - printf(" 1 extra squeeze, including 0 fast squeezes: "), run_test(0, 1, 1); - printf(" 2 extra squeezes, including 0 fast squeezes: "), run_test(0, 2, 1); - printf(" 2 extra squeezes, including 1 fast squeeze: "), run_test(1, 2, 1); - printf(" 3 extra squeezes, including 0 fast squeezes: "), run_test(0, 3, 1); - printf(" 3 extra squeezes, including 1 fast squeeze: "), run_test(1, 3, 1); - printf(" 3 extra squeezes, including 2 fast squeezes: "), run_test(2, 3, 1); - printf(" 4 extra squeezes, including 0 fast squeezes: "), run_test(0, 4, 1); - printf(" 4 extra squeezes, including 1 fast squeeze: "), run_test(1, 4, 1); - printf(" 4 extra squeezes, including 2 fast squeezes: "), run_test(2, 4, 1); - printf(" 4 extra squeezes, including 3 fast squeezes: "), run_test(3, 4, 1); - printf("\n"); - - libkeccak_state_fast_destroy(&state); - free(hashsum); - free(hexsum); - return 0; - +#define answer1 "03fe12b4b51d56d96377d927e5cd498fc4bc3aee389b2f2ff8393aa5" +#define answer2 "0b8fb64ee5d8836956f49cbe4577afbc638c855c1d553452fc1eceb8" +#define answer3 "1e03b4cd9eef3892a7b5e865fce393c4bc90120d9aea84d0a0dff3b8" +#define answer4 "aac92fbfd22ce62e83ddaf2e61bd7bf696326e46d1327defa4530e20" + +#define run_test(fast_squeezes, squeezes, fast_digest)\ + test_squeeze_case(&state, &spec, fast_squeezes, squeezes, fast_digest, hashsum, hexsum, answer##squeezes) + + libkeccak_spec_t spec; + libkeccak_state_t state; + char *restrict hashsum; + char *restrict hexsum; + + libkeccak_spec_sha3(&spec, 224); + if (hashsum = malloc((spec.output + 7) / 8), hashsum == NULL) + return perror("malloc"), -1; + if (hexsum = malloc((spec.output + 7) / 8 * 2 + 1), hexsum == NULL) + return perror("malloc"), -1; + if (libkeccak_state_initialise(&state, &spec)) + return perror("libkeccak_state_initialise"), -1; + + printf("Testing squeeze functions with slow initial digest:\n"); + printf(" 1 extra squeeze, including 0 fast squeezes: "), run_test(0, 1, 0); + printf(" 2 extra squeezes, including 0 fast squeezes: "), run_test(0, 2, 0); + printf(" 2 extra squeezes, including 1 fast squeeze: "), run_test(1, 2, 0); + printf(" 3 extra squeezes, including 0 fast squeezes: "), run_test(0, 3, 0); + printf(" 3 extra squeezes, including 1 fast squeeze: "), run_test(1, 3, 0); + printf(" 3 extra squeezes, including 2 fast squeezes: "), run_test(2, 3, 0); + printf(" 4 extra squeezes, including 0 fast squeezes: "), run_test(0, 4, 0); + printf(" 4 extra squeezes, including 1 fast squeeze: "), run_test(1, 4, 0); + printf(" 4 extra squeezes, including 2 fast squeezes: "), run_test(2, 4, 0); + printf(" 4 extra squeezes, including 3 fast squeezes: "), run_test(3, 4, 0); + printf("\n"); + + printf("Testing squeeze functions with fast initial digest:\n"); + printf(" 1 extra squeeze, including 0 fast squeezes: "), run_test(0, 1, 1); + printf(" 2 extra squeezes, including 0 fast squeezes: "), run_test(0, 2, 1); + printf(" 2 extra squeezes, including 1 fast squeeze: "), run_test(1, 2, 1); + printf(" 3 extra squeezes, including 0 fast squeezes: "), run_test(0, 3, 1); + printf(" 3 extra squeezes, including 1 fast squeeze: "), run_test(1, 3, 1); + printf(" 3 extra squeezes, including 2 fast squeezes: "), run_test(2, 3, 1); + printf(" 4 extra squeezes, including 0 fast squeezes: "), run_test(0, 4, 1); + printf(" 4 extra squeezes, including 1 fast squeeze: "), run_test(1, 4, 1); + printf(" 4 extra squeezes, including 2 fast squeezes: "), run_test(2, 4, 1); + printf(" 4 extra squeezes, including 3 fast squeezes: "), run_test(3, 4, 1); + printf("\n"); + + libkeccak_state_fast_destroy(&state); + free(hashsum); + free(hexsum); + return 0; + #undef run_test #undef answer4 #undef answer3 @@ -587,38 +581,39 @@ static int test_squeeze(void) * @param expected_answer The hashum we expect, must be in lowercase hexadecimal * @return Zero on success, -1 on error */ -static int test_file(const libkeccak_spec_t* restrict spec, const char* restrict suffix, - const char* restrict filename, const char* restrict expected_answer) +static int +test_file(const libkeccak_spec_t *restrict spec, const char *restrict suffix, + const char *restrict filename, const char *restrict expected_answer) { - libkeccak_state_t state; - char* restrict hashsum; - char* restrict hexsum; - int ok, fd; - - printf("Testing libkeccak_generalised_sum_fd on %s: ", filename); - - if (hashsum = malloc((spec->output + 7) / 8), hashsum == NULL) - return perror("malloc"), -1; - if (hexsum = malloc((spec->output + 7) / 8 * 2 + 1), hexsum == NULL) - return perror("malloc"), -1; - - if (fd = open(filename, O_RDONLY), fd < 0) - return perror("open"), -1; - - if (libkeccak_generalised_sum_fd(fd, &state, spec, suffix, hashsum)) - return perror("libkeccak_generalised_sum_fd"), close(fd), -1; - - libkeccak_behex_lower(hexsum, hashsum, (spec->output + 7) / 8); - ok = !strcmp(hexsum, expected_answer); - printf("%s%s\n", ok ? "OK" : "Fail: ", ok ? "" : hexsum); - if (!ok) - printf(" r, c, n = %li, %li, %li\n", spec->bitrate, spec->capacity, spec->output); - - close(fd); - free(hashsum); - free(hexsum); - libkeccak_state_fast_destroy(&state); - return ok - 1; + libkeccak_state_t state; + char *restrict hashsum; + char *restrict hexsum; + int ok, fd; + + printf("Testing libkeccak_generalised_sum_fd on %s: ", filename); + + if (hashsum = malloc((spec->output + 7) / 8), hashsum == NULL) + return perror("malloc"), -1; + if (hexsum = malloc((spec->output + 7) / 8 * 2 + 1), hexsum == NULL) + return perror("malloc"), -1; + + if (fd = open(filename, O_RDONLY), fd < 0) + return perror("open"), -1; + + if (libkeccak_generalised_sum_fd(fd, &state, spec, suffix, hashsum)) + return perror("libkeccak_generalised_sum_fd"), close(fd), -1; + + libkeccak_behex_lower(hexsum, hashsum, (spec->output + 7) / 8); + ok = !strcmp(hexsum, expected_answer); + printf("%s%s\n", ok ? "OK" : "Fail: ", ok ? "" : hexsum); + if (!ok) + printf(" r, c, n = %li, %li, %li\n", spec->bitrate, spec->capacity, spec->output); + + close(fd); + free(hashsum); + free(hexsum); + libkeccak_state_fast_destroy(&state); + return ok - 1; } @@ -629,39 +624,39 @@ static int test_file(const libkeccak_spec_t* restrict spec, const char* restrict * * @return Zero on success, 1 on failure or incorrectness */ -int main(void) +int +main(void) { - libkeccak_generalised_spec_t gspec; - libkeccak_spec_t spec; - - libkeccak_generalised_spec_initialise(&gspec); - if (libkeccak_degeneralise_spec(&gspec, &spec)) - return printf("libkeccak_degeneralise_spec failed with all members at automatic.\n"), 1; - - printf("Resolution of default specification:\n"); - printf(" bitrate: %li\n", gspec.bitrate); - printf(" capacity: %li\n", gspec.capacity); - printf(" output: %li\n", gspec.output); - printf(" state size: %li\n", gspec.state_size); - printf(" word size: %li\n", gspec.word_size); - if (gspec.word_size * 25 != gspec.state_size) return printf("Invalid information\n"), 1; - if (gspec.bitrate + gspec.capacity != gspec.state_size) return printf("Invalid information\n"), 1; - if (gspec.state_size != 1600) return printf("Incorrect information\n"), 1; - if (gspec.bitrate != gspec.output * 2) return printf("Incorrect information\n"), 1; - if (gspec.output != 512) return printf("Incorrect information\n"), 1; - printf("\n"); - - if (test_hex()) return 1; - if (test_state(&spec)) return 1; - if (test_digest()) return 1; - if (test_update()) return 1; - if (test_squeeze()) return 1; - - if (test_file(&spec, LIBKECCAK_SHA3_SUFFIX, "LICENSE", - "68dd720832a594c1986078d2d09ab21d80b9d66d98c52f2679e81699519e2f8a" - "3c970bb9c514206b574a944ffaa6466d546eb17f64f47c01ec053ab4ce35575a")) - return 1; + libkeccak_generalised_spec_t gspec; + libkeccak_spec_t spec; + + libkeccak_generalised_spec_initialise(&gspec); + if (libkeccak_degeneralise_spec(&gspec, &spec)) + return printf("libkeccak_degeneralise_spec failed with all members at automatic.\n"), 1; + + printf("Resolution of default specification:\n"); + printf(" bitrate: %li\n", gspec.bitrate); + printf(" capacity: %li\n", gspec.capacity); + printf(" output: %li\n", gspec.output); + printf(" state size: %li\n", gspec.state_size); + printf(" word size: %li\n", gspec.word_size); + if (gspec.word_size * 25 != gspec.state_size) return printf("Invalid information\n"), 1; + if (gspec.bitrate + gspec.capacity != gspec.state_size) return printf("Invalid information\n"), 1; + if (gspec.state_size != 1600) return printf("Incorrect information\n"), 1; + if (gspec.bitrate != gspec.output * 2) return printf("Incorrect information\n"), 1; + if (gspec.output != 512) return printf("Incorrect information\n"), 1; + printf("\n"); + + if (test_hex()) return 1; + if (test_state(&spec)) return 1; + if (test_digest()) return 1; + if (test_update()) return 1; + if (test_squeeze()) return 1; + + if (test_file(&spec, LIBKECCAK_SHA3_SUFFIX, ".testfile", + "a95484492e9ade0f1d28f872d197ff45d891e85e78f918643f41d524c5d6ab0f" + "17974dc08ec82870b132612dcbeb062213bf594881dc764d6078865a7c694c57")) + return 1; - return 0; + return 0; } - |