working on driver

This commit is contained in:
Bill Cox
2014-10-17 15:35:29 -04:00
parent d4b8fdae6f
commit b0f15bc5f7
8 changed files with 452 additions and 77 deletions

View File

@@ -376,7 +376,7 @@ key, the more likely it is insecure. Therefore, the initial Infinite Noise Mult
does not even have a microcontroller onboard, and only returns raw data, direct from the
noise source. Whitening is done in the INM driver.
The INM driver uses the reference versoin of the SHA3 "sponge" with a 1600 bit state. The
The INM driver uses the reference version of the SHA3 "sponge" with a 1600 bit state. The
state of the sponge needs to be made unpredictable. It is initialized with 3200 bits of
entropy before any data is output. After that, reading bytes from the SHA3 sponge blocks
until twice as many bytes of entropy have been fed into the sponge from the INM. Data is

View File

@@ -0,0 +1,26 @@
/*
The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
Michaël Peeters and Gilles Van Assche. For more information, feedback or
questions, please refer to our website: http://keccak.noekeon.org/
Implementation by the designers,
hereby denoted as "the implementer".
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 _KeccakPermutationInterface_h_
#define _KeccakPermutationInterface_h_
#define KeccakPermutationSize 1600
#define KeccakPermutationSizeInBytes (KeccakPermutationSize/8)
void KeccakInitializeState(unsigned char *state);
void KeccakPermutation(unsigned char *state);
void KeccakAbsorb(unsigned char *state, const unsigned char *data, unsigned int laneCount);
void KeccakExtract(const unsigned char *state, unsigned char *data, unsigned int laneCount);
#endif

View File

@@ -0,0 +1,209 @@
/*
The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
Michaël Peeters and Gilles Van Assche. For more information, feedback or
questions, please refer to our website: http://keccak.noekeon.org/
Implementation by the designers,
hereby denoted as "the implementer".
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 <stdio.h>
#include <string.h>
#include "brg_endian.h"
#include "KeccakF-1600-interface.h"
typedef unsigned char UINT8;
typedef unsigned long long int UINT64;
#define nrRounds 24
UINT64 KeccakRoundConstants[nrRounds];
#define nrLanes 25
unsigned int KeccakRhoOffsets[nrLanes];
void KeccakPermutationOnWords(UINT64 *state);
void theta(UINT64 *A);
void rho(UINT64 *A);
void pi(UINT64 *A);
void chi(UINT64 *A);
void iota(UINT64 *A, unsigned int indexRound);
void fromBytesToWords(UINT64 *stateAsWords, const unsigned char *state)
{
unsigned int i, j;
for(i=0; i<(KeccakPermutationSize/64); i++) {
stateAsWords[i] = 0;
for(j=0; j<(64/8); j++)
stateAsWords[i] |= (UINT64)(state[i*(64/8)+j]) << (8*j);
}
}
void fromWordsToBytes(unsigned char *state, const UINT64 *stateAsWords)
{
unsigned int i, j;
for(i=0; i<(KeccakPermutationSize/64); i++)
for(j=0; j<(64/8); j++)
state[i*(64/8)+j] = (stateAsWords[i] >> (8*j)) & 0xFF;
}
void KeccakPermutation(unsigned char *state)
{
#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN)
UINT64 stateAsWords[KeccakPermutationSize/64];
#endif
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
KeccakPermutationOnWords((UINT64*)state);
#else
fromBytesToWords(stateAsWords, state);
KeccakPermutationOnWords(stateAsWords);
fromWordsToBytes(state, stateAsWords);
#endif
}
void KeccakPermutationAfterXor(unsigned char *state, const unsigned char *data, unsigned int dataLengthInBytes)
{
unsigned int i;
for(i=0; i<dataLengthInBytes; i++)
state[i] ^= data[i];
KeccakPermutation(state);
}
void KeccakPermutationOnWords(UINT64 *state)
{
unsigned int i;
for(i=0; i<nrRounds; i++) {
theta(state);
rho(state);
pi(state);
chi(state);
iota(state, i);
}
}
#define index(x, y) (((x)%5)+5*((y)%5))
#define ROL64(a, offset) ((offset != 0) ? ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64-offset))) : a)
void theta(UINT64 *A)
{
unsigned int x, y;
UINT64 C[5], D[5];
for(x=0; x<5; x++) {
C[x] = 0;
for(y=0; y<5; y++)
C[x] ^= A[index(x, y)];
}
for(x=0; x<5; x++)
D[x] = ROL64(C[(x+1)%5], 1) ^ C[(x+4)%5];
for(x=0; x<5; x++)
for(y=0; y<5; y++)
A[index(x, y)] ^= D[x];
}
void rho(UINT64 *A)
{
unsigned int x, y;
for(x=0; x<5; x++) for(y=0; y<5; y++)
A[index(x, y)] = ROL64(A[index(x, y)], KeccakRhoOffsets[index(x, y)]);
}
void pi(UINT64 *A)
{
unsigned int x, y;
UINT64 tempA[25];
for(x=0; x<5; x++) for(y=0; y<5; y++)
tempA[index(x, y)] = A[index(x, y)];
for(x=0; x<5; x++) for(y=0; y<5; y++)
A[index(0*x+1*y, 2*x+3*y)] = tempA[index(x, y)];
}
void chi(UINT64 *A)
{
unsigned int x, y;
UINT64 C[5];
for(y=0; y<5; y++) {
for(x=0; x<5; x++)
C[x] = A[index(x, y)] ^ ((~A[index(x+1, y)]) & A[index(x+2, y)]);
for(x=0; x<5; x++)
A[index(x, y)] = C[x];
}
}
void iota(UINT64 *A, unsigned int indexRound)
{
A[index(0, 0)] ^= KeccakRoundConstants[indexRound];
}
int LFSR86540(UINT8 *LFSR)
{
int result = ((*LFSR) & 0x01) != 0;
if (((*LFSR) & 0x80) != 0)
// Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1
(*LFSR) = ((*LFSR) << 1) ^ 0x71;
else
(*LFSR) <<= 1;
return result;
}
void KeccakInitializeRoundConstants()
{
UINT8 LFSRstate = 0x01;
unsigned int i, j, bitPosition;
for(i=0; i<nrRounds; i++) {
KeccakRoundConstants[i] = 0;
for(j=0; j<7; j++) {
bitPosition = (1<<j)-1; //2^j-1
if (LFSR86540(&LFSRstate))
KeccakRoundConstants[i] ^= (UINT64)1<<bitPosition;
}
}
}
void KeccakInitializeRhoOffsets()
{
unsigned int x, y, t, newX, newY;
KeccakRhoOffsets[index(0, 0)] = 0;
x = 1;
y = 0;
for(t=0; t<24; t++) {
KeccakRhoOffsets[index(x, y)] = ((t+1)*(t+2)/2) % 64;
newX = (0*x+1*y) % 5;
newY = (2*x+3*y) % 5;
x = newX;
y = newY;
}
}
void KeccakInitialize()
{
KeccakInitializeRoundConstants();
KeccakInitializeRhoOffsets();
}
void KeccakInitializeState(unsigned char *state)
{
memset(state, 0, KeccakPermutationSizeInBytes);
}
void KeccakAbsorb(unsigned char *state, const unsigned char *data, unsigned int laneCount)
{
KeccakPermutationAfterXor(state, data, laneCount*8);
}
void KeccakExtract(const unsigned char *state, unsigned char *data, unsigned int laneCount)
{
memcpy(data, state, laneCount*8);
}

View File

@@ -1,10 +1,10 @@
all: hello-ftdi healthcheck
all: infnoise healthcheck
hello-ftdi: hello-ftdi.c
gcc -Wall -std=c11 -O3 -m64 -march=native -o hello-ftdi hello-ftdi.c -lftdi
infnoise: infnoise.c healthcheck.c KeccakF-1600-reference.c brg_endian.h
gcc -Wall -std=c11 -O3 -m64 -march=native -o infnoise infnoise.c healthcheck.c KeccakF-1600-reference.c -lftdi -lm
healthcheck: healthcheck.c
gcc -Wall -std=c11 -g -m64 -march=native -o healthcheck healthcheck.c -lm
gcc -Wall -std=c11 -g -m64 -march=native -D TEST_HEALTHCHECK -o healthcheck healthcheck.c -lm
clean:
rm -f healthcheck hello-ftdi
rm -f healthcheck infnoise

142
software/brg_endian.h Normal file
View File

@@ -0,0 +1,142 @@
/*
---------------------------------------------------------------------------
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
LICENSE TERMS
The redistribution and use of this software (with or without changes)
is allowed without the payment of fees or royalties provided that:
1. source code distributions include the above copyright notice, this
list of conditions and the following disclaimer;
2. binary distributions include the above copyright notice, this list
of conditions and the following disclaimer in their documentation;
3. the name of the copyright holder is not used to endorse products
built using this software without specific written permission.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue Date: 20/12/2007
Changes for ARM 9/9/2010
*/
#ifndef _BRG_ENDIAN_H
#define _BRG_ENDIAN_H
#define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
#define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
#if 0
/* Include files where endian defines and byteswap functions may reside */
#if defined( __sun )
# include <sys/isa_defs.h>
#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ )
# include <sys/endian.h>
#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \
defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ )
# include <machine/endian.h>
#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )
# if !defined( __MINGW32__ ) && !defined( _AIX )
# include <endian.h>
# if !defined( __BEOS__ )
# include <byteswap.h>
# endif
# endif
#endif
#endif
/* Now attempt to set the define for platform byte order using any */
/* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which */
/* seem to encompass most endian symbol definitions */
#if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN )
# if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
# elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
# endif
#elif defined( BIG_ENDIAN )
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
#elif defined( LITTLE_ENDIAN )
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
#endif
#if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN )
# if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
# elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
# endif
#elif defined( _BIG_ENDIAN )
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
#elif defined( _LITTLE_ENDIAN )
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
#endif
#if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN )
# if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
# elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
# endif
#elif defined( __BIG_ENDIAN )
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
#elif defined( __LITTLE_ENDIAN )
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
#endif
#if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ )
# if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
# elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
# endif
#elif defined( __BIG_ENDIAN__ )
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
#elif defined( __LITTLE_ENDIAN__ )
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
#endif
/* if the platform byte order could not be determined, then try to */
/* set this define using common machine defines */
#if !defined(PLATFORM_BYTE_ORDER)
#if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \
defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \
defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \
defined( vax ) || defined( vms ) || defined( VMS ) || \
defined( __VMS ) || defined( _M_X64 )
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
#elif defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \
defined( _CRAY ) || defined( __hppa ) || defined( __hp9000 ) || \
defined( ibm370 ) || defined( mc68000 ) || defined( m68k ) || \
defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \
defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \
defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM ) || \
defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX )
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
#elif defined(__arm__)
# ifdef __BIG_ENDIAN
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
# else
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
# endif
#elif 1 /* **** EDIT HERE IF NECESSARY **** */
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
#elif 0 /* **** EDIT HERE IF NECESSARY **** */
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
#else
# error Please edit lines 132 or 134 in brg_endian.h to set the platform byte order
#endif
#endif
#endif

View File

@@ -26,6 +26,7 @@ confirmed.
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "healthcheck.h"
#define INM_MIN_SAMPLE_SIZE 100
#define INM_ACCURACY 1.05
@@ -44,18 +45,8 @@ static double inmCurrentProbability;
static uint64_t inmTotalBits;
static bool inmPrevBit;
// 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]);
//}
}
}
// Free memory used by the health checker.
void inmHealthCheckerStop(void) {
// Free memory used by the health check.
void inmHealthCheckStop(void) {
if(inmOnes != NULL) {
free(inmOnes);
}
@@ -64,10 +55,18 @@ void inmHealthCheckerStop(void) {
}
}
// Initialize the health checker. N is the number of bits used to predict the next bit.
// Reset the statistics.
static void resetStats(void) {
inmNumBitsSampled = 0;
inmNumBitsCounted = 0;
inmCurrentProbability = 1.0;
inmNumBitsOfEntropy = 0;
}
// Initialize the health 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 inmHealthCheckerStart(uint8_t N, double K) {
bool inmHealthCheckStart(uint8_t N, double K) {
if(N < 1 || N > 30) {
return false;
}
@@ -76,31 +75,37 @@ bool inmHealthCheckerStart(uint8_t N, double K) {
inmK = K;
inmN = N;
inmPrevBits = 0;
inmNumBitsCounted = 0;
inmNumBitsSampled = 0;
inmOnes = calloc(1u << N, sizeof(uint32_t));
inmZeros = calloc(1u << N, sizeof(uint32_t));
inmExpectedEntropyPerBit = log(K)/log(2.0);
inmTotalBits = 0;
inmPrevBit = false;
resetStats();
if(inmOnes == NULL || inmZeros == NULL) {
inmHealthCheckerStop();
inmHealthCheckStop();
return false;
}
return true;
}
// Reset the statistics.
static void resetStats(void) {
printf("Resetting with numSampled=%u and numCounted=%u\n", inmNumBitsSampled, inmNumBitsCounted);
inmNumBitsSampled = 0;
inmNumBitsCounted = 0;
inmCurrentProbability = 1.0;
inmNumBitsOfEntropy = 0;
// 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;
printf("Scaling stats...\n");
for(i = 0; i < (1 << inmN); i++) {
inmZeros[i] >>= 1;
inmOnes[i] >>= 1;
}
if(inmNumBitsSampled > 20000) {
inmNumBitsCounted = inmNumBitsCounted*(uint64_t)20000/inmNumBitsSampled;
inmNumBitsOfEntropy = inmNumBitsOfEntropy*(uint64_t)20000/inmNumBitsSampled;
inmNumBitsSampled = 20000;
}
}
// This should be called for each bit generated.
bool inmHealthCheckerAddBit(bool bit) {
bool inmHealthCheckAddBit(bool bit) {
inmTotalBits++;
if(inmOnes[inmPrevBits] > INM_MIN_SAMPLE_SIZE ||
inmZeros[inmPrevBits] > INM_MIN_SAMPLE_SIZE) {
@@ -124,8 +129,14 @@ bool inmHealthCheckerAddBit(bool bit) {
inmNumBitsSampled++;
if(bit) {
inmOnes[inmPrevBits]++;
if(inmOnes[inmPrevBits] == INM_MAX_COUNT) {
scaleStats();
}
} else {
inmZeros[inmPrevBits]++;
if(inmZeros[inmPrevBits] == INM_MAX_COUNT) {
scaleStats();
}
}
// Check for max sequence of 0's or 1's.
uint32_t lowBits = inmPrevBits & ((1 << (INM_MAX_SEQUENCE+1))-1);
@@ -143,7 +154,7 @@ bool inmHealthCheckerAddBit(bool bit) {
return true;
}
if(inmNumBitsSampled == 10000) {
printf("Generated a total of %lu bits to initialize health checker\n", inmTotalBits);
printf("Generated a total of %lu bits to initialize health check\n", inmTotalBits);
}
// Check the entropy is in line with expectations
uint32_t expectedEntropy = inmExpectedEntropyPerBit*inmNumBitsCounted;
@@ -157,7 +168,7 @@ bool inmHealthCheckerAddBit(bool bit) {
// Once we have enough samples, we know that entropyPerBit = log(K)/log(2), so
// K must be 2^entryopPerBit.
double inmHealthCheckerEstimateK(void) {
double inmHealthCheckEstimateK(void) {
if(inmNumBitsOfEntropy <= 10000) {
return inmK;
}
@@ -167,13 +178,26 @@ double inmHealthCheckerEstimateK(void) {
// Once we have enough samples, we know that entropyPerBit = log(K)/log(2), so
// K must be 2^entryopPerBit.
double inmHealthCheckerEstimateEntropyPerBit(void) {
double inmHealthCheckEstimateEntropyPerBit(void) {
if(inmNumBitsOfEntropy <= 10000) {
return inmExpectedEntropyPerBit;
}
return (double)inmNumBitsOfEntropy/inmNumBitsCounted;
}
#ifdef TEST_HEALTHCHECK
// 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]);
//}
}
}
// Compare the ability to predict with 1 fewer bits and see how much less accurate we are.
static void checkLSBStatsForNBits(uint8_t N) {
uint32_t i, j;
@@ -207,37 +231,6 @@ static void checkLSBStats(void) {
}
}
// 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 reduceStatsIfNeeded(void) {
uint32_t i;
uint32_t maxValue = 0;
for(i = 0; i < (1 << inmN); i++) {
uint32_t zeros = inmZeros[i];
uint32_t ones = inmOnes[i];
if(zeros >= maxValue) {
maxValue = zeros;
}
if(ones > maxValue) {
maxValue = ones;
}
}
if(maxValue > INM_MAX_COUNT) {
printf("Scaling stats...\n");
for(i = 0; i < (1 << inmN); i++) {
inmZeros[i] = inmZeros[i]*INM_MAX_COUNT/maxValue;
inmOnes[i] = inmOnes[i]*INM_MAX_COUNT/maxValue;
}
}
/*
if(numBitsSampled > 20000) {
inmNumBitsCounted = inmNumBitsCounted*20000/inmNumBitsSampled;
inmNumBitsOfEntropy = inmNumBitsOfEntropy*20000/inmNumBitsSampled;
inmNumBitsSampled = 20000;
}
*/
}
/* This could be built with one opamp for the multiplier, a comparator with
rail-to-rail outputs, and switches and caps and resistors.*/
static inline bool updateA(double *A, double K, double noise) {
@@ -270,7 +263,7 @@ int main() {
//double K = sqrt(2.0);
double K = 1.82;
uint8_t N = 7;
inmHealthCheckerStart(N, K);
inmHealthCheckStart(N, K);
srand(time(NULL));
double A = (double)rand()/RAND_MAX; // Simulating INM
double noiseAmplitude = 1.0/(1 << 10);
@@ -281,19 +274,18 @@ int main() {
}
for(i = 0; i < 1 << 24; i++) {
bool bit = computeRandBit(&A, K, noiseAmplitude);
if(!inmHealthCheckerAddBit(bit)) {
if(!inmHealthCheckAddBit(bit)) {
printf("Failed health check!\n");
resetStats();
return 1;
} else if(inmNumBitsCounted > 0 && (inmNumBitsCounted & 0xfffff) == 0) {
printf("Estimated entropy per bit: %f, estimated K: %f\n", inmHealthCheckerEstimateEntropyPerBit(),
inmHealthCheckerEstimateK());
}
if(inmTotalBits > 0 && (inmTotalBits & 0xfffff) == 0) {
printf("Estimated entropy per bit: %f, estimated K: %f\n", inmHealthCheckEstimateEntropyPerBit(),
inmHealthCheckEstimateK());
checkLSBStats();
reduceStatsIfNeeded();
//resetStats();
}
}
inmDumpStats();
inmHealthCheckerStop();
inmHealthCheckStop();
return 0;
}
#endif

5
software/healthcheck.h Normal file
View File

@@ -0,0 +1,5 @@
bool inmHealthCheckStart(uint8_t N, double K);
void inmHealthCheckStop(void);
bool inmHealthCheckAddBit(bool bit);
double inmHealthCheckEstimateK(void);
double inmHealthCheckEstimateEntropyPerBit(void);

View File

@@ -6,6 +6,7 @@
#include <stdbool.h>
#include <stdio.h>
#include <ftdi.h>
#include "healthcheck.h"
#define BUFLEN 64
//#define BUFLEN 1
@@ -26,7 +27,7 @@ int main()
/* Open FTDI device based on FT232R vendor & product IDs */
if(ftdi_usb_open(&ftdic, 0x0403, 0x6015) < 0) {
puts("Can't open device");
puts("Can't find Infinite Noise Multiplier");
return 1;
}
@@ -39,7 +40,7 @@ int main()
puts("Setting baud rate failed\n");
return -1;
} else if(rc == -3) {
puts("USB device unavailable\n");
puts("Infinite Noise Multiplier unavailable\n");
return -1;
}
@@ -50,7 +51,7 @@ int main()
puts("Can't enable bit-bang mode\n");
return -1;
} else if(rc == -2) {
puts("USB device unavailable\n");
puts("Infinite Noise Multiplier unavailable\n");
return -1;
}