aboutsummaryrefslogtreecommitdiff
path: root/standalone/src
diff options
context:
space:
mode:
Diffstat (limited to 'standalone/src')
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java50
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/libs/BoringsslLib.java6
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/libs/GcryptLib.java6
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/libs/LibresslLib.java6
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/libs/NativeECLibrary.java3
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile37
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_preload.c316
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_prng.c18
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h8
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/preload.c255
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplex-common.h37
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplex.inc192
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplexWidth200.c29
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplexWidth200.h25
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakP-200-SnP.h34
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakP-200-compact.c187
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRG-common.h28
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRG.h20
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRG.inc123
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRGWidth200.c22
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRGWidth200.h24
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/align.h32
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/prng.c21
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/prng.h13
-rw-r--r--standalone/src/test/java/cz/crcs/ectester/standalone/DeterministicTests.java4
25 files changed, 1224 insertions, 272 deletions
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java
index dc61192..6822a30 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java
@@ -23,6 +23,7 @@
*/
package cz.crcs.ectester.standalone;
+import com.sun.source.tree.StringTemplateTree;
import cz.crcs.ectester.common.cli.*;
import cz.crcs.ectester.common.ec.EC_Consts;
import cz.crcs.ectester.common.ec.EC_Curve;
@@ -105,12 +106,52 @@ public class ECTesterStandalone {
if (!System.getProperty("os.name").startsWith("Windows")) {
FileUtil.write(LIB_RESOURCE_DIR + "lib_timing.so", reqs.resolve("lib_timing.so"));
- System.load(reqs.resolve("lib_timing.so").toString());
-
+ FileUtil.write(LIB_RESOURCE_DIR + "lib_preload.so", reqs.resolve("lib_preload.so"));
+ FileUtil.write(LIB_RESOURCE_DIR + "lib_prng.so", reqs.resolve("lib_prng.so"));
FileUtil.write(LIB_RESOURCE_DIR + "lib_csignals.so", reqs.resolve("lib_csignals.so"));
- System.load(reqs.resolve("lib_csignals.so").toString());
FileUtil.write(LIB_RESOURCE_DIR + "lib_cppsignals.so", reqs.resolve("lib_cppsignals.so"));
- System.load(reqs.resolve("lib_cppsignals.so").toString());
+
+ String preloadLibPath = reqs.resolve("lib_preload.so").toAbsolutePath().toString();
+ String preload = System.getenv("LD_PRELOAD");
+ if (preload == null && !cli.hasOption("no-preload")) {
+ ProcessBuilder builder = new ProcessBuilder();
+ Map<String, String> env = builder.environment();
+ env.put("LD_PRELOAD", preloadLibPath);
+
+ ProcessHandle.Info info = ProcessHandle.current().info();
+ List<String> argList = new LinkedList<>();
+ if (info.command().isPresent()) {
+ argList.add(info.command().get());
+ } else {
+ System.err.println("Cannot locate command to spawn preloaded-subprocess.");
+ return;
+ }
+ if (info.arguments().isPresent()) {
+ argList.addAll(List.of(info.arguments().get()));
+ } else {
+ System.err.println("Cannot locate arguments to spawn preloaded-subprocess.");
+ return;
+ }
+ builder.command(argList);
+ builder.inheritIO();
+
+ Process process = builder.start();
+ int result;
+ while (true) {
+ try {
+ result = process.waitFor();
+ break;
+ } catch (InterruptedException ignored) {
+ }
+ }
+ System.exit(result);
+ } else {
+ // Load the utility libs.
+ System.load(reqs.resolve("lib_prng.so").toString());
+ System.load(reqs.resolve("lib_timing.so").toString());
+ System.load(reqs.resolve("lib_csignals.so").toString());
+ System.load(reqs.resolve("lib_cppsignals.so").toString());
+ }
}
List<ProviderECLibrary> libObjects = new LinkedList<>();
@@ -296,6 +337,7 @@ public class ECTesterStandalone {
opts.addOption(Option.builder("V").longOpt("version").desc("Print version info.").build());
opts.addOption(Option.builder("h").longOpt("help").desc("Print help(about <command>).").hasArg().argName("command").optionalArg(true).build());
opts.addOption(Option.builder("C").longOpt("color").desc("Print stuff with color, requires ANSI terminal.").build());
+ opts.addOption(Option.builder().longOpt("no-preload").desc("Do not use LD_PRELOAD.").build());
return optParser.parse(opts, args);
}
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/BoringsslLib.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/BoringsslLib.java
index af4d969..06e6b4a 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/BoringsslLib.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/BoringsslLib.java
@@ -16,4 +16,10 @@ public class BoringsslLib extends NativeECLibrary {
@Override
public native Set<String> getCurves();
+
+ @Override
+ public boolean supportsDeterministicPRNG() {
+ // This is provided by the native preload that hooks all randomness sources.
+ return true;
+ }
}
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/GcryptLib.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/GcryptLib.java
index 83d78ef..d1452a9 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/GcryptLib.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/GcryptLib.java
@@ -17,4 +17,10 @@ public class GcryptLib extends NativeECLibrary {
@Override
public native Set<String> getCurves();
+
+ @Override
+ public boolean supportsDeterministicPRNG() {
+ // This is provided by the native preload that hooks all randomness sources.
+ return true;
+ }
}
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/LibresslLib.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/LibresslLib.java
index 2dba049..e53399c 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/LibresslLib.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/LibresslLib.java
@@ -16,4 +16,10 @@ public class LibresslLib extends NativeECLibrary {
@Override
public native Set<String> getCurves();
+
+ @Override
+ public boolean supportsDeterministicPRNG() {
+ // This is provided by the native preload that hooks all randomness sources.
+ return true;
+ }
}
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/NativeECLibrary.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/NativeECLibrary.java
index c11dbdb..fb4e430 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/NativeECLibrary.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/NativeECLibrary.java
@@ -86,5 +86,8 @@ public abstract class NativeECLibrary extends ProviderECLibrary {
@Override
public native long getLastNativeTiming();
+ @Override
+ public native boolean setupDeterministicPRNG(byte[] seed);
+
abstract Provider createProvider();
}
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile
index d243f68..f947c78 100644
--- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile
@@ -73,8 +73,17 @@ c_utils.o: c_utils.c
lib_timing.so: c_timing.c
$(CC) -o $@ -shared $(CFLAGS) -Wl,-soname,lib_timing.so $<
-lib_preload.so: preload.c
- $(CC) -shared -fPIC -ldl $< -o $@
+prng.o: prng/prng.c
+ $(CC) $(CFLAGS) -c $<
+
+lib_prng.so: c_prng.c
+ $(CC) -o $@ -shared -Wl,-soname,lib_prng.so $(CFLAGS) $<
+
+c_preload.o: c_preload.c
+ $(CC) $(CFLAGS) -c $<
+
+lib_preload.so: c_preload.o prng.o
+ $(CC) -o $@ -shared $(CFLAGS) -ldl -Wl,-soname,lib_preload.so $^
lib_csignals.so: c_signals.c
$(CC) -o $@ -shared $(CFLAGS) -pthread -lpthread -Wl,-soname,lib_csignals.so $<
@@ -86,10 +95,14 @@ cpp_utils.o: cpp_utils.cpp
$(CXX) $(CXXFLAGS) -c $<
+clibs: lib_timing.so lib_csignals.so lib_preload.so lib_prng.so
+
+cpplibs: lib_timing.so lib_cppsignals.so lib_preload.so lib_prng.so
+
# OpenSSL shim
openssl: openssl_provider.so
-openssl_provider.so: openssl.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so
+openssl_provider.so: openssl.o c_utils.o | clibs
$(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs openssl) -l:lib_timing.so -l:lib_csignals.so
openssl.o: openssl.c
@@ -102,7 +115,7 @@ boringssl: boringssl_provider.so
lib_boringssl.so:
cp $(PROJECT_ROOT_PATH)/ext/boringssl/build/crypto/libcrypto.so lib_boringssl.so
-boringssl_provider.so: boringssl.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so lib_boringssl.so
+boringssl_provider.so: boringssl.o c_utils.o | clibs lib_boringssl.so
$(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_boringssl.so -l:lib_timing.so -l:lib_csignals.so
boringssl.o: boringssl.c
@@ -112,7 +125,7 @@ boringssl.o: boringssl.c
# libgcrypt shim
gcrypt: gcrypt_provider.so
-gcrypt_provider.so: gcrypt.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so
+gcrypt_provider.so: gcrypt.o c_utils.o | clibs
$(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. -pthread -lpthread $(shell libgcrypt-config --libs) -l:lib_timing.so -l:lib_csignals.so
gcrypt.o: gcrypt.c
@@ -122,7 +135,7 @@ gcrypt.o: gcrypt.c
# Libtomcrypt shim
tomcrypt: tomcrypt_provider.so
-tomcrypt_provider.so: tomcrypt.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so
+tomcrypt_provider.so: tomcrypt.o c_utils.o | clibs
$(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. -ltommath $(shell pkg-config --libs libtomcrypt) -l:lib_timing.so -l:lib_csignals.so
tomcrypt.o: tomcrypt.c
@@ -132,7 +145,7 @@ tomcrypt.o: tomcrypt.c
# Botan-2 shim
botan: botan_provider.so
-botan_provider.so: botan.o cpp_utils.o | lib_timing.so lib_cppsignals.so lib_preload.so
+botan_provider.so: botan.o cpp_utils.o | cpplibs
$(CXX) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs botan-2) -l:lib_timing.so -l:lib_cppsignals.so
botan.o: botan.cpp
@@ -146,7 +159,7 @@ ifeq ($(shell pkg-config --exists $(CRYPTOPP_NAME); echo $$?),1)
endif
cryptopp: cryptopp_provider.so
-cryptopp_provider.so: cryptopp.o cpp_utils.o | lib_timing.so lib_cppsignals.so lib_preload.so
+cryptopp_provider.so: cryptopp.o cpp_utils.o | cpplibs
$(CXX) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs $(CRYPTOPP_NAME)) -l:lib_timing.so -l:lib_cppsignals.so
cryptopp.o: cryptopp.cpp
@@ -159,7 +172,7 @@ mbedtls: mbedtls_provider.so
lib_mbedtls.so:
cp $(PROJECT_ROOT_PATH)/ext/mbedtls/build/library/libmbedcrypto.so lib_mbedtls.so
-mbedtls_provider.so: mbedtls.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so lib_mbedtls.so
+mbedtls_provider.so: mbedtls.o c_utils.o | clibs lib_mbedtls.so
$(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_mbedtls.so -l:lib_timing.so -l:lib_csignals.so
mbedtls.o: mbedtls.c
@@ -172,7 +185,7 @@ ippcp: ippcp_provider.so
lib_ippcp.so:
cp $(PROJECT_ROOT_PATH)/ext/ipp-crypto/build/.build/RELEASE/lib/libippcp.so lib_ippcp.so
-ippcp_provider.so: ippcp.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so lib_ippcp.so
+ippcp_provider.so: ippcp.o c_utils.o | clibs lib_ippcp.so
$(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_ippcp.so -l:lib_timing.so -l:lib_csignals.so
ippcp.o: ippcp.c
@@ -182,7 +195,7 @@ ippcp.o: ippcp.c
# Nettle shim
nettle: nettle_provider.so
-nettle_provider.so: nettle.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so
+nettle_provider.so: nettle.o c_utils.o | clibs
$(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs nettle) -l:lib_timing.so -l:lib_csignals.so $(shell pkg-config --libs hogweed) -lgmp
nettle.o: nettle.c
@@ -195,7 +208,7 @@ libressl: libressl_provider.so
lib_libressl.so:
cp $(PROJECT_ROOT_PATH)/ext/libressl/build/crypto/libcrypto.so lib_libressl.so
-libressl_provider.so: libressl.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so lib_libressl.so
+libressl_provider.so: libressl.o c_utils.o | clibs lib_libressl.so
$(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_libressl.so -l:lib_timing.so -l:lib_csignals.so
libressl.o: libressl.c
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_preload.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_preload.c
new file mode 100644
index 0000000..1f597a3
--- /dev/null
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_preload.c
@@ -0,0 +1,316 @@
+#define _GNU_SOURCE
+
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/random.h>
+#include <sys/syscall.h>
+
+#include "native.h"
+#include "prng/prng.h"
+
+
+#ifdef DEBUG_PRELOAD
+
+void print_buf(uint8_t *buf, size_t len) {
+ for (int i = 0; i < len; ++i) {
+ fprintf(stderr, "%02x ", buf[i]);
+ }
+ fprintf(stderr, "\n");
+}
+
+#else
+
+#define print_buf(buf, len)
+
+#endif
+
+typedef int (*open_t)(const char *pathname, int flags, ...);
+static open_t real_open;
+typedef int (*openat_t)(int fd, const char *pathname, int flags, ...);
+static openat_t real_openat;
+typedef ssize_t (*read_t)(int fd, void *buf, size_t count);
+static read_t real_read;
+typedef FILE *(*fopen_t)(const char *pathname, const char *mode);
+static fopen_t real_fopen;
+typedef size_t (*fread_t)(void *ptr, size_t size, size_t nmemb, FILE *stream);
+static fread_t real_fread;
+typedef ssize_t (*getrandom_t)(void *buf, size_t buflen, unsigned int flags);
+static getrandom_t real_getrandom;
+typedef int (*getentropy_t)(void *buffer, size_t length);
+static getentropy_t real_getentropy;
+typedef long (*syscall_t)(long number, ...);
+static syscall_t real_syscall;
+typedef uint32_t (*arc4random_t)(void);
+static arc4random_t real_arc4random;
+typedef uint32_t (*arc4random_uniform_t)(uint32_t upper_bound);
+static arc4random_uniform_t real_arc4random_uniform;
+typedef void (*arc4random_buf_t)(void *buf, size_t n);
+static arc4random_buf_t real_arc4random_buf;
+
+prng_state preload_prng_state;
+bool preload_prng_enabled = false;
+
+static int *random_fds = NULL;
+static size_t random_fds_used = 0;
+static size_t random_fds_allocd = 0;
+
+void check_random_fds() {
+ if (random_fds_allocd == 0) {
+ random_fds_allocd = 10;
+ random_fds = calloc(random_fds_allocd, sizeof(int));
+ } else if (random_fds_allocd == random_fds_used) {
+ random_fds_allocd *= 2;
+ random_fds = realloc(random_fds, random_fds_allocd * sizeof(int));
+ }
+}
+
+void store_random_fd(int fd) {
+ check_random_fds();
+ random_fds[random_fds_used++] = fd;
+}
+
+int open(const char *pathname, int flags, ...) {
+ if (!real_open) {
+ real_open = dlsym(RTLD_NEXT, "open");
+ }
+
+ va_list args;
+ va_start(args, flags);
+ int mode = va_arg(args, int);
+ va_end(args);
+
+ int result = real_open(pathname, flags, mode);
+ if (strcmp(pathname, "/dev/random") == 0 || strcmp(pathname, "/dev/urandom") == 0) {
+#ifdef DEBUG_PRELOAD
+ fprintf(stderr, "called open(%s, %i, %i)\n", pathname, flags, mode);
+#endif
+ store_random_fd(result);
+ }
+ return result;
+}
+
+int openat(int fd, const char *pathname, int flags, ...) {
+ if (!real_openat) {
+ real_openat = dlsym(RTLD_NEXT, "openat");
+ }
+
+ va_list args;
+ va_start(args, flags);
+ int mode = va_arg(args, int);
+ va_end(args);
+
+ int result = real_openat(fd, pathname, flags, mode);
+ if (strcmp(pathname, "/dev/random") == 0 || strcmp(pathname, "/dev/urandom") == 0) {
+#ifdef DEBUG_PRELOAD
+ fprintf(stderr, "called openat(%s, %i, %i)\n", pathname, flags, mode);
+#endif
+ store_random_fd(result);
+ }
+ return result;
+}
+
+ssize_t read(int fd, void *buf, size_t count) {
+ if (!real_read) {
+ real_read = dlsym(RTLD_NEXT, "read");
+ }
+
+ if (preload_prng_enabled) {
+ for (int i = 0; i < random_fds_used; ++i) {
+ int random_fd = random_fds[i];
+ if (random_fd == fd) {
+ prng_get(&preload_prng_state, buf, count);
+#ifdef DEBUG_PRELOAD
+ fprintf(stderr, "read from random\n");
+ print_buf(buf, count);
+#endif
+ return count;
+ }
+ }
+ }
+
+ return real_read(fd, buf, count);
+}
+
+static FILE **random_files = NULL;
+static size_t random_files_used = 0;
+static size_t random_files_allocd = 0;
+
+void check_random_files() {
+ if (random_files_allocd == 0) {
+ random_files_allocd = 10;
+ random_files = calloc(random_files_allocd, sizeof(FILE *));
+ } else if (random_files_allocd == random_files_used) {
+ random_files_allocd *= 2;
+ random_files = realloc(random_files, random_files_allocd * sizeof(FILE*));
+ }
+}
+
+void store_random_file(FILE *file) {
+ check_random_files();
+ random_files[random_files_used++] = file;
+}
+
+FILE *fopen(const char *pathname, const char *mode) {
+ if (!real_fopen) {
+ real_fopen = dlsym(RTLD_NEXT, "fopen");
+ }
+
+ FILE *result = real_fopen(pathname, mode);
+
+ if (strcmp(pathname, "/dev/random") == 0 || strcmp(pathname, "/dev/urandom") == 0) {
+#ifdef DEBUG_PRELOAD
+ fprintf(stderr, "called fopen(%s, %s)\n", pathname, mode);
+#endif
+ store_random_file(result);
+ }
+ return result;
+}
+
+size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) {
+ if (!real_fread) {
+ real_fread = dlsym(RTLD_NEXT, "fread");
+ }
+
+ if (preload_prng_enabled) {
+ for (int i = 0; i < random_files_used; ++i) {
+ FILE *random_file = random_files[i];
+ if (random_file == stream) {
+ prng_get(&preload_prng_state, ptr, size * nmemb);
+#ifdef DEBUG_PRELOAD
+ fprintf(stderr, "fread from random\n");
+ print_buf(ptr, size * nmemb);
+#endif
+ return size * nmemb;
+ }
+ }
+ }
+
+ return real_fread(ptr, size, nmemb, stream);
+}
+
+ssize_t getrandom(void *buf, size_t buflen, unsigned int flags) {
+ if (!real_getrandom) {
+ real_getrandom = dlsym(RTLD_NEXT, "getrandom");
+ }
+
+#ifdef DEBUG_PRELOAD
+ fprintf(stderr, "called getrandom(*, %lu, %u)\n", buflen, flags);
+#endif
+ if (preload_prng_enabled) {
+ prng_get(&preload_prng_state, buf, buflen);
+ print_buf(buf, buflen);
+ return buflen;
+ } else {
+ return real_getrandom(buf, buflen, flags);
+ }
+}
+
+int getentropy(void *buffer, size_t length) {
+ if (!real_getentropy) {
+ real_getentropy = dlsym(RTLD_NEXT, "getentropy");
+ }
+
+#ifdef DEBUG_PRELOAD
+ fprintf(stderr, "called getentropy(*, %lu)\n", length);
+#endif
+ if (preload_prng_enabled) {
+ prng_get(&preload_prng_state, buffer, length);
+ print_buf(buffer, length);
+ return 0;
+ } else {
+ return real_getentropy(buffer, length);
+ }
+}
+
+long syscall(long number, ...) {
+ if (!real_syscall) {
+ real_syscall = dlsym(RTLD_NEXT, "syscall");
+ }
+ va_list args;
+
+ va_start(args, number);
+ long int a0 = va_arg(args, long int);
+ long int a1 = va_arg(args, long int);
+ long int a2 = va_arg(args, long int);
+ long int a3 = va_arg(args, long int);
+ long int a4 = va_arg(args, long int);
+ long int a5 = va_arg(args, long int);
+ va_end(args);
+
+ if (number == SYS_getrandom) {
+#ifdef DEBUG_PRELOAD
+ fprintf(stderr, "called syscall(getrandom, %li, %li, %li, %li, %li, %li)\n", a0, a1, a2, a3, a4, a5);
+#endif
+ if (preload_prng_enabled) {
+ uint8_t *buf = (uint8_t*)a0;
+ long n = a1;
+ prng_get(&preload_prng_state, buf, n);
+ print_buf(buf, n);
+ return n;
+ }
+ }
+ return real_syscall(number, a0, a1, a2, a3, a4, a5);
+}
+
+uint32_t arc4random(void) {
+ if (!real_arc4random) {
+ real_arc4random = dlsym(RTLD_NEXT, "arc4random");
+ }
+
+#ifdef DEBUG_PRELOAD
+ fprintf(stderr, "called arc4random\n");
+#endif
+ if (preload_prng_enabled) {
+ uint32_t val = 0;
+ prng_get(&preload_prng_state, (uint8_t*)&val, sizeof(val));
+#ifdef DEBUG_PRELOAD
+ fprintf(stderr, "%u\n", val);
+#endif
+ return val;
+ } else {
+ return real_arc4random();
+ }
+}
+
+uint32_t arc4random_uniform(uint32_t upper_bound) {
+ if (!real_arc4random_uniform) {
+ real_arc4random_uniform = dlsym(RTLD_NEXT, "arc4random_uniform");
+ }
+
+#ifdef DEBUG_PRELOAD
+ fprintf(stderr, "called arc4random_uniform(%u)\n", upper_bound);
+#endif
+ if (preload_prng_enabled) {
+ uint64_t val = 0;
+ prng_get(&preload_prng_state, (uint8_t*)&val, sizeof(val));
+ uint32_t result = (uint32_t)(val % (uint64_t)upper_bound);
+#ifdef DEBUG_PRELOAD
+ fprintf(stderr, "%u\n", result);
+#endif
+ return result;
+ } else {
+ return real_arc4random_uniform(upper_bound);
+ }
+}
+
+void arc4random_buf(void *buf, size_t n) {
+ if (!real_arc4random_buf) {
+ real_arc4random_buf = dlsym(RTLD_NEXT, "arc4random_buf");
+ }
+
+#ifdef DEBUG_PRELOAD
+ fprintf(stderr, "called arc4random_buf(%p, %lu) = ", buf, n);
+#endif
+ if (preload_prng_enabled) {
+ prng_get(&preload_prng_state, buf, n);
+ print_buf(buf, n);
+ } else {
+ real_arc4random_buf(buf, n);
+ }
+} \ No newline at end of file
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_prng.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_prng.c
new file mode 100644
index 0000000..13bd172
--- /dev/null
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_prng.c
@@ -0,0 +1,18 @@
+#include <jni.h>
+#include <stdbool.h>
+#include "prng/prng.h"
+
+extern prng_state preload_prng_state;
+extern bool preload_prng_enabled;
+
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_NativeECLibrary_setupDeterministicPRNG(JNIEnv *env, jobject self, jbyteArray seed) {
+ jsize seed_length = (*env)->GetArrayLength(env, seed);
+ jbyte *seed_data = (*env)->GetByteArrayElements(env, seed, NULL);
+
+ preload_prng_enabled = true;
+ prng_init(&preload_prng_state);
+ prng_seed(&preload_prng_state, seed_data, seed_length);
+
+ (*env)->ReleaseByteArrayElements(env, seed, seed_data, JNI_ABORT);
+ return JNI_TRUE;
+} \ No newline at end of file
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h
index 91cada9..881243f 100644
--- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h
@@ -47,6 +47,14 @@ JNIEXPORT jstring JNICALL Java_cz_crcs_ectester_standalone_libs_NativeECLibrary_
JNIEXPORT jlong JNICALL Java_cz_crcs_ectester_standalone_libs_NativeECLibrary_getLastNativeTiming
(JNIEnv *, jobject);
+/*
+ * Class: cz_crcs_ectester_standalone_libs_NativeECLibrary
+ * Method: setupDeterministicPRNG
+ * Signature: ([B)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_NativeECLibrary_setupDeterministicPRNG
+ (JNIEnv *, jobject, jbyteArray);
+
#ifdef __cplusplus
}
#endif
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/preload.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/preload.c
index ff7b67b..e69de29 100644
--- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/preload.c
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/preload.c
@@ -1,255 +0,0 @@
-#define _GNU_SOURCE
-
-#include <dlfcn.h>
-#include <fcntl.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/random.h>
-#include <sys/syscall.h>
-
-typedef int (*open_t)(const char *pathname, int flags, ...);
-static open_t real_open;
-typedef int (*openat_t)(int fd, const char *pathname, int flags, ...);
-static openat_t real_openat;
-typedef ssize_t (*read_t)(int fd, void *buf, size_t count);
-static read_t real_read;
-typedef FILE *(*fopen_t)(const char *pathname, const char *mode);
-static fopen_t real_fopen;
-typedef size_t (*fread_t)(void *ptr, size_t size, size_t nmemb, FILE *stream);
-static fread_t real_fread;
-typedef ssize_t (*getrandom_t)(void *buf, size_t buflen, unsigned int flags);
-static getrandom_t real_getrandom;
-typedef int (*getentropy_t)(void *buffer, size_t length);
-static getentropy_t real_getentropy;
-typedef long (*syscall_t)(long number, ...);
-static syscall_t real_syscall;
-typedef uint32_t (*arc4random_t)(void);
-static arc4random_t real_arc4random;
-typedef uint32_t (*arc4random_uniform_t)(uint32_t upper_bound);
-static arc4random_uniform_t real_arc4random_uniform;
-typedef void (*arc4random_buf_t)(void *buf, size_t n);
-static arc4random_buf_t real_arc4random_buf;
-
-static int *random_fds = NULL;
-static size_t random_fds_used = 0;
-static size_t random_fds_allocd = 0;
-
-void check_random_fds() {
- if (random_fds_allocd == 0) {
- random_fds_allocd = 10;
- random_fds = calloc(random_fds_allocd, sizeof(int));
- } else if (random_fds_allocd == random_fds_used) {
- random_fds_allocd *= 2;
- random_fds = realloc(random_fds, random_fds_allocd * sizeof(int));
- }
-}
-
-void store_random_fd(int fd) {
- check_random_fds();
- random_fds[random_fds_used++] = fd;
-}
-
-int open(const char *pathname, int flags, ...) {
- if (!real_open) {
- real_open = dlsym(RTLD_NEXT, "open");
- }
-
- va_list args;
- va_start(args, flags);
- int mode = va_arg(args, int);
- va_end(args);
-
- int result = real_open(pathname, flags, mode);
- if (strcmp(pathname, "/dev/random") == 0 || strcmp(pathname, "/dev/urandom") == 0) {
- fprintf(stderr, "called open(%s, %i, %i)\n", pathname, flags, mode);
- store_random_fd(result);
- }
- return result;
-}
-
-int openat(int fd, const char *pathname, int flags, ...) {
- if (!real_openat) {
- real_openat = dlsym(RTLD_NEXT, "openat");
- }
-
- va_list args;
- va_start(args, flags);
- int mode = va_arg(args, int);
- va_end(args);
-
- int result = real_openat(fd, pathname, flags, mode);
- if (strcmp(pathname, "/dev/random") == 0 || strcmp(pathname, "/dev/urandom") == 0) {
- fprintf(stderr, "called openat(%s, %i, %i)\n", pathname, flags, mode);
- store_random_fd(result);
- }
- return result;
-}
-
-ssize_t read(int fd, void *buf, size_t count) {
- if (!real_read) {
- real_read = dlsym(RTLD_NEXT, "read");
- }
-
- for (int i = 0; i < random_fds_used; ++i) {
- int random_fd = random_fds[i];
- if (random_fd == fd) {
- fprintf(stderr, "read from random\n");
- uint8_t *buffer = (uint8_t*)buf;
- for (size_t c = 0; c < count; ++c) {
- buffer[c] = (uint8_t)0x00;
- }
- return count;
- }
- }
-
- return real_read(fd, buf, count);
-}
-
-static FILE **random_files = NULL;
-static size_t random_files_used = 0;
-static size_t random_files_allocd = 0;
-
-void check_random_files() {
- if (random_files_allocd == 0) {
- random_files_allocd = 10;
- random_files = calloc(random_files_allocd, sizeof(FILE *));
- } else if (random_files_allocd == random_files_used) {
- random_files_allocd *= 2;
- random_files = realloc(random_files, random_files_allocd * sizeof(FILE*));
- }
-}
-
-void store_random_file(FILE *file) {
- check_random_files();
- random_files[random_files_used++] = file;
-}
-
-FILE *fopen(const char *pathname, const char *mode) {
- if (!real_fopen) {
- real_fopen = dlsym(RTLD_NEXT, "fopen");
- }
-
- FILE *result = real_fopen(pathname, mode);
-
- if (strcmp(pathname, "/dev/random") == 0 || strcmp(pathname, "/dev/urandom") == 0) {
- fprintf(stderr, "called fopen(%s, %s)\n", pathname, mode);
- store_random_file(result);
- }
- return result;
-}
-
-size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) {
- if (!real_fread) {
- real_fread = dlsym(RTLD_NEXT, "fread");
- }
-
- for (int i = 0; i < random_files_used; ++i) {
- FILE *random_file = random_files[i];
- if (random_file == stream) {
- fprintf(stderr, "fread from random\n");
- uint8_t *buffer = (uint8_t*)ptr;
- for (size_t c = 0; c < size * nmemb; ++c) {
- buffer[c] = (uint8_t)0x00;
- }
- return size * nmemb;
- }
- }
-
- return real_fread(ptr, size, nmemb, stream);
-}
-
-ssize_t getrandom(void *buf, size_t buflen, unsigned int flags) {
- if (!real_getrandom) {
- real_getrandom = dlsym(RTLD_NEXT, "getrandom");
- }
-
- fprintf(stderr, "called getrandom(*, %lu, %u)\n", buflen, flags);
- uint8_t *buffer = (uint8_t*)buf;
- for (size_t i = 0; i < buflen; ++i) {
- buffer[i] = (uint8_t)0x00;
- }
- return buflen;
-}
-
-int getentropy(void *buffer, size_t length) {
- if (!real_getentropy) {
- real_getentropy = dlsym(RTLD_NEXT, "getentropy");
- }
-
- fprintf(stderr, "called getentropy(*, %lu)\n", length);
- uint8_t *buf = (uint8_t*)buffer;
- for (size_t i = 0; i < length; ++i) {
- buf[i] = (uint8_t)0x00;
- }
- return 0;
-}
-
-long syscall(long number, ...) {
- if (!real_syscall) {
- real_syscall = dlsym(RTLD_NEXT, "syscall");
- }
- va_list args;
-
- va_start(args, number);
- long int a0 = va_arg(args, long int);
- long int a1 = va_arg(args, long int);
- long int a2 = va_arg(args, long int);
- long int a3 = va_arg(args, long int);
- long int a4 = va_arg(args, long int);
- long int a5 = va_arg(args, long int);
- va_end(args);
-
- if (number == SYS_getrandom) {
- fprintf(stderr, "called syscall(getrandom, %li, %li, %li, %li, %li, %li)\n", a0, a1, a2, a3, a4, a5);
- uint8_t *buf = (uint8_t*)a0;
- long n = a1;
- for (size_t i = 0; i < n; ++i) {
- buf[i] = (uint8_t)0x00;
- }
- return n;
- }
- return real_syscall(number, a0, a1, a2, a3, a4, a5);
-}
-
-uint32_t arc4random(void) {
- if (!real_arc4random) {
- real_arc4random = dlsym(RTLD_NEXT, "arc4random");
- }
-
- fprintf(stderr, "called arc4random\n");
- return 0;
-}
-
-uint32_t arc4random_uniform(uint32_t upper_bound) {
- if (!real_arc4random_uniform) {
- real_arc4random_uniform = dlsym(RTLD_NEXT, "arc4random_uniform");
- }
-
- fprintf(stderr, "called arc4random_uniform(%u)\n", upper_bound);
- return 0;
-}
-
-void arc4random_buf(void *buf, size_t n) {
- if (!real_arc4random_buf) {
- real_arc4random_buf = dlsym(RTLD_NEXT, "arc4random_buf");
- }
-
- fprintf(stderr, "called arc4random_buf(%p, %lu)\n", buf, n);
- uint8_t *buffer = (uint8_t*)buf;
- for (size_t i = 0; i < n; ++i) {
- buffer[i] = (uint8_t)0x00;
- }
-}
-
-
-void __attribute__((destructor)) dealloc() {
- if (random_fds != NULL) {
- free(random_fds);
- }
- if (random_files != NULL) {
- free(random_files);
- }
-}
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplex-common.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplex-common.h
new file mode 100644
index 0000000..6371611
--- /dev/null
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplex-common.h
@@ -0,0 +1,37 @@
+/*
+Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
+Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
+hereby denoted as "the implementer".
+
+For more information, feedback or questions, please refer to our website:
+https://keccak.team/
+
+To the extent possible under law, the implementer has waived all copyright
+and related or neighboring rights to the source code in this file.
+http://creativecommons.org/publicdomain/zero/1.0/
+*/
+
+#ifndef _KeccakDuplexCommon_h_
+#define _KeccakDuplexCommon_h_
+
+#include "align.h"
+
+#define KCP_DeclareDuplexStructure(prefix, size, alignment) \
+ ALIGN(alignment) typedef struct prefix##_DuplexInstanceStruct { \
+ unsigned char state[size]; \
+ unsigned int rate; \
+ unsigned int byteInputIndex; \
+ unsigned int byteOutputIndex; \
+ } prefix##_DuplexInstance;
+
+#define KCP_DeclareDuplexFunctions(prefix) \
+ int prefix##_DuplexInitialize(prefix##_DuplexInstance *duplexInstance, unsigned int rate, unsigned int capacity); \
+ int prefix##_Duplexing(prefix##_DuplexInstance *duplexInstance, const unsigned char *sigmaBegin, unsigned int sigmaBeginByteLen, unsigned char *Z, unsigned int ZByteLen, unsigned char delimitedSigmaEnd); \
+ int prefix##_DuplexingFeedPartialInput(prefix##_DuplexInstance *duplexInstance, const unsigned char *input, unsigned int inputByteLen); \
+ int prefix##_DuplexingFeedZeroes(prefix##_DuplexInstance *duplexInstance, unsigned int inputByteLen); \
+ int prefix##_DuplexingOverwritePartialInput(prefix##_DuplexInstance *duplexInstance, const unsigned char *input, unsigned int inputByteLen); \
+ int prefix##_DuplexingOverwriteWithZeroes(prefix##_DuplexInstance *duplexInstance, unsigned int inputByteLen); \
+ int prefix##_DuplexingGetFurtherOutput(prefix##_DuplexInstance *duplexInstance, unsigned char *out, unsigned int outByteLen); \
+ int prefix##_DuplexingGetFurtherOutputAndAdd(prefix##_DuplexInstance *duplexInstance, const unsigned char *input, unsigned char *output, unsigned int outputByteLen);
+
+#endif
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplex.inc b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplex.inc
new file mode 100644
index 0000000..bd58043
--- /dev/null
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplex.inc
@@ -0,0 +1,192 @@
+/*
+Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
+Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
+hereby denoted as "the implementer".
+
+For more information, feedback or questions, please refer to our website:
+https://keccak.team/
+
+To the extent possible under law, the implementer has waived all copyright
+and related or neighboring rights to the source code in this file.
+http://creativecommons.org/publicdomain/zero/1.0/
+*/
+
+#define JOIN0(a, b) a ## b
+#define JOIN(a, b) JOIN0(a, b)
+
+#define DuplexInstance JOIN(prefix, _DuplexInstance)
+#define DuplexInitialize JOIN(prefix, _DuplexInitialize)
+#define Duplexing JOIN(prefix, _Duplexing)
+#define DuplexingFeedPartialInput JOIN(prefix, _DuplexingFeedPartialInput)
+#define DuplexingFeedZeroes JOIN(prefix, _DuplexingFeedZeroes)
+#define DuplexingOverwritePartialInput JOIN(prefix, _DuplexingOverwritePartialInput)
+#define DuplexingOverwriteWithZeroes JOIN(prefix, _DuplexingOverwriteWithZeroes)
+#define DuplexingGetFurtherOutput JOIN(prefix, _DuplexingGetFurtherOutput)
+#define DuplexingGetFurtherOutputAndAdd JOIN(prefix, _DuplexingGetFurtherOutputAndAdd)
+
+#define SnP_stateSizeInBytes JOIN(SnP, _stateSizeInBytes)
+#define SnP_stateAlignment JOIN(SnP, _stateAlignment)
+#define SnP_StaticInitialize JOIN(SnP, _StaticInitialize)
+#define SnP_Initialize JOIN(SnP, _Initialize)
+#define SnP_AddByte JOIN(SnP, _AddByte)
+#define SnP_AddBytes JOIN(SnP, _AddBytes)
+#define SnP_OverwriteBytes JOIN(SnP, _OverwriteBytes)
+#define SnP_OverwriteWithZeroes JOIN(SnP, _OverwriteWithZeroes)
+#define SnP_ExtractBytes JOIN(SnP, _ExtractBytes)
+#define SnP_ExtractAndAddBytes JOIN(SnP, _ExtractAndAddBytes)
+
+int DuplexInitialize(DuplexInstance *instance, unsigned int rate, unsigned int capacity)
+{
+ if (rate+capacity != SnP_width)
+ return 1;
+ if ((rate <= 2) || (rate > SnP_width))
+ return 1;
+ SnP_StaticInitialize();
+ instance->rate = rate;
+ SnP_Initialize(instance->state);
+ instance->byteInputIndex = 0;
+ instance->byteOutputIndex = (instance->rate+7)/8;
+ return 0;
+}
+
+int Duplexing(DuplexInstance *instance, const unsigned char *sigmaBegin, unsigned int sigmaBeginByteLen, unsigned char *Z, unsigned int ZByteLen, unsigned char delimitedSigmaEnd)
+{
+ const unsigned int rho_max = instance->rate - 2;
+
+ if (delimitedSigmaEnd == 0)
+ return 1;
+ if ((instance->byteInputIndex+sigmaBeginByteLen)*8 > rho_max)
+ return 1;
+ if (rho_max - sigmaBeginByteLen*8 < 7) {
+ unsigned int maxBitsInDelimitedSigmaEnd = rho_max - sigmaBeginByteLen*8;
+ if (delimitedSigmaEnd >= (1 << (maxBitsInDelimitedSigmaEnd+1)))
+ return 1;
+ }
+ if (ZByteLen > (instance->rate+7)/8)
+ return 1; /* The output length must not be greater than the rate (rounded up to a byte) */
+
+ SnP_AddBytes(instance->state, sigmaBegin, instance->byteInputIndex, sigmaBeginByteLen);
+ #ifdef KeccakReference
+ {
+ unsigned char block[SnP_width/8];
+ memcpy(block, sigmaBegin, sigmaBeginByteLen);
+ block[sigmaBeginByteLen] = delimitedSigmaEnd;
+ memset(block+sigmaBeginByteLen+1, 0, sizeof(block)-sigmaBeginByteLen-1);
+ block[(instance->rate-1)/8] |= 1 << ((instance->rate-1) % 8);
+ displayBytes(1, "Block to be absorbed (after padding)", block, (instance->rate+7)/8);
+ }
+ #endif
+
+ /* Last few bits, whose delimiter coincides with first bit of padding */
+ SnP_AddByte(instance->state, delimitedSigmaEnd, instance->byteInputIndex+sigmaBeginByteLen);
+ /* Second bit of padding */
+ SnP_AddByte(instance->state, (unsigned char)1 << ((instance->rate - 1)%8), (instance->rate - 1)/8);
+ SnP_Permute(instance->state);
+ SnP_ExtractBytes(instance->state, Z, 0, ZByteLen);
+
+ if (ZByteLen*8 > instance->rate) {
+ unsigned char mask = (unsigned char)(1 << (instance->rate % 8)) - 1;
+ Z[ZByteLen-1] &= mask;
+ }
+
+ instance->byteInputIndex = 0;
+ instance->byteOutputIndex = ZByteLen;
+
+ return 0;
+}
+
+int DuplexingFeedPartialInput(DuplexInstance *instance, const unsigned char *input, unsigned int inputByteLen)
+{
+ const unsigned int rho_max = instance->rate - 2;
+
+ if ((instance->byteInputIndex+inputByteLen)*8 > rho_max)
+ return 1;
+
+ SnP_AddBytes(instance->state, input, instance->byteInputIndex, inputByteLen);
+ instance->byteInputIndex += inputByteLen;
+ return 0;
+}
+
+int DuplexingFeedZeroes(DuplexInstance *instance, unsigned int inputByteLen)
+{
+ const unsigned int rho_max = instance->rate - 2;
+
+ if ((instance->byteInputIndex+inputByteLen)*8 > rho_max)
+ return 1;
+
+ instance->byteInputIndex += inputByteLen;
+ return 0;
+}
+
+int DuplexingOverwritePartialInput(DuplexInstance *instance, const unsigned char *input, unsigned int inputByteLen)
+{
+ const unsigned int rho_max = instance->rate - 2;
+
+ if ((instance->byteInputIndex+inputByteLen)*8 > rho_max)
+ return 1;
+
+ SnP_OverwriteBytes(instance->state, input, instance->byteInputIndex, inputByteLen);
+ instance->byteInputIndex += inputByteLen;
+ return 0;
+}
+
+int DuplexingOverwriteWithZeroes(DuplexInstance *instance, unsigned int inputByteLen)
+{
+ const unsigned int rho_max = instance->rate - 2;
+
+ if ((instance->byteInputIndex != 0) || (inputByteLen*8 > rho_max))
+ return 1;
+
+ SnP_OverwriteWithZeroes(instance->state, inputByteLen);
+ instance->byteInputIndex = inputByteLen;
+
+ return 0;
+}
+
+int DuplexingGetFurtherOutput(DuplexInstance *instance, unsigned char *output, unsigned int outputByteLen)
+{
+ if ((outputByteLen+instance->byteOutputIndex) > (instance->rate+7)/8)
+ return 1; /* The output length must not be greater than the rate (rounded up to a byte) */
+
+ SnP_ExtractBytes(instance->state, output, instance->byteOutputIndex, outputByteLen);
+ instance->byteOutputIndex += outputByteLen;
+ if (instance->byteOutputIndex*8 > instance->rate) {
+ unsigned char mask = (1 << (instance->rate % 8)) - 1;
+ output[outputByteLen-1] &= mask;
+ }
+ return 0;
+}
+
+int DuplexingGetFurtherOutputAndAdd(DuplexInstance *instance, const unsigned char *input, unsigned char *output, unsigned int outputByteLen)
+{
+ if ((outputByteLen+instance->byteOutputIndex) > (instance->rate+7)/8)
+ return 1; /* The output length must not be greater than the rate (rounded up to a byte) */
+
+ SnP_ExtractAndAddBytes(instance->state, input, output, instance->byteOutputIndex, outputByteLen);
+ instance->byteOutputIndex += outputByteLen;
+ if (instance->byteOutputIndex*8 > instance->rate) {
+ unsigned char mask = (1 << (instance->rate % 8)) - 1;
+ output[outputByteLen-1] &= mask;
+ }
+ return 0;
+}
+
+#undef DuplexInstance
+#undef DuplexInitialize
+#undef Duplexing
+#undef DuplexingFeedPartialInput
+#undef DuplexingFeedZeroes
+#undef DuplexingOverwritePartialInput
+#undef DuplexingOverwriteWithZeroes
+#undef DuplexingGetFurtherOutput
+#undef DuplexingGetFurtherOutputAndAdd
+#undef SnP_stateSizeInBytes
+#undef SnP_stateAlignment
+#undef SnP_StaticInitialize
+#undef SnP_Initialize
+#undef SnP_AddByte
+#undef SnP_AddBytes
+#undef SnP_OverwriteBytes
+#undef SnP_OverwriteWithZeroes
+#undef SnP_ExtractBytes
+#undef SnP_ExtractAndAddBytes
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplexWidth200.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplexWidth200.c
new file mode 100644
index 0000000..d6f56d2
--- /dev/null
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplexWidth200.c
@@ -0,0 +1,29 @@
+/*
+Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
+Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
+hereby denoted as "the implementer".
+
+For more information, feedback or questions, please refer to our website:
+https://keccak.team/
+
+To the extent possible under law, the implementer has waived all copyright
+and related or neighboring rights to the source code in this file.
+http://creativecommons.org/publicdomain/zero/1.0/
+*/
+
+#include "KeccakDuplexWidth200.h"
+
+#ifndef KeccakP200_excluded
+ #include "KeccakP-200-SnP.h"
+
+ #define prefix KeccakWidth200
+ #define SnP KeccakP200
+ #define SnP_width 200
+ #define SnP_Permute KeccakP200_Permute_18rounds
+ #include "KeccakDuplex.inc"
+ #undef prefix
+ #undef SnP
+ #undef SnP_width
+ #undef SnP_Permute
+ #undef SnP_FastLoop_Absorb
+#endif
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplexWidth200.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplexWidth200.h
new file mode 100644
index 0000000..8bb76f4
--- /dev/null
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplexWidth200.h
@@ -0,0 +1,25 @@
+/*
+Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
+Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
+hereby denoted as "the implementer".
+
+For more information, feedback or questions, please refer to our website:
+https://keccak.team/
+
+To the extent possible under law, the implementer has waived all copyright
+and related or neighboring rights to the source code in this file.
+http://creativecommons.org/publicdomain/zero/1.0/
+*/
+
+#ifndef _KeccakDuplexWidth200_h_
+#define _KeccakDuplexWidth200_h_
+
+#include "KeccakDuplex-common.h"
+
+#ifndef KeccakP200_excluded
+ #include "KeccakP-200-SnP.h"
+ KCP_DeclareDuplexStructure(KeccakWidth200, KeccakP200_stateSizeInBytes, KeccakP200_stateAlignment)
+ KCP_DeclareDuplexFunctions(KeccakWidth200)
+#endif
+
+#endif
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakP-200-SnP.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakP-200-SnP.h
new file mode 100644
index 0000000..4acf932
--- /dev/null
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakP-200-SnP.h
@@ -0,0 +1,34 @@
+/*
+Implementation by Ronny Van Keer, hereby denoted as "the implementer".
+
+For more information, feedback or questions, please refer to our website:
+https://keccak.team/
+
+To the extent possible under law, the implementer has waived all copyright
+and related or neighboring rights to the source code in this file.
+http://creativecommons.org/publicdomain/zero/1.0/
+
+---
+
+Please refer to SnP-documentation.h for more details.
+*/
+
+#ifndef _KeccakP_200_SnP_h_
+#define _KeccakP_200_SnP_h_
+
+#define KeccakP200_implementation "8-bit compact implementation"
+#define KeccakP200_stateSizeInBytes 25
+#define KeccakP200_stateAlignment 1
+
+#define KeccakP200_StaticInitialize()
+void KeccakP200_Initialize(void *state);
+void KeccakP200_AddByte(void *state, unsigned char data, unsigned int offset);
+void KeccakP200_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length);
+void KeccakP200_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length);
+void KeccakP200_OverwriteWithZeroes(void *state, unsigned int byteCount);
+void KeccakP200_Permute_Nrounds(void *state, unsigned int nrounds);
+void KeccakP200_Permute_18rounds(void *state);
+void KeccakP200_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length);
+void KeccakP200_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length);
+
+#endif
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakP-200-compact.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakP-200-compact.c
new file mode 100644
index 0000000..f07bae9
--- /dev/null
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakP-200-compact.c
@@ -0,0 +1,187 @@
+/*
+Implementation by Ronny Van Keer, hereby denoted as "the implementer".
+
+For more information, feedback or questions, please refer to our website:
+https://keccak.team/
+
+To the extent possible under law, the implementer has waived all copyright
+and related or neighboring rights to the source code in this file.
+http://creativecommons.org/publicdomain/zero/1.0/
+
+---
+
+This file implements Keccak-p[200] in a SnP-compatible way.
+Please refer to SnP-documentation.h for more details.
+
+This implementation comes with KeccakP-200-SnP.h in the same folder.
+Please refer to LowLevel.build for the exact list of other files it must be combined with.
+*/
+
+#include <string.h>
+#include <stdlib.h>
+#include "KeccakP-200-SnP.h"
+
+// #define DIVISION_INSTRUCTION /* comment if no division instruction or more compact when not using division */
+#define UNROLL_CHILOOP /* comment if more compact using for loop */
+
+typedef unsigned char UINT8;
+typedef unsigned int tSmallUInt; /*INFO It could be more optimized to use "unsigned char" on an 8-bit CPU */
+typedef UINT8 tKeccakLane;
+
+#define ROL8(a, offset) (UINT8)((((UINT8)a) << (offset&7)) ^ (((UINT8)a) >> (8-(offset&7))))
+
+const UINT8 KeccakP200_RotationConstants[25] =
+{
+ 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44
+};
+
+const UINT8 KeccakP200_PiLane[25] =
+{
+ 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1
+};
+
+#if defined(DIVISION_INSTRUCTION)
+#define MOD5(argValue) ((argValue) % 5)
+#else
+const UINT8 KeccakP200_Mod5[10] =
+{
+ 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
+};
+#define MOD5(argValue) KeccakP200_Mod5[argValue]
+#endif
+
+const UINT8 KeccakF200_RoundConstants[] =
+{
+ 0x01, 0x82, 0x8a, 0x00, 0x8b, 0x01, 0x81, 0x09, 0x8a, 0x88, 0x09, 0x0a, 0x8b, 0x8b, 0x89, 0x03, 0x02, 0x80
+};
+
+/* ---------------------------------------------------------------- */
+
+void KeccakP200_Initialize(void *argState)
+{
+ memset( argState, 0, 25 * sizeof(tKeccakLane) );
+}
+
+/* ---------------------------------------------------------------- */
+
+void KeccakP200_AddByte(void *argState, unsigned char byte, unsigned int offset)
+{
+ ((tKeccakLane*)argState)[offset] ^= byte;
+}
+
+/* ---------------------------------------------------------------- */
+
+void KeccakP200_AddBytes(void *argState, const unsigned char *data, unsigned int offset, unsigned int length)
+{
+ tSmallUInt i;
+ tKeccakLane * state = (tKeccakLane*)argState + offset;
+ for(i=0; i<length; i++)
+ state[i] ^= data[i];
+}
+
+/* ---------------------------------------------------------------- */
+
+void KeccakP200_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length)
+{
+ memcpy((unsigned char*)state+offset, data, length);
+}
+
+/* ---------------------------------------------------------------- */
+
+void KeccakP200_OverwriteWithZeroes(void *state, unsigned int byteCount)
+{
+ memset(state, 0, byteCount);
+}
+
+/* ---------------------------------------------------------------- */
+
+void KeccakP200_Permute_Nrounds(void *argState, unsigned int nr)
+{
+ tSmallUInt x, y;
+ tKeccakLane temp;
+ tKeccakLane BC[5];
+ tKeccakLane *state;
+ const tKeccakLane *rc;
+
+ state = (tKeccakLane*)argState;
+ rc = KeccakF200_RoundConstants + 18 - nr;
+ do
+ {
+ /* Theta */
+ for ( x = 0; x < 5; ++x )
+ {
+ BC[x] = state[x] ^ state[5 + x] ^ state[10 + x] ^ state[15 + x] ^ state[20 + x];
+ }
+ for ( x = 0; x < 5; ++x )
+ {
+ temp = BC[MOD5(x+4)] ^ ROL8(BC[MOD5(x+1)], 1);
+ for ( y = 0; y < 25; y += 5 )
+ {
+ state[y + x] ^= temp;
+ }
+ }
+
+ /* Rho Pi */
+ temp = state[1];
+ for ( x = 0; x < 24; ++x )
+ {
+ BC[0] = state[KeccakP200_PiLane[x]];
+ state[KeccakP200_PiLane[x]] = ROL8( temp, KeccakP200_RotationConstants[x] );
+ temp = BC[0];
+ }
+
+ /* Chi */
+ for ( y = 0; y < 25; y += 5 )
+ {
+#if defined(UNROLL_CHILOOP)
+ BC[0] = state[y + 0];
+ BC[1] = state[y + 1];
+ BC[2] = state[y + 2];
+ BC[3] = state[y + 3];
+ BC[4] = state[y + 4];
+#else
+ for ( x = 0; x < 5; ++x )
+ {
+ BC[x] = state[y + x];
+ }
+#endif
+ for ( x = 0; x < 5; ++x )
+ {
+ state[y + x] = BC[x] ^((~BC[MOD5(x+1)]) & BC[MOD5(x+2)]);
+ }
+ }
+
+ /* Iota */
+ temp = *(rc++);
+ state[0] ^= temp;
+ }
+ while( temp != 0x80 );
+}
+
+/* ---------------------------------------------------------------- */
+
+void KeccakP200_Permute_18rounds(void *argState)
+{
+ KeccakP200_Permute_Nrounds(argState, 18);
+}
+
+/* ---------------------------------------------------------------- */
+
+void KeccakP200_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length)
+{
+ if (length) {
+ memcpy(data, (UINT8*)state+offset, length);
+ }
+}
+
+/* ---------------------------------------------------------------- */
+
+void KeccakP200_ExtractAndAddBytes(const void *argState, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length)
+{
+ unsigned int i;
+ tKeccakLane * state = (tKeccakLane*)argState + offset;
+ for(i=0; i<length; i++)
+ output[i] = input[i] ^ state[i];
+}
+
+/* ---------------------------------------------------------------- */
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRG-common.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRG-common.h
new file mode 100644
index 0000000..eca5d2e
--- /dev/null
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRG-common.h
@@ -0,0 +1,28 @@
+/*
+Implementation by Gilles Van Assche, hereby denoted as "the implementer".
+
+For more information, feedback or questions, please refer to our website:
+https://keccak.team/
+
+To the extent possible under law, the implementer has waived all copyright
+and related or neighboring rights to the source code in this file.
+http://creativecommons.org/publicdomain/zero/1.0/
+*/
+
+#ifndef _KeccakPRGCommon_h_
+#define _KeccakPRGCommon_h_
+
+#include "align.h"
+
+#define KCP_DeclareSpongePRG_Structure(prefix, size, alignment) \
+ ALIGN(alignment) typedef struct prefix##_SpongePRG_InstanceStruct { \
+ prefix##_DuplexInstance duplex; \
+ } prefix##_SpongePRG_Instance;
+
+#define KCP_DeclareSpongePRG_Functions(prefix) \
+ int prefix##_SpongePRG_Initialize(prefix##_SpongePRG_Instance *instance, unsigned int capacity); \
+ int prefix##_SpongePRG_Feed(prefix##_SpongePRG_Instance *instance, const unsigned char *input, unsigned int inputByteLen); \
+ int prefix##_SpongePRG_Fetch(prefix##_SpongePRG_Instance *Instance, unsigned char *out, unsigned int outByteLen); \
+ int prefix##_SpongePRG_Forget(prefix##_SpongePRG_Instance *instance);
+
+#endif
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRG.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRG.h
new file mode 100644
index 0000000..83a2144
--- /dev/null
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRG.h
@@ -0,0 +1,20 @@
+/*
+Implementation by Gilles Van Assche, hereby denoted as "the implementer".
+
+For more information, feedback or questions, please refer to our website:
+https://keccak.team/
+
+To the extent possible under law, the implementer has waived all copyright
+and related or neighboring rights to the source code in this file.
+http://creativecommons.org/publicdomain/zero/1.0/
+*/
+
+#ifndef _KeccakPRG_h_
+#define _KeccakPRG_h_
+
+/* For the documentation, please follow the link: */
+/* #include "KeccakPRG-documentation.h" */
+
+#include "KeccakPRGWidth200.h"
+
+#endif
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRG.inc b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRG.inc
new file mode 100644
index 0000000..aa65db0
--- /dev/null
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRG.inc
@@ -0,0 +1,123 @@
+/*
+Implementation by Gilles Van Assche, hereby denoted as "the implementer".
+
+For more information, feedback or questions, please refer to our website:
+https://keccak.team/
+
+To the extent possible under law, the implementer has waived all copyright
+and related or neighboring rights to the source code in this file.
+http://creativecommons.org/publicdomain/zero/1.0/
+*/
+
+#define JOIN0(a, b) a ## b
+#define JOIN(a, b) JOIN0(a, b)
+
+#define SpongePRG_Instance JOIN(prefix, _SpongePRG_Instance)
+#define SpongePRG_Initialize JOIN(prefix, _SpongePRG_Initialize)
+#define SpongePRG_Feed JOIN(prefix, _SpongePRG_Feed)
+#define SpongePRG_Fetch JOIN(prefix, _SpongePRG_Fetch)
+#define SpongePRG_Forget JOIN(prefix, _SpongePRG_Forget)
+
+#define DuplexInstance JOIN(prefix, _DuplexInstance)
+#define DuplexInitialize JOIN(prefix, _DuplexInitialize)
+#define Duplexing JOIN(prefix, _Duplexing)
+#define DuplexingFeedPartialInput JOIN(prefix, _DuplexingFeedPartialInput)
+#define DuplexingOverwriteWithZeroes JOIN(prefix, _DuplexingOverwriteWithZeroes)
+#define DuplexingGetFurtherOutput JOIN(prefix, _DuplexingGetFurtherOutput)
+#define DuplexGetInputIndex(duplex) (duplex)->byteInputIndex
+#define DuplexGetOutputIndex(duplex) (duplex)->byteOutputIndex
+#define DuplexSetOutputIndex(duplex, i) (duplex)->byteOutputIndex = (i)
+
+int SpongePRG_Initialize(SpongePRG_Instance *instance, unsigned int capacity)
+{
+ unsigned int rate;
+ unsigned int rhoInBytes;
+
+ if (capacity > (SnP_width-10))
+ return 1;
+
+ rate = SnP_width - capacity;
+ rhoInBytes = (rate-2)/8;
+
+ if ( (rhoInBytes == 0) || (rhoInBytes >= SnP_width/8) )
+ return 1;
+ return DuplexInitialize(&instance->duplex, rate, capacity);
+}
+
+int SpongePRG_Feed(SpongePRG_Instance *instance, const unsigned char *input, unsigned int inputByteLen)
+{
+ unsigned int rhoInBytes = (instance->duplex.rate-2)/8;
+ int error = 0;
+
+ while( !error && ((DuplexGetInputIndex(&instance->duplex) + inputByteLen) >= rhoInBytes)) {
+ unsigned int localSize = rhoInBytes - DuplexGetInputIndex(&instance->duplex);
+ error |= DuplexingFeedPartialInput(&instance->duplex, input, localSize);
+ error |= Duplexing(&instance->duplex, 0, 0, 0, 0, 0x01);
+ input += localSize;
+ inputByteLen -= localSize;
+ }
+ if (!error)
+ error = DuplexingFeedPartialInput(&instance->duplex, input, inputByteLen);
+ DuplexSetOutputIndex(&instance->duplex, rhoInBytes);
+ return error;
+}
+
+int SpongePRG_Fetch(SpongePRG_Instance *instance, unsigned char *output, unsigned int outputByteLen)
+{
+ unsigned int rhoInBytes = (instance->duplex.rate-2)/8;
+ int error = 0;
+
+ if (DuplexGetOutputIndex(&instance->duplex) < rhoInBytes) {
+ unsigned int localSize = rhoInBytes - DuplexGetOutputIndex(&instance->duplex);
+ localSize = (localSize <= outputByteLen) ? localSize : outputByteLen;
+ error = DuplexingGetFurtherOutput(&instance->duplex, output, localSize);
+ output += localSize;
+ outputByteLen -= localSize;
+ }
+
+ while( !error && (outputByteLen > 0) ) {
+ error = Duplexing(&instance->duplex, 0, 0, 0, 0, 0x01);
+ if (!error) {
+ unsigned int localSize = (rhoInBytes <= outputByteLen) ? rhoInBytes : outputByteLen;
+ error = DuplexingGetFurtherOutput(&instance->duplex, output, localSize);
+ output += localSize;
+ outputByteLen -= localSize;
+ }
+ }
+ return error;
+}
+
+int SpongePRG_Forget(SpongePRG_Instance *instance)
+{
+ unsigned int rhoInBytes = (instance->duplex.rate-2)/8;
+ unsigned int capacity = SnP_width - instance->duplex.rate;
+ int error;
+
+ if ((rhoInBytes*8) < capacity)
+ return 1;
+
+ error = Duplexing(&instance->duplex, 0, 0, 0, 0, 0x01);
+ if ( !error ) {
+ error = DuplexingOverwriteWithZeroes(&instance->duplex, rhoInBytes);
+ if ( !error )
+ error = Duplexing(&instance->duplex, 0, 0, 0, 0, 0x01);
+ }
+ DuplexSetOutputIndex(&instance->duplex, rhoInBytes);
+ return error;
+}
+
+#undef SpongePRG_Instance
+#undef SpongePRG_Initialize
+#undef SpongePRG_Feed
+#undef SpongePRG_Fetch
+#undef SpongePRG_Forget
+
+#undef DuplexInstance
+#undef DuplexInitialize
+#undef Duplexing
+#undef DuplexingFeedPartialInput
+#undef DuplexingOverwriteWithZeroes
+#undef DuplexingGetFurtherOutput
+#undef DuplexGetInputIndex
+#undef DuplexGetOutputIndex
+#undef DuplexSetOutputIndex
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRGWidth200.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRGWidth200.c
new file mode 100644
index 0000000..067375e
--- /dev/null
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRGWidth200.c
@@ -0,0 +1,22 @@
+/*
+Implementation by Gilles Van Assche, hereby denoted as "the implementer".
+
+For more information, feedback or questions, please refer to our website:
+https://keccak.team/
+
+To the extent possible under law, the implementer has waived all copyright
+and related or neighboring rights to the source code in this file.
+http://creativecommons.org/publicdomain/zero/1.0/
+*/
+
+#include "KeccakPRGWidth200.h"
+
+#ifndef KeccakP200_excluded
+ #include "KeccakP-200-SnP.h"
+
+ #define prefix KeccakWidth200
+ #define SnP_width 200
+ #include "KeccakPRG.inc"
+ #undef prefix
+ #undef SnP_width
+#endif
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRGWidth200.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRGWidth200.h
new file mode 100644
index 0000000..d7cfcc9
--- /dev/null
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRGWidth200.h
@@ -0,0 +1,24 @@
+/*
+Implementation by Gilles Van Assche, hereby denoted as "the implementer".
+
+For more information, feedback or questions, please refer to our website:
+https://keccak.team/
+
+To the extent possible under law, the implementer has waived all copyright
+and related or neighboring rights to the source code in this file.
+http://creativecommons.org/publicdomain/zero/1.0/
+*/
+
+#ifndef _KeccakPRGWidth200_h_
+#define _KeccakPRGWidth200_h_
+
+#include "KeccakDuplexWidth200.h"
+#include "KeccakPRG-common.h"
+
+#ifndef KeccakP200_excluded
+ #include "KeccakP-200-SnP.h"
+ KCP_DeclareSpongePRG_Structure(KeccakWidth200, KeccakP200_stateSizeInBytes, KeccakP200_stateAlignment)
+ KCP_DeclareSpongePRG_Functions(KeccakWidth200)
+#endif
+
+#endif
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/align.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/align.h
new file mode 100644
index 0000000..90c1b37
--- /dev/null
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/align.h
@@ -0,0 +1,32 @@
+/*
+Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
+Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
+hereby denoted as "the implementer".
+
+For more information, feedback or questions, please refer to our website:
+https://keccak.team/
+
+To the extent possible under law, the implementer has waived all copyright
+and related or neighboring rights to the source code in this file.
+http://creativecommons.org/publicdomain/zero/1.0/
+*/
+
+#ifndef _align_h_
+#define _align_h_
+
+/* on Mac OS-X and possibly others, ALIGN(x) is defined in param.h, and -Werror chokes on the redef. */
+#ifdef ALIGN
+#undef ALIGN
+#endif
+
+#if defined(__GNUC__)
+#define ALIGN(x) __attribute__ ((aligned(x)))
+#elif defined(_MSC_VER)
+#define ALIGN(x) __declspec(align(x))
+#elif defined(__ARMCC_VERSION)
+#define ALIGN(x) __align(x)
+#else
+#define ALIGN(x)
+#endif
+
+#endif
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/prng.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/prng.c
new file mode 100644
index 0000000..c44db6f
--- /dev/null
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/prng.c
@@ -0,0 +1,21 @@
+#include "KeccakPRG.h"
+#include "KeccakP-200-compact.c"
+#include "KeccakDuplexWidth200.c"
+#include "KeccakPRGWidth200.c"
+#include "prng.h"
+#include <stdlib.h>
+
+
+void prng_init(prng_state *state) {
+ memset(state, 0, sizeof(state));
+ KeccakWidth200_SpongePRG_Initialize(state, 70);
+}
+
+void prng_seed(prng_state *state, const uint8_t *seed, size_t size) {
+ KeccakWidth200_SpongePRG_Feed(state, seed, size);
+ KeccakWidth200_SpongePRG_Forget(state);
+}
+
+void prng_get(prng_state *state, uint8_t *out, size_t size) {
+ KeccakWidth200_SpongePRG_Fetch(state, out, size);
+} \ No newline at end of file
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/prng.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/prng.h
new file mode 100644
index 0000000..2cc4f21
--- /dev/null
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/prng.h
@@ -0,0 +1,13 @@
+#include "KeccakPRG.h"
+#include <stdint.h>
+
+typedef KeccakWidth200_SpongePRG_Instance prng_state;
+
+void prng_init(prng_state *state);
+
+void prng_seed(prng_state *state, const uint8_t *seed, size_t size);
+
+void prng_get(prng_state *state, uint8_t *out, size_t size);
+
+
+
diff --git a/standalone/src/test/java/cz/crcs/ectester/standalone/DeterministicTests.java b/standalone/src/test/java/cz/crcs/ectester/standalone/DeterministicTests.java
index bebb3c5..e5caae8 100644
--- a/standalone/src/test/java/cz/crcs/ectester/standalone/DeterministicTests.java
+++ b/standalone/src/test/java/cz/crcs/ectester/standalone/DeterministicTests.java
@@ -14,7 +14,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
public class DeterministicTests {
static Stream<String> libs() {
- return Stream.of("Botan", "BouncyCastle", "Crypto++", "IPPCP", "mbedTLS", "Nettle", "OpenSSL", "SunEC", "tomcrypt");
+ return Stream.of("Botan", "BouncyCastle", "Crypto++", "IPPCP", "mbedTLS", "Nettle", "OpenSSL", "SunEC", "tomcrypt", "LibreSSL");
+ // BoringSSL and libgcrypt cannot be easily tested here, because they initialize their RNG only once per process.
}
@SuppressWarnings("JUnitMalformedDeclaration")
@@ -110,6 +111,7 @@ public class DeterministicTests {
case "Crypto++":
args = new String[]{"ecdsa", "-ps", "12345678", "-d", "1234", "-n", "10", "-nc", "secg/secp256r1", "-t", "ECDSA", libName};
break;
+ case "LibreSSL":
case "mbedTLS":
args = new String[]{"ecdsa", "-ps", "12345678", "-d", "1234", "-n", "10", "-nc", "secg/secp256r1", "-t", "NONEwithECDSA", libName};
break;