VALUE rb_rt_final(VALUE self) { rt_ctx *ctx; Data_Get_Struct(self, rt_ctx, ctx); if (! ctx->ended) rt_end(ctx); return self; }
VALUE rb_rt_scc_force(VALUE self) { rt_ctx *ctx; Data_Get_Struct(self, rt_ctx, ctx); if(! ctx->ended) rt_end(ctx); return DBL2NUM(ctx->r_scc); }
/** * Run the entire unit test. **/ int main(void) { int i; int port; guint16 real_port; /* port at its actual size (for randomtest) */ double ent, chisq, mean, montepi, scc; /* randomtest results */ printf("Testing source port randomness; iterations=%d, minimal entropy=%f\n", ITERATIONS, MIN_ENTROPY); rt_init(FALSE); /* initialize randomtest, not binary */ /* run test iterations */ for (i = 0; i < ITERATIONS; i++) { port = try_bind_once(); #if PRINT_PORTS printf("Port bound to: %d\n", port); #endif if (port < PORT_MIN) { printf("Failed: port number below minimum.\n"); exit(1); } if (port > PORT_MAX) { printf("Failed: port number above maximum.\n"); exit(1); } real_port = (guint16)port; rt_add(&real_port, sizeof(real_port)); } /* check randomness */ rt_end(&ent, &chisq, &mean, &montepi, &scc); printf("Randomness: entropy=%f, chi-square=%f, mean=%f, monte-carlo-pi=%f, serial correlation=%f\n", ent, chisq, mean, montepi, scc); /* make decision */ if (ent >= MIN_ENTROPY) { printf("Passed: entropy is high enough.\n"); exit(0); } else { printf("Failed: entropy is not high enough.\n"); exit(1); } }
VALUE rb_rt_result(VALUE self) { rt_ctx *ctx; VALUE ret; Data_Get_Struct(self, rt_ctx, ctx); if(! ctx->ended) rt_end(ctx); ret = rb_hash_new(); rb_hash_aset(ret, ID2SYM(rb_intern("entropy")), DBL2NUM(ctx->r_ent)); rb_hash_aset(ret, ID2SYM(rb_intern("mean")), DBL2NUM(ctx->r_mean)); rb_hash_aset(ret, ID2SYM(rb_intern("chisquare")), DBL2NUM(ctx->r_chisq)); rb_hash_aset(ret, ID2SYM(rb_intern("montepi")), DBL2NUM(ctx->r_montepicalc)); rb_hash_aset(ret, ID2SYM(rb_intern("scc")), DBL2NUM(ctx->r_scc)); return ret; }
VALUE rb_rt_chisquare_probability_force(VALUE self) { rt_ctx *ctx; double ret, chip; Data_Get_Struct(self, rt_ctx, ctx); if(! ctx->ended) rt_end(ctx); chip = pochisq(ctx->r_chisq, (ctx->binary ? 1 : 255)); if (chip < 0.0001) ret = 0.009; else if (chip > 0.9999) ret = 99.991; else ret = chip * 100; return DBL2NUM(ret); }
int main(int argc, char *argv[]) { if (!getenv("FORCE_PRNG_VERF")) { fprintf(stderr, "prng: Skipping PRNG verification test\n" "prng: Set FORCE_PRNG_VERF=1 to enable PRNG verification\n"); return 77; } uint8_t ob[BUFFER_SIZE]; unsigned long totalc = 0; /* Total character count */ double montepi, chip, scc, ent, mean, chisq; /* Initialise for calculations */ rt_init(0); /* Scan input and count character occurrences */ for (totalc = 0; totalc < SAMPLE_SIZE_BYTES; totalc += BUFFER_SIZE) { assert(prng_get_random_bytes(ob, BUFFER_SIZE) >= 0); rt_add(ob, BUFFER_SIZE); } /* Complete calculation and return sequence metrics */ rt_end(&ent, &chisq, &mean, &montepi, &scc); /* Calculate probability of observed distribution occurring from the results of the Chi-Square test */ chip = pochisq(chisq, 255); /* Print calculated results */ printf("Entropy:\n"); printf("========\n"); printf("Entropy = %f bits per byte.\n", ent); printf("\nOptimum compression would reduce the size\n"); printf("of this %ld byte input by %d percent.\n\n", totalc, (int16_t)(100 * (8 - ent) / 8.0)); // Optimum compression would reduction equal to 0% assert((int16_t)(100 * (8 - ent) / 8.0) == 0); printf("Chi-square Test:\n"); printf("================\n"); printf("Chi square distribution for %ld samples is %1.2f, and randomly\n", totalc, chisq); if (chip < 0.0001) { printf( "would exceed this value less than 0.01 percent of the times.\n\n"); } else if (chip > 0.9999) { printf("would exceed this value more than than 99.99 percent of the " "times.\n\n"); } else { printf("would exceed this value %1.2f percent of the times.\n\n", chip * 100); } // Chi-square test result between 10% and 90% assert(90 > (chip * 100)); assert((chip * 100) > 10); printf("Arithmetic Mean:\n"); printf("================\n"); printf("Arithmetic mean value of data bytes is %1.4f (%.1f = random).\n\n", mean, 127.5); // Arithmetic Mean between 127 and 128 assert(127.0 < mean); assert(mean < 128.0); printf("Monte Carlo Value for Pi:\n"); printf("=========================\n"); printf("Monte Carlo value for Pi is %1.9f (error %1.2f percent).\n\n", montepi, 100.0 * (fabs(PI - montepi) / PI)); // Monte Carlo Value for Pi less than 0.5 assert(0.5 > 100.0 * (fabs(PI - montepi) / PI)); printf("Serial Correlation Coefficient:\n"); printf("===============================\n"); printf("Serial correlation coefficient is "); if (scc >= -99999) { printf("%1.6f (totally uncorrelated = 0.0).\n", scc); } else { printf("undefined (all values equal!).\n"); } printf("\nSee https://www.fourmilab.ch/random/ for detailed description of " "output\n"); // Serial Correlation Coefficient between -0.005 and 0.005 assert(0.005 > scc); assert(scc > -0.005); return 0; }