// Tests randomness of the BaseCryptoRandomStream and returns the random value bool RunsTest::IsRandom(BaseCryptoRandomStream* bitStream) { unsigned long int i; unsigned short int *r; double product, sum; if (bitStream->GetBitLength() < this->GetMinimumLength()) { this->error = InsufficientNumberOfBits; this->random = false; return this->random; } bitStream->SetBitPosition(0); this->error = NoError; if ((r = (unsigned short int *) calloc(bitStream->GetBitLength(),sizeof(unsigned short int))) == NULL) { this->error = InsufficientMemory; this->random = false; } else { sum = 0.0; for(i = 0; i < bitStream->GetBitLength(); i++) sum += (int)bitStream->GetBitForward(); this->pi = sum/bitStream->GetBitLength(); for(i = 0; i < bitStream->GetBitLength()-1; i++) { if ((int)bitStream->GetBitPosition(i) == (int)bitStream->GetBitPosition(i+1)) r[i] = 0; else r[i] = 1; } this->totalNumberRuns = 0; for(i = 0; i < bitStream->GetBitLength()-1; i++) this->totalNumberRuns += r[i]; this->totalNumberRuns++; product = this->pi * (1.e0 - this->pi); this->argument = fabs(this->totalNumberRuns - 2.e0*bitStream->GetBitLength()*product)/(2.e0*sqrt(2.e0*bitStream->GetBitLength())*product); this->pValue = this->mathFuncs->ErFc(this->argument); if (this->pValue < this->alpha) { this->random = false; } else { this->random = true; } free(r); if (isNegative(this->pValue) || isGreaterThanOne(this->pValue)) { this->random = false; this->error = PValueOutOfRange; } } return this->random; }
// Tests randomness of the BaseCryptoRandomStream and returns the random value bool CumulativeSumReverseTest::IsRandom(BaseCryptoRandomStream* bitStream) { signed long int i, k, start, finish; double z, sum, sum1, sum2; if (bitStream->GetBitLength() < this->GetMinimumLength()) { this->error = InsufficientNumberOfBits; this->random = false; return this->random; } bitStream->SetBitPosition(bitStream->GetBitLength() -1); this->error = NoError; sum = 0.0; this->cuSum = 1; for(i = bitStream->GetBitLength() -1; i >= 0; i--) { sum += 2*(int)bitStream->GetBitReverse() - 1; this->cuSum = MAX(this->cuSum, fabs(sum)); } z = this->cuSum; sum1 = 0.0; start = (-(long)bitStream->GetBitLength()/(int)z+1)/4; finish = (bitStream->GetBitLength()/(int)z-1)/4; for(k = start; k <= finish; k++) sum1 += (this->mathFuncs->Normal((4*k+1)*z/sqrt((double)bitStream->GetBitLength()))-this->mathFuncs->Normal((4*k-1)*z/sqrt((double)bitStream->GetBitLength()))); sum2 = 0.0; start = (-(long)bitStream->GetBitLength()/(int)z-3)/4; finish = (bitStream->GetBitLength()/(int)z-1)/4; for(k = start; k <= finish; k++) sum2 += (this->mathFuncs->Normal((4*k+3)*z/sqrt((double)bitStream->GetBitLength()))-this->mathFuncs->Normal((4*k+1)*z/sqrt((double)bitStream->GetBitLength()))); this->pValue = 1.0 - sum1 + sum2; if (isNegative(this->pValue) || isGreaterThanOne(this->pValue)) { this->error = PValueOutOfRange; this->random = false; } else { if (this->pValue < this->alpha) { this->random = false; } else { this->random = true; } } return this->random; }
void LongestRunOfOnes(int n) { double pval, chi2, pi[7]; int run, v_n_obs, N, i, j, K, M, V[7]; unsigned int nu[7] = { 0, 0, 0, 0, 0, 0, 0 }; if ( n < 128 ) { fprintf(stats[TEST_LONGEST_RUN], "\t\t\t LONGEST RUNS OF ONES TEST\n"); fprintf(stats[TEST_LONGEST_RUN], "\t\t---------------------------------------------\n"); fprintf(stats[TEST_LONGEST_RUN], "\t\t n=%d is too short\n", n); return; } if ( n < 6272 ) { K = 3; M = 8; V[0] = 1; V[1] = 2; V[2] = 3; V[3] = 4; pi[0] = 0.21484375; pi[1] = 0.3671875; pi[2] = 0.23046875; pi[3] = 0.1875; } else if ( n < 750000 ) { K = 5; M = 128; V[0] = 4; V[1] = 5; V[2] = 6; V[3] = 7; V[4] = 8; V[5] = 9; pi[0] = 0.1174035788; pi[1] = 0.242955959; pi[2] = 0.249363483; pi[3] = 0.17517706; pi[4] = 0.102701071; pi[5] = 0.112398847; } else { K = 6; M = 10000; V[0] = 10; V[1] = 11; V[2] = 12; V[3] = 13; V[4] = 14; V[5] = 15; V[6] = 16; pi[0] = 0.0882; pi[1] = 0.2092; pi[2] = 0.2483; pi[3] = 0.1933; pi[4] = 0.1208; pi[5] = 0.0675; pi[6] = 0.0727; } N = n/M; for ( i=0; i<N; i++ ) { v_n_obs = 0; run = 0; for ( j=0; j<M; j++ ) { if ( epsilon[i*M+j] == 1 ) { run++; if ( run > v_n_obs ) v_n_obs = run; } else run = 0; } if ( v_n_obs < V[0] ) nu[0]++; for ( j=0; j<=K; j++ ) { if ( v_n_obs == V[j] ) nu[j]++; } if ( v_n_obs > V[K] ) nu[K]++; } chi2 = 0.0; for ( i=0; i<=K; i++ ) chi2 += ((nu[i] - N * pi[i]) * (nu[i] - N * pi[i])) / (N * pi[i]); pval = cephes_igamc((double)(K/2.0), chi2 / 2.0); fprintf(stats[TEST_LONGEST_RUN], "\t\t\t LONGEST RUNS OF ONES TEST\n"); fprintf(stats[TEST_LONGEST_RUN], "\t\t---------------------------------------------\n"); fprintf(stats[TEST_LONGEST_RUN], "\t\tCOMPUTATIONAL INFORMATION:\n"); fprintf(stats[TEST_LONGEST_RUN], "\t\t---------------------------------------------\n"); fprintf(stats[TEST_LONGEST_RUN], "\t\t(a) N (# of substrings) = %d\n", N); fprintf(stats[TEST_LONGEST_RUN], "\t\t(b) M (Substring Length) = %d\n", M); fprintf(stats[TEST_LONGEST_RUN], "\t\t(c) Chi^2 = %f\n", chi2); fprintf(stats[TEST_LONGEST_RUN], "\t\t---------------------------------------------\n"); fprintf(stats[TEST_LONGEST_RUN], "\t\t F R E Q U E N C Y\n"); fprintf(stats[TEST_LONGEST_RUN], "\t\t---------------------------------------------\n"); if ( K == 3 ) { fprintf(stats[TEST_LONGEST_RUN], "\t\t <=1 2 3 >=4 P-value Assignment"); fprintf(stats[TEST_LONGEST_RUN], "\n\t\t %3d %3d %3d %3d ", nu[0], nu[1], nu[2], nu[3]); } else if ( K == 5 ) { fprintf(stats[TEST_LONGEST_RUN], "\t\t<=4 5 6 7 8 >=9 P-value Assignment"); fprintf(stats[TEST_LONGEST_RUN], "\n\t\t %3d %3d %3d %3d %3d %3d ", nu[0], nu[1], nu[2], nu[3], nu[4], nu[5]); } else { fprintf(stats[TEST_LONGEST_RUN],"\t\t<=10 11 12 13 14 15 >=16 P-value Assignment"); fprintf(stats[TEST_LONGEST_RUN],"\n\t\t %3d %3d %3d %3d %3d %3d %3d ", nu[0], nu[1], nu[2], nu[3], nu[4], nu[5], nu[6]); } if ( isNegative(pval) || isGreaterThanOne(pval) ) fprintf(stats[TEST_LONGEST_RUN], "WARNING: P_VALUE IS OUT OF RANGE.\n"); fprintf(stats[TEST_LONGEST_RUN], "%s\t\tp_value = %f\n\n", pval < ALPHA ? "FAILURE" : "SUCCESS", pval); fflush(stats[TEST_LONGEST_RUN]); fprintf(results[TEST_LONGEST_RUN], "%f\n", pval); fflush(results[TEST_LONGEST_RUN]); }
void Rank(int n) { int N, i, k, r; double p_value, product, chi_squared, arg1, p_32, p_31, p_30, R, F_32, F_31, F_30; BitSequence **matrix = create_matrix(32, 32); N = n/(32*32); if ( isZero(N) ) { fprintf(stats[TEST_RANK], "\t\t\t\tRANK TEST\n"); fprintf(stats[TEST_RANK], "\t\tError: Insuffucient # Of Bits To Define An 32x32 (%dx%d) Matrix\n", 32, 32); p_value = 0.00; } else { r = 32; /* COMPUTE PROBABILITIES */ product = 1; for ( i=0; i<=r-1; i++ ) product *= ((1.e0-pow(2, i-32))*(1.e0-pow(2, i-32)))/(1.e0-pow(2, i-r)); p_32 = pow(2, r*(32+32-r)-32*32) * product; r = 31; product = 1; for ( i=0; i<=r-1; i++ ) product *= ((1.e0-pow(2, i-32))*(1.e0-pow(2, i-32)))/(1.e0-pow(2, i-r)); p_31 = pow(2, r*(32+32-r)-32*32) * product; p_30 = 1 - (p_32+p_31); F_32 = 0; F_31 = 0; for ( k=0; k<N; k++ ) { /* FOR EACH 32x32 MATRIX */ def_matrix(32, 32, matrix, k); #if (DISPLAY_MATRICES == 1) display_matrix(32, 32, matrix); #endif R = computeRank(32, 32, matrix); if ( R == 32 ) F_32++; /* DETERMINE FREQUENCIES */ if ( R == 31 ) F_31++; } F_30 = (double)N - (F_32+F_31); chi_squared =(pow(F_32 - N*p_32, 2)/(double)(N*p_32) + pow(F_31 - N*p_31, 2)/(double)(N*p_31) + pow(F_30 - N*p_30, 2)/(double)(N*p_30)); arg1 = -chi_squared/2.e0; fprintf(stats[TEST_RANK], "\t\t\t\tRANK TEST\n"); fprintf(stats[TEST_RANK], "\t\t---------------------------------------------\n"); fprintf(stats[TEST_RANK], "\t\tCOMPUTATIONAL INFORMATION:\n"); fprintf(stats[TEST_RANK], "\t\t---------------------------------------------\n"); fprintf(stats[TEST_RANK], "\t\t(a) Probability P_%d = %f\n", 32,p_32); fprintf(stats[TEST_RANK], "\t\t(b) P_%d = %f\n", 31,p_31); fprintf(stats[TEST_RANK], "\t\t(c) P_%d = %f\n", 30,p_30); fprintf(stats[TEST_RANK], "\t\t(d) Frequency F_%d = %d\n", 32,(int)F_32); fprintf(stats[TEST_RANK], "\t\t(e) F_%d = %d\n", 31,(int)F_31); fprintf(stats[TEST_RANK], "\t\t(f) F_%d = %d\n", 30,(int)F_30); fprintf(stats[TEST_RANK], "\t\t(g) # of matrices = %d\n", N); fprintf(stats[TEST_RANK], "\t\t(h) Chi^2 = %f\n", chi_squared); fprintf(stats[TEST_RANK], "\t\t(i) NOTE: %d BITS WERE DISCARDED.\n", n%(32*32)); fprintf(stats[TEST_RANK], "\t\t---------------------------------------------\n"); p_value = exp(arg1); if ( isNegative(p_value) || isGreaterThanOne(p_value) ) fprintf(stats[TEST_RANK], "WARNING: P_VALUE IS OUT OF RANGE.\n"); for ( i=0; i<32; i++ ) /* DEALLOCATE MATRIX */ free(matrix[i]); free(matrix); } fprintf(stats[TEST_RANK], "%s\t\tp_value = %f\n\n", p_value < ALPHA ? "FAILURE" : "SUCCESS", p_value); fflush(stats[TEST_RANK]); fprintf(results[TEST_RANK], "%f\n", p_value); fflush(results[TEST_RANK]); }
void Universal(int n) { int i, j, p, L, Q, K; double arg, sqrt2, sigma, phi, sum, p_value, c; long *T, decRep; double expected_value[17] = { 0, 0, 0, 0, 0, 0, 5.2177052, 6.1962507, 7.1836656, 8.1764248, 9.1723243, 10.170032, 11.168765, 12.168070, 13.167693, 14.167488, 15.167379 }; double variance[17] = { 0, 0, 0, 0, 0, 0, 2.954, 3.125, 3.238, 3.311, 3.356, 3.384, 3.401, 3.410, 3.416, 3.419, 3.421 }; /* * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * THE FOLLOWING REDEFINES L, SHOULD THE CONDITION: n >= 1010*2^L*L * * NOT BE MET, FOR THE BLOCK LENGTH L. * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * * * * * * * * */ L = 5; if ( n >= 387840 ) L = 6; if ( n >= 904960 ) L = 7; if ( n >= 2068480 ) L = 8; if ( n >= 4654080 ) L = 9; if ( n >= 10342400 ) L = 10; if ( n >= 22753280 ) L = 11; if ( n >= 49643520 ) L = 12; if ( n >= 107560960 ) L = 13; if ( n >= 231669760 ) L = 14; if ( n >= 496435200 ) L = 15; if ( n >= 1059061760 ) L = 16; Q = 10*(int)pow(2, L); K = (int) (floor(n/L) - (double)Q); /* BLOCKS TO TEST */ p = (int)pow(2, L); if ( (L < 6) || (L > 16) || ((double)Q < 10*pow(2, L)) || ((T = (long *)calloc(p, sizeof(long))) == NULL) ) { fprintf(stats[TEST_UNIVERSAL], "\t\tUNIVERSAL STATISTICAL TEST\n"); fprintf(stats[TEST_UNIVERSAL], "\t\t---------------------------------------------\n"); fprintf(stats[TEST_UNIVERSAL], "\t\tERROR: L IS OUT OF RANGE.\n"); fprintf(stats[TEST_UNIVERSAL], "\t\t-OR- : Q IS LESS THAN %f.\n", 10*pow(2, L)); fprintf(stats[TEST_UNIVERSAL], "\t\t-OR- : Unable to allocate T.\n"); return; } /* COMPUTE THE EXPECTED: Formula 16, in Marsaglia's Paper */ c = 0.7 - 0.8/(double)L + (4 + 32/(double)L)*pow(K, -3/(double)L)/15; sigma = c * sqrt(variance[L]/(double)K); sqrt2 = sqrt(2); sum = 0.0; for ( i=0; i<p; i++ ) T[i] = 0; for ( i=1; i<=Q; i++ ) { /* INITIALIZE TABLE */ decRep = 0; for ( j=0; j<L; j++ ) decRep += epsilon[(i-1)*L+j] * (long)pow(2, L-1-j); T[decRep] = i; } for ( i=Q+1; i<=Q+K; i++ ) { /* PROCESS BLOCKS */ decRep = 0; for ( j=0; j<L; j++ ) decRep += epsilon[(i-1)*L+j] * (long)pow(2, L-1-j); sum += log(i - T[decRep])/log(2); T[decRep] = i; } phi = (double)(sum/(double)K); fprintf(stats[TEST_UNIVERSAL], "\t\tUNIVERSAL STATISTICAL TEST\n"); fprintf(stats[TEST_UNIVERSAL], "\t\t--------------------------------------------\n"); fprintf(stats[TEST_UNIVERSAL], "\t\tCOMPUTATIONAL INFORMATION:\n"); fprintf(stats[TEST_UNIVERSAL], "\t\t--------------------------------------------\n"); fprintf(stats[TEST_UNIVERSAL], "\t\t(a) L = %d\n", L); fprintf(stats[TEST_UNIVERSAL], "\t\t(b) Q = %d\n", Q); fprintf(stats[TEST_UNIVERSAL], "\t\t(c) K = %d\n", K); fprintf(stats[TEST_UNIVERSAL], "\t\t(d) sum = %f\n", sum); fprintf(stats[TEST_UNIVERSAL], "\t\t(e) sigma = %f\n", sigma); fprintf(stats[TEST_UNIVERSAL], "\t\t(f) variance = %f\n", variance[L]); fprintf(stats[TEST_UNIVERSAL], "\t\t(g) exp_value = %f\n", expected_value[L]); fprintf(stats[TEST_UNIVERSAL], "\t\t(h) phi = %f\n", phi); fprintf(stats[TEST_UNIVERSAL], "\t\t(i) WARNING: %d bits were discarded.\n", n-(Q+K)*L); fprintf(stats[TEST_UNIVERSAL], "\t\t-----------------------------------------\n"); arg = fabs(phi-expected_value[L])/(sqrt2 * sigma); p_value = erfc(arg); if ( isNegative(p_value) || isGreaterThanOne(p_value) ) fprintf(stats[TEST_UNIVERSAL], "\t\tWARNING: P_VALUE IS OUT OF RANGE\n"); fprintf(stats[TEST_UNIVERSAL], "%s\t\tp_value = %f\n\n", p_value < ALPHA ? "FAILURE" : "SUCCESS", p_value); fflush(stats[TEST_UNIVERSAL]); fprintf(results[TEST_UNIVERSAL], "%f\n", p_value); fflush(results[TEST_UNIVERSAL]); free(T); }
// Tests randomness of the BaseCryptoRandomStream and returns the random value bool LongestRunOfOnesTest::IsRandom(BaseCryptoRandomStream* bitStream) { double run = 0, v_n_obs = 0; double pi[7]; unsigned long int K; unsigned long int i = 0, j = 0; signed long int k[7]; unsigned long int nu[7] = {0, 0, 0, 0, 0, 0, 0}; if ( bitStream->GetBitLength() < 128 ) { this->error = InsufficientNumberOfBits; this->random = false; return this->random; } if ( bitStream->GetBitLength() < 6272 ) { K = 3; substringLength = 8; pi[0] = 0.21484375; pi[1] = 0.3671875; pi[2] = 0.23046875; pi[3] = 0.1875; k[0] = 1; k[1] = 2; k[2] = 3; k[3] = 4; } else { if ( bitStream->GetBitLength() < 750000 ) { K = 5; substringLength = 128; pi[0] = 0.1174035788; pi[1] = 0.242955959; pi[2] = 0.249363483; pi[3] = 0.17517706; pi[4] = 0.102701071; pi[5] = 0.112398847; k[0] = 4; k[1] = 5; k[2] = 6; k[3] = 7; k[4] = 8; k[5] = 9; } else { K = 6; substringLength = 10000; pi[0] = 0.0882; pi[1] = 0.2092; pi[2] = 0.2483; pi[3] = 0.1933; pi[4] = 0.1208; pi[5] = 0.0675; pi[6] = 0.0727; k[0] = 10; k[1] = 11; k[2] = 12; k[3] = 13; k[4] = 14; k[5] = 15; k[6] = 16; } } this->error = NoError; this->substringNumber = (int)floor((long double)(bitStream->GetBitLength()/substringLength)); bitStream->SetBitPosition(0); for(i = 0; i < this->substringNumber; i++) { v_n_obs = 0.e0; run = 0.e0; for(j = 0; j < substringLength; j++) { if ((int)bitStream->GetBitPosition(i * substringLength + j) == 1) { run++; v_n_obs = MAX(v_n_obs, run); } else { run = 0.e0; } } if ( v_n_obs < k[0] ) { nu[0]++; } for (j = 0; j <= K; j++) { if ( v_n_obs == k[j] ) { nu[j]++; } } if ( v_n_obs > k[K] ) { nu[K]++; } } this->chiSquared = 0.0; for(i = 0; i <= K; i++) { this->chiSquared += (((double)nu[i] - (double)this->substringNumber * pi[i]) * (nu[i] - (double)this->substringNumber * pi[i])) / ((double)this->substringNumber * pi[i]); } this->pValue = mathFuncs->IGammaC((double)(K/2.0),(this->chiSquared/2.0)); if (isNegative(this->pValue) || isGreaterThanOne(this->pValue)) { this->error = PValueOutOfRange; this->random = false; } else { if (this->pValue < this->alpha) { this->random = false; } else { this->random = true; } } for (i = 0; i < K+1; i++) this->assignment[i] = nu[i]; return this->random; }
void NonOverlappingTemplateMatchings(int m, int n) { int numOfTemplates[100] = {0, 0, 2, 4, 6, 12, 20, 40, 74, 148, 284, 568, 1116, 2232, 4424, 8848, 17622, 35244, 70340, 140680, 281076, 562152}; /*---------------------------------------------------------------------------- NOTE: Should additional templates lengths beyond 21 be desired, they must first be constructed, saved into files and then the corresponding number of nonperiodic templates for that file be stored in the m-th position in the numOfTemplates variable. ----------------------------------------------------------------------------*/ unsigned int bit, W_obs, nu[6], *Wj = NULL; FILE *fp; double sum, chi2, p_value, lambda, pi[6], varWj; int i, j, jj, k, match, SKIP, M, N, K = 5; char directory[100]; BitSequence *sequence = NULL; N = 8; M = n/N; if ( (Wj = (unsigned int*)calloc(N, sizeof(unsigned int))) == NULL ) { fprintf(stats[TEST_NONPERIODIC], "\tNONOVERLAPPING TEMPLATES TESTS ABORTED DUE TO ONE OF THE FOLLOWING : \n"); fprintf(stats[TEST_NONPERIODIC], "\tInsufficient memory for required work space.\n"); return; } lambda = (M-m+1)/pow(2, m); varWj = M*(1.0/pow(2.0, m) - (2.0*m-1.0)/pow(2.0, 2.0*m)); sprintf(directory, "templates/template%d", m); if ( ((isNegative(lambda)) || (isZero(lambda))) || ((fp = fopen(directory, "r")) == NULL) || ((sequence = (BitSequence *) calloc(m, sizeof(BitSequence))) == NULL) ) { fprintf(stats[TEST_NONPERIODIC], "\tNONOVERLAPPING TEMPLATES TESTS ABORTED DUE TO ONE OF THE FOLLOWING : \n"); fprintf(stats[TEST_NONPERIODIC], "\tLambda (%f) not being positive!\n", lambda); fprintf(stats[TEST_NONPERIODIC], "\tTemplate file <%s> not existing\n", directory); fprintf(stats[TEST_NONPERIODIC], "\tInsufficient memory for required work space.\n"); if ( sequence != NULL ) free(sequence); } else { fprintf(stats[TEST_NONPERIODIC], "\t\t NONPERIODIC TEMPLATES TEST\n"); fprintf(stats[TEST_NONPERIODIC], "-------------------------------------------------------------------------------------\n"); fprintf(stats[TEST_NONPERIODIC], "\t\t COMPUTATIONAL INFORMATION\n"); fprintf(stats[TEST_NONPERIODIC], "-------------------------------------------------------------------------------------\n"); fprintf(stats[TEST_NONPERIODIC], "\tLAMBDA = %f\tM = %d\tN = %d\tm = %d\tn = %d\n", lambda, M, N, m, n); fprintf(stats[TEST_NONPERIODIC], "-------------------------------------------------------------------------------------\n"); fprintf(stats[TEST_NONPERIODIC], "\t\tF R E Q U E N C Y\n"); fprintf(stats[TEST_NONPERIODIC], "Template W_1 W_2 W_3 W_4 W_5 W_6 W_7 W_8 Chi^2 P_value Assignment Index\n"); fprintf(stats[TEST_NONPERIODIC], "-------------------------------------------------------------------------------------\n"); if ( numOfTemplates[m] < MAXNUMOFTEMPLATES ) SKIP = 1; else SKIP = (int)(numOfTemplates[m]/MAXNUMOFTEMPLATES); numOfTemplates[m] = (int)numOfTemplates[m]/SKIP; sum = 0.0; for ( i=0; i<2; i++ ) { /* Compute Probabilities */ pi[i] = exp(-lambda+i*log(lambda)-cephes_lgam(i+1)); sum += pi[i]; } pi[0] = sum; for ( i=2; i<=K; i++ ) { /* Compute Probabilities */ pi[i-1] = exp(-lambda+i*log(lambda)-cephes_lgam(i+1)); sum += pi[i-1]; } pi[K] = 1 - sum; for( jj=0; jj<MIN(MAXNUMOFTEMPLATES, numOfTemplates[m]); jj++ ) { sum = 0; for ( k=0; k<m; k++ ) { fscanf(fp, "%d", &bit); sequence[k] = bit; fprintf(stats[TEST_NONPERIODIC], "%d", sequence[k]); } fprintf(stats[TEST_NONPERIODIC], " "); for ( k=0; k<=K; k++ ) nu[k] = 0; for ( i=0; i<N; i++ ) { W_obs = 0; for ( j=0; j<M-m+1; j++ ) { match = 1; for ( k=0; k<m; k++ ) { if ( (int)sequence[k] != (int)epsilon[i*M+j+k] ) { match = 0; break; } } if ( match == 1 ) W_obs++; } Wj[i] = W_obs; } sum = 0; chi2 = 0.0; /* Compute Chi Square */ for ( i=0; i<N; i++ ) { if ( m == 10 ) fprintf(stats[TEST_NONPERIODIC], "%3d ", Wj[i]); else fprintf(stats[TEST_NONPERIODIC], "%4d ", Wj[i]); chi2 += pow(((double)Wj[i] - lambda)/pow(varWj, 0.5), 2); } p_value = cephes_igamc(N/2.0, chi2/2.0); if ( isNegative(p_value) || isGreaterThanOne(p_value) ) fprintf(stats[TEST_NONPERIODIC], "\t\tWARNING: P_VALUE IS OUT OF RANGE.\n"); fprintf(stats[TEST_NONPERIODIC], "%9.6f %f %s %3d\n", chi2, p_value, p_value < ALPHA ? "FAILURE" : "SUCCESS", jj); if ( SKIP > 1 ) fseek(fp, (long)(SKIP-1)*2*m, SEEK_CUR); fprintf(results[TEST_NONPERIODIC], "%f\n", p_value); } } fprintf(stats[TEST_NONPERIODIC], "\n"); if ( sequence != NULL ) free(sequence); free(Wj); fclose(fp); }
// Tests randomness of the BaseCryptoRandomStream and returns the random value bool UniversalTest::IsRandom(BaseCryptoRandomStream* bitStream) { unsigned long int i, j, p; double arg, sqrt2, c; unsigned long int* T, decRep; if (bitStream->GetBitLength() < this->GetMinimumLength()) { this->error = InsufficientNumberOfBits; this->random = false; this->pValue = 0.0; return this->random; } this->error = NoError; bitStream->SetBitPosition(0); if (bitStream->GetBitLength() >= 1059061760) this->L = 16; else if (bitStream->GetBitLength() >= 496435200) this->L = 15; else if (bitStream->GetBitLength() >= 231669760) this->L = 14; else if (bitStream->GetBitLength() >= 107560960) this->L = 13; else if (bitStream->GetBitLength() >= 49643520) this->L = 12; else if (bitStream->GetBitLength() >= 22753280) this->L = 11; else if (bitStream->GetBitLength() >= 10342400) this->L = 10; else if (bitStream->GetBitLength() >= 4654080) this->L = 9; else if (bitStream->GetBitLength() >= 2068480) this->L = 8; else if (bitStream->GetBitLength() >= 904960) this->L = 7; else if (bitStream->GetBitLength() >= 387840) this->L = 6; this->Q = 10*(int)pow((double)2, (int)this->L); this->K = (int)((long double)floor((double)(bitStream->GetBitLength()/this->L)) - (double)this->Q); if ((double)this->Q < 10*pow((double)2,(int)this->L)) { this->random = false; this->error = LOrQOutOfRange; } else { this->varianceResult = variance[this->L]; this->expectedValueResult = expectedValue[this->L]; this->bitsDiscarded = bitStream->GetBitLength()-(this->Q+this->K)*this->L; c = 0.7 - 0.8/(double)this->L + (4 + 32/(double)this->L)*pow(this->K,-3/(double)this->L)/15; this->sigma = c * sqrt(this->varianceResult /(double)this->K); sqrt2 = sqrt((double)2); this->sum = 0.0; p = (int)pow((double)2,(int)this->L); T = (unsigned long int*) calloc(p, sizeof(unsigned long int)); if (T == NULL) { this->error = InsufficientMemory; this->random = false; return this->random ; } for(i = 0; i < p; i++) T[i] = 0; for(i = 1; i <= this->Q; i++) { decRep = 0; for(j = 0; j < this->L; j++) decRep += bitStream->GetBitPosition((i-1)*this->L+j) * (long)pow((double)2, (int)(this->L-1-j)); T[decRep] = i; } for(i = this->Q+1; i <= this->Q+this->K; i++) { decRep = 0; for(j = 0; j < this->L; j++) decRep += bitStream->GetBitPosition((i-1)*this->L+j) * (long)pow((double)2,(int)(this->L-1-j)); this->sum += log((double)(i - T[decRep]))/log((double)2); T[decRep] = i; } this->phi = (double)(this->sum/(double)this->K); arg = fabs(this->phi-this->expectedValueResult)/(sqrt2 * this->sigma); this->pValue = this->mathFuncs->ErFc(arg); if (isNegative(this->pValue) || isGreaterThanOne(this->pValue)) this->error = PValueOutOfRange; if (this->pValue < this->alpha) { this->random = false; } else { this->random = true; } } free(T); return this->random; }