#include "tweak.h" #include #include #include "my-string.h" #include static int bitcount[16]; static int rounds; static int result; #define MAX_WORST_ALLOWED 0.1f /** Tests how to get 16 bit unsigned short number from long random(void) function without losing randomness */ /* FSP classic algo */ static unsigned short classic (void) { unsigned long k; k = random(); k = k ^ (k >> 8) ^ (k >> 16) ^ (k << 8); return k; } /* get low bits from random result */ static unsigned short simple (void) { return random(); } /* get high bits from random() result. In most classic random implementations used in libc highest bits have better randomness. In modern random() generators there should be no difference. */ static unsigned short simple2 (void) { /* we assume that our return value is 16 bits long and random() returns only positive long integers */ return ( random() >> (SIZEOF_LONG*8 - 16 - 1) ); } /* The following algorithm is recommended by Numerical Recipies: */ /* Best, but needs floating point division */ static unsigned short nr(void) { unsigned short ulRandom = ((float)(0xffff)*rand()/(RAND_MAX+1.0f)); return(ulRandom); } static void run_randomtest( unsigned short (*keygen)(void) ) { int i,j; unsigned short rnd; /* zero bitcount first */ memset(bitcount, 0, sizeof(bitcount)); for(i=0;i>1; } } } static float print_bitcount(void) { int i; float worst; float ratio; printf("Set ratio: "); worst=0; for(i=0;i<16;i++) { float delta; ratio=(float)bitcount[i]/rounds; delta = fabs(ratio-0.5f); if(delta > worst) worst=delta; printf("%.2f ", ratio); } printf(" Worst: %.4f\n", worst); if(worst>MAX_WORST_ALLOWED) result++; return worst; } int main(int argc,const char *argv[]) { /* 100k rounds by default */ rounds=100000; if(argc>1) { rounds=atoi(argv[1]); } printf("Running %d rounds.\n\n", rounds); result=0; #ifdef HAVE_SRANDOMDEV srandomdev(); #endif printf("Generator: classic\n"); run_randomtest(classic); print_bitcount(); printf("Generator: simple\n"); run_randomtest(simple); print_bitcount(); printf("Generator: simple2\n"); run_randomtest(simple2); print_bitcount(); result=0; printf("Generator: Numerical Recipes\n"); run_randomtest(nr); print_bitcount(); return result; }