diff --git a/software/Makefile.linux b/software/Makefile.linux
index db48aa5..c246dcc 100644
--- a/software/Makefile.linux
+++ b/software/Makefile.linux
@@ -4,7 +4,7 @@ GIT_DATE := $(firstword $(shell git --no-pager show --date=iso-strict --forma
PREFIX = $(DESTDIR)/usr/local
-CFLAGS = -Wall -Wextra -Werror -std=c99 -O3 -fPIC -I Keccak -I /usr/include/libftdi1 \
+CFLAGS = -Wall -Wextra -Werror -std=c99 -O3 -fPIC -I BLAKE3 -I /usr/include/libftdi1 \
-DGIT_VERSION=\"$(GIT_VERSION)\"\
-DGIT_COMMIT=\"$(GIT_COMMIT)\"\
-DGIT_DATE=\"$(GIT_DATE)\"\
@@ -15,25 +15,22 @@ FTDI = $(shell $(CC) -o /dev/null -x c /dev/null -shared -lftdi 2>/dev/null && e
all: libinfnoise.a libinfnoise.so infnoise
infnoise: libinfnoise.a infnoise.o daemon.o
- $(CC) $(CFLAGS) -o infnoise infnoise.o daemon.o libinfnoise.a $(FTDI) -lm -lrt -L.
+ $(CC) $(CFLAGS) -o infnoise infnoise.o daemon.o libinfnoise.a $(FTDI) -lm -lrt -L. -LBLAKE3 -lblake3
%.o: %.c infnoise.h libinfnoise.h
$(CC) -c -o $@ $< $(CFLAGS)
-KeccakF-1600-reference.o: Keccak/KeccakF-1600-reference.c Keccak/KeccakF-1600-interface.h Keccak/brg_endian.h
- $(CC) -c -o $@ $< $(CFLAGS)
-
# static lib compiled into infnoise binary
libinfnoise.o: libinfnoise.c libinfnoise.h libinfnoise_private.h healthcheck.c
$(CC) $(CFLAGS) -c libinfnoise.c
-libinfnoise.a: libinfnoise.o healthcheck.o KeccakF-1600-reference.o writeentropy.o
- ar rcs libinfnoise.a libinfnoise.o healthcheck.o KeccakF-1600-reference.o writeentropy.o
+libinfnoise.a: libinfnoise.o healthcheck.o BLAKE3/blake3.o writeentropy.o
+ ar rcs libinfnoise.a libinfnoise.o healthcheck.o BLAKE3/blake3.o writeentropy.o
ranlib libinfnoise.a
# shared lib
-libinfnoise.so: libinfnoise.o healthcheck.o KeccakF-1600-reference.o writeentropy.o
- $(CC) $(CFLAGS) -fvisibility=hidden -o libinfnoise.so libinfnoise.o healthcheck.o KeccakF-1600-reference.o writeentropy.o -Wl,--version-script=libinfnoise.version $(FTDI) -lm -shared
+libinfnoise.so: libinfnoise.o healthcheck.o BLAKE3/blake3.o writeentropy.o
+ $(CC) $(CFLAGS) -fvisibility=hidden -o libinfnoise.so libinfnoise.o healthcheck.o BLAKE3/blake3.o writeentropy.o -Wl,--version-script=libinfnoise.version $(FTDI) -lm -shared
libs: libinfnoise.a
diff --git a/software/infnoise.c b/software/infnoise.c
index 0361b6a..a0f85a6 100644
--- a/software/infnoise.c
+++ b/software/infnoise.c
@@ -30,7 +30,6 @@ void term(int signum)
}
static void initOpts(struct opt_struct *opts) {
- opts->outputMultiplier = 0u;
opts->daemon = false;
opts->debug = false;
opts->devRandom = false;
@@ -50,7 +49,6 @@ static struct option longopts[] = {
{"debug", no_argument, NULL, 'D'},
{"dev-random", no_argument, NULL, 'R'},
{"no-output", no_argument, NULL, 'n'},
- {"multiplier", required_argument, NULL, 'm'},
{"pidfile", required_argument, NULL, 'p'},
{"serial", required_argument, NULL, 's'},
{"daemon", no_argument, NULL, 'd'},
@@ -104,7 +102,6 @@ int main(int argc, char **argv) {
struct infnoise_context context;
struct opt_struct opts;
int ch;
- bool multiplierAssigned = false;
initOpts(&opts);
@@ -124,15 +121,6 @@ int main(int argc, char **argv) {
case 'n':
opts.noOutput = true;
break;
- case 'm':
- multiplierAssigned = true;
- int tmpOutputMult = atoi(optarg);
- if (tmpOutputMult < 0) {
- fputs("Multiplier must be >= 0\n", stderr);
- return 1;
- }
- opts.outputMultiplier = tmpOutputMult;
- break;
case 'p':
opts.pidFileName = optarg;
if (opts.pidFileName == NULL || opts.pidFileName[0] == '\0') {
@@ -172,8 +160,6 @@ int main(int argc, char **argv) {
" -R, --dev-random - write entropy to /dev/random instead of "
"stdout\n"
" -r, --raw - do not whiten the output\n"
- " -m, --multiplier <value> - write 256 bits * value for each 512 bits written to\n"
- " the Keccak sponge. Default of 0 means write all the entropy.\n"
" -n, --no-output - do not write random output data\n"
" -p, --pidfile <file> - write process ID to file\n"
" -d, --daemon - run in the background\n"
@@ -203,23 +189,6 @@ int main(int argc, char **argv) {
&& !strcmp("true", envDbg));
}
- if (!multiplierAssigned) {
- char *envMultiplier = getenv("INFNOISE_MULTIPLIER");
- if (envMultiplier != NULL) {
- int tmpOutputMult = atoi(envMultiplier);
- if (tmpOutputMult < 0) {
- fputs("Multiplier must be >= 0\n", stderr);
- return 1;
- }
- multiplierAssigned = true;
- opts.outputMultiplier = tmpOutputMult;
- }
- }
-
- if (!multiplierAssigned && opts.devRandom) {
- opts.outputMultiplier = 2u; // Don't throw away entropy when writing to /dev/random unless told to do so
- }
-
if (opts.listDevices) {
infnoise_devlist_node_t* devlist = listUSBDevices(&context.message);
if (devlist == NULL) {
@@ -263,21 +232,12 @@ int main(int argc, char **argv) {
// Optionally run in the background and optionally write a PID-file
startDaemon(&opts);
- // initialize USB device, health check and Keccak state (see libinfnoise)
+ // initialize USB device, health check and BLAKE3 (see libinfnoise)
if (!initInfnoise(&context, opts.serial, !opts.raw, opts.debug)) {
fprintf(stderr, "Error: %s\n", context.message);
return 1; // ERROR
}
- // calculate output size based on the parameters:
- uint64_t resultSize;
- if (opts.outputMultiplier <= 2 || opts.raw) {
- resultSize = 64u;
- } else {
- resultSize = 128u;
- }
- //fprintf(stderr, "resultsize: %lu\n", resultSize);
-
// get proper shutdown
struct sigaction action;
memset(&action, 0, sizeof(action));
@@ -288,8 +248,8 @@ int main(int argc, char **argv) {
// endless loop
uint64_t totalBytesWritten = 0u;
while (running) {
- uint8_t result[resultSize];
- uint64_t bytesWritten = readData(&context, result, opts.raw, opts.outputMultiplier);
+ uint8_t result[64u];
+ uint64_t bytesWritten = readData(&context, result, opts.raw);
totalBytesWritten += bytesWritten;
if (context.errorFlag) {
diff --git a/software/infnoise.h b/software/infnoise.h
index 3f894de..7ba96a1 100644
--- a/software/infnoise.h
+++ b/software/infnoise.h
@@ -9,7 +9,6 @@
// Structure for parsed command line options
struct opt_struct {
- uint32_t outputMultiplier; // We output all the entropy when outputMultiplier == 0
bool daemon; // Run as daemon?
bool debug; // Print debugging info?
bool devRandom; // Feed /dev/random?
diff --git a/software/libinfnoise.c b/software/libinfnoise.c
index 7c7f9f5..14744a5 100644
--- a/software/libinfnoise.c
+++ b/software/libinfnoise.c
@@ -16,20 +16,18 @@
#include <sys/types.h>
#include <ftdi.h>
#include "libinfnoise_private.h"
-#include "KeccakF-1600-interface.h"
+#include "blake3.h"
#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__FreeBSD__)
#include <fcntl.h>
#endif
-uint8_t keccakState[KeccakPermutationSizeInBytes];
+blake3_hasher blake3hasher;
-bool initInfnoise(struct infnoise_context *context, char *serial, bool keccak, bool debug) {
+bool initInfnoise(struct infnoise_context *context, char *serial, bool blake3, bool debug) {
context->message="";
context->entropyThisTime=0;
context->errorFlag=false;
- context->bytesGiven=0;
- context->bytesWritten=0;
prepareOutputBuffer();
@@ -47,11 +45,9 @@ bool initInfnoise(struct infnoise_context *context, char *serial, bool keccak, b
}
}
- // initialize keccak
- if (keccak) {
- KeccakInitialize();
- KeccakInitializeState(keccakState);
- }
+ // initialize blake3
+ if (blake3)
+ blake3_hasher_init(&blake3hasher);
// let healthcheck collect some data
uint32_t maxWarmupRounds = 5000;
@@ -59,7 +55,7 @@ bool initInfnoise(struct infnoise_context *context, char *serial, bool keccak, b
//bool errorFlag = false;
while (!inmHealthCheckOkToUseData()) {
- readData(context, NULL, true, 1);
+ readData(context, NULL, true);
warmupRounds++;
}
@@ -120,15 +116,9 @@ uint32_t extractBytes(uint8_t *bytes, uint32_t length, uint8_t *inBuf, const cha
return inmGetEntropyLevel();
}
-// Whiten the output, if requested, with a Keccak sponge. Output bytes only if the health
-// checker says it's OK. Using outputMultiplier > 1 is a nice way to generate a lot more
-// cryptographically secure pseudo-random data than the INM generates. If
-// outputMultiplier is 0, we output only as many bits as we measure in entropy.
-// This allows a user to generate hundreds of MiB per second if needed, for use
-// as cryptographic keys.
-uint32_t processBytes(uint8_t *bytes, uint8_t *result, uint32_t *entropy,
- uint32_t *bytesGiven, uint32_t *bytesWritten,
- bool raw, uint32_t outputMultiplier) {
+// Whiten the output, if requested. Output bytes only if the health
+// checker says it's OK.
+uint32_t processBytes(uint8_t *bytes, uint8_t *result, uint32_t *entropy, bool raw) {
//Use the lower of the measured entropy and the provable lower bound on
//average entropy.
if (*entropy > inmExpectedEntropyPerBit * BUFLEN / INM_ACCURACY) {
@@ -142,50 +132,11 @@ uint32_t processBytes(uint8_t *bytes, uint8_t *result, uint32_t *entropy,
return BUFLEN / 8u;
}
- // Note that BUFLEN has to be less than 1600 by enough to make the sponge secure,
- // since outputting all 1600 bits would tell an attacker the Keccak state, allowing
- // him to predict any further output, when outputMultiplier > 1, until the next call
- // to processBytes. All 512 bits are absorbed before squeezing data out to ensure that
- // we instantly recover (reseed) from a state compromise, which is when an attacker
- // gets a snapshot of the keccak state. BUFLEN must be a multiple of 64, since
- // Keccak-1600 uses 64-bit "lanes".
- uint8_t resultSize;
- if (outputMultiplier <= 2) {
- resultSize = 64u;
- } else {
- resultSize = 128u;
- }
-
- uint8_t dataOut[resultSize];
- KeccakAbsorb(keccakState, bytes, BUFLEN / 64u);
-
- if (outputMultiplier == 0u) {
- // Output all the bytes of entropy we have
- KeccakExtract(keccakState, dataOut, (*entropy + 63u) / 64u);
- if (result != NULL) {
- memcpy(result, dataOut, *entropy / 8u * sizeof(uint8_t));
- }
- return *entropy / 8u;
+ blake3_hasher_update(&blake3hasher, bytes, *entropy / 8u * sizeof(uint8_t));
+ if (result != NULL) {
+ blake3_hasher_finalize(&blake3hasher, result, *entropy / 8u * sizeof(uint8_t));
}
-
- // Output 256*outputMultipler bits (in chunks of 1024)
- // only the first 1024 now,
- if (*bytesGiven == 0u) {
- *bytesGiven = outputMultiplier*256u / 8u;
- *bytesWritten = 0u;
-
- // Output up to 1024 bits at a time.
- uint32_t bytesToWrite = 1024u / 8u;
- if (bytesToWrite > *bytesGiven) {
- bytesToWrite = *bytesGiven;
- }
-
- KeccakExtract(keccakState, result, bytesToWrite / 8u);
- KeccakPermutation(keccakState);
- *bytesWritten = bytesToWrite;
- *bytesGiven -= bytesToWrite;
- }
- return *bytesWritten;
+ return *entropy / 8u;
}
// Return the difference in the times as a double in microseconds.
@@ -351,25 +302,7 @@ bool initializeUSB(struct ftdi_context *ftdic, const char **message, char *seria
return true;
}
-uint32_t readData(struct infnoise_context *context, uint8_t *result, bool raw, uint32_t outputMultiplier) {
- // check if data can be squeezed from the keccak sponge from previous state (or we need to collect some new entropy to get bytesGiven >0)
- if (context->bytesGiven > 0u) {
- // squeeze the sponge!
-
- // Output up to 1024 bits at a time.
- uint32_t bytesToWrite = 1024u / 8u;
-
- if (bytesToWrite > context->bytesGiven) {
- bytesToWrite = context->bytesGiven;
- }
-
- KeccakExtract(keccakState, result, bytesToWrite / 8u);
- KeccakPermutation(keccakState);
-
- context->bytesWritten += bytesToWrite;
- context->bytesGiven -= bytesToWrite;
- return bytesToWrite;
- } else { // collect new entropy
+uint32_t readData(struct infnoise_context *context, uint8_t *result, bool raw) {
uint8_t inBuf[BUFLEN];
struct timespec start;
clock_gettime(CLOCK_REALTIME, &start);
@@ -400,10 +333,9 @@ uint32_t readData(struct infnoise_context *context, uint8_t *result, bool raw, u
}
// call health check and return bytes if OK
if (inmHealthCheckOkToUseData() && inmEntropyOnTarget(context->entropyThisTime, BUFLEN)) {
- return processBytes(bytes, result, &context->entropyThisTime, &context->bytesGiven, &context->bytesWritten,
- raw, outputMultiplier);
+ return processBytes(bytes, result, &context->entropyThisTime, raw);
}
}
- }
+
return 0;
}
diff --git a/software/libinfnoise.h b/software/libinfnoise.h
index 4c0b75b..a21c9e0 100644
--- a/software/libinfnoise.h
+++ b/software/libinfnoise.h
@@ -12,7 +12,6 @@
#include <time.h>
// The FT240X has a 512 byte buffer. Must be multiple of 64
-// We also write this in one go to the Keccak sponge, which is at most 1600 bits
#define BUFLEN 512u
#ifdef __cplusplus
@@ -25,11 +24,6 @@ struct infnoise_context {
uint32_t entropyThisTime;
const char *message;
bool errorFlag;
- //uint8_t keccakState[KeccakPermutationSizeInBytes];
-
- // used in multiplier mode to keep track of bytes to be put out
- uint32_t bytesGiven;
- uint32_t bytesWritten;
};
typedef struct _infnoise_devlist_node_t infnoise_devlist_node_t;
@@ -56,11 +50,11 @@ infnoise_devlist_node_t* listUSBDevices(const char **message);
* parameters:
* - context: pointer to infnoise_context struct
* - serial: optional serial number of the device (NULL)
- * - keccak: initialize Keccak sponge (required to use readData with raw=false)
+ * - blake3: use BLAKE3 (required to use readData with raw=false)
* - debug: debug flag
* returns: boolean success indicator (0=success)
*/
-bool initInfnoise(struct infnoise_context *context, char *serial, bool keccak, bool debug);
+bool initInfnoise(struct infnoise_context *context, char *serial, bool blake3, bool debug);
/*
@@ -74,7 +68,6 @@ void deinitInfnoise(struct infnoise_context *context);
/*
* Reads some bytes from the TRNG and stores them in the "result" byte array.
* The array has to be of sufficient size. Please refer to the example programs.
- * (64 byte for normal operation or 128byte for multiplier mode)
*
* After every read operation, the infnoise_context's errorFlag must be checked,
* and the data from this call has to be discarded when it returns true!
@@ -85,11 +78,10 @@ void deinitInfnoise(struct infnoise_context *context);
* - context: infnoise_context struct with device pointer and state variables
* - result: pointer to byte array to store the result
* - raw: boolean flag for raw or whitened output
- * - outputMultiplier: only used for whitened output
*
* returns: number of bytes written to the byte-array
*/
-uint32_t readData(struct infnoise_context *context, uint8_t *result, bool raw, uint32_t outputMultiplier);
+uint32_t readData(struct infnoise_context *context, uint8_t *result, bool raw);
#ifdef __cplusplus
}
diff --git a/software/libinfnoise_private.h b/software/libinfnoise_private.h
index 6c10c34..2302439 100644
--- a/software/libinfnoise_private.h
+++ b/software/libinfnoise_private.h
@@ -70,7 +70,6 @@ uint32_t extractBytes(uint8_t *bytes, uint32_t length, uint8_t *inBuf, const cha
bool outputBytes(uint8_t *bytes, uint32_t length, uint32_t entropy, bool writeDevRandom, const char **message);
-uint32_t processBytes(uint8_t *bytes, uint8_t *result, uint32_t *entropy, uint32_t *bytesGiven, uint32_t *bytesWritten, bool raw,
- uint32_t outputMultiplier);
+uint32_t processBytes(uint8_t *bytes, uint8_t *result, uint32_t *entropy, bool raw);
#endif
Comments