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 | ||||
| 	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 | ||||
| 	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 | ||||
| 	gcc -Wall -std=c99 -O3 -o findlongest findlongest.c | ||||
|  | ||||
| hex2bin: hex2bin.c | ||||
| 	gcc -Wall -std=c99 -O3 -o hex2bin hex2bin.c | ||||
|  | ||||
| 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