Got the first breadboard working
This commit is contained in:
@@ -31,7 +31,7 @@ confirmed.
|
||||
#define INM_MIN_DATA 10000
|
||||
#define INM_MIN_SAMPLE_SIZE 100
|
||||
#define INM_ACCURACY 1.05
|
||||
#define INM_MAX_SEQUENCE 5
|
||||
#define INM_MAX_SEQUENCE 20
|
||||
#define INM_MAX_COUNT (1 << 14)
|
||||
// Matches the Keccac sponge size
|
||||
#define INM_MAX_ENTROPY 1600
|
||||
@@ -48,6 +48,7 @@ static double inmCurrentProbability;
|
||||
static uint64_t inmTotalBits;
|
||||
static bool inmPrevBit;
|
||||
static uint32_t inmEntropyLevel;
|
||||
static uint32_t inmNumSequentialZeros, inmNumSequentialOnes;
|
||||
|
||||
// Free memory used by the health check.
|
||||
void inmHealthCheckStop(void) {
|
||||
@@ -85,6 +86,8 @@ bool inmHealthCheckStart(uint8_t N, double K) {
|
||||
inmExpectedEntropyPerBit = log(K)/log(2.0);
|
||||
inmTotalBits = 0;
|
||||
inmPrevBit = false;
|
||||
inmNumSequentialZeros = 0;
|
||||
inmNumSequentialOnes = 0;
|
||||
resetStats();
|
||||
if(inmOnes == NULL || inmZeros == NULL) {
|
||||
inmHealthCheckStop();
|
||||
@@ -112,6 +115,32 @@ static void scaleStats(void) {
|
||||
// This should be called for each bit generated.
|
||||
bool inmHealthCheckAddBit(bool bit) {
|
||||
inmTotalBits++;
|
||||
if((inmTotalBits & 0xfff) == 0) {
|
||||
printf("Estimated entropy per bit: %f, estimated K: %f\n", inmHealthCheckEstimateEntropyPerBit(),
|
||||
inmHealthCheckEstimateK());
|
||||
}
|
||||
inmPrevBits = (inmPrevBits << 1) & ((1 << inmN)-1);
|
||||
if(inmPrevBit) {
|
||||
inmPrevBits |= 1;
|
||||
}
|
||||
inmPrevBit = bit;
|
||||
if(inmNumBitsSampled > 100) {
|
||||
if(bit) {
|
||||
inmNumSequentialOnes++;
|
||||
inmNumSequentialZeros = 0;
|
||||
if(inmNumSequentialOnes > INM_MAX_SEQUENCE) {
|
||||
printf("Maximum sequence of %d 1's exceeded\n", INM_MAX_SEQUENCE);
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
inmNumSequentialZeros++;
|
||||
inmNumSequentialOnes = 0;
|
||||
if(inmNumSequentialZeros > INM_MAX_SEQUENCE) {
|
||||
printf("Maximum sequence of %d 0's exceeded\n", INM_MAX_SEQUENCE);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(inmOnes[inmPrevBits] > INM_MIN_SAMPLE_SIZE ||
|
||||
inmZeros[inmPrevBits] > INM_MIN_SAMPLE_SIZE) {
|
||||
uint32_t total = inmZeros[inmPrevBits] + inmOnes[inmPrevBits];
|
||||
@@ -146,12 +175,6 @@ bool inmHealthCheckAddBit(bool bit) {
|
||||
scaleStats();
|
||||
}
|
||||
}
|
||||
// Check for max sequence of 0's or 1's.
|
||||
uint32_t lowBits = inmPrevBits & ((1 << (INM_MAX_SEQUENCE+1))-1);
|
||||
if(lowBits == 0 || lowBits == ((1 << (INM_MAX_SEQUENCE+1))-1)) {
|
||||
printf("Maximum sequence of %d 0's or 1's exceeded\n", INM_MAX_SEQUENCE);
|
||||
return false;
|
||||
}
|
||||
//printf("prevBits: %x\n", inmPrevBits);
|
||||
if(inmNumBitsSampled < INM_MIN_DATA) {
|
||||
return true; // Not enough data yet to test
|
||||
@@ -177,9 +200,6 @@ bool inmHealthCheckAddBit(bool bit) {
|
||||
// Once we have enough samples, we know that entropyPerBit = log(K)/log(2), so
|
||||
// K must be 2^entryopPerBit.
|
||||
double inmHealthCheckEstimateK(void) {
|
||||
if(inmNumBitsOfEntropy < INM_MIN_DATA) {
|
||||
return inmK;
|
||||
}
|
||||
double entropyPerBit = (double)inmNumBitsOfEntropy/inmNumBitsCounted;
|
||||
return pow(2.0, entropyPerBit);
|
||||
}
|
||||
@@ -187,9 +207,6 @@ double inmHealthCheckEstimateK(void) {
|
||||
// Once we have enough samples, we know that entropyPerBit = log(K)/log(2), so
|
||||
// K must be 2^entryopPerBit.
|
||||
double inmHealthCheckEstimateEntropyPerBit(void) {
|
||||
if(inmNumBitsSampled < INM_MIN_DATA) {
|
||||
return inmExpectedEntropyPerBit;
|
||||
}
|
||||
return (double)inmNumBitsOfEntropy/inmNumBitsCounted;
|
||||
}
|
||||
|
||||
@@ -277,13 +294,8 @@ static inline bool updateA(double *A, double K, double noise) {
|
||||
}
|
||||
|
||||
static inline bool computeRandBit(double *A, double K, double noiseAmplitude) {
|
||||
inmPrevBits = (inmPrevBits << 1) & ((1 << inmN)-1);
|
||||
if(inmPrevBit) {
|
||||
inmPrevBits |= 1;
|
||||
}
|
||||
double noise = noiseAmplitude*(((double)rand()/RAND_MAX) - 0.5);
|
||||
inmPrevBit = updateA(A, K, noise);
|
||||
return inmPrevBit;
|
||||
return updateA(A, K, noise);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
@@ -27,26 +27,23 @@ static void extractBytes(uint8_t *bytes, uint8_t *inBuf, bool raw) {
|
||||
uint32_t j;
|
||||
uint8_t byte = 0;
|
||||
for(j = 0; j < 8; j++) {
|
||||
byte <<= 1;
|
||||
uint8_t bit = 0;
|
||||
//printf("%x ", inBuf[i*8 + j] & ~MASK);
|
||||
uint8_t val = inBuf[i*8 + j];
|
||||
uint8_t bit;
|
||||
if(j & 1) {
|
||||
// SWEN2 is enabled on odd cycles. We should read COMP1 since it's stable
|
||||
if(bytes[i*8 + j] & (1 << COMP1)) {
|
||||
bit = 1;
|
||||
}
|
||||
bit = (val >> COMP1) & 1;
|
||||
} else {
|
||||
// SWEN1 is enabled on even cycles. We should read COMP2 since it's stable
|
||||
if(bytes[i*8 + j] & (1 << COMP1)) {
|
||||
bit = 1;
|
||||
}
|
||||
bit = (val >> COMP2) & 1;
|
||||
}
|
||||
byte |= bit;
|
||||
byte = (byte << 1) | bit;
|
||||
// This is a good place to feed the bit from the INM to the health checker.
|
||||
//printf("Adding bit %u\n", bit);
|
||||
if(!raw && !inmHealthCheckAddBit(bit)) {
|
||||
fprintf(stderr, "Health check of Infinite Noise Multiplier failed!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
//printf("extracted byte:%x\n", byte);
|
||||
bytes[i] = byte;
|
||||
}
|
||||
}
|
||||
@@ -58,10 +55,12 @@ static void processBytes(uint8_t *keccakState, uint8_t *bytes, bool raw) {
|
||||
if(raw) {
|
||||
// In raw mode, we disable the health check and whitening, and just output raw
|
||||
// data from the INM.
|
||||
/*
|
||||
if(fwrite(bytes, 1, BUFLEN/8, stdout) != BUFLEN/8) {
|
||||
fprintf(stderr, "Unable to write output from Infinite Noise Multiplier\n");
|
||||
exit(1);
|
||||
}
|
||||
*/
|
||||
return;
|
||||
}
|
||||
uint32_t i;
|
||||
@@ -73,10 +72,12 @@ static void processBytes(uint8_t *keccakState, uint8_t *bytes, bool raw) {
|
||||
// Also, we output data at 1/2 the rate of entropy added to the sponge
|
||||
uint8_t dataOut[8];
|
||||
KeccakExtract(keccakState, dataOut, 1);
|
||||
/*
|
||||
if(fwrite(dataOut, 1, 8, stdout) != 8) {
|
||||
fprintf(stderr, "Unable to write output from Infinite Noise Multiplier\n");
|
||||
exit(1);
|
||||
}
|
||||
*/
|
||||
inmHealthCheckReduceEntropyLevel(16);
|
||||
}
|
||||
}
|
||||
@@ -98,7 +99,7 @@ int main(int argc, char **argv)
|
||||
|
||||
// Initialize FTDI context
|
||||
ftdi_init(&ftdic);
|
||||
if(!inmHealthCheckStart(7, 1.82)) {
|
||||
if(!inmHealthCheckStart(9, 1.82)) {
|
||||
puts("Can't intialize health checker\n");
|
||||
return 1;
|
||||
}
|
||||
@@ -112,7 +113,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
// Set high baud rate
|
||||
int rc = ftdi_set_baudrate(&ftdic, 3000000);
|
||||
int rc = 0;
|
||||
//rc = ftdi_set_baudrate(&ftdic, 3000000);
|
||||
if(rc == -1) {
|
||||
puts("Invalid baud rate\n");
|
||||
return -1;
|
||||
@@ -134,15 +136,27 @@ int main(int argc, char **argv)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Endless loop: invert LED state, write output, pause 1 second */
|
||||
// Endless loop: set SW1EN and SW2EN alternately
|
||||
uint32_t i;
|
||||
uint8_t outBuf[BUFLEN], inBuf[BUFLEN];
|
||||
for(i = 0; i < BUFLEN; i++) {
|
||||
// Alternate Ph1 and Ph2 - maybe should have both off in between
|
||||
outBuf[i] = i & 1? (1 << SWEN2) : (1 << SWEN1);
|
||||
//outBuf[i] = i;
|
||||
}
|
||||
//outBuf[BUFLEN-1] = 0;
|
||||
|
||||
while(true) {
|
||||
for(i = 0; i < BUFLEN; i++) {
|
||||
if(ftdi_write_data(&ftdic, outBuf + i, 1) != 1) {
|
||||
puts("USB write failed\n");
|
||||
return -1;
|
||||
}
|
||||
if(ftdi_read_data(&ftdic, inBuf + i, 1) != 1) {
|
||||
puts("USB read failed\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/*
|
||||
if(ftdi_write_data(&ftdic, outBuf, BUFLEN) != BUFLEN) {
|
||||
puts("USB write failed\n");
|
||||
return -1;
|
||||
@@ -151,9 +165,10 @@ int main(int argc, char **argv)
|
||||
puts("USB read failed\n");
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
uint8_t bytes[BUFLEN/8];
|
||||
extractBytes(bytes, inBuf, raw);
|
||||
processBytes(keccakState, bytes, raw);
|
||||
//processBytes(keccakState, bytes, raw);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user