aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile14
-rw-r--r--src/benchmark.c152
2 files changed, 165 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index cb7ab19..47612ed 100644
--- a/Makefile
+++ b/Makefile
@@ -86,7 +86,7 @@ LIB_OBJ = digest files generalised-spec hex state
.PHONY: all
-all: lib test
+all: lib test benchmark
.PHONY: lib
@@ -120,6 +120,18 @@ obj/test.o: src/test.c src/libkeccak/*.h src/libkeccak.h
$(CC) $(FLAGS) $(CFLAGS) $(CPPFLAGS) -Isrc -O3 -c -o $@ $<
+.PHONY: benchmark
+benchmark: bin/benchmark
+
+bin/benchmark: obj/benchmark.o bin/libkeccak.so
+ $(CC) $(FLAGS) $(LDFLAGS) -Lbin -lkeccak -o $@ $<
+
+obj/benchmark.o: src/benchmark.c src/libkeccak/*.h src/libkeccak.h
+ @mkdir -p obj
+ $(CC) $(FLAGS) $(CFLAGS) $(CPPFLAGS) -Isrc -O3 -c -o $@ $<
+
+
+
.PHONY: check
check: bin/test
@test $$(sha256sum LICENSE | cut -d ' ' -f 1) = \
diff --git a/src/benchmark.c b/src/benchmark.c
new file mode 100644
index 0000000..119f6ed
--- /dev/null
+++ b/src/benchmark.c
@@ -0,0 +1,152 @@
+/**
+ * libkeccak – Keccak-family hashing library
+ *
+ * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <libkeccak.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <time.h>
+
+
+#define MESSAGE_LEN 34520 /* The size of the file LICENSE. */
+#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
+ * convertion 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];
+ char hexsum[OUTPUT / 8 * 2 + 1];
+ struct timespec start, end;
+ long i, r;
+
+ /* Fill message with connent from the file LICENSE. */
+ {
+ int fd;
+ ssize_t got;
+ size_t ptr;
+ if (fd = open("LICENSE", 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_MONOTONIC_RAW, &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_update(&state, message, MESSAGE_LEN) < 0)
+ return perror("libkeccak_update"), 1;
+#endif
+
+ /* Digest. */
+ if (libkeccak_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_MONOTONIC_RAW, &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 (FAST_SQUEEZE_RUNS == 0) && (SLOW_SQUEEZE_RUNS == 0)
+ (void) i;
+#endif
+}
+