Added entcheck
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
all: infnoise infnoise-v1 healthcheck findlongest
|
all: infnoise infnoise-v1 healthcheck findlongest entcheck hex2bin
|
||||||
|
|
||||||
infnoise: infnoise.c infnoise.h healthcheck.c writeentropy.c Keccak/KeccakF-1600-reference.c Keccak/brg_endian.h
|
infnoise: infnoise.c infnoise.h healthcheck.c writeentropy.c Keccak/KeccakF-1600-reference.c Keccak/brg_endian.h
|
||||||
gcc -Wall -std=c99 -O3 -I Keccak -o infnoise infnoise.c healthcheck.c writeentropy.c Keccak/KeccakF-1600-reference.c -lftdi -lm -lrt
|
gcc -Wall -std=c99 -O3 -I Keccak -o infnoise infnoise.c healthcheck.c writeentropy.c Keccak/KeccakF-1600-reference.c -lftdi -lm -lrt
|
||||||
@@ -9,8 +9,14 @@ infnoise-v1: infnoise.c infnoise.h healthcheck.c writeentropy.c Keccak/KeccakF-1
|
|||||||
healthcheck: healthcheck.c
|
healthcheck: healthcheck.c
|
||||||
gcc -Wall -std=c99 -O3 -D TEST_HEALTHCHECK -o healthcheck healthcheck.c -lm -lrt
|
gcc -Wall -std=c99 -O3 -D TEST_HEALTHCHECK -o healthcheck healthcheck.c -lm -lrt
|
||||||
|
|
||||||
|
entcheck: entcheck.c
|
||||||
|
gcc -Wall -std=c99 -O3 -o entcheck entcheck.c -lm -lrt
|
||||||
|
|
||||||
findlongest: findlongest.c
|
findlongest: findlongest.c
|
||||||
gcc -Wall -std=c99 -O3 -o findlongest findlongest.c
|
gcc -Wall -std=c99 -O3 -o findlongest findlongest.c
|
||||||
|
|
||||||
|
hex2bin: hex2bin.c
|
||||||
|
gcc -Wall -std=c99 -O3 -o hex2bin hex2bin.c
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f healthcheck infnoise infnoise-v1 findlongest
|
rm -f healthcheck infnoise infnoise-v1 findlongest hex2bin
|
||||||
|
|||||||
189
software/entcheck.c
Normal file
189
software/entcheck.c
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
/*
|
||||||
|
Measure the entropy level of an input sample.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include "infnoise.h"
|
||||||
|
|
||||||
|
#define INM_MIN_DATA 80000
|
||||||
|
#define INM_MIN_SAMPLE_SIZE 100
|
||||||
|
#define INM_MAX_SEQUENCE 20
|
||||||
|
#define INM_MAX_COUNT (1 << 14)
|
||||||
|
|
||||||
|
static uint8_t inmN;
|
||||||
|
static uint32_t inmPrevBits;
|
||||||
|
static uint32_t inmNumBitsSampled;
|
||||||
|
static uint32_t *inmOnes, *inmZeros;
|
||||||
|
// The total probability of generating the string of states we did is
|
||||||
|
// 1/(2^inmNumBitsOfEntropy * inmCurrentProbability).
|
||||||
|
static uint32_t inmNumBitsOfEntropy;
|
||||||
|
static double inmCurrentProbability;
|
||||||
|
static uint64_t inmTotalBits;
|
||||||
|
static bool inmPrevBit;
|
||||||
|
static uint32_t inmTotalOnes, inmTotalZeros;
|
||||||
|
static bool inmDebug;
|
||||||
|
|
||||||
|
// Free memory used by the entropy check.
|
||||||
|
void inmEntCheckStop(void) {
|
||||||
|
if(inmOnes != NULL) {
|
||||||
|
free(inmOnes);
|
||||||
|
}
|
||||||
|
if(inmZeros != NULL) {
|
||||||
|
free(inmZeros);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the statistics.
|
||||||
|
static void resetStats(void) {
|
||||||
|
inmNumBitsSampled = 0;
|
||||||
|
inmCurrentProbability = 1.0;
|
||||||
|
inmNumBitsOfEntropy = 0;
|
||||||
|
inmTotalOnes = 0;
|
||||||
|
inmTotalZeros = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the entropy check. N is the number of bits used to predict the next bit.
|
||||||
|
// At least 8 bits must be used, and no more than 30. In general, we should use bits
|
||||||
|
// large enough so that INM output will be uncorrelated with bits N samples back in time.
|
||||||
|
bool inmEntCheckStart(uint8_t N, bool debug) {
|
||||||
|
if(N < 1 || N > 30) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inmDebug = debug;
|
||||||
|
inmNumBitsOfEntropy = 0;
|
||||||
|
inmCurrentProbability = 1.0;
|
||||||
|
inmN = N;
|
||||||
|
inmPrevBits = 0;
|
||||||
|
inmOnes = calloc(1u << N, sizeof(uint32_t));
|
||||||
|
inmZeros = calloc(1u << N, sizeof(uint32_t));
|
||||||
|
inmTotalBits = 0;
|
||||||
|
inmPrevBit = false;
|
||||||
|
resetStats();
|
||||||
|
if(inmOnes == NULL || inmZeros == NULL) {
|
||||||
|
inmEntCheckStop();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If running continuously, it is possible to start overflowing the 32-bit counters for
|
||||||
|
// zeros and ones. Check for this, and scale the stats if needed.
|
||||||
|
static void scaleStats(void) {
|
||||||
|
uint32_t i;
|
||||||
|
for(i = 0; i < (1 << inmN); i++) {
|
||||||
|
inmZeros[i] >>= 1;
|
||||||
|
inmOnes[i] >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If running continuously, it is possible to start overflowing the 32-bit counters for
|
||||||
|
// zeros and ones. Check for this, and scale the stats if needed.
|
||||||
|
static void scaleEntropy(void) {
|
||||||
|
if(inmNumBitsSampled == INM_MIN_DATA) {
|
||||||
|
inmNumBitsOfEntropy >>= 1;
|
||||||
|
inmNumBitsSampled >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If running continuously, it is possible to start overflowing the 32-bit counters for
|
||||||
|
// zeros and ones. Check for this, and scale the stats if needed.
|
||||||
|
static void scaleZeroOneCounts(void) {
|
||||||
|
uint64_t maxVal = inmTotalZeros >= inmTotalOnes? inmTotalZeros : inmTotalOnes;
|
||||||
|
if(maxVal == INM_MIN_DATA) {
|
||||||
|
inmTotalZeros >>= 1;
|
||||||
|
inmTotalOnes >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should be called for each bit generated.
|
||||||
|
bool inmEntCheckAddBit(bool bit) {
|
||||||
|
inmTotalBits++;
|
||||||
|
inmPrevBits = (inmPrevBits << 1) & ((1 << inmN)-1);
|
||||||
|
if(inmPrevBit) {
|
||||||
|
inmPrevBits |= 1;
|
||||||
|
}
|
||||||
|
inmPrevBit = bit;
|
||||||
|
if(inmNumBitsSampled > 100) {
|
||||||
|
if(bit) {
|
||||||
|
inmTotalOnes++;
|
||||||
|
} else {
|
||||||
|
inmTotalZeros++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint32_t zeros, ones;
|
||||||
|
zeros = inmZeros[inmPrevBits];
|
||||||
|
ones = inmOnes[inmPrevBits];
|
||||||
|
uint32_t total = zeros + ones;
|
||||||
|
if(bit) {
|
||||||
|
if(ones != 0) {
|
||||||
|
inmCurrentProbability *= (double)ones/total;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(zeros != 0) {
|
||||||
|
inmCurrentProbability *= (double)zeros/total;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(inmCurrentProbability <= 0.5) {
|
||||||
|
inmCurrentProbability *= 2.0;
|
||||||
|
inmNumBitsOfEntropy++;
|
||||||
|
}
|
||||||
|
//printf("probability:%f\n", inmCurrentProbability);
|
||||||
|
inmNumBitsSampled++;
|
||||||
|
if(bit) {
|
||||||
|
inmOnes[inmPrevBits]++;
|
||||||
|
if(inmOnes[inmPrevBits] == INM_MAX_COUNT) {
|
||||||
|
scaleStats();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
inmZeros[inmPrevBits]++;
|
||||||
|
if(inmZeros[inmPrevBits] == INM_MAX_COUNT) {
|
||||||
|
scaleStats();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scaleEntropy();
|
||||||
|
scaleZeroOneCounts();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Once we have enough samples, we know that entropyPerBit = log(K)/log(2), so
|
||||||
|
// K must be 2^entryopPerBit.
|
||||||
|
double inmEntCheckEstimateEntropyPerBit(void) {
|
||||||
|
return (double)inmNumBitsOfEntropy/inmNumBitsSampled;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the tables of statistics.
|
||||||
|
static void inmDumpStats(void) {
|
||||||
|
uint32_t i;
|
||||||
|
for(i = 0; i < 1 << inmN; i++) {
|
||||||
|
//if(inmOnes[i] > 0 || inmZeros[i] > 0) {
|
||||||
|
printf("%x ones:%u zeros:%u\n", i, inmOnes[i], inmZeros[i]);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
uint8_t N = 16;
|
||||||
|
inmEntCheckStart(N, false);
|
||||||
|
int value = getchar();
|
||||||
|
while(value != EOF) {
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < 8; i++) {
|
||||||
|
inmEntCheckAddBit(value & 1);
|
||||||
|
value >>= 1;
|
||||||
|
}
|
||||||
|
value = getchar();
|
||||||
|
if((inmTotalBits & 0xffff) == 0) {
|
||||||
|
printf("Added %llu bits, estimated entropy per bit:%f\n", (long long)inmTotalBits,
|
||||||
|
inmEntCheckEstimateEntropyPerBit());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(inmDebug) {
|
||||||
|
inmDumpStats();
|
||||||
|
}
|
||||||
|
inmEntCheckStop();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
35
software/hex2bin.c
Normal file
35
software/hex2bin.c
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
int isHexDigit(int c) {
|
||||||
|
return isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
|
||||||
|
}
|
||||||
|
|
||||||
|
int readChar(void) {
|
||||||
|
int c = getchar();
|
||||||
|
while(c != EOF && !isHexDigit(c)) {
|
||||||
|
c = getchar();
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getDigit(char c) {
|
||||||
|
c = tolower(c);
|
||||||
|
if(c >= 'a' && c <= 'f') {
|
||||||
|
return 10 + c - 'a';
|
||||||
|
}
|
||||||
|
return c - '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int upper = readChar();
|
||||||
|
int lower = readChar();
|
||||||
|
while(upper != EOF && lower != EOF) {
|
||||||
|
int upperDigit = getDigit(upper);
|
||||||
|
int lowerDigit = getDigit(lower);
|
||||||
|
putchar((upperDigit << 4) | lowerDigit);
|
||||||
|
upper = getchar();
|
||||||
|
lower = getchar();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user