Skip to content

Commit

Permalink
Adding sinusoidal bias, so match one of the models used by NIST to te…
Browse files Browse the repository at this point in the history
…st the SP800-90B tests
  • Loading branch information
dj-on-github committed Apr 1, 2018
1 parent 8f376bd commit d5a98b3
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 8 deletions.
9 changes: 8 additions & 1 deletion README
Expand Up @@ -7,13 +7,14 @@ Usage: djrandom [-bsvh] [-x <bits>] [-y <bits>] [-z <bits>] [-c <generate length
[-r <right_stepsize>] [--stepnoise=<noise on step>] [--bias=<bias>]
[--correlation=<correlation>] [--mean=<normal mean>] [--variance=<normal variance>]
[--pcg_state_16=<16|32|64>] [--pcg_generator=<LCG|MCG>] [--pcg_of=<XSH_RS|XSH|RR]
[--sinbias_offset=<0.0 to 1.0>] [--sinbias_amplitude=<0.0 to 1.0>] [--sinbias_period=<samples per cycle>]
[-o <output_filename>] [-j <j filename>] [-i <input filename>] [-f <hex|binary|01>]
[-k <1K_Blocks>] [-w [1..256]]

Generate random bits with configurable non-uniformities.
Author: David Johnston, dj@deadhat.com

-m, --model=<pure(default)|sums|biased|correlated|lcg|pcg|xorshift|normal|file> Select random source model
-m, --model=<pure(default)|sums|biased|correlated|sinbias|lcg|pcg|xorshift|normal|file> Select random source model

Step Update Metastable Source model (-m sums) Options

Expand All @@ -29,6 +30,12 @@ Correlated model (-m correlated) Options

--correlation=<correlation> correlation with previous bit as a number between -1.0 and 1.0. Only for correlation model

Sinusoidally Varying Bias model (-m sinbias) Options

--sinbias_amplitude=<0.0 to 1.0> Amplitude of the variation of the bias between 0.0 and 1.0. Only for sinbias model
--sinbias_offset=<0.0 to 1.0> Midpoint Offset of the varying bias between 0.0 and 1.0. Only for sinbias model
--sinbias_period=<samples per cycle> Number of samples for a full cycle of the sinusoidally varying bias. Only for sinbias model

Normal model (-m normal) Options

--mean=<normal mean> mean of the normally distributed data. Only for normal model
Expand Down
60 changes: 56 additions & 4 deletions djenrandom.c
Expand Up @@ -46,6 +46,7 @@
#define MODEL_LCG 6
#define MODEL_PCG 7
#define MODEL_XORSHIFT 8
#define MODEL_SINBIAS 9

#define INFORMAT_01 0
#define INFORMAT_HEX 1
Expand All @@ -55,10 +56,11 @@ int aesni_supported;

void display_usage() {
fprintf(stderr,"Usage: djrandom [-bsvhn] [-x <bits>] [-y <bits>] [-z <bits>] [-c <generate length>]\n");
fprintf(stderr," [-m <|pure(default)|sums|biased|correlated|normal|file>] [-l <left_stepsize>]\n");
fprintf(stderr," [-m <|pure(default)|sums|biased|correlated|normal|sinbias|file>] [-l <left_stepsize>]\n");
fprintf(stderr," [-r <right_stepsize>] [--stepnoise=<noise on step>] [--bias=<bias>]\n");
fprintf(stderr," [--correlation=<correlation>] [--mean=<normal mean>] [--variance=<normal variance>]\n");
fprintf(stderr," [--pcg_state_16=<16|32|64>] [--pcg_generator=<LCG|MCG>] [--pcg_of=<XSH_RS|XSH|RR]\n");
fprintf(stderr," [--sinbias_offset=<0.0 to 1.0>] [--sinbias_amplitude=<0.0 to 1.0>] [--sinbias_period=<samples per cycle>]\n");
fprintf(stderr," [-o <output_filename>] [-j <j filename>] [-i <input filename>] [-f <hex|binary|01>]\n");
fprintf(stderr," [--bpb=<binary bits per byte>]\n");
fprintf(stderr," [-k <1K_Blocks>] [-w [1..256]]\n");
Expand All @@ -68,29 +70,41 @@ fprintf(stderr," Author: David Johnston, dj@deadhat.com\n");
fprintf(stderr,"\n");

fprintf(stderr," -m, --model=<pure(default)|sums|biased|correlated|lcg|pcg|xorshift|normal|file> Select random source model\n");

fprintf(stderr,"\nStep Update Metastable Source model (-m sums) Options\n\n");
fprintf(stderr," -l, --left=<left_stepsize> stepsize when moving left as a fraction of sigma_m.\n");
fprintf(stderr," -r, --right=<right_stepsize> stepsize when moving right as a fraction of sigma_m.\n");
fprintf(stderr," --stepnoise=<noise on step> variance of the noise on stepsize. e.g. 0.00001.\n");

fprintf(stderr,"\nBiased model (-m biased) Options\n\n");
fprintf(stderr," --bias=<bias> bias as a number between 0.0 and 1.0. Only for biased model\n");
fprintf(stderr,"\nCorrelated model (-m correlated) Options\n\n");
fprintf(stderr," --correlation=<correlation> correlation with previous bit as a number between -1.0 and 1.0. Only for correlation model\n");

fprintf(stderr,"\nSinusoidally Varying Bias model (-m sinbias) Options\n\n");
fprintf(stderr," --sinbias_amplitude=<0.0 to 1.0> Amplitude of the variation of the bias between 0.0 and 1.0. Only for sinbias model\n");
fprintf(stderr," --sinbias_offset=<0.0 to 1.0> Midpoint Offset of the varying bias between 0.0 and 1.0. Only for sinbias model\n");
fprintf(stderr," --sinbias_period=<samples per cycle> Number of samples for a full cycle of the sinusoidally varying bias. Only for sinbias model\n");

fprintf(stderr,"\nNormal model (-m normal) Options\n\n");
fprintf(stderr," --mean=<normal mean> mean of the normally distributed data. Only for normal model\n");
fprintf(stderr," --variance=<normal variance> variance of the normally distributed data\n");

fprintf(stderr,"\nLinear Congruential Generator model (-m lcg) Options\n\n");
fprintf(stderr," --lcg_a=<LCG multipler term> Positive integer less than lcg_m\n");
fprintf(stderr," --lcg_c=<LCG additive term> Positive integer less than lcg_m\n");
fprintf(stderr," --lcg_m=<LCG modulo term> Positive integer defining size of the group\n");
fprintf(stderr," --lcg_truncate=<lower bits to truncate> Positive integer\n");
fprintf(stderr," --lcg_outbits=<Number of bits per output> Positive integer\n");

fprintf(stderr,"\nPermuted Congruential Generator model (-m pcg) Options\n\n");
fprintf(stderr," --pcg_state_size=<state size of PCG> 16 ,32 or 64\n");
fprintf(stderr," --pcg_generator=<Generator Algorithm> MCG or LCG\n");
fprintf(stderr," --pcg_of=<Output Function> XSH_RS or XSH_RR\n");

fprintf(stderr,"\nXorShift model (-m xorshift) Options\n\n");
fprintf(stderr," --xorshift_size=[state size of xorshift] 32 or 128\n");

fprintf(stderr,"\nGeneral Options\n\n");
fprintf(stderr," -x, --xor=<bits> XOR 'bits' of entropy together for each output bit\n");
fprintf(stderr," -y, --xmin=<bits> Provides the start of a range of XOR ratios to be chosen at random per sample\n");
Expand All @@ -99,16 +113,19 @@ fprintf(stderr," -s, --seed seed the internal RNG with /dev
fprintf(stderr," -n, --noaesni Don't use AESNI instruction.\n");
fprintf(stderr," -c, --cmax=<generate length> number of PRNG generates before a reseed\n");
fprintf(stderr," -v, --verbose output the parameters\n");

fprintf(stderr,"\nFile Options\n\n");
fprintf(stderr," -o <output_filename> output file\n");
fprintf(stderr," -j, --jfile=<j filename> filename to push source model internal state to\n");
fprintf(stderr," -i, --infile=<input filename> filename of entropy file for file model\n");
fprintf(stderr," -f, --informat=<hex|binary|01> Format of input file. hex=Ascii hex(default), 4 bit per hex character. binary=raw binary. 01=ascii binary. Non valid characters are ignored\n");
fprintf(stderr," -k, --blocks=<1K_Blocks> Size of output in kilobytes\n");

fprintf(stderr,"\nOutput Format Options\n\n");
fprintf(stderr," -b, --binary output in raw binary format\n");
fprintf(stderr," --bpb Number of bits per byte to output in binary output mode. Default 8.\n");
fprintf(stderr," -w, --width=[1...256] Byte per line of output\n");

fprintf(stderr,"\nThe most important option of all\n\n");
fprintf(stderr," -h, --help print this help and exit\n");
}
Expand Down Expand Up @@ -223,6 +240,11 @@ int entropysource(int model, t_modelstate* modelstate, t_rngstate* rngstate)
result = correlatedsource(modelstate, rngstate);
return result;
}
else if (model==MODEL_SINBIAS)
{
result = sinbiassource(modelstate, rngstate);
return result;
}
else if (model==MODEL_LCG)
{
result = lcgsource(modelstate, rngstate);
Expand Down Expand Up @@ -270,6 +292,10 @@ void initialize_sim(int model, t_modelstate* modelstate, t_rngstate* rngstate)
{
correlatedinit(modelstate, rngstate);
}
else if (model==MODEL_SINBIAS)
{
sinbiasinit(modelstate, rngstate);
}
else if (model==MODEL_NORMAL)
{
normalinit(modelstate, rngstate);
Expand Down Expand Up @@ -380,7 +406,13 @@ int main(int argc, char** argv)
modelstate.pcg_index=0;
modelstate.pcg_alg = PCG_LCG;
modelstate.pcg_of = XSH_RR;


modelstate.sinbias_amplitude = 0.5;
modelstate.sinbias_offset = 0.5;
modelstate.sinbias_period = 1000;

modelstate.time = 0;

rngstate.c_max=511;

modelstate.left_stepsize = 0.1;
Expand Down Expand Up @@ -451,6 +483,10 @@ int main(int argc, char** argv)
{ "pcg_generator", required_argument, NULL, 0 },
{ "pcg_of", required_argument, NULL, 0 },

{ "sinbias_amplitude", required_argument, NULL, 0 },
{ "sinbias_offset", required_argument, NULL, 0 },
{ "sinbias_period", required_argument, NULL, 0 },

{ "xorshift_size", required_argument, NULL, 0 },

{ "output", required_argument, NULL, 'o' },
Expand Down Expand Up @@ -527,6 +563,7 @@ int main(int argc, char** argv)
else if (strcmp(optarg,"pure")==0) model=MODEL_PURE;
else if (strcmp(optarg,"biased")==0) model=MODEL_BIASED;
else if (strcmp(optarg,"correlated")==0) model=MODEL_CORRELATED;
else if (strcmp(optarg,"sinbias")==0) model=MODEL_SINBIAS;
else if (strcmp(optarg,"lcg")==0) model=MODEL_LCG;
else if (strcmp(optarg,"pcg")==0) model=MODEL_PCG;
else if (strcmp(optarg,"xorshift")==0) model=MODEL_XORSHIFT;
Expand Down Expand Up @@ -624,8 +661,17 @@ int main(int argc, char** argv)
if( strcmp( "xorshift_size", longOpts[longIndex].name ) == 0 ) {
modelstate.xorshift_size = atoi(optarg);
}
break;

if( strcmp( "sinbias_amplitude", longOpts[longIndex].name ) == 0 ) {
modelstate.sinbias_amplitude = atof(optarg);
}
if( strcmp( "sinbias_offset", longOpts[longIndex].name ) == 0 ) {
modelstate.sinbias_offset = atof(optarg);
}
if( strcmp( "sinbias_period", longOpts[longIndex].name ) == 0 ) {
modelstate.sinbias_period = atoi(optarg);
}
break;
case 'h': /* fall-through is intentional */
case '?':
display_usage();
Expand Down Expand Up @@ -707,11 +753,17 @@ int main(int argc, char** argv)
abort=1;
}

if (modelstate.sinbias_period < 4)
{
printf("Error: --sinbiad_period=%llu: Sinusoid period must be 4 or more\n",modelstate.sinbias_period);
abort=1;
}

if (modelstate.left_stepsize == 0.0)
{
printf("Error: -l n: left stepsize cannot be 0.0. Supplied value = %f\n",modelstate.left_stepsize);
abort=1;
}
}
if (modelstate.right_stepsize == 0.0)
{
printf("Error: -l n: right stepsize cannot be 0.0 . Supplied value = %f\n",modelstate.right_stepsize);
Expand Down
69 changes: 69 additions & 0 deletions djenrandommodel.c
Expand Up @@ -434,6 +434,56 @@ int correlatedsource(t_modelstate *modelstate, t_rngstate* rngstate)
return(result);
}

int sinbiassource(t_modelstate *modelstate, t_rngstate* rngstate)
{
int result;
double dthreshold;
int threshold;
unsigned long int theint;
double bias;
double period;
double amplitude;
double offset;
int t;
double maxp;
double entropy;

/* get a uniform Random number. */

theint = getrand16(rngstate);

period = modelstate->sinbias_period;
amplitude = modelstate->sinbias_amplitude;
offset = modelstate->sinbias_offset;
t = modelstate->time;

bias = offset + (amplitude*(sin(2.0*M_PI*t/period)));

if (bias < 0.0) bias =0.0;
if (bias > 1.0) bias = 1.0;

dthreshold = 65536.0*bias;
threshold = (int)dthreshold;


if (theint < threshold) result = 1;
else result = 0;

modelstate->sinbias_bias = bias;

if (modelstate->using_jfile ==1)
{
if (bias > 0.5) maxp = bias;
else maxp = 1.0 - bias;

entropy = -log(maxp)/log(2);
fprintf(modelstate->jfile,"%0.6f\n",entropy);
}

modelstate->time = t+1;
return(result);
}

int lcgsource(t_modelstate* modelstate, t_rngstate* rngstate)
{
unsigned long long a;
Expand Down Expand Up @@ -1048,6 +1098,25 @@ void correlatedinit(t_modelstate *modelstate, t_rngstate *rngstate)

}

void sinbiasinit(t_modelstate *modelstate, t_rngstate *rngstate)
{
unsigned char out[16];

smoothinit(modelstate, rngstate);
if (rngstate->randseed==1)
{
nondeterministic_bytes(16, rngstate->rngbits, rngstate);
/*fread(rngstate->rngbits,16,1,rngstate->devrandom);*/
}
else
{
aes128k128d(rngstate->k,rngstate->v,out);
aes128k128d(out,rngstate->k,rngstate->rngbits);
}

modelstate->time = 0;
}

void lcginit(t_modelstate *modelstate, t_rngstate *rngstate)
{
if (rngstate->randseed==0) {
Expand Down
15 changes: 12 additions & 3 deletions djenrandommodel.h
Expand Up @@ -71,6 +71,13 @@ typedef struct {
uint64_t pcg64_adder;
uint64_t pcg128_adder[2];

/* sin bias states */
uint64_t sinbias_period;
double sinbias_amplitude;
double sinbias_offset;
int sinbias_bias;
uint64_t time;

/* XORSHIFT States */

uint32_t xorshift_size;
Expand Down Expand Up @@ -122,6 +129,7 @@ int smoothsource( t_modelstate* modelstate, t_rngstate* rngstate);
int puresource( t_modelstate *modelstate, t_rngstate* rngstate);
int biasedsource( t_modelstate *modelstate, t_rngstate* rngstate);
int correlatedsource( t_modelstate *modelstate, t_rngstate* rngstate);
int sinbiassource( t_modelstate *modelstate, t_rngstate* rngstate);
int lcgsource( t_modelstate *modelstate, t_rngstate* rngstate);
int pcgsource( t_modelstate *modelstate, t_rngstate* rngstate);
int xorshiftsource( t_modelstate *modelstate, t_rngstate* rngstate);
Expand All @@ -140,9 +148,10 @@ void smoothinit( t_modelstate* modelstate, t_rngstate* rngstate);
void pureinit( t_modelstate* modelstate, t_rngstate* rngstate);
void biasedinit( t_modelstate* modelstate, t_rngstate* rngstate);
void correlatedinit( t_modelstate* modelstate, t_rngstate* rngstate);
void lcginit( t_modelstate* modelstate, t_rngstate* rngstate);
void pcginit( t_modelstate* modelstate, t_rngstate* rngstate);
void xorshiftinit( t_modelstate* modelstate, t_rngstate* rngstate);
void sinbiasinit( t_modelstate* modelstate, t_rngstate* rngstate);
void lcginit( t_modelstate* modelstate, t_rngstate* rngstate);
void pcginit( t_modelstate* modelstate, t_rngstate* rngstate);
void xorshiftinit( t_modelstate* modelstate, t_rngstate* rngstate);
void normalinit( t_modelstate *modelstate, t_rngstate* rngstate);
void fileinit( t_modelstate *modelstate, t_rngstate* rngstate);

Expand Down

0 comments on commit d5a98b3

Please sign in to comment.