aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2017-10-14 01:01:14 +0200
committerMattias Andrée <maandree@kth.se>2017-10-14 01:01:14 +0200
commit3e1864aa14a33a3c917537a241f6a032cfcacf78 (patch)
tree25297b1363fa88c9f45b5102afa5e95d08e986c1 /src
parentChange style and license (diff)
downloadlibkeccak-3e1864aa14a33a3c917537a241f6a032cfcacf78.tar.gz
libkeccak-3e1864aa14a33a3c917537a241f6a032cfcacf78.tar.bz2
libkeccak-3e1864aa14a33a3c917537a241f6a032cfcacf78.tar.xz
General improvements
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'src')
-rwxr-xr-xsrc/benchmark-flags116
-rw-r--r--src/benchmark.c139
-rw-r--r--src/libkeccak.h13
-rw-r--r--src/libkeccak/digest.c588
-rw-r--r--src/libkeccak/digest.h100
-rw-r--r--src/libkeccak/files.c57
-rw-r--r--src/libkeccak/files.h115
-rw-r--r--src/libkeccak/generalised-spec.c111
-rw-r--r--src/libkeccak/generalised-spec.h142
-rw-r--r--src/libkeccak/hex.c65
-rw-r--r--src/libkeccak/hex.h44
-rw-r--r--src/libkeccak/internal.h26
-rw-r--r--src/libkeccak/mac/hmac.c418
-rw-r--r--src/libkeccak/mac/hmac.h393
-rw-r--r--src/libkeccak/spec.h177
-rw-r--r--src/libkeccak/state.c175
-rw-r--r--src/libkeccak/state.h295
-rw-r--r--src/test.c662
18 files changed, 0 insertions, 3636 deletions
diff --git a/src/benchmark-flags b/src/benchmark-flags
deleted file mode 100755
index 1168ec0..0000000
--- a/src/benchmark-flags
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/bin/sh
-# See LICENSE file for copyright and license details.
-
-set -e
-
-export LD_LIBRARY_PATH=bin
-if test "${TRIES}" = ""; then
- TRIES=10
-fi
-
-# List all flags that affect the object files
-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
-EOF
-}
-
-cppflags="-DIGNORE_BEHEXING"
-base_flags='-march=native -O0'
-test_flags=" $(echo $(list_test_flags)) "
-
-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 "${test_flag}" = ""; then
- test_flag=zzz
- fi
- echo "$(bin/benchmark || echo error) ${test_flag}" >&3
- 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 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
- 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.
-# -faggressive-loop-optimizations -fauto-inc-dec -fbranch-target-load-optimize
-# -fbranch-target-load-optimize2 -fbtr-bb-exclusive -fcaller-saves -fcheck-data-deps
-# -fcombine-stack-adjustments -fconserve-stack -fcompare-elim -fcprop-registers
-# -fcse-follow-jumps -fcse-skip-blocks -fcx-fortran-rules -fcx-limited-range -fdce
-# -fdelete-null-pointer-checks -fdevirtualize -fdevirtualize-speculatively -fdse
-# -fearly-inlining -fipa-sra -ffat-lto-objects -fbranch-probabilities
-# -fassociative-math -fforward-propagate -ffunction-sections -fforward-propagate
-# -ffast-math -ffinite-math-only -ffloat-store -fgcse -fgcse-after-reload -fgcse-las
-# -fgcse-lm -fgraphite-identity -fgcse-sm -fhoist-adjacent-loads -fif-conversion
-# -fif-conversion2 -findirect-inlining -finline-functions -finline-functions-called-once
-# -finline-small-functions -fipa-cp -fipa-cp-clone -fipa-pta -fipa-profile
-# -fipa-pure-const -fipa-reference -fira-hoist-pressure -fira-loop-pressure
-# -fno-ira-share-save-slots -fno-ira-share-spill-slots -fisolate-erroneous-paths-dereference
-# -fisolate-erroneous-paths-attribute -fivopts -fkeep-static-consts -flive-range-shrinkage
-# -floop-block -floop-interchange -floop-strip-mine -floop-nest-optimize
-# -floop-parallelize-all -fmodulo-sched -fmodulo-sched-allow-regmoves -fmove-loop-invariants
-# -fno-branch-count-reg -fno-defer-pop -fno-function-cse -fno-guess-branch-probability
-# -fno-defer-pop -fno-function-cse -fno-guess-branch-probability -fno-inline -fno-math-errno
-# -fno-peephole -fno-peephole2 -fno-sched-interblock -fno-sched-spec -fno-signed-zeros
-# -fno-toplevel-reorder -fno-trapping-math -fno-zero-initialized-in-bss
-# -foptimize-sibling-calls -fpartial-inlining -fpeel-loops -fpredictive-commoning
-# -fprefetch-loop-arrays -fprofile-report -fprofile-use -fprofile-values
-# -fprofile-reorder-functions -freciprocal-math -free -frename-registers -freorder-blocks
-# -frerun-cse-after-loop -freschedule-modulo-scheduled-loops -frounding-math
-# -fsched2-use-superblocks -fsched-pressure -fsched-spec-load -fsched-spec-load-dangerous
-# -fsched-group-heuristic -fsched-critical-path-heuristic -fsched-spec-insn-heuristic
-# -fsched-rank-heuristic -fsched-last-insn-heuristic -fsched-dep-count-heuristic
-# -fselective-scheduling -fselective-scheduling2 -fsel-sched-pipelining
-# -fsel-sched-pipelining-outer-loops -fshrink-wrap -fsignaling-nans
-# -fsingle-precision-constant -fstrict-overflow -fthread-jumps -ftracer -ftree-bit-ccp
-# -ftree-builtin-call-dce -ftree-ccp -ftree-ch -ftree-copyrename -ftree-dce
-# -ftree-dominator-opts -ftree-dse -ftree-forwprop -ftree-fre -ftree-loop-if-convert
-# -ftree-loop-if-convert-stores -ftree-loop-im -ftree-phiprop -ftree-loop-distribution
-# -ftree-loop-distribute-patterns -ftree-loop-ivcanon -ftree-loop-linear
-# -ftree-loop-optimize -ftree-loop-vectorize -ftree-pre -ftree-partial-pre -ftree-pta
-# -ftree-reassoc -ftree-sink -ftree-slsr -ftree-sra -ftree-vectorize -ftree-vrp
-# -funit-at-a-time -funroll-all-loops -funroll-loops -funsafe-loop-optimizations
-# -funsafe-math-optimizations -funswitch-loops -fvariable-expansion-in-unroller
-# -fvect-cost-model -fvpt -fweb -fprofile-correction -freorder-functions
-# -fschedule-insns -fschedule-insns2 -fsplit-ivs-in-unroller -fsplit-wide-types
-# -fstrict-aliasing -ftree-coalesce-vars -ftree-copy-prop -ftree-switch-conversion
-# -ftree-switch-conversion -ftree-tail-merge -ftree-coalesce-inlined-vars
-# -falign-jumps=0 -falign-labels=0 -falign-loops=0 -ftree-parallelize-loops=10
-# -fsched-stalled-insns-dep=0 -fsched-stalled-insns=0
-
diff --git a/src/benchmark.c b/src/benchmark.c
deleted file mode 100644
index 1ce7da9..0000000
--- a/src/benchmark.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <libkeccak.h>
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
-
-#ifndef MESSAGE_FILE
-# define MESSAGE_FILE "LICENSE"
-#endif
-#ifndef MESSAGE_LEN
-# define MESSAGE_LEN 34520
-#endif
-
-
-#ifndef BITRATE
-# define BITRATE 1024
-#endif
-#ifndef CAPACITY
-# define CAPACITY 576
-#endif
-#ifndef OUTPUT
-# define OUTPUT 512
-#endif
-
-#ifndef UPDATE_RUNS
-# define UPDATE_RUNS 100
-#endif
-#ifndef FAST_SQUEEZE_RUNS
-# define FAST_SQUEEZE_RUNS 100
-#endif
-#ifndef SLOW_SQUEEZE_RUNS
-# define SLOW_SQUEEZE_RUNS 100
-#endif
-#ifndef RERUNS
-# define RERUNS 50
-#endif
-
-
-
-/**
- * Benchmark, will print the number of nanoseconds
- * spent with hashing algorithms and representation
- * conversion from binary to hexadecimal. The latter
- * can be compiled out by compiling with -DIGNORE_BEHEXING.
- *
- * @return Zero on success, 1 on error
- */
-int
-main(void)
-{
- 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];
-#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. */
-#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;
-#endif
-
- /* 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);
-#endif
-
- /* Fast squeezes. */
-#if FAST_SQUEEZE_RUNS > 0
- libkeccak_fast_squeeze(&state, FAST_SQUEEZE_RUNS);
-#endif
-
- /* Slow squeezes. */
-#if SLOW_SQUEEZE_RUNS > 0
- for (i = 0; i < SLOW_SQUEEZE_RUNS; i++) {
- libkeccak_squeeze(&state, hashsum);
-# ifndef IGNORE_BEHEXING
- 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;
-
-#if (UPDATE_RUNS == 0) && (SLOW_SQUEEZE_RUNS == 0)
- (void) i;
-#endif
-}
diff --git a/src/libkeccak.h b/src/libkeccak.h
deleted file mode 100644
index 7c71801..0000000
--- a/src/libkeccak.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#ifndef LIBKECCAK_H
-#define LIBKECCAK_H 1
-
-#include "libkeccak/spec.h"
-#include "libkeccak/generalised-spec.h"
-#include "libkeccak/state.h"
-#include "libkeccak/digest.h"
-#include "libkeccak/hex.h"
-#include "libkeccak/files.h"
-#include "libkeccak/mac/hmac.h"
-
-#endif
diff --git a/src/libkeccak/digest.c b/src/libkeccak/digest.c
deleted file mode 100644
index 5f7a32c..0000000
--- a/src/libkeccak/digest.c
+++ /dev/null
@@ -1,588 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include "digest.h"
-
-#include "state.h"
-
-
-
-/**
- * X-macro-enabled listing of all intergers in [0, 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)
-
-/**
- * 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)
-
-/**
- * X-macro-enabled listing of all intergers in [0, 24]
- */
-#define LIST_25 LIST_24 X(24)
-
-
-
-#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
- */
-static const long LANE_TRANSPOSE_MAP[] = { LIST_25 };
-#undef X
-
-
-
-/**
- * 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
-};
-
-
-/**
- * Rotate a word
- *
- * @param x:int_fast64_t The value to rotate
- * @param n:long Rotation steps, may be zero mod `w`
- * @param w:long `state->w`
- * @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))
-
-
-/**
- * Rotate a 64-bit word
- *
- * @param x:int_fast64_t The value to rotate
- * @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))))
-
-
-/**
- * Perform one round of computation
- *
- * @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)
-{
- 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);
-#undef X
-
- /* ξ step. */
-#define X(N) A[N] = B[N] ^ ((~(B[(N + 5) % 25])) & B[(N + 10) % 25]);
- LIST_25;
-#undef X
-
- /* ι step. */
- A[0] ^= rc;
-}
-
-
-/**
- * 64-bit word version of `libkeccak_f_round`
- *
- * @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)
-{
- 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);
-#undef X
-
- /* ξ step. */
-#define X(N) A[N] = B[N] ^ ((~(B[(N + 5) % 25])) & B[(N + 10) % 25]);
- LIST_25;
-#undef X
-
- /* ι step. */
- A[0] ^= rc;
-}
-
-
-/**
- * Convert a chunk of bytes to a lane
- *
- * @param state The hashing 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));
- }
-}
-
-
-/**
- * Convert a chunk of bytes to a lane
- *
- * @param message The message
- * @param msglen The length of the message
- * @param rr Bitrate in bytes
- * @param ww Word size in bytes
- * @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)
-{
- 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;
-}
-
-
-/**
- * 64-bit lane version of `libkeccak_to_lane`
- *
- * @param message The message
- * @param msglen The length of the message
- * @param rr Bitrate in bytes
- * @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)
-{
- 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;
-}
-
-
-/**
- * pad 10*1
- *
- * @param state The hashing state, `state->M` and `state->mptr` will be updated,
- * `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)
-{
- 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;
- }
-}
-
-
-/**
- * Perform the absorption phase
- *
- * @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)
-{
- 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;
-#undef X
- libkeccak_f(state);
- message += (size_t)rr;
- len -= (size_t)rr;
- }
- }
-}
-
-
-/**
- * Perform the squeezing phase
- *
- * @param state The hashing state
- * @param rr The bitrate in bytes
- * @param nn The output size in bytes, rounded up to whole bytes
- * @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)
-{
- 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 (state->n & 7)
- hashsum[-1] &= (char)((1 << (state->n & 7)) - 1);
-}
-
-
-/**
- * Absorb more of the message to the Keccak sponge
- * without wiping sensitive data when possible
- *
- * @param state The hashing state
- * @param msg The partial message
- * @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)
-{
- 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;
-}
-
-
-/**
- * Absorb more of the message to the Keccak sponge
- * and wipe sensitive data when possible
- *
- * @param state The hashing state
- * @param msg The partial message
- * @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)
-{
- 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;
-}
-
-
-/**
- * Absorb the last part of the message and squeeze the Keccak sponge
- * without wiping sensitive data when possible
- *
- * @param state The hashing state
- * @param msg The rest of the message, may be `NULL`
- * @param msglen The length of the partial message
- * @param bits The number of bits at the end of the message not covered by `msglen`
- * @param suffix The suffix concatenate to the message, only '1':s and '0':s, and NUL-termination
- * @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)
-{
- 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);
- }
-
- return 0;
-}
-
-
-/**
- * Absorb the last part of the message and squeeze the Keccak sponge
- * and wipe sensitive data when possible
- *
- * @param state The hashing state
- * @param msg The rest of the message, may be `NULL`
- * @param msglen The length of the partial message
- * @param bits The number of bits at the end of the message not covered by `msglen`
- * @param suffix The suffix concatenate to the message, only '1':s and '0':s, and NUL-termination
- * @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)
-{
- 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);
- }
-
- return 0;
-}
-
-
-/**
- * Force some rounds of Keccak-f
- *
- * @param state The hashing state
- * @param times The number of rounds
- */
-void
-libkeccak_simple_squeeze(register libkeccak_state_t *restrict state, register long times)
-{
- while (times--)
- libkeccak_f(state);
-}
-
-
-/**
- * Squeeze as much as is needed to get a digest a number of times
- *
- * @param state The hashing state
- * @param times The number of digests
- */
-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);
-}
-
-
-/**
- * Squeeze out another digest
- *
- * @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)
-{
- 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
deleted file mode 100644
index 832f0c0..0000000
--- a/src/libkeccak/digest.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#ifndef LIBKECCAK_DIGEST_H
-#define LIBKECCAK_DIGEST_H 1
-
-#include "state.h"
-#include "internal.h"
-
-
-/**
- * Absorb more of the message to the Keccak sponge
- * without wiping sensitive data when possible
- *
- * @param state The hashing state
- * @param msg The partial message
- * @param msglen The length of the partial message
- * @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);
-
-
-/**
- * Absorb more of the message to the Keccak sponge
- * and wipe sensitive data when possible
- *
- * @param state The hashing state
- * @param msg The partial message
- * @param msglen The length of the partial message
- * @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);
-
-
-/**
- * Absorb the last part of the message and squeeze the Keccak sponge
- * without wiping sensitive data when possible
- *
- * @param state The hashing state
- * @param msg The rest of the message, may be `NULL`
- * @param msglen The length of the partial message
- * @param bits The number of bits at the end of the message not covered by `msglen`
- * @param suffix The suffix concatenate to the message, only '1':s and '0':s, and NUL-termination
- * @param hashsum Output parameter for the hashsum, may be `NULL`
- * @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);
-
-
-/**
- * Absorb the last part of the message and squeeze the Keccak sponge
- * and wipe sensitive data when possible
- *
- * @param state The hashing state
- * @param msg The rest of the message, may be `NULL`
- * @param msglen The length of the partial message
- * @param bits The number of bits at the end of the message not covered by `msglen`
- * @param suffix The suffix concatenate to the message, only '1':s and '0':s, and NUL-termination
- * @param hashsum Output parameter for the hashsum, may be `NULL`
- * @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);
-
-
-/**
- * Force some rounds of Keccak-f
- *
- * @param state The hashing state
- * @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);
-
-
-/**
- * Squeeze as much as is needed to get a digest a number of times
- *
- * @param state The hashing state
- * @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);
-
-
-/**
- * Squeeze out another digest
- *
- * @param state The hashing state
- * @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);
-
-
-#endif
-
diff --git a/src/libkeccak/files.c b/src/libkeccak/files.c
deleted file mode 100644
index 22d12f3..0000000
--- a/src/libkeccak/files.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include "files.h"
-
-#include <sys/stat.h>
-#include <alloca.h>
-#include <errno.h>
-#include <stddef.h>
-#include <unistd.h>
-
-
-
-/**
- * Calculate a Keccak-family hashsum of a file,
- * the content of the file is assumed non-sensitive
- *
- * @param fd The file descriptor of the file to hash
- * @param state The hashing state, should not be initialised (memory leak otherwise)
- * @param spec Specifications for the hashing algorithm
- * @param suffix The data suffix, see `libkeccak_digest`
- * @param hashsum Output array for the hashsum, have an allocation size of
- * 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)
-{
- 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);
-
- 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;
- }
-
- return libkeccak_fast_digest(state, NULL, 0, 0, suffix, hashsum);
-}
diff --git a/src/libkeccak/files.h b/src/libkeccak/files.h
deleted file mode 100644
index 92038fb..0000000
--- a/src/libkeccak/files.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#ifndef LIBKECCAK_FILES_H
-#define LIBKECCAK_FILES_H 1
-
-#include "../libkeccak.h"
-#include "internal.h"
-
-
-/**
- * Calculate a Keccak-family hashsum of a file,
- * the content of the file is assumed non-sensitive
- *
- * @param fd The file descriptor of the file to hash
- * @param state The hashing state, should not be initialised (memory leak otherwise)
- * @param spec Specifications for the hashing algorithm
- * @param suffix The data suffix, see `libkeccak_digest`
- * @param hashsum Output array for the hashsum, have an allocation size of
- * at least `((spec->output + 7) / 8) * sizeof(char)`, may be `NULL`
- * @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);
-
-
-/**
- * Calculate the Keccak hashsum of a file,
- * the content of the file is assumed non-sensitive
- *
- * @param fd The file descriptor of the file to hash
- * @param state The hashing state, should not be initialised (memory leak otherwise)
- * @param spec Specifications for the hashing algorithm
- * @param hashsum Output array for the hashsum, have an allocation size of
- * at least `((spec->output + 7) / 8) * sizeof(char)`, may be `NULL`
- * @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)
-{
- return libkeccak_generalised_sum_fd(fd, state, spec, NULL, hashsum);
-}
-
-
-/**
- * Calculate the SHA3 hashsum of a file,
- * the content of the file is assumed non-sensitive
- *
- * @param fd The file descriptor of the file to hash
- * @param state The hashing state, should not be initialised (memory leak otherwise)
- * @param output The output size parameter for the hashing algorithm
- * @param hashsum Output array for the hashsum, have an allocation size of
- * at least `((output + 7) / 8) * sizeof(char)`, may be `NULL`
- * @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)
-{
- libkeccak_spec_t spec;
- libkeccak_spec_sha3(&spec, output);
- return libkeccak_generalised_sum_fd(fd, state, &spec, LIBKECCAK_SHA3_SUFFIX, hashsum);
-}
-
-
-/**
- * Calculate the RawSHAKE hashsum of a file,
- * the content of the file is assumed non-sensitive
- *
- * @param fd The file descriptor of the file to hash
- * @param state The hashing state, should not be initialised (memory leak otherwise)
- * @param semicapacity The semicapacity parameter for the hashing algorithm
- * @param output The output size parameter for the hashing algorithm
- * @param hashsum Output array for the hashsum, have an allocation size of
- * at least `((output + 7) / 8) * sizeof(char)`, may be `NULL`
- * @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)
-{
- libkeccak_spec_t spec;
- libkeccak_spec_rawshake(&spec, semicapacity, output);
- return libkeccak_generalised_sum_fd(fd, state, &spec, LIBKECCAK_RAWSHAKE_SUFFIX, hashsum);
-}
-
-
-/**
- * Calculate the SHAKE hashsum of a file,
- * the content of the file is assumed non-sensitive
- *
- * @param fd The file descriptor of the file to hash
- * @param state The hashing state, should not be initialised (memory leak otherwise)
- * @param semicapacity The semicapacity parameter for the hashing algorithm
- * @param output The output size parameter for the hashing algorithm
- * @param hashsum Output array for the hashsum, have an allocation size of
- * at least `((output + 7) / 8) * sizeof(char)`, may be `NULL`
- * @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)
-{
- 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
deleted file mode 100644
index 9dfa918..0000000
--- a/src/libkeccak/generalised-spec.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* 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))
-
-
-
-/**
- * Convert a `libkeccak_generalised_spec_t` to a `libkeccak_spec_t`
- *
- * If you are interrested in finding errors, you should call
- * `libkeccak_spec_check(output)` if this function returns zero
- *
- * @param spec The generalised input specifications, will be update with resolved automatic values
- * @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)
-{
- 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;
-}
-
-
-#undef deft
-#undef copy
-#undef have
-
-#ifdef __GNUC__
-# pragma GCC diagnostic pop
-#endif
diff --git a/src/libkeccak/generalised-spec.h b/src/libkeccak/generalised-spec.h
deleted file mode 100644
index 2725961..0000000
--- a/src/libkeccak/generalised-spec.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#ifndef LIBKECCAK_GENERALISED_SPEC_H
-#define LIBKECCAK_GENERALISED_SPEC_H 1
-
-#include "spec.h"
-#include "internal.h"
-
-#include <inttypes.h>
-
-
-
-/**
- * Value for `libkeccak_generalised_spec_t` member that
- * is used to automatically select the value
- */
-#define LIBKECCAK_GENERALISED_SPEC_AUTOMATIC (-65536L)
-
-
-/**
- * Invalid `libkeccak_generalised_spec_t.state_size`: non-positive
- */
-#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
-
-/**
- * Invalid `libkeccak_generalised_spec_t.state_size`: not a multiple of 25
- */
-#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
-
-/**
- * Invalid `libkeccak_generalised_spec_t.word_size`: larger than 1600 / 25
- */
-#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
-
-/**
- * Invalid `libkeccak_generalised_spec_t.capacity`: non-positive
- */
-#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
-
-/**
- * Invalid `libkeccak_generalised_spec_t.bitrate`: non-positive
- */
-#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
-
-/**
- * Invalid `libkeccak_generalised_spec_t.output`: non-positive
- */
-#define LIBKECCAK_GENERALISED_SPEC_ERROR_OUTPUT_NONPOSITIVE 11
-
-
-
-/**
- * Generalised datastructure that describes the
- * parameters that should be used when hashing
- */
-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;
-
-} libkeccak_generalised_spec_t;
-
-
-
-/**
- * Set all specification parameters to automatic
- *
- * @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)
-{
- 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;
-}
-
-
-/**
- * Convert a `libkeccak_generalised_spec_t` to a `libkeccak_spec_t`
- *
- * @param spec The generalised input specifications, will be update with resolved automatic values
- * @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
- */
-LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull, nothrow)))
-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
deleted file mode 100644
index 7531223..0000000
--- a/src/libkeccak/hex.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include "hex.h"
-
-#include <string.h>
-
-
-
-/**
- * Convert a binary hashsum to lower case hexadecimal representation
- *
- * @param output Output array, should have an allocation size of at least `2 * n + 1`
- * @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)
-{
- output[2 * n] = '\0';
- while (n--) {
- output[2 * n + 0] = "0123456789abcdef"[(hashsum[n] >> 4) & 15];
- output[2 * n + 1] = "0123456789abcdef"[(hashsum[n] >> 0) & 15];
- }
-}
-
-
-/**
- * Convert a binary hashsum to upper case hexadecimal representation
- *
- * @param output Output array, should have an allocation size of at least `2 * n + 1`
- * @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)
-{
- output[2 * n] = '\0';
- while (n--) {
- output[2 * n + 0] = "0123456789ABCDEF"[(hashsum[n] >> 4) & 15];
- output[2 * n + 1] = "0123456789ABCDEF"[(hashsum[n] >> 0) & 15];
- }
-}
-
-
-/**
- * Convert a hexadecimal hashsum (both lower case, upper
- * case and mixed is supported) to binary representation
- *
- * @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)
-{
- 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
deleted file mode 100644
index 25375d5..0000000
--- a/src/libkeccak/hex.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#ifndef LIBKECCAK_HEX_H
-#define LIBKECCAK_HEX_H 1
-
-#include "internal.h"
-
-#include <stddef.h>
-
-
-/**
- * Convert a binary hashsum to lower case hexadecimal representation
- *
- * @param output Output array, should have an allocation size of at least `2 * n + 1`
- * @param hashsum The hashsum to convert
- * @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);
-
-
-/**
- * Convert a binary hashsum to upper case hexadecimal representation
- *
- * @param output Output array, should have an allocation size of at least `2 * n + 1`
- * @param hashsum The hashsum to convert
- * @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);
-
-
-/**
- * Convert a hexadecimal hashsum (both lower case, upper
- * case and mixed is supported) to binary representation
- *
- * @param output Output array, should have an allocation size of at least `strlen(hashsum) / 2`
- * @param hashsum The hashsum to convert
- */
-LIBKECCAK_GCC_ONLY(__attribute__((leaf, nonnull, nothrow)))
-void libkeccak_unhex(char *restrict output, const char *restrict hashsum);
-
-
-#endif
-
diff --git a/src/libkeccak/internal.h b/src/libkeccak/internal.h
deleted file mode 100644
index 466abf9..0000000
--- a/src/libkeccak/internal.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#ifndef LIBKECCAK_INTERNAL_H
-#define LIBKECCAK_INTERNAL_H 1
-
-
-/**
- * Only include some C code (not for CPP directives)
- * if compiling with GCC.
- */
-#ifdef __GNUC__
-# 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
deleted file mode 100644
index ee3bc6a..0000000
--- a/src/libkeccak/mac/hmac.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include "hmac.h"
-
-#include "../digest.h"
-
-
-
-/**
- * The outer pad pattern
- */
-#define OUTER_PAD 0x5C
-
-/**
- * The inner pad pattern
- */
-#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)
-{
- (*my_explicit_memset)(ptr, 0, size);
-}
-
-
-/**
- * Change the HMAC-hashing key on the state
- *
- * @param state The state that should be reset
- * @param key The new key
- * @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)
-{
- 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;
-}
-
-
-/**
- * Wipe sensitive data wihout freeing any data
- *
- * @param state The state that should be wipe
- */
-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);
-}
-
-
-/**
- * Make a copy of an HMAC hashing-state
- *
- * @param dest The slot for the duplicate, must not be initialised (memory leak otherwise)
- * @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)
-{
- 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;
-}
-
-
-/**
- * Unmarshal a `libkeccak_hmac_state_t` from a buffer
- *
- * @param state The slot for the unmarshalled state, must not be initialised (memory leak otherwise)
- * @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 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);
-}
-
-
-/**
- * Absorb more, or the first part, of the message
- * without wiping sensitive data when possible
- *
- * @param state The hashing state
- * @param msg The partial message
- * @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)
-{
- 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);
-}
-
-
-/**
- * Absorb more, or the first part, of the message
- * and wipe sensitive data when possible
- *
- * @param state The hashing state
- * @param msg The partial message
- * @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)
-{
- 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;
-}
-
-
-/**
- * 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
- *
- * @param state The hashing state
- * @param msg The rest of the message, may be `NULL`, may be modified
- * @param msglen The length of the partial message
- * @param bits The number of bits at the end of the message not covered by `msglen`
- * @param suffix The suffix concatenate to the message, only '1':s and '0':s, and NUL-termination
- * @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)
-{
- 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;
-}
-
-
-/**
- * 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
- *
- * @param state The hashing state
- * @param msg The rest of the message, may be `NULL`, may be modified
- * @param msglen The length of the partial message
- * @param bits The number of bits at the end of the message not covered by `msglen`
- * @param suffix The suffix concatenate to the message, only '1':s and '0':s, and NUL-termination
- * @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)
-{
- 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:
- 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
deleted file mode 100644
index 2681e61..0000000
--- a/src/libkeccak/mac/hmac.h
+++ /dev/null
@@ -1,393 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#ifndef LIBKECCAK_MAC_HMAC_H
-#define LIBKECCAK_MAC_HMAC_H 1
-
-/*
- * 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"
-
-#include <stddef.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-
-
-
-/**
- * Datastructure that describes the state of an HMAC-hashing process
- */
-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];
-
-} libkeccak_hmac_state_t;
-
-
-
-/**
- * Change the HMAC-hashing key on the state
- *
- * @param state The state that should be reset
- * @param key The new key
- * @param key_length The length of key, in bits
- * @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);
-
-
-/**
- * Initialise an HMAC hashing-state according to hashing specifications
- *
- * @param state The state that should be initialised
- * @param spec The specifications for the state
- * @param key The key
- * @param key_length The length of key, in bits
- * @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)
-{
- 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;
-}
-
-
-/**
- * Wrapper for `libkeccak_hmac_initialise` that also allocates the states
- *
- * @param spec The specifications for the state
- * @param key The key
- * @param key_length The length of key, in bits
- * @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)
-{
- 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;
-}
-
-
-/**
- * Reset an HMAC-hashing state according to hashing specifications,
- * you can choose whether to change the key
- *
- * @param state The state that should be reset
- * @param key The new key, `NULL` to keep the old key
- * @param key_length The length of key, in bits, ignored if `key == NULL`
- * @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)
-{
- libkeccak_state_reset(&state->sponge);
- return key ? libkeccak_hmac_set_key(state, key, key_length) : 0;
-}
-
-
-/**
- * Wipe sensitive data wihout freeing any data
- *
- * @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);
-
-
-/**
- * Release resources allocation for an HMAC hashing-state without wiping sensitive data
- *
- * @param state The state that should be destroyed
- */
-static inline void
-libkeccak_hmac_fast_destroy(libkeccak_hmac_state_t *restrict state)
-{
- 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;
-}
-
-
-/**
- * Release resources allocation for an HMAC hasing-state and wipe sensitive data
- *
- * @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)
-{
- 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;
-}
-
-
-/**
- * Wrapper for `libkeccak_fast_destroy` that also frees the allocation of the 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)
-{
- libkeccak_hmac_fast_destroy(state);
- free(state);
-}
-
-
-/**
- * Wrapper for `libkeccak_hmac_destroy` that also frees the allocation of the 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)
-{
-#ifdef __GNUC__
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wcast-qual"
-#endif
- libkeccak_hmac_destroy(state);
- free((libkeccak_hmac_state_t*)state);
-#ifdef __GNUC__
-# pragma GCC diagnostic pop
-#endif
-}
-
-
-/**
- * Make a copy of an HMAC hashing-state
- *
- * @param dest The slot for the duplicate, must not be initialised (memory leak otherwise)
- * @param src The state to duplicate
- * @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);
-
-
-/**
- * A wrapper for `libkeccak_hmac_copy` that also allocates the duplicate
- *
- * @param src The state to duplicate
- * @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)
-{
- 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;
-}
-
-
-/**
- * Calculates the allocation size required for the second argument
- * of `libkeccak_hmac_marshal` (`char* restrict data)`)
- *
- * @param state The state as it will be marshalled by a subsequent call to `libkeccak_hamc_marshal`
- * @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)
-{
- return libkeccak_state_marshal_size(&state->sponge) + sizeof(size_t) +
- ((state->key_length + 7) >> 3) + 2 * sizeof(char);
-}
-
-
-/**
- * Marshal a `libkeccak_hmac_state_t` into a buffer
- *
- * @param state The state to marshal
- * @param data The output buffer
- * @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)
-{
- 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);
-}
-
-
-/**
- * Unmarshal a `libkeccak_hmac_state_t` from a buffer
- *
- * @param state The slot for the unmarshalled state, must not be initialised (memory leak otherwise)
- * @param data The input buffer
- * @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);
-
-
-/**
- * Gets the number of bytes the `libkeccak_hmac_state_t` stored
- * at the beginning of `data` occupies
- *
- * @param data The data buffer
- * @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)
-{
- size_t skip = libkeccak_state_unmarshal_skip(data);
- data += skip / sizeof(char);
- return skip + sizeof(size_t) + *(const size_t *)data + 2 * sizeof(char);
-}
-
-
-/**
- * Absorb more, or the first part, of the message
- * without wiping sensitive data when possible
- *
- * @param state The hashing state
- * @param msg The partial message
- * @param msglen The length of the partial message, in bytes
- * @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);
-
-
-/**
- * Absorb more, or the first part, of the message
- * and wipe sensitive data when possible
- *
- * @param state The hashing state
- * @param msg The partial message
- * @param msglen The length of the partial message, in bytes
- * @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);
-
-
-/**
- * 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
- *
- * @param state The hashing state
- * @param msg The rest of the message, may be `NULL`, may be modified
- * @param msglen The length of the partial message
- * @param bits The number of bits at the end of the message not covered by `msglen`
- * @param suffix The suffix concatenate to the message, only '1':s and '0':s, and NUL-termination
- * @param hashsum Output parameter for the hashsum, may be `NULL`
- * @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);
-
-
-/**
- * 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
- *
- * @param state The hashing state
- * @param msg The rest of the message, may be `NULL`, may be modified
- * @param msglen The length of the partial message
- * @param bits The number of bits at the end of the message not covered by `msglen`
- * @param suffix The suffix concatenate to the message, only '1':s and '0':s, and NUL-termination
- * @param hashsum Output parameter for the hashsum, may be `NULL`
- * @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);
-
-
-#endif
diff --git a/src/libkeccak/spec.h b/src/libkeccak/spec.h
deleted file mode 100644
index 8d73c52..0000000
--- a/src/libkeccak/spec.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#ifndef LIBKECCAK_SPEC_H
-#define LIBKECCAK_SPEC_H 1
-
-#include "internal.h"
-
-#include <stdint.h>
-#include <limits.h>
-
-
-/**
- * Message suffix for SHA3 hashing
- */
-#define LIBKECCAK_SHA3_SUFFIX "01"
-
-/**
- * Message suffix for RawSHAKE hashing
- */
-#define LIBKECCAK_RAWSHAKE_SUFFIX "11"
-
-/**
- * Message suffix for SHAKE hashing
- */
-#define LIBKECCAK_SHAKE_SUFFIX "1111"
-
-
-/**
- * Invalid `libkeccak_spec_t.bitrate`: non-positive
- */
-#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
-
-/**
- * Invalid `libkeccak_spec_t.capacity`: non-positive
- */
-#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
-
-/**
- * Invalid `libkeccak_spec_t.output`: non-positive
- */
-#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
-
-/**
- * Invalid `libkeccak_spec_t` values:
- * `.bitrate + `.capacity` is not a multiple of 25
- */
-#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
-
-/**
- * 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
-
-
-
-/**
- * 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;
-
-} libkeccak_spec_t;
-
-
-
-/**
- * Fill in a `libkeccak_spec_t` for a SHA3-x hashing
- *
- * @param spec The specifications datastructure to fill in
- * @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)
-{
- spec->bitrate = 1600 - 2 * x;
- spec->capacity = 2 * x;
- spec->output = x;
-}
-
-
-/**
- * Fill in a `libkeccak_spec_t` for a RawSHAKEx hashing
- *
- * @param spec The specifications datastructure to fill in
- * @param x The value of x in `RawSHAKEx`, half the capacity
- * @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)
-{
- spec->bitrate = 1600 - 2 * x;
- spec->capacity = 2 * x;
- spec->output = d;
-}
-
-
-/**
- * Fill in a `libkeccak_spec_t` for a SHAKEx hashing
- *
- * @param spec:libkeccak_spec_t* The specifications datastructure to fill in
- * @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
-
-
-/**
- * Check for errors in a `libkeccak_spec_t`
- *
- * @param spec The specifications datastructure to check
- * @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)
-{
- 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
deleted file mode 100644
index c6360b7..0000000
--- a/src/libkeccak/state.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include "state.h"
-
-#include <string.h>
-
-
-
-/**
- * Initialise a state according to hashing specifications
- *
- * @param state The state that should be initialised
- * @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)
-{
- 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;
-}
-
-
-/**
- * Wipe data in the state's message wihout freeing any data
- *
- * @param state The state that should be wipe
- */
-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;
-}
-
-/**
- * Wipe data in the state's sponge wihout freeing any data
- *
- * @param state The state that should be wipe
- */
-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;
-}
-
-/**
- * Wipe sensitive data wihout freeing any data
- *
- * @param state The state that should be wipe
- */
-void
-libkeccak_state_wipe(volatile libkeccak_state_t *restrict state)
-{
- libkeccak_state_wipe_message(state);
- libkeccak_state_wipe_sponge(state);
-}
-
-
-/**
- * Make a copy of a state
- *
- * @param dest The slot for the duplicate, must not be initialised (memory leak otherwise)
- * @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)
-{
- 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;
-}
-
-
-/**
- * Marshal a `libkeccak_state_t` into a buffer
- *
- * @param state The state to marshal
- * @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)
-{
-#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
-}
-
-
-/**
- * Unmarshal a `libkeccak_state_t` from a buffer
- *
- * @param state The slot for the unmarshalled state, must not be initialised (memory leak otherwise)
- * @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)
-{
-#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
-}
-
-
-/**
- * Gets the number of bytes the `libkeccak_state_t` stored
- * at the beginning of `data` occupies
- *
- * @param data The data buffer
- * @return The byte size of the stored state
- */
-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);
-}
-
diff --git a/src/libkeccak/state.h b/src/libkeccak/state.h
deleted file mode 100644
index 1c4b24e..0000000
--- a/src/libkeccak/state.h
+++ /dev/null
@@ -1,295 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#ifndef LIBKECCAK_STATE_H
-#define LIBKECCAK_STATE_H 1
-
-#include "spec.h"
-#include "internal.h"
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-
-/**
- * Datastructure that describes the state of a hashing process
- *
- * 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;
-
-} libkeccak_state_t;
-
-
-
-/**
- * Initialise a state according to hashing specifications
- *
- * @param state The state that should be initialised
- * @param spec The specifications for the 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);
-
-
-/**
- * Reset a state according to hashing specifications
- *
- * @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)
-{
- state->mptr = 0;
- memset(state->S, 0, sizeof(state->S));
-}
-
-
-/**
- * Release resources allocation for a state without wiping sensitive data
- *
- * @param state The state that should be destroyed
- */
-static inline void
-libkeccak_state_fast_destroy(libkeccak_state_t *restrict state)
-{
- if (state == NULL)
- return;
- free(state->M);
- state->M = NULL;
-}
-
-
-/**
- * Wipe data in the state's message wihout freeing any data
- *
- * @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);
-
-/**
- * Wipe data in the state's sponge wihout freeing any data
- *
- * @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);
-
-/**
- * Wipe sensitive data wihout freeing any data
- *
- * @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);
-
-
-/**
- * Release resources allocation for a state and wipe sensitive data
- *
- * @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)
-{
- if (!state)
- return;
- libkeccak_state_wipe(state);
- free(state->M);
- state->M = NULL;
-}
-
-
-/**
- * Wrapper for `libkeccak_state_initialise` that also allocates the states
- *
- * @param spec The specifications for the 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)
-{
- libkeccak_state_t *restrict state = malloc(sizeof(libkeccak_state_t));
- if (!state || libkeccak_state_initialise(state, spec))
- return free(state), NULL;
- return state;
-}
-
-
-/**
- * Wrapper for `libkeccak_state_fast_destroy` that also frees the allocation of the state
- *
- * @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)
-{
- libkeccak_state_fast_destroy(state);
- free(state);
-}
-
-
-/**
- * Wrapper for `libkeccak_state_destroy` that also frees the allocation of the 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)
-{
-#ifdef __GNUC__
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wcast-qual"
-#endif
- libkeccak_state_destroy(state);
- free((libkeccak_state_t *)state);
-#ifdef __GNUC__
-# pragma GCC diagnostic pop
-#endif
-}
-
-
-/**
- * Make a copy of a state
- *
- * @param dest The slot for the duplicate, must not be initialised (memory leak otherwise)
- * @param src The state to duplicate
- * @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);
-
-
-/**
- * A wrapper for `libkeccak_state_copy` that also allocates the duplicate
- *
- * @param src The state to duplicate
- * @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)
-{
- 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;
-}
-
-
-/**
- * Calculates the allocation size required for the second argument
- * of `libkeccak_state_marshal` (`char* restrict data)`)
- *
- * @param state The state as it will be marshalled by a subsequent call to `libkeccak_state_marshal`
- * @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)
-{
- return sizeof(libkeccak_state_t) - sizeof(char*) + state->mptr * sizeof(char);
-}
-
-
-/**
- * Marshal a `libkeccak_state_t` into a buffer
- *
- * @param state The state to marshal
- * @param data The output buffer
- * @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);
-
-
-/**
- * Unmarshal a `libkeccak_state_t` from a buffer
- *
- * @param state The slot for the unmarshalled state, must not be initialised (memory leak otherwise)
- * @param data The input buffer
- * @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);
-
-
-/**
- * Gets the number of bytes the `libkeccak_state_t` stored
- * at the beginning of `data` occupies
- *
- * @param data The data buffer
- * @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);
-
-#endif
diff --git a/src/test.c b/src/test.c
deleted file mode 100644
index 8394568..0000000
--- a/src/test.c
+++ /dev/null
@@ -1,662 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <libkeccak.h>
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-
-/**
- * Test functions in <libkeccak/hex.h>
- *
- * @return Zero on success, -1 on error
- */
-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;
-}
-
-
-/**
- * Test functions in <libkeccak/state.h>
- *
- * @param spec The specifications for the state
- * @return Zero on success, -1 on error
- */
-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;
-
- free(marshalled_data);
- libkeccak_state_free(state);
- libkeccak_state_free(state2);
- return 0;
-}
-
-
-/**
- * Run a test case for `libkeccak_digest`
- *
- * @param spec The specification for the hashing
- * @param suffix The message suffix (padding prefix)
- * @param msg The message to digest
- * @param bits Bits at the end of `message` that does not make up a whole byte
- * @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)
-{
- 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;
-}
-
-
-/**
- * Run test cases for `libkeccak_digest`
- *
- * @return Zero on success, -1 on error
- */
-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;
-
-#undef keccak_g
-#undef shake
-#undef rawshake_bits
-#undef rawshake
-#undef keccak_bits
-#undef keccak
-#undef sha3
-}
-
-
-/**
- * Run a test case for `libkeccak_update`
- *
- * @param spec The specification for the hashing
- * @param suffix The message suffix (padding prefix)
- * @param msg The message to digest
- * @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)
-{
- 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;
-}
-
-
-/**
- * Run test cases for `libkeccak_update`
- *
- * @return Zero on success, -1 on error
- */
-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;
-
-#undef sha3
-}
-
-
-/**
- * Run a test for `libkeccak_*squeeze` functions
- *
- * @param state The state whould should use, we will reset it
- * @param spec The specification for the hashing
- * @param fast_squeezes The number of fast squeezes to perform
- * @param squeezes The number of extra squeezes to perform in total
- * @param fast_digest Whether `libkeccak_digest` should do a fast squeeze rather than a slow squeeze
- * @param hashsum A buffer in which we can used to store the binary hashsum
- * @param hexsum A buffer in which we can used to store the hexadecimal hashsum
- * @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)
-{
-#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
-}
-
-
-/**
- * Test `libkeccak_*squeeze` functions
- *
- * @return Zero on success, -1 on error
- */
-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;
-
-#undef run_test
-#undef answer4
-#undef answer3
-#undef answer2
-#undef answer1
-}
-
-
-
-/**
- * Run a test for `libkeccak_generalised_sum_fd`
- *
- * @param spec The specification for the hashing
- * @param suffix The message suffix (padding prefix)
- * @param filename The name of the file we should hash
- * @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)
-{
- 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;
-}
-
-
-/**
- * Basically, verify the correctness of the library.
- * The current working path must be the root directory
- * of the repository (the project directory).
- *
- * @return Zero on success, 1 on failure or incorrectness
- */
-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, ".testfile",
- "a95484492e9ade0f1d28f872d197ff45d891e85e78f918643f41d524c5d6ab0f"
- "17974dc08ec82870b132612dcbeb062213bf594881dc764d6078865a7c694c57"))
- return 1;
-
- return 0;
-}