add socks_decoder, stratum_decoder and session_flags

This commit is contained in:
root
2024-09-03 07:01:58 +00:00
parent a8206cffc0
commit 6f1ac6b36b
160 changed files with 11861 additions and 1 deletions

View File

@@ -0,0 +1,15 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/)
file(GLOB STS_SRC
"src/*.c"
)
#add_compile_options(-Wno-error=unused-parameter -Wno-unused-but-set-variable -Wno-error=misleading-indentation -Wno-unused-variable -Wno-maybe-uninitialized -Wno-error=unused-function)
add_library(libmesa_sts ${STS_SRC})
target_include_directories(libmesa_sts PUBLIC ${CMAKE_SOURCE_DIR}/decoders/session_flags/mesa_sts/include)
target_compile_options(libmesa_sts PRIVATE -Wno-error=unused-parameter -Wno-unused-but-set-variable -Wno-error=misleading-indentation -Wno-unused-variable -Wno-maybe-uninitialized -Wno-error=unused-function)
set_target_properties(libmesa_sts PROPERTIES LINK_FLAGS
"-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/version.map")
add_subdirectory(test)

View File

@@ -0,0 +1,57 @@
#ifndef _MESA_STS_H_
#define _MESA_STS_H_
#define STS_RANDOM_JUDGE_NUM 15
#define STS_SET_FLAG(flag, idx) (flag |= (1 << idx))
#define STS_TEST_FLAG(flag, idx) (flag & (1 << idx))
enum sts_random_judge_list_idx
{
STS_FREQUENCY = 0,
STS_BLOCK_FREQUENCY,
STS_CUMULATIVE_SUMS,
STS_RUNS,
STS_LONGEST_RUN,
STS_RANK,
STS_NON_OVERLAPPING_TEMPLATE_MATCHING,
STS_OVERLAPPING_TEMPLATE_MATCHING,
STS_UNIVERSAL,
STS_RANDOM_EXCURSIONS,
STS_RANDOM_EXCURSIONS_VARIANT,
STS_POKER_DETECT,
STS_RUNS_DISTRIBUTION,
STS_SELF_CORRELATION,
STS_BINARY_DERIVATE,
STS_RANDOM_IDX_MAX
};
struct sts_result {
unsigned char frequency;
unsigned char block_frequency;
unsigned char cumulative_sums;
unsigned char runs;
unsigned char longest_run;
unsigned char rank;
unsigned char non_overlapping_template_matching;
unsigned char overlapping_template_matching;
unsigned char universal;
unsigned char random_excursions;
unsigned char random_excursions_variant;
unsigned char poker_detect;
unsigned char runs_distribution;
unsigned char self_correlation;
unsigned char binary_derivative;
};
#ifdef __cplusplus
extern "C" {
#endif
int mesa_statistical_test_suite(void* data,unsigned int datalen, struct sts_result* result, unsigned int random_judge_switch_flag);
#ifdef __cplusplus
}
#endif
#endif /* _MESA_STS_H_ */

View File

@@ -0,0 +1,72 @@
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "include/externs.h"
#include "include/cephes.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
A P P R O X I M A T E E N T R O P Y T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
ApproximateEntropy(int m, int n, BitSequence *epsilon)
{
int i, j, k, r, blockSize, seqLength, powLen, index;
double sum, numOfBlocks, ApEn[2], apen, chi_squared, p_value;
unsigned int *P;
seqLength = n;
r = 0;
for ( blockSize=m; blockSize<=m+1; blockSize++ ) {
if ( blockSize == 0 ) {
ApEn[0] = 0.00;
r++;
}
else {
numOfBlocks = (double)seqLength;
powLen = (int)pow(2, blockSize+1)-1;
if ( (P = (unsigned int*)calloc(powLen,sizeof(unsigned int)))== NULL ) {
return 0;
}
for ( i=1; i<powLen-1; i++ )
P[i] = 0;
for ( i=0; i<numOfBlocks; i++ ) { /* COMPUTE FREQUENCY */
k = 1;
for ( j=0; j<blockSize; j++ ) {
k <<= 1;
if ( (int)epsilon[(i+j) % seqLength] == 1 )
k++;
}
P[k-1]++;
}
/* DISPLAY FREQUENCY */
sum = 0.0;
index = (int)pow(2, blockSize)-1;
for ( i=0; i<(int)pow(2, blockSize); i++ ) {
if ( P[index] > 0 )
sum += P[index]*log(P[index]/numOfBlocks);
index++;
}
sum /= numOfBlocks;
ApEn[r] = sum;
r++;
free(P);
}
}
apen = ApEn[0] - ApEn[1];
chi_squared = 2.0*seqLength*(log(2) - apen);
p_value = cephes_igamc(pow(2, m-1), chi_squared/2.0);
if ( m > (int)(log(seqLength)/log(2)-5) ) {
return 0;
}
if (p_value < ALPHA) {
return 0;
} else {
return 1;
}
}

View File

@@ -0,0 +1,30 @@
#include <math.h>
#include "include/stat_fncs.h"
int BinaryDerivate(int k, int n, BitSequence *epsilon, int epsilon_l)
{
int i = 0, j = 0;
int Sn_k = 0;
int n_k = n - k;
double V = 0.0, p_value = 0.0, sqrt2 = 1.41421356237309504880;
for (i = 0; i < k; ++i) {
for (j = 0; j < epsilon_l - 1; ++j) {
epsilon[j] = epsilon[j] ^ epsilon[j + 1];
}
}
for (i = 0; i < n_k; ++i) {
Sn_k += (2 * (int)epsilon[i]) - 1;
}
V = fabs(Sn_k) / sqrt(n_k);
p_value = erfc(fabs(V) / sqrt2);
if (p_value < ALPHA) {
return 0;
} else {
return 1;
}
}

View File

@@ -0,0 +1,36 @@
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "include/externs.h"
#include "include/cephes.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
B L O C K F R E Q U E N C Y T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
BlockFrequency(int M, int n, BitSequence *epsilon)
{
int i, j, N, blockSum;
double p_value, sum, pi, v, chi_squared;
N = n/M; /* # OF SUBSTRING BLOCKS */
sum = 0.0;
for ( i=0; i<N; i++ ) {
blockSum = 0;
for ( j=0; j<M; j++ )
blockSum += epsilon[j+i*M];
pi = (double)blockSum/(double)M;
v = pi - 0.5;
sum += v*v;
}
chi_squared = 4.0 * M * sum;
p_value = cephes_igamc(N/2.0, chi_squared/2.0);
if (p_value < ALPHA) {
return 0;
} else {
return 1;
}
}

View File

@@ -0,0 +1,31 @@
#include "include/stat_fncs.h"
static unsigned char _compute(unsigned char b, unsigned char factor)
{
if ((factor & b) == factor) {
return 0x01;
} else {
return 0x00;
}
}
int BytesToBitSequence(unsigned char *in, int inl, BitSequence *outbuf, int bufsize)
{
int j = 0, i = 0;
if (bufsize < inl * 8) {
return 0;
}
for (i = 0; i < inl; ++i) {
j = i * 8;
outbuf[j] = (BitSequence) (_compute(in[i], 0x80));
outbuf[j + 1] = (BitSequence) (_compute(in[i], 0x40));
outbuf[j + 2] = (BitSequence) (_compute(in[i], 0x20));
outbuf[j + 3] = (BitSequence) (_compute(in[i], 0x10));
outbuf[j + 4] = (BitSequence) (_compute(in[i], 0x08));
outbuf[j + 5] = (BitSequence) (_compute(in[i], 0x04));
outbuf[j + 6] = (BitSequence) (_compute(in[i], 0x02));
outbuf[j + 7] = (BitSequence) (_compute(in[i], 0x01));
}
return 1;
}

View File

@@ -0,0 +1,348 @@
#include <stdio.h>
#include <math.h>
#include "include/cephes.h"
static const double rel_error = 1E-12;
double MACHEP = 1.11022302462515654042E-16; // 2**-53
double MAXLOG = 7.09782712893383996732224E2; // log(MAXNUM)
double MAXNUM = 1.7976931348623158E308; // 2**1024*(1-MACHEP)
double PI = 3.14159265358979323846; // pi, duh!
static double big = 4.503599627370496e15;
static double biginv = 2.22044604925031308085e-16;
int sgngam = 0;
double
cephes_igamc(double a, double x)
{
double ans, ax, c, yc, r, t, y, z;
double pk, pkm1, pkm2, qk, qkm1, qkm2;
if ( (x <= 0) || ( a <= 0) )
return( 1.0 );
if ( (x < 1.0) || (x < a) )
return( 1.e0 - cephes_igam(a,x) );
ax = a * log(x) - x - cephes_lgam(a);
if ( ax < -MAXLOG ) {
printf("igamc: UNDERFLOW\n");
return 0.0;
}
ax = exp(ax);
/* continued fraction */
y = 1.0 - a;
z = x + y + 1.0;
c = 0.0;
pkm2 = 1.0;
qkm2 = x;
pkm1 = x + 1.0;
qkm1 = z * x;
ans = pkm1/qkm1;
do {
c += 1.0;
y += 1.0;
z += 2.0;
yc = y * c;
pk = pkm1 * z - pkm2 * yc;
qk = qkm1 * z - qkm2 * yc;
if ( qk != 0 ) {
r = pk/qk;
t = fabs( (ans - r)/r );
ans = r;
}
else
t = 1.0;
pkm2 = pkm1;
pkm1 = pk;
qkm2 = qkm1;
qkm1 = qk;
if ( fabs(pk) > big ) {
pkm2 *= biginv;
pkm1 *= biginv;
qkm2 *= biginv;
qkm1 *= biginv;
}
} while ( t > MACHEP );
return ans*ax;
}
double
cephes_igam(double a, double x)
{
double ans, ax, c, r;
if ( (x <= 0) || ( a <= 0) )
return 0.0;
if ( (x > 1.0) && (x > a ) )
return 1.e0 - cephes_igamc(a,x);
/* Compute x**a * exp(-x) / gamma(a) */
ax = a * log(x) - x - cephes_lgam(a);
if ( ax < -MAXLOG ) {
printf("igam: UNDERFLOW\n");
return 0.0;
}
ax = exp(ax);
/* power series */
r = a;
c = 1.0;
ans = 1.0;
do {
r += 1.0;
c *= x/r;
ans += c;
} while ( c/ans > MACHEP );
return ans * ax/a;
}
union A_Array {
double d[5];
unsigned short us[20];
};
union BC_Array {
double d[6];
unsigned short us[24];
};
/* A[]: Stirling's formula expansion of log gamma
* B[], C[]: log gamma function between 2 and 3
*/
/**/
static union A_Array A = {
.us = {
0x6661,0x2733,0x9850,0x3f4a,
0xe943,0xb580,0x7fbd,0xbf43,
0x5ebb,0x20dc,0x019f,0x3f4a,
0xa5a1,0x16b0,0xc16c,0xbf66,
0x554b,0x5555,0x5555,0x3fb5
}
};
static union BC_Array B = {
.us = {
0x6761,0x8ff3,0x8901,0xc095,
0xb93e,0x355b,0xf234,0xc0e2,
0x89e5,0xf890,0x3d73,0xc114,
0xdb51,0xf994,0xbc82,0xc131,
0xf20b,0x0219,0x4589,0xc13a,
0x055e,0x5418,0x0c67,0xc12a
}
};
static union BC_Array C = {
/*0x0000,0x0000,0x0000,0x3ff0,*/
.us = {
0x12b2,0x1cf3,0xfd0d,0xc075,
0xd757,0x7b89,0xaa0d,0xc0d0,
0x4c9b,0xb974,0xeb84,0xc10a,
0x0043,0x7195,0x6286,0xc131,
0xf34c,0x892f,0x5255,0xc143,
0xe14a,0x6a11,0xce4b,0xc13e
}
};
#define MAXLGM 2.556348e305
/* Logarithm of gamma function */
double
cephes_lgam(double x)
{
double p, q, u, w, z;
int i;
sgngam = 1;
if ( x < -34.0 ) {
q = -x;
w = cephes_lgam(q); /* note this modifies sgngam! */
p = floor(q);
if ( p == q ) {
lgsing:
goto loverf;
}
i = (int)p;
if ( (i & 1) == 0 )
sgngam = -1;
else
sgngam = 1;
z = q - p;
if ( z > 0.5 ) {
p += 1.0;
z = p - q;
}
z = q * sin( PI * z );
if ( z == 0.0 )
goto lgsing;
/* z = log(PI) - log( z ) - w;*/
z = log(PI) - log( z ) - w;
return z;
}
if ( x < 13.0 ) {
z = 1.0;
p = 0.0;
u = x;
while ( u >= 3.0 ) {
p -= 1.0;
u = x + p;
z *= u;
}
while ( u < 2.0 ) {
if ( u == 0.0 )
goto lgsing;
z /= u;
p += 1.0;
u = x + p;
}
if ( z < 0.0 ) {
sgngam = -1;
z = -z;
}
else
sgngam = 1;
if ( u == 2.0 )
return( log(z) );
p -= 2.0;
x = x + p;
p = x * cephes_polevl( x, (double *)B.d, 5 ) / cephes_p1evl( x, (double *)C.d, 6);
return log(z) + p;
}
if ( x > MAXLGM ) {
loverf:
printf("lgam: OVERFLOW\n");
return sgngam * MAXNUM;
}
q = ( x - 0.5 ) * log(x) - x + log( sqrt( 2*PI ) );
if ( x > 1.0e8 )
return q;
p = 1.0/(x*x);
if ( x >= 1000.0 )
q += (( 7.9365079365079365079365e-4 * p
- 2.7777777777777777777778e-3) *p
+ 0.0833333333333333333333) / x;
else
q += cephes_polevl( p, (double *)A.d, 4 ) / x;
return q;
}
double
cephes_polevl(double x, double *coef, int N)
{
double ans;
int i;
double *p;
p = coef;
ans = *p++;
i = N;
do
ans = ans * x + *p++;
while ( --i );
return ans;
}
double
cephes_p1evl(double x, double *coef, int N)
{
double ans;
double *p;
int i;
p = coef;
ans = x + *p++;
i = N-1;
do
ans = ans * x + *p++;
while ( --i );
return ans;
}
double
cephes_erf(double x)
{
static const double two_sqrtpi = 1.128379167095512574;
double sum = x, term = x, xsqr = x * x;
int j = 1;
if ( fabs(x) > 2.2 )
return 1.0 - cephes_erfc(x);
do {
term *= xsqr/j;
sum -= term/(2*j+1);
j++;
term *= xsqr/j;
sum += term/(2*j+1);
j++;
} while ( fabs(term)/sum > rel_error );
return two_sqrtpi*sum;
}
double
cephes_erfc(double x)
{
static const double one_sqrtpi = 0.564189583547756287;
double a = 1, b = x, c = x, d = x*x + 0.5;
double q1, q2 = b/d, n = 1.0, t;
if ( fabs(x) < 2.2 )
return 1.0 - cephes_erf(x);
if ( x < 0 )
return 2.0 - cephes_erfc(-x);
do {
t = a*n + b*x;
a = b;
b = t;
t = c*n + d*x;
c = d;
d = t;
n += 0.5;
q1 = q2;
q2 = b/d;
} while ( fabs(q1-q2)/q2 > rel_error );
return one_sqrtpi*exp(-x*x)*q2;
}
double
cephes_normal(double x)
{
double arg, result, sqrt2=1.414213562373095048801688724209698078569672;
if (x > 0) {
arg = x/sqrt2;
result = 0.5 * ( 1 + erf(arg) );
}
else {
arg = -x/sqrt2;
result = 0.5 * (erfc(arg) );
}
return( result);
}

View File

@@ -0,0 +1,95 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "include/externs.h"
#include "include/cephes.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
C U M U L A T I V E S U M S T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
CumulativeSums(int n, BitSequence *epsilon)
{
int S, sup, inf, z=1, zrev, k;
double sum1, sum2, p_value;
S = 0;
sup = 0;
inf = 0;
for ( k=0; k<n; k++ ) {
epsilon[k] ? S++ : S--;
if ( S > sup )
sup++;
if ( S < inf )
inf--;
z = (sup > -inf) ? sup : -inf;
zrev = (sup-S > S-inf) ? sup-S : S-inf;
}
// forward
sum1 = 0.0;
for ( k=(-n/z+1)/4; k<=(n/z-1)/4; k++ ) {
sum1 += cephes_normal(((4*k+1)*z)/sqrt(n));
sum1 -= cephes_normal(((4*k-1)*z)/sqrt(n));
}
sum2 = 0.0;
for ( k=(-n/z-3)/4; k<=(n/z-1)/4; k++ ) {
sum2 += cephes_normal(((4*k+3)*z)/sqrt(n));
sum2 -= cephes_normal(((4*k+1)*z)/sqrt(n));
}
p_value = 1.0 - sum1 + sum2;
// fprintf(stats[TEST_CUSUM], "\t\t CUMULATIVE SUMS (FORWARD) TEST\n");
// fprintf(stats[TEST_CUSUM], "\t\t-------------------------------------------\n");
// fprintf(stats[TEST_CUSUM], "\t\tCOMPUTATIONAL INFORMATION:\n");
// fprintf(stats[TEST_CUSUM], "\t\t-------------------------------------------\n");
// fprintf(stats[TEST_CUSUM], "\t\t(a) The maximum partial sum = %d\n", z);
// fprintf(stats[TEST_CUSUM], "\t\t-------------------------------------------\n");
if ( isNegative(p_value) || isGreaterThanOne(p_value) ) {
// fprintf(stats[TEST_CUSUM], "\t\tWARNING: P_VALUE IS OUT OF RANGE\n");
return 0;
}
// fprintf(stats[TEST_CUSUM], "%s\t\tp_value = %f\n\n", p_value < ALPHA ? "FAILURE" : "SUCCESS", p_value);
// fprintf(results[TEST_CUSUM], "%f\n", p_value);
if (p_value < ALPHA) {
return 0;
}
// backwards
sum1 = 0.0;
for ( k=(-n/zrev+1)/4; k<=(n/zrev-1)/4; k++ ) {
sum1 += cephes_normal(((4*k+1)*zrev)/sqrt(n));
sum1 -= cephes_normal(((4*k-1)*zrev)/sqrt(n));
}
sum2 = 0.0;
for ( k=(-n/zrev-3)/4; k<=(n/zrev-1)/4; k++ ) {
sum2 += cephes_normal(((4*k+3)*zrev)/sqrt(n));
sum2 -= cephes_normal(((4*k+1)*zrev)/sqrt(n));
}
p_value = 1.0 - sum1 + sum2;
// fprintf(stats[TEST_CUSUM], "\t\t CUMULATIVE SUMS (REVERSE) TEST\n");
// fprintf(stats[TEST_CUSUM], "\t\t-------------------------------------------\n");
// fprintf(stats[TEST_CUSUM], "\t\tCOMPUTATIONAL INFORMATION:\n");
// fprintf(stats[TEST_CUSUM], "\t\t-------------------------------------------\n");
// fprintf(stats[TEST_CUSUM], "\t\t(a) The maximum partial sum = %d\n", zrev);
// fprintf(stats[TEST_CUSUM], "\t\t-------------------------------------------\n");
if ( isNegative(p_value) || isGreaterThanOne(p_value) ) {
// fprintf(stats[TEST_CUSUM], "\t\tWARNING: P_VALUE IS OUT OF RANGE\n");
return 0;
}
// fprintf(stats[TEST_CUSUM], "%s\t\tp_value = %f\n\n", p_value < ALPHA ? "FAILURE" : "SUCCESS", p_value); fflush(stats[TEST_CUSUM]);
// fprintf(results[TEST_CUSUM], "%f\n", p_value); fflush(results[TEST_CUSUM]);
if (p_value < ALPHA) {
return 0;
} else {
return 1;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,60 @@
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "include/externs.h"
#include "include/cephes.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
D I S C R E T E F O U R I E R T R A N S F O R M T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void __ogg_fdrffti(int n, double *wsave, int *ifac);
void __ogg_fdrfftf(int n, double *X, double *wsave, int *ifac);
int
DiscreteFourierTransform(int n, BitSequence *epsilon)
{
double p_value, upperBound, percentile, N_l, N_o, d, *m, *X, *wsave;
int i, count, ifac[15];
if ( ((X = (double*) calloc(n,sizeof(double))) == NULL) ||
((wsave = (double *)calloc(2*n,sizeof(double))) == NULL) ||
((m = (double*)calloc(n/2+1, sizeof(double))) == NULL) ) {
if( X != NULL )
free(X);
if( wsave != NULL )
free(wsave);
if( m != NULL )
free(m);
return 0;
}
for ( i=0; i<n; i++ )
X[i] = 2*(int)epsilon[i] - 1;
__ogg_fdrffti(n, wsave, ifac); /* INITIALIZE WORK ARRAYS */
__ogg_fdrfftf(n, X, wsave, ifac); /* APPLY FORWARD FFT */
m[0] = sqrt(X[0]*X[0]); /* COMPUTE MAGNITUDE */
for ( i=0; i<n/2; i++ )
m[i+1] = sqrt(pow(X[2*i+1],2)+pow(X[2*i+2],2));
count = 0; /* CONFIDENCE INTERVAL */
upperBound = sqrt(2.995732274*n);
for ( i=0; i<n/2; i++ )
if ( m[i] < upperBound )
count++;
percentile = (double)count/(n/2)*100;
N_l = (double) count; /* number of peaks less than h = sqrt(3*n) */
N_o = (double) 0.95*n/2.0;
d = (N_l - N_o)/sqrt(n/4.0*0.95*0.05);
p_value = erfc(fabs(d)/sqrt(2.0));
free(X);
free(wsave);
free(m);
if (p_value < ALPHA) {
return 0;
} else {
return 1;
}
}

View File

@@ -0,0 +1,38 @@
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "include/externs.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
F R E Q U E N C Y T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
Frequency(int n, BitSequence *epsilon)
{
int i;
double f, s_obs, p_value, sum, sqrt2 = 1.41421356237309504880;
sum = 0.0;
for ( i=0; i<n; i++ )
sum += 2*(int)epsilon[i]-1;
s_obs = fabs(sum)/sqrt(n);
f = s_obs/sqrt2;
p_value = erfc(f);
// fprintf(stats[TEST_FREQUENCY], "\t\t\t FREQUENCY TEST\n");
// fprintf(stats[TEST_FREQUENCY], "\t\t---------------------------------------------\n");
// fprintf(stats[TEST_FREQUENCY], "\t\tCOMPUTATIONAL INFORMATION:\n");
// fprintf(stats[TEST_FREQUENCY], "\t\t---------------------------------------------\n");
// fprintf(stats[TEST_FREQUENCY], "\t\t(a) The nth partial sum = %d\n", (int)sum);
// fprintf(stats[TEST_FREQUENCY], "\t\t(b) S_n/n = %f\n", sum/n);
// fprintf(stats[TEST_FREQUENCY], "\t\t---------------------------------------------\n");
// fprintf(stats[TEST_FREQUENCY], "%s\t\tp_value = %f\n\n", p_value < ALPHA ? "FAILURE" : "SUCCESS", p_value); fflush(stats[TEST_FREQUENCY]);
// fprintf(results[TEST_FREQUENCY], "%f\n", p_value); fflush(results[TEST_FREQUENCY]);
if (p_value < ALPHA) {
return 0;
} else {
return 1;
}
}

View File

@@ -0,0 +1,667 @@
/*
* file: mp.c
*
* DESCRIPTION
*
* These functions comprise a multi-precision integer arithmetic
* and discrete function package.
*/
#include "include/genutils.h"
#define MAXPLEN 384
/*****************************************
** greater - Test if x > y *
** *
** Returns TRUE (1) if x greater than y, *
** otherwise FALSE (0). *
** *
** Parameters: *
** *
** x Address of array x *
** y Address of array y *
** l Length both x and y in bytes *
** *
******************************************/
int greater(BYTE *x, BYTE *y, int l)
{
int i;
for ( i=0; i<l; i++ )
if ( x[i] != y[i] )
break;
if ( i == l )
return 0;
if ( x[i] > y[i] )
return 1;
return 0;
}
/*****************************************
** less - Test if x < y *
** *
** Returns TRUE (1) if x less than y, *
** otherwise FALSE (0). *
** *
** Parameters: *
** *
** x Address of array x *
** y Address of array y *
** l Length both x and y in bytes *
** *
******************************************/
int less(BYTE *x, BYTE *y, int l)
{
int i;
for ( i=0; i<l; i++ )
if ( x[i] != y[i] )
break;
if ( i == l ) {
return 0;
}
if ( x[i] < y[i] ) {
return 1;
}
return 0;
}
/*****************************************
** bshl - shifts array left *
** by one bit. *
** *
** x = x * 2 *
** *
** Parameters: *
** *
** x Address of array x *
** l Length array x in bytes *
** *
******************************************/
BYTE bshl(BYTE *x, int l)
{
BYTE *p;
int c1, c2;
p = x + l - 1;
c1 = 0;
c2 = 0;
while ( p != x ) {
if ( *p & 0x80 )
c2 = 1;
*p <<= 1; /* shift the word left once (ls bit = 0) */
if ( c1 )
*p |= 1;
c1 = c2;
c2 = 0;
p--;
}
if ( *p & 0x80 )
c2 = 1;
*p <<= 1; /* shift the word left once (ls bit = 0) */
if ( c1 )
*p |= (DIGIT)1;
return (BYTE)c2;
}
/*****************************************
** bshr - shifts array right *
** by one bit. *
** *
** x = x / 2 *
** *
** Parameters: *
** *
** x Address of array x *
** l Length array x in bytes *
** *
******************************************/
void bshr(BYTE *x, int l)
{
BYTE *p;
int c1,c2;
p = x;
c1 = 0;
c2 = 0;
while ( p != x+l-1 ) {
if ( *p & 0x01 )
c2 = 1;
*p >>= 1; /* shift the word right once (ms bit = 0) */
if ( c1 )
*p |= 0x80;
c1 = c2;
c2 = 0;
p++;
}
*p >>= 1; /* shift the word right once (ms bit = 0) */
if ( c1 )
*p |= 0x80;
}
/*****************************************
** Mult - Multiply two integers *
** *
** A = B * C *
** *
** Parameters: *
** *
** A Address of the result *
** B Address of the multiplier *
** C Address of the multiplicand *
** LB Length of B in bytes *
** LC Length of C in bytes *
** *
** NOTE: A MUST be LB+LC in length *
** *
******************************************/
int Mult(BYTE *A, BYTE *B, int LB, BYTE *C, int LC)
{
int i, j, k, LA;
DIGIT result;
LA = LB + LC;
for ( i=LB-1; i>=0; i-- ) {
result = 0;
for ( j=LC-1; j>=0; j-- ) {
k = i+j+1;
result = (DIGIT)A[k] + ((DIGIT)(B[i] * C[j])) + (result >> 8);
A[k] = (BYTE)result;
}
A[--k] = (BYTE)(result >> 8);
}
return 0;
}
void ModSqr(BYTE *A, BYTE *B, int LB, BYTE *M, int LM)
{
Square(A, B, LB);
Mod(A, 2*LB, M, LM);
}
void ModMult(BYTE *A, BYTE *B, int LB, BYTE *C, int LC, BYTE *M, int LM)
{
Mult(A, B, LB, C, LC);
Mod(A, (LB+LC), M, LM);
}
/*****************************************
** smult - Multiply array by a scalar. *
** *
** A = b * C *
** *
** Parameters: *
** *
** A Address of the result *
** b Scalar (1 BYTE) *
** C Address of the multiplicand *
** L Length of C in bytes *
** *
** NOTE: A MUST be L+1 in length *
** *
******************************************/
void smult(BYTE *A, BYTE b, BYTE *C, int L)
{
int i;
DIGIT result;
result = 0;
for ( i=L-1; i>0; i-- ) {
result = A[i] + ((DIGIT)b * C[i]) + (result >> 8);
A[i] = (BYTE)(result & 0xff);
A[i-1] = (BYTE)(result >> 8);
}
}
/*****************************************
** Square() - Square an integer *
** *
** A = B^2 *
** *
** Parameters: *
** *
** A Address of the result *
** B Address of the operand *
** L Length of B in bytes *
** *
** NOTE: A MUST be 2*L in length *
** *
******************************************/
void Square(BYTE *A, BYTE *B, int L)
{
Mult(A, B, L, B, L);
}
/*****************************************
** ModExp - Modular Exponentiation *
** *
** A = B ** C (MOD M) *
** *
** Parameters: *
** *
** A Address of result *
** B Address of mantissa *
** C Address of exponent *
** M Address of modulus *
** LB Length of B in bytes *
** LC Length of C in bytes *
** LM Length of M in bytes *
** *
** NOTE: The integer B must be less *
** than the modulus M. *
** NOTE: A must be at least 3*LM *
** bytes long. However, the *
** result stored in A will be *
** only LM bytes long. *
******************************************/
void ModExp(BYTE *A, BYTE *B, int LB, BYTE *C, int LC, BYTE *M, int LM)
{
BYTE wmask;
int bits;
bits = LC*8;
wmask = 0x80;
A[LM-1] = 1;
while ( !sniff_bit(C,wmask) ) {
wmask >>= 1;
bits--;
if ( !wmask ) {
wmask = 0x80;
C++;
}
}
while ( bits-- ) {
memset(A+LM, 0x00, LM*2);
/* temp = A*A (MOD M) */
ModSqr(A+LM, A,LM, M,LM);
/* A = lower L bytes of temp */
memcpy(A, A+LM*2, LM);
memset(A+LM, 0x00, 2*LM);
if ( sniff_bit(C,wmask) ) {
memset(A+LM, 0x00, (LM+LB));
ModMult(A+LM, B,LB, A,LM, M,LM); /* temp = B * A (MOD M) */
memcpy(A, A+LM+(LM+LB)-LM, LM); /* A = lower LM bytes of temp */
memset(A+LM, 0x00, 2*LM);
}
wmask >>= 1;
if ( !wmask ) {
wmask = 0x80;
C++;
}
}
}
/* DivMod:
*
* computes:
* quot = x / n
* rem = x % n
* returns:
* length of "quot"
*
* len of rem is lenx+1
*/
int DivMod(BYTE *x, int lenx, BYTE *n, int lenn, BYTE *quot, BYTE *rem)
{
BYTE *tx, *tn, *ttx, *ts, bmult[1];
int i, shift, lgth_x, lgth_n, t_len, lenq;
DIGIT tMSn, mult;
unsigned long tMSx;
int underflow;
tx = x;
tn = n;
/* point to the MSD of n */
for ( i=0, lgth_n=lenn; i<lenn; i++, lgth_n-- ) {
if ( *tn )
break;
tn++;
}
if ( !lgth_n )
return 0;
/* point to the MSD of x */
for ( i=0, lgth_x=lenx; i<lenx; i++, lgth_x-- ) {
if ( *tx )
break;
tx++;
}
if ( !lgth_x )
return 0;
if ( lgth_x < lgth_n )
lenq = 1;
else
lenq = lgth_x - lgth_n + 1;
memset(quot, 0x00, lenq);
/* Loop while x > n, WATCH OUT if lgth_x == lgth_n */
while ( (lgth_x > lgth_n) || ((lgth_x == lgth_n) && !less(tx, tn, lgth_n)) ) {
shift = 1;
if ( lgth_n == 1 ) {
if ( *tx < *tn ) {
tMSx = (DIGIT) (((*tx) << 8) | *(tx+1));
tMSn = *tn;
shift = 0;
}
else {
tMSx = *tx;
tMSn = *tn;
}
}
else if ( lgth_n > 1 ) {
tMSx = (DIGIT) (((*tx) << 8) | *(tx+1));
tMSn = (DIGIT) (((*tn) << 8) | *(tn+1));
if ( (tMSx < tMSn) || ((tMSx == tMSn) && less(tx, tn, lgth_n)) ) {
tMSx = (tMSx << 8) | *(tx+2);
shift = 0;
}
}
else {
tMSx = (DIGIT) (((*tx) << 8) | *(tx+1));
tMSn = *tn;
shift = 0;
}
mult = (DIGIT) (tMSx / tMSn);
if ( mult > 0xff )
mult = 0xff;
bmult[0] = mult & 0xff;
ts = rem;
do {
memset(ts, 0x00, lgth_x+1);
Mult(ts, tn, lgth_n, bmult, 1);
underflow = 0;
if ( shift ) {
if ( ts[0] != 0 )
underflow = 1;
else {
for ( i=0; i<lgth_x; i++ )
ts[i] = ts[i+1];
ts[lgth_x] = 0x00;
}
}
if ( greater(ts, tx, lgth_x) || underflow ) {
bmult[0]--;
underflow = 1;
}
else
underflow = 0;
} while ( underflow );
sub(tx, lgth_x, ts, lgth_x);
if ( shift )
quot[lenq - (lgth_x - lgth_n) - 1] = bmult[0];
else
quot[lenq - (lgth_x - lgth_n)] = bmult[0];
ttx = tx;
t_len = lgth_x;
for ( i=0, lgth_x=t_len; i<t_len; i++, lgth_x-- ) {
if ( *ttx )
break;
ttx++;
}
tx = ttx;
}
memset(rem, 0x00, lenn);
if ( lgth_x )
memcpy(rem+lenn-lgth_x, tx, lgth_x);
return lenq;
}
/*
* Mod - Computes an integer modulo another integer
*
* x = x (mod n)
*
*/
void Mod(BYTE *x, int lenx, BYTE *n, int lenn)
{
BYTE quot[MAXPLEN+1], rem[2*MAXPLEN+1];
memset(quot, 0x00, sizeof(quot));
memset(rem, 0x00, sizeof(rem));
if ( DivMod(x, lenx, n, lenn, quot, rem) ) {
memset(x, 0x00, lenx);
memcpy(x+lenx-lenn, rem, lenn);
}
}
/*
* Div - Computes the integer division of two numbers
*
* x = x / n
*
*/
void Div(BYTE *x, int lenx, BYTE *n, int lenn)
{
BYTE quot[MAXPLEN+1], rem[2*MAXPLEN+1];
int lenq;
memset(quot, 0x00, sizeof(quot));
memset(rem, 0x00, sizeof(rem));
if ( (lenq = DivMod(x, lenx, n, lenn, quot, rem)) != 0 ) {
memset(x, 0x00, lenx);
memcpy(x+lenx-lenq, quot, lenq);
}
}
/*****************************************
** sub - Subtract two integers *
** *
** A = A - B *
** *
** *
** Parameters: *
** *
** A Address of subtrahend integer *
** B Address of subtractor integer *
** L Length of A and B in bytes *
** *
** NOTE: In order to save RAM, B is *
** two's complemented twice, *
** rather than using a copy of B *
** *
******************************************/
void sub(BYTE *A, int LA, BYTE *B, int LB)
{
BYTE *tb;
tb = (BYTE *)calloc(LA, 1);
memcpy(tb, B, LB);
negate(tb, LB);
add(A, LA, tb, LA);
FREE(tb);
}
/*****************************************
** negate - Negate an integer *
** *
** A = -A *
** *
** *
** Parameters: *
** *
** A Address of integer to negate *
** L Length of A in bytes *
** *
******************************************/
int negate(BYTE *A, int L)
{
int i, tL;
DIGIT accum;
/* Take one's complement of A */
for ( i=0; i<L; i++ )
A[i] = ~(A[i]);
/* Add one to get two's complement of A */
accum = 1;
tL = L-1;
while ( accum && (tL >= 0) ) {
accum += A[tL];
A[tL--] = (BYTE)(accum & 0xff);
accum = accum >> 8;
}
return accum;
}
/*
* add()
*
* A = A + B
*
* LB must be <= LA
*
*/
BYTE add(BYTE *A, int LA, BYTE *B, int LB)
{
int i, indexA, indexB;
DIGIT accum;
indexA = LA - 1; /* LSD of result */
indexB = LB - 1; /* LSD of B */
accum = 0;
for ( i = 0; i < LB; i++ ) {
accum += A[indexA];
accum += B[indexB--];
A[indexA--] = (BYTE)(accum & 0xff);
accum = accum >> 8;
}
if ( LA > LB )
while ( accum && (indexA >= 0) ) {
accum += A[indexA];
A[indexA--] = (BYTE)(accum & 0xff);
accum = accum >> 8;
}
return (BYTE)accum;
}
void prettyprintBstr(char *S, BYTE *A, int L)
{
int i, extra, ctrb, ctrl;
if ( L == 0 )
printf("%s <empty>", S);
else
printf("%s\n\t", S);
extra = L % 24;
if ( extra ) {
ctrb = 0;
for ( i=0; i<24-extra; i++ ) {
printf(" ");
if ( ++ctrb == 4) {
printf(" ");
ctrb = 0;
}
}
for ( i=0; i<extra; i++ ) {
printf("%02X", A[i]);
if ( ++ctrb == 4) {
printf(" ");
ctrb = 0;
}
}
printf("\n\t");
}
ctrb = ctrl = 0;
for ( i=extra; i<L; i++ ) {
printf("%02X", A[i]);
if ( ++ctrb == 4) {
ctrl++;
if ( ctrl == 6 ) {
printf("\n\t");
ctrl = 0;
}
else
printf(" ");
ctrb = 0;
}
}
printf("\n\n");
}
/**********************************************************************/
/* Performs byte reverse for PC based implementation (little endian) */
/**********************************************************************/
void byteReverse(unsigned long *buffer, int byteCount)
{
unsigned long value;
int count;
byteCount /= sizeof( unsigned long );
for( count = 0; count < byteCount; count++ ) {
value = ( buffer[ count ] << 16 ) | ( buffer[ count ] >> 16 );
buffer[ count ] = ( ( value & 0xFF00FF00L ) >> 8 ) | ( ( value & 0x00FF00FFL ) << 8 );
}
}
void
ahtopb (char *ascii_hex, BYTE *p_binary, int bin_len)
{
BYTE nibble;
int i;
for ( i=0; i<bin_len; i++ ) {
nibble = ascii_hex[i * 2];
if ( nibble > 'F' )
nibble -= 0x20;
if ( nibble > '9' )
nibble -= 7;
nibble -= '0';
p_binary[i] = nibble << 4;
nibble = ascii_hex[i * 2 + 1];
if ( nibble > 'F' )
nibble -= 0x20;
if ( nibble > '9' )
nibble -= 7;
nibble -= '0';
p_binary[i] += nibble;
}
}

View File

@@ -0,0 +1,13 @@
#ifndef _NIST_CEPHES_H_
#define _NIST_CEPHES_H_
double cephes_igamc(double a, double x);
double cephes_igam(double a, double x);
double cephes_lgam(double x);
double cephes_p1evl(double x, double *coef, int N);
double cephes_polevl(double x, double *coef, int N);
double cephes_erf(double x);
double cephes_erfc(double x);
double cephes_normal(double x);
#endif /* _CEPHES_H_ */

View File

@@ -0,0 +1,52 @@
#if defined(__cplusplus)
extern "C" {
#endif
#ifndef _NIST_CONFIG_H_
#define _NIST_CONFIG_H_
#define WINDOWS32
//#define PROTOTYPES
//#define LITTLE_ENDIAN
//#define LOWHI
/*
* AUTO DEFINES (DON'T TOUCH!)
*/
#ifndef CSTRTD
typedef char *CSTRTD;
#endif
#ifndef BSTRTD
typedef unsigned char *BSTRTD;
#endif
#ifndef BYTE
typedef unsigned char BYTE;
#endif
#ifndef UINT
typedef unsigned int UINT;
#endif
#ifndef USHORT
typedef unsigned short USHORT;
#endif
//#ifndef ULONG
//typedef unsigned long ULONG;
//#endif
#ifndef DIGIT
typedef USHORT DIGIT; /* 16-bit word */
#endif
#ifndef DBLWORD
typedef unsigned long DBLWORD; /* 32-bit word */
#endif
#ifndef WORD64
typedef unsigned long WORD64[2]; /* 64-bit word */
#endif
#endif /* _CONFIG_H_ */
#if defined(__cplusplus)
}
#endif

View File

@@ -0,0 +1,24 @@
#ifndef _NIST_DECLS_H_
#define _NIST_DECLS_H_
#include <stdio.h>
#include "defs.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
G L O B A L D A T A S T R U C T U R E S
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BitSequence *epsilon; // BIT STREAM
TP tp; // TEST PARAMETER STRUCTURE
FILE *stats[NUMOFTESTS+1]; // FILE OUTPUT STREAM
FILE *results[NUMOFTESTS+1]; // FILE OUTPUT STREAM
FILE *freqfp; // FILE OUTPUT STREAM
FILE *summary; // FILE OUTPUT STREAM
int testVector[NUMOFTESTS+1];
char generatorDir[NUMOFGENERATORS][20] = { "AlgorithmTesting", "LCG", "QCG1", "QCG2","CCG", "XOR",
"MODEXP", "BBS", "MS", "G-SHA1" };
#endif

View File

@@ -0,0 +1,73 @@
#ifndef _NIST_DEFS_H_
#define _NIST_DEFS_H_
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
D E B U G G I N G A I D E S
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "config.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
M A C R O S
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#define MAX(x,y) ((x) < (y) ? (y) : (x))
#define MIN(x,y) ((x) > (y) ? (y) : (x))
#define isNonPositive(x) ((x) <= 0.e0 ? 1 : 0)
#define isPositive(x) ((x) > 0.e0 ? 1 : 0)
#define isNegative(x) ((x) < 0.e0 ? 1 : 0)
#define isGreaterThanOne(x) ((x) > 1.e0 ? 1 : 0)
#define isZero(x) ((x) == 0.e0 ? 1 : 0)
#define isOne(x) ((x) == 1.e0 ? 1 : 0)
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
G L O B A L C O N S T A N T S
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#define ALPHA 0.01 /* SIGNIFICANCE LEVEL */
#define MAXNUMOFTEMPLATES 148 /* APERIODIC TEMPLATES: 148=>temp_length=9 */
#define NUMOFGENERATORS 10 /* MAX PRNGs */
#define MAXFILESPERMITTEDFORPARTITION 148
#define TEST_FREQUENCY 1
#define TEST_BLOCK_FREQUENCY 2
#define TEST_CUSUM 3
#define TEST_RUNS 4
#define TEST_LONGEST_RUN 5
#define TEST_RANK 6
#define TEST_FFT 7
#define TEST_NONPERIODIC 8
#define TEST_OVERLAPPING 9
#define TEST_UNIVERSAL 10
#define TEST_APEN 11
#define TEST_RND_EXCURSION 12
#define TEST_RND_EXCURSION_VAR 13
#define TEST_SERIAL 14
#define TEST_LINEARCOMPLEXITY 15
#define TEST_POKER_DETECT 16
#define TEST_RUNS_DISTRIBUTION 17
#define TEST_BIN_DERIVATE 18
#define TEST_SELF_CORR 19
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
G L O B A L D A T A S T R U C T U R E S
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
typedef unsigned char BitSequence;
typedef struct _testParameters {
int n;
int blockFrequencyBlockLength;
int nonOverlappingTemplateBlockLength;
int overlappingTemplateBlockLength;
int serialBlockLength;
int linearComplexitySequenceLength;
int approximateEntropyBlockLength;
int PokerDetectMLength;
int BinaryDerivateKLength;
int SelfCorrelationDLength;
int numOfBitStreams;
} TP;
#endif

View File

@@ -0,0 +1,21 @@
#ifndef _NIST_EXTERNS_H_
#define _NIST_EXTERNS_H_
#include "defs.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
G L O B A L D A T A S T R U C T U R E S
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//extern BitSequence *epsilon; // BIT STREAM
//extern TP tp; // TEST PARAMETER STRUCTURE
//extern FILE *stats[NUMOFTESTS+1]; // FILE OUTPUT STREAM
//extern FILE *results[NUMOFTESTS+1]; // FILE OUTPUT STREAM
//extern FILE *freqfp; // FILE OUTPUT STREAM
//extern FILE *summary; // FILE OUTPUT STREAM
//extern int testVector[NUMOFTESTS+1];
//
//extern char generatorDir[NUMOFGENERATORS][20];
//extern char testNames[NUMOFTESTS+1][32];
#endif

View File

@@ -0,0 +1,78 @@
#ifndef _NIST_GENERATORS_H_
#define _NIST_GENERATORS_H_
/* The circular shifts. */
#define CS1(x) ((((ULONG)x)<<1)|(((ULONG)x)>>31))
#define CS5(x) ((((ULONG)x)<<5)|(((ULONG)x)>>27))
#define CS30(x) ((((ULONG)x)<<30)|(((ULONG)x)>>2))
/* K constants */
#define K0 0x5a827999L
#define K1 0x6ed9eba1L
#define K2 0x8f1bbcdcL
#define K3 0xca62c1d6L
#define f1(x,y,z) ( (x & (y ^ z)) ^ z )
#define f3(x,y,z) ( (x & ( y ^ z )) ^ (z & y) )
#define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */
#define expand(x) Wbuff[x%16] = CS1(Wbuff[(x - 3)%16 ] ^ Wbuff[(x - 8)%16 ] ^ Wbuff[(x - 14)%16] ^ Wbuff[x%16])
#define sub1Round1(count) { \
temp = CS5(A) + f1(B, C, D) + E + Wbuff[count] + K0; \
E = D; \
D = C; \
C = CS30( B ); \
B = A; \
A = temp; \
} \
#define sub2Round1(count) \
{ \
expand(count); \
temp = CS5(A) + f1(B, C, D) + E + Wbuff[count%16] + K0; \
E = D; \
D = C; \
C = CS30( B ); \
B = A; \
A = temp; \
} \
#define Round2(count) \
{ \
expand(count); \
temp = CS5( A ) + f2( B, C, D ) + E + Wbuff[count%16] + K1; \
E = D; \
D = C; \
C = CS30( B ); \
B = A; \
A = temp; \
} \
#define Round3(count) \
{ \
expand(count); \
temp = CS5( A ) + f3( B, C, D ) + E + Wbuff[count%16] + K2; \
E = D; \
D = C; \
C = CS30( B ); \
B = A; \
A = temp; \
}
#define Round4(count) \
{ \
expand(count); \
temp = CS5( A ) + f2( B, C, D ) + E + Wbuff[count%16] + K3; \
E = D; \
D = C; \
C = CS30( B ); \
B = A; \
A = temp; \
}
#endif

View File

@@ -0,0 +1,47 @@
#ifndef _NIST_GENUTILS_H_
#define _NIST_GENUTILS_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
typedef struct _MP_struct {
int size; /* in bytes */
int bitlen; /* in bits, duh */
BYTE *val;
} MP;
#define FREE(A) if ( (A) ) { free((A)); (A) = NULL; }
#define ASCII2BIN(ch) ( (((ch) >= '0') && ((ch) <= '9')) ? ((ch) - '0') : (((ch) >= 'A') && ((ch) <= 'F')) ? ((ch) - 'A' + 10) : ((ch) - 'a' + 10) )
#ifndef EXPWD
#define EXPWD ((DBLWORD)1<<NUMLEN)
#endif
#define sniff_bit(ptr,mask) (*(ptr) & mask)
/*
* Function Declarations
*/
int greater(BYTE *x, BYTE *y, int l);
int less(BYTE *x, BYTE *y, int l);
BYTE bshl(BYTE *x, int l);
void bshr(BYTE *x, int l);
int Mult(BYTE *A, BYTE *B, int LB, BYTE *C, int LC);
void ModSqr(BYTE *A, BYTE *B, int LB, BYTE *M, int LM);
void ModMult(BYTE *A, BYTE *B, int LB, BYTE *C, int LC, BYTE *M, int LM);
void smult(BYTE *A, BYTE b, BYTE *C, int L);
void Square(BYTE *A, BYTE *B, int L);
void ModExp(BYTE *A, BYTE *B, int LB, BYTE *C, int LC, BYTE *M, int LM);
int DivMod(BYTE *x, int lenx, BYTE *n, int lenn, BYTE *quot, BYTE *rem);
void Mod(BYTE *x, int lenx, BYTE *n, int lenn);
void Div(BYTE *x, int lenx, BYTE *n, int lenn);
void sub(BYTE *A, int LA, BYTE *B, int LB);
int negate(BYTE *A, int L);
BYTE add(BYTE *A, int LA, BYTE *B, int LB);
void prettyprintBstr(char *S, BYTE *A, int L);
void byteReverse(unsigned long *buffer, int byteCount);
void ahtopb (char *ascii_hex, BYTE *p_binary, int bin_len);
#endif /* _GENUTILS_H_ */

View File

@@ -0,0 +1,18 @@
#ifndef _NIST_MATRIX_H_
#define _NIST_MATRIX_H_
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
R A N K A L G O R I T H M F U N C T I O N P R O T O T Y P E S
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int computeRank(int M, int Q, BitSequence **matrix);
void perform_elementary_row_operations(int flag, int i, int M, int Q, BitSequence **A);
int find_unit_element_and_swap(int flag, int i, int M, int Q, BitSequence **A);
int swap_rows(int i, int index, int Q, BitSequence **A);
int determine_rank(int m, int M, int Q, BitSequence **A);
BitSequence** create_matrix(int M, int Q);
void display_matrix(int M, int Q, BitSequence **m);
void def_matrix(int M, int Q, BitSequence **m, int k, BitSequence *epsilon);
void delete_matrix(int M, BitSequence **matrix);
#endif

View File

@@ -0,0 +1,166 @@
#ifndef _STAT_FNCS_H_
#define _STAT_FNCS_H_
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
S T A T I S T I C A L T E S T F U N C T I O N P R O T O T Y P E S
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "defs.h"
/**
*
* @param in
* @param inl
* @param out 外部预先分配缓冲区缓冲区大小因最少为字节数的8倍
* @param outbufsize
* @return
*/
int BytesToBitSequence(unsigned char *in, int inl, BitSequence *outbuf, int bufsize);
/**
* 单比特频数检测
* @param n
* @return
*/
int Frequency(int n, BitSequence *epsilon);
/**
* 块内频数检测
* @param M
* @param n
* @return
*/
int BlockFrequency(int M, int n, BitSequence *epsilon);
/**
* 累加和检测
* @param n
* @return
*/
int CumulativeSums(int n, BitSequence *epsilon);
/**
* 游程总数检测
* @param n
* @return
*/
int Runs(int n, BitSequence *epsilon);
/**
* 块内最大“1”游程检测
* @param n
* @return
*/
int LongestRunOfOnes(int n, BitSequence *epsilon);
/**
* 矩阵秩检测
* @param n
* @return
*/
int Rank(int n, BitSequence *epsilon);
/**
* 离散傅立叶检测
* @param n
* @return
*/
int DiscreteFourierTransform(int n, BitSequence *epsilon);
/**
* 非重叠模版匹配测试
* @param m
* @param n
* @return
*/
int NonOverlappingTemplateMatchings(int m, int n, BitSequence *epsilon);
/**
* 重叠模版匹配测试
* @param m
* @param n
* @return
*/
int OverlappingTemplateMatchings(int m, int n, BitSequence *epsilon);
/**
* 通用统计检测
* @param n
* @return
*/
int Universal(int n, BitSequence *epsilon);
/**
* 近似熵检测
* @param m
* @param n
* @return
*/
int ApproximateEntropy(int m, int n, BitSequence *epsilon);
/**
* 自由游程测试
* @param n
* @return
*/
int RandomExcursions(int n, BitSequence *epsilon);
/**
* 自由变量测试
* @param n
* @return
*/
int RandomExcursionsVariant(int n, BitSequence *epsilon);
/**
* 线性复杂度检测
* @param M
* @param n
* @return
*/
int LinearComplexity(int M, int n, BitSequence *epsilon);
/**
* 重叠子序列检测
* @param m
* @param n
* @return
*/
int Serial(int m, int n, BitSequence *epsilon);
/**
* 二元推导检测
* @param k
* @param n
* @param epsilon
* @return
*/
int BinaryDerivate(int k, int n, BitSequence *epsilon, int epsilon_l);
/**
* 自相关测试
* @param d
* @param n
* @param epsilon
* @return
*/
int SelfCorrelation(int d, int n, BitSequence *epsilon);
/**
* 扑克检测
* @param M
* @param n
* @param epsilon
* @return
*/
int PokerDetect(int M, int n, BitSequence *epsilon);
/**
* 游程分布检测
* @param n
* @param epsilon
* @return
*/
int RunsDistribution(int n, BitSequence *epsilon);
#endif

View File

@@ -0,0 +1,4 @@
#include "include/config.h"
#include "include/defs.h"
int convertToBits(BYTE *x, int xBitLength, int bitsNeeded, int *num_0s, int *num_1s, int *bitsRead, BitSequence* epsilon);

View File

@@ -0,0 +1,135 @@
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "include/externs.h"
#include "include/cephes.h"
int
LinearComplexity(int M, int n, BitSequence *epsilon)
{
int i, ii, j, d, N, L, m, N_, parity, sign, K = 6;
double p_value, T_, mean, nu[7], chi2;
const double pi[7] = { 0.01047, 0.03125, 0.12500, 0.50000, 0.25000, 0.06250, 0.020833 };
BitSequence *T, *P, *B_, *C;
N = (int)floor(n/M);
if ( ((B_ = (BitSequence *) calloc(M, sizeof(BitSequence))) == NULL) ||
((C = (BitSequence *) calloc(M, sizeof(BitSequence))) == NULL) ||
((P = (BitSequence *) calloc(M, sizeof(BitSequence))) == NULL) ||
((T = (BitSequence *) calloc(M, sizeof(BitSequence))) == NULL) ) {
printf("Insufficient Memory for Work Space:: Linear Complexity Test\n");
if ( B_!= NULL )
free(B_);
if ( C != NULL )
free(C);
if ( P != NULL )
free(P);
if ( T != NULL )
free(T);
return 0;
}
// fprintf(stats[TEST_LINEARCOMPLEXITY], "-----------------------------------------------------\n");
// fprintf(stats[TEST_LINEARCOMPLEXITY], "\tL I N E A R C O M P L E X I T Y\n");
// fprintf(stats[TEST_LINEARCOMPLEXITY], "-----------------------------------------------------\n");
// fprintf(stats[TEST_LINEARCOMPLEXITY], "\tM (substring length) = %d\n", M);
// fprintf(stats[TEST_LINEARCOMPLEXITY], "\tN (number of substrings) = %d\n", N);
// fprintf(stats[TEST_LINEARCOMPLEXITY], "-----------------------------------------------------\n");
// fprintf(stats[TEST_LINEARCOMPLEXITY], " F R E Q U E N C Y \n");
// fprintf(stats[TEST_LINEARCOMPLEXITY], "-----------------------------------------------------\n");
// fprintf(stats[TEST_LINEARCOMPLEXITY], " C0 C1 C2 C3 C4 C5 C6 CHI2 P-value\n");
// fprintf(stats[TEST_LINEARCOMPLEXITY], "-----------------------------------------------------\n");
// fprintf(stats[TEST_LINEARCOMPLEXITY], "\tNote: %d bits were discarded!\n", n%M);
for ( i=0; i<K+1; i++ )
nu[i] = 0.00;
for ( ii=0; ii<N; ii++ ) {
for ( i=0; i<M; i++ ) {
B_[i] = 0;
C[i] = 0;
T[i] = 0;
P[i] = 0;
}
L = 0;
m = -1;
d = 0;
C[0] = 1;
B_[0] = 1;
/* DETERMINE LINEAR COMPLEXITY */
N_ = 0;
while ( N_ < M ) {
d = (int)epsilon[ii*M+N_];
for ( i=1; i<=L; i++ )
d += C[i] * epsilon[ii*M+N_-i];
d = d%2;
if ( d == 1 ) {
for ( i=0; i<M; i++ ) {
T[i] = C[i];
P[i] = 0;
}
for ( j=0; j<M; j++ )
if ( B_[j] == 1 )
P[j+N_-m] = 1;
for ( i=0; i<M; i++ )
C[i] = (C[i] + P[i])%2;
if ( L <= N_/2 ) {
L = N_ + 1 - L;
m = N_;
for ( i=0; i<M; i++ )
B_[i] = T[i];
}
}
N_++;
}
if ( (parity = (M+1)%2) == 0 )
sign = -1;
else
sign = 1;
mean = M/2.0 + (9.0+sign)/36.0 - 1.0/pow(2, M) * (M/3.0 + 2.0/9.0);
if ( (parity = M%2) == 0 )
sign = 1;
else
sign = -1;
T_ = sign * (L - mean) + 2.0/9.0;
if ( T_ <= -2.5 )
nu[0]++;
else if ( T_ <= -1.5 )
nu[1]++;
else if (T_ <= -0.5 )
nu[2]++;
else if ( T_ <= 0.5 )
nu[3]++;
else if ( T_ <= 1.5 )
nu[4]++;
else if (T_ <= 2.5 )
nu[5]++;
else
nu[6]++;
}
chi2 = 0.00;
// for ( i=0; i<K+1; i++ ) {
// fprintf(stats[TEST_LINEARCOMPLEXITY], "%4d ", (int) nu[i]);
// }
for ( i=0; i<K+1; i++ ) {
chi2 += pow(nu[i] - N * pi[i], 2) / (N * pi[i]);
}
p_value = cephes_igamc(K/2.0, chi2/2.0);
// fprintf(stats[TEST_LINEARCOMPLEXITY], "%9.6f%9.6f\n", chi2, p_value); fflush(stats[TEST_LINEARCOMPLEXITY]);
// fprintf(results[TEST_LINEARCOMPLEXITY], "%f\n", p_value); fflush(results[TEST_LINEARCOMPLEXITY]);
free(B_);
free(P);
free(C);
free(T);
if (p_value < ALPHA) {
return 0;
} else {
return 1;
}
}

View File

@@ -0,0 +1,125 @@
/* got rid of unused 'k' */
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "include/externs.h"
#include "include/cephes.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
L O N G E S T R U N S T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
LongestRunOfOnes(int n, BitSequence *epsilon)
{
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 0;
}
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");
return 0;
}
// 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]);
if (pval < ALPHA) {
return 0;
} else {
return 1;
}
}

View File

@@ -0,0 +1,170 @@
#include <stdio.h>
#include <stdlib.h>
#include "include/externs.h"
#include "include/matrix.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
R A N K A L G O R I T H M R O U T I N E S
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#define MATRIX_FORWARD_ELIMINATION 0
#define MATRIX_BACKWARD_ELIMINATION 1
int
computeRank(int M, int Q, BitSequence **matrix)
{
int i, rank, m=MIN(M,Q);
/* FORWARD APPLICATION OF ELEMENTARY ROW OPERATIONS */
for ( i=0; i<m-1; i++ ) {
if ( matrix[i][i] == 1 )
perform_elementary_row_operations(MATRIX_FORWARD_ELIMINATION, i, M, Q, matrix);
else { /* matrix[i][i] = 0 */
if ( find_unit_element_and_swap(MATRIX_FORWARD_ELIMINATION, i, M, Q, matrix) == 1 )
perform_elementary_row_operations(MATRIX_FORWARD_ELIMINATION, i, M, Q, matrix);
}
}
/* BACKWARD APPLICATION OF ELEMENTARY ROW OPERATIONS */
for ( i=m-1; i>0; i-- ) {
if ( matrix[i][i] == 1 )
perform_elementary_row_operations(MATRIX_BACKWARD_ELIMINATION, i, M, Q, matrix);
else { /* matrix[i][i] = 0 */
if ( find_unit_element_and_swap(MATRIX_BACKWARD_ELIMINATION, i, M, Q, matrix) == 1 )
perform_elementary_row_operations(MATRIX_BACKWARD_ELIMINATION, i, M, Q, matrix);
}
}
rank = determine_rank(m, M, Q, matrix);
return rank;
}
void
perform_elementary_row_operations(int flag, int i, int M, int Q, BitSequence **A)
{
int j, k;
if ( flag == MATRIX_FORWARD_ELIMINATION ) {
for ( j=i+1; j<M; j++ )
if ( A[j][i] == 1 )
for ( k=i; k<Q; k++ )
A[j][k] = (A[j][k] + A[i][k]) % 2;
}
else {
for ( j=i-1; j>=0; j-- )
if ( A[j][i] == 1 )
for ( k=0; k<Q; k++ )
A[j][k] = (A[j][k] + A[i][k]) % 2;
}
}
int
find_unit_element_and_swap(int flag, int i, int M, int Q, BitSequence **A)
{
int index, row_op=0;
if ( flag == MATRIX_FORWARD_ELIMINATION ) {
index = i+1;
while ( (index < M) && (A[index][i] == 0) )
index++;
if ( index < M )
row_op = swap_rows(i, index, Q, A);
}
else {
index = i-1;
while ( (index >= 0) && (A[index][i] == 0) )
index--;
if ( index >= 0 )
row_op = swap_rows(i, index, Q, A);
}
return row_op;
}
int
swap_rows(int i, int index, int Q, BitSequence **A)
{
int p;
BitSequence temp;
for ( p=0; p<Q; p++ ) {
temp = A[i][p];
A[i][p] = A[index][p];
A[index][p] = temp;
}
return 1;
}
int
determine_rank(int m, int M, int Q, BitSequence **A)
{
int i, j, rank, allZeroes;
/* DETERMINE RANK, THAT IS, COUNT THE NUMBER OF NONZERO ROWS */
rank = m;
for ( i=0; i<M; i++ ) {
allZeroes = 1;
for ( j=0; j<Q; j++) {
if ( A[i][j] == 1 ) {
allZeroes = 0;
break;
}
}
if ( allZeroes == 1 )
rank--;
}
return rank;
}
BitSequence**
create_matrix(int M, int Q)
{
int i;
BitSequence **matrix;
if ( (matrix = (BitSequence **) calloc(M, sizeof(BitSequence *))) == NULL ) {
printf("ERROR IN FUNCTION create_matrix: Insufficient memory available.\n");
return NULL;
}
else {
for ( i=0; i<M; i++ ) {
if ( (matrix[i] = calloc(Q, sizeof(BitSequence))) == NULL ) {
printf("ERROR IN FUNCTION create_matrix: Insufficient memory for %dx%d matrix.\n", M, M);
return NULL;
}
}
return matrix;
}
}
void
def_matrix(int M, int Q, BitSequence **m, int k, BitSequence *epsilon)
{
int i,j;
for ( i=0; i<M; i++ )
for ( j=0; j<Q; j++ )
m[i][j] = epsilon[k*(M*Q)+j+i*M];
}
void
delete_matrix(int M, BitSequence **matrix)
{
int i;
if (matrix != NULL) {
for (i = 0; i < M; i++) {
if (matrix[i] != NULL) {
free(matrix[i]);
matrix[i] = NULL;
}
}
free(matrix);
}
}

View File

@@ -0,0 +1,114 @@
#include <stdlib.h>
#include "include/utilities.h"
#include "include/stat_fncs.h"
#include "mesa_sts.h"
int mesa_statistical_test_suite(void* data,unsigned int datalen, struct sts_result* result, unsigned int random_judge_switch_flag)
{
TP tp;
tp.n = datalen;
tp.blockFrequencyBlockLength = 128;
tp.nonOverlappingTemplateBlockLength = 9;
tp.overlappingTemplateBlockLength = 9;
tp.approximateEntropyBlockLength = 10;
tp.serialBlockLength = 16;
tp.linearComplexitySequenceLength = 500;
tp.numOfBitStreams = 1;
tp.PokerDetectMLength = 8;
tp.BinaryDerivateKLength = 3;
tp.SelfCorrelationDLength = 8;
BitSequence* epsilon = (BitSequence *)calloc(tp.n,sizeof(BitSequence));
int done, num_0s, num_1s, bitsRead;
num_0s = 0;
num_1s = 0;
bitsRead = 0;
done = 0;
done = convertToBits((BYTE*)data,datalen,tp.n,&num_0s,&num_1s,&bitsRead,epsilon);
if (STS_TEST_FLAG(random_judge_switch_flag, STS_FREQUENCY))
{
result->frequency = Frequency(tp.n,epsilon);
}
if (STS_TEST_FLAG(random_judge_switch_flag, STS_BLOCK_FREQUENCY))
{
result->block_frequency = BlockFrequency(tp.blockFrequencyBlockLength, tp.n,epsilon);
}
if (STS_TEST_FLAG(random_judge_switch_flag, STS_CUMULATIVE_SUMS))
{
result->cumulative_sums = CumulativeSums(tp.n,epsilon);
}
if (STS_TEST_FLAG(random_judge_switch_flag, STS_RUNS))
{
result->runs = Runs(tp.n,epsilon);
}
if (STS_TEST_FLAG(random_judge_switch_flag, STS_LONGEST_RUN))
{
result->longest_run = LongestRunOfOnes(tp.n,epsilon);
}
if (STS_TEST_FLAG(random_judge_switch_flag, STS_RANK))
{
result->rank = Rank(tp.n,epsilon);
}
//result->discrete_fourier_transform = DiscreteFourierTransform(tp.n,epsilon);//cost too much time
if (STS_TEST_FLAG(random_judge_switch_flag, STS_NON_OVERLAPPING_TEMPLATE_MATCHING))
{
result->non_overlapping_template_matching = NonOverlappingTemplateMatchings(tp.nonOverlappingTemplateBlockLength, tp.n,epsilon);
}
if (STS_TEST_FLAG(random_judge_switch_flag, STS_OVERLAPPING_TEMPLATE_MATCHING))
{
result->overlapping_template_matching = OverlappingTemplateMatchings(tp.overlappingTemplateBlockLength, tp.n,epsilon);
}
if (STS_TEST_FLAG(random_judge_switch_flag, STS_UNIVERSAL))
{
result->universal = Universal(tp.n,epsilon);
}
//result->approximate_entropy = ApproximateEntropy(tp.approximateEntropyBlockLength, tp.n,epsilon);//cost too much time
if (STS_TEST_FLAG(random_judge_switch_flag, STS_RANDOM_EXCURSIONS))
{
result->random_excursions = RandomExcursions(tp.n,epsilon);
}
if (STS_TEST_FLAG(random_judge_switch_flag, STS_RANDOM_EXCURSIONS_VARIANT))
{
result->random_excursions_variant = RandomExcursionsVariant(tp.n,epsilon);
}
//result->serial = Serial(tp.serialBlockLength,tp.n,epsilon);//cost too much time
//sresult->linear_complexity = LinearComplexity(tp.linearComplexitySequenceLength, tp.n,epsilon);//cost too much time
if (STS_TEST_FLAG(random_judge_switch_flag, STS_POKER_DETECT))
{
result->poker_detect = PokerDetect(tp.PokerDetectMLength,tp.n,epsilon);
}
if (STS_TEST_FLAG(random_judge_switch_flag, STS_RUNS_DISTRIBUTION))
{
result->runs_distribution = RunsDistribution(tp.n,epsilon);
}
if (STS_TEST_FLAG(random_judge_switch_flag, STS_SELF_CORRELATION))
{
result->self_correlation = SelfCorrelation(tp.SelfCorrelationDLength,tp.n,epsilon);
}
if (STS_TEST_FLAG(random_judge_switch_flag, STS_BINARY_DERIVATE))
{
result->binary_derivative = BinaryDerivate(tp.BinaryDerivateKLength,tp.n,epsilon,tp.n);//this function will change the value of epsilon, must be the last one
}
free(epsilon);
epsilon = NULL;
return 0;
}

View File

@@ -0,0 +1,281 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "include/externs.h"
#include "include/cephes.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
N O N O V E R L A P P I N G T E M P L A T E T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static unsigned int template9[] = {
0,0,0,0,0,0,0,0,1,
0,0,0,0,0,0,0,1,1,
0,0,0,0,0,0,1,0,1,
0,0,0,0,0,0,1,1,1,
0,0,0,0,0,1,0,0,1,
0,0,0,0,0,1,0,1,1,
0,0,0,0,0,1,1,0,1,
0,0,0,0,0,1,1,1,1,
0,0,0,0,1,0,0,0,1,
0,0,0,0,1,0,0,1,1,
0,0,0,0,1,0,1,0,1,
0,0,0,0,1,0,1,1,1,
0,0,0,0,1,1,0,0,1,
0,0,0,0,1,1,0,1,1,
0,0,0,0,1,1,1,0,1,
0,0,0,0,1,1,1,1,1,
0,0,0,1,0,0,0,1,1,
0,0,0,1,0,0,1,0,1,
0,0,0,1,0,0,1,1,1,
0,0,0,1,0,1,0,0,1,
0,0,0,1,0,1,0,1,1,
0,0,0,1,0,1,1,0,1,
0,0,0,1,0,1,1,1,1,
0,0,0,1,1,0,0,1,1,
0,0,0,1,1,0,1,0,1,
0,0,0,1,1,0,1,1,1,
0,0,0,1,1,1,0,0,1,
0,0,0,1,1,1,0,1,1,
0,0,0,1,1,1,1,0,1,
0,0,0,1,1,1,1,1,1,
0,0,1,0,0,0,0,1,1,
0,0,1,0,0,0,1,0,1,
0,0,1,0,0,0,1,1,1,
0,0,1,0,0,1,0,1,1,
0,0,1,0,0,1,1,0,1,
0,0,1,0,0,1,1,1,1,
0,0,1,0,1,0,0,1,1,
0,0,1,0,1,0,1,0,1,
0,0,1,0,1,0,1,1,1,
0,0,1,0,1,1,0,1,1,
0,0,1,0,1,1,1,0,1,
0,0,1,0,1,1,1,1,1,
0,0,1,1,0,0,1,0,1,
0,0,1,1,0,0,1,1,1,
0,0,1,1,0,1,0,1,1,
0,0,1,1,0,1,1,0,1,
0,0,1,1,0,1,1,1,1,
0,0,1,1,1,0,1,0,1,
0,0,1,1,1,0,1,1,1,
0,0,1,1,1,1,0,1,1,
0,0,1,1,1,1,1,0,1,
0,0,1,1,1,1,1,1,1,
0,1,0,0,0,0,0,1,1,
0,1,0,0,0,0,1,1,1,
0,1,0,0,0,1,0,1,1,
0,1,0,0,0,1,1,1,1,
0,1,0,0,1,0,0,1,1,
0,1,0,0,1,0,1,1,1,
0,1,0,0,1,1,0,1,1,
0,1,0,0,1,1,1,1,1,
0,1,0,1,0,0,0,1,1,
0,1,0,1,0,0,1,1,1,
0,1,0,1,0,1,0,1,1,
0,1,0,1,0,1,1,1,1,
0,1,0,1,1,0,0,1,1,
0,1,0,1,1,0,1,1,1,
0,1,0,1,1,1,0,1,1,
0,1,0,1,1,1,1,1,1,
0,1,1,0,0,0,1,1,1,
0,1,1,0,0,1,1,1,1,
0,1,1,0,1,0,1,1,1,
0,1,1,0,1,1,1,1,1,
0,1,1,1,0,1,1,1,1,
0,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,
1,0,0,0,1,0,0,0,0,
1,0,0,1,0,0,0,0,0,
1,0,0,1,0,1,0,0,0,
1,0,0,1,1,0,0,0,0,
1,0,0,1,1,1,0,0,0,
1,0,1,0,0,0,0,0,0,
1,0,1,0,0,0,1,0,0,
1,0,1,0,0,1,0,0,0,
1,0,1,0,0,1,1,0,0,
1,0,1,0,1,0,0,0,0,
1,0,1,0,1,0,1,0,0,
1,0,1,0,1,1,0,0,0,
1,0,1,0,1,1,1,0,0,
1,0,1,1,0,0,0,0,0,
1,0,1,1,0,0,1,0,0,
1,0,1,1,0,1,0,0,0,
1,0,1,1,0,1,1,0,0,
1,0,1,1,1,0,0,0,0,
1,0,1,1,1,0,1,0,0,
1,0,1,1,1,1,0,0,0,
1,0,1,1,1,1,1,0,0,
1,1,0,0,0,0,0,0,0,
1,1,0,0,0,0,0,1,0,
1,1,0,0,0,0,1,0,0,
1,1,0,0,0,1,0,0,0,
1,1,0,0,0,1,0,1,0,
1,1,0,0,1,0,0,0,0,
1,1,0,0,1,0,0,1,0,
1,1,0,0,1,0,1,0,0,
1,1,0,0,1,1,0,0,0,
1,1,0,0,1,1,0,1,0,
1,1,0,1,0,0,0,0,0,
1,1,0,1,0,0,0,1,0,
1,1,0,1,0,0,1,0,0,
1,1,0,1,0,1,0,0,0,
1,1,0,1,0,1,0,1,0,
1,1,0,1,0,1,1,0,0,
1,1,0,1,1,0,0,0,0,
1,1,0,1,1,0,0,1,0,
1,1,0,1,1,0,1,0,0,
1,1,0,1,1,1,0,0,0,
1,1,0,1,1,1,0,1,0,
1,1,0,1,1,1,1,0,0,
1,1,1,0,0,0,0,0,0,
1,1,1,0,0,0,0,1,0,
1,1,1,0,0,0,1,0,0,
1,1,1,0,0,0,1,1,0,
1,1,1,0,0,1,0,0,0,
1,1,1,0,0,1,0,1,0,
1,1,1,0,0,1,1,0,0,
1,1,1,0,1,0,0,0,0,
1,1,1,0,1,0,0,1,0,
1,1,1,0,1,0,1,0,0,
1,1,1,0,1,0,1,1,0,
1,1,1,0,1,1,0,0,0,
1,1,1,0,1,1,0,1,0,
1,1,1,0,1,1,1,0,0,
1,1,1,1,0,0,0,0,0,
1,1,1,1,0,0,0,1,0,
1,1,1,1,0,0,1,0,0,
1,1,1,1,0,0,1,1,0,
1,1,1,1,0,1,0,0,0,
1,1,1,1,0,1,0,1,0,
1,1,1,1,0,1,1,0,0,
1,1,1,1,0,1,1,1,0,
1,1,1,1,1,0,0,0,0,
1,1,1,1,1,0,0,1,0,
1,1,1,1,1,0,1,0,0,
1,1,1,1,1,0,1,1,0,
1,1,1,1,1,1,0,0,0,
1,1,1,1,1,1,0,1,0,
1,1,1,1,1,1,1,0,0,
1,1,1,1,1,1,1,1,0,
};
static size_t template_size = sizeof(template9)/sizeof(template9[0]);
int
NonOverlappingTemplateMatchings(int m, int n, BitSequence *epsilon)
{
int ret = 0;
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 W_obs, nu[6], *Wj = NULL;
size_t template_idx = 0;
double sum, chi2, p_value, lambda, pi[6], varWj;
int i, j, jj, k, match, SKIP, M, N, K = 5;
BitSequence *sequence = NULL;
N = 8;
M = n/N;
if ( (Wj = (unsigned int*)calloc(N, sizeof(unsigned int))) == NULL ) {
return 0;
}
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));
if ( ((isNegative(lambda)) || (isZero(lambda))) ||
((sequence = (BitSequence *) calloc(m, sizeof(BitSequence))) == NULL) ) {
goto end;
}
else {
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++ ) {
if (template_idx < template_size) {
sequence[k] = template9[template_idx];
template_idx++;
}
else {
sequence[k] = 0;
}
// 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");
goto end;
}
// fprintf(stats[TEST_NONPERIODIC], "%9.6f %f %s %3d\n", chi2, p_value, p_value < ALPHA ? "FAILURE" : "SUCCESS", jj);
if ( SKIP > 1 )
template_idx += (SKIP-1)*2*m;
// fprintf(results[TEST_NONPERIODIC], "%f\n", p_value); fflush(results[TEST_NONPERIODIC]);
if (p_value < ALPHA) {
goto end;
}
}
}
ret = 1;
// fprintf(stats[TEST_NONPERIODIC], "\n"); fflush(stats[TEST_NONPERIODIC]);
end:
if (Wj != NULL) {
free(Wj);
}
if (sequence != NULL) {
free(sequence);
}
return ret;
}

View File

@@ -0,0 +1,97 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "include/externs.h"
#include "include/cephes.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
O V E R L A P P I N G T E M P L A T E T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
double Pr(int u, double eta);
int
OverlappingTemplateMatchings(int m, int n, BitSequence *epsilon)
{
int ret = 0;
int i, k, match;
double W_obs, eta, sum, chi2, p_value, lambda;
int M, N, j, K = 5;
unsigned int nu[6] = { 0, 0, 0, 0, 0, 0 };
double pi[6] = { 0.143783, 0.139430, 0.137319, 0.124314, 0.106209, 0.348945 };
BitSequence *sequence;
M = 1032;
N = n/M;
if ( (sequence = (BitSequence *) calloc(m, sizeof(BitSequence))) == NULL ) {
return 0;
}
else {
for (i = 0; i < m; i++)
sequence[i] = 1;
}
lambda = (double)(M-m+1)/pow(2,m);
eta = lambda/2.0;
sum = 0.0;
for ( i=0; i<K; i++ ) { /* Compute Probabilities */
pi[i] = Pr(i, eta);
sum += pi[i];
}
pi[K] = 1 - sum;
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 ( sequence[k] != epsilon[i*M+j+k] )
match = 0;
}
if ( match == 1 )
W_obs++;
}
if ( W_obs <= 4 )
nu[(int)W_obs]++;
else
nu[K]++;
}
sum = 0;
chi2 = 0.0; /* Compute Chi Square */
for ( i=0; i<K+1; i++ ) {
chi2 += pow((double)nu[i] - (double)N*pi[i], 2)/((double)N*pi[i]);
sum += nu[i];
}
p_value = cephes_igamc(K/2.0, chi2/2.0);
if ( isNegative(p_value) || isGreaterThanOne(p_value) ) {
goto end;
}
if (p_value < ALPHA) {
goto end;
}
ret = 1;
end:
free(sequence);
return ret;
}
double
Pr(int u, double eta)
{
int l;
double sum, p;
if ( u == 0 )
p = exp(-eta);
else {
sum = 0.0;
for ( l=1; l<=u; l++ )
sum += exp(-eta-u*log(2)+l*log(eta)-cephes_lgam(l+1)+cephes_lgam(u)-cephes_lgam(l)-cephes_lgam(u-l+1));
p = sum;
}
return p;
}

View File

@@ -0,0 +1,79 @@
#include <stdlib.h>
#include <math.h>
#include "include/stat_fncs.h"
#include "include/cephes.h"
typedef struct _PokerNi {
unsigned int flag;
unsigned int count;
} PokerNi;
unsigned char toByte(BitSequence *subEpsilon, int M)
{
int i = 0;
unsigned char result = 0;
for (i = 0; i < M; ++i) {
result |= (subEpsilon[i] << (M - i - 1));
}
return result;
}
int findIndex(PokerNi *tab, int tabSize, unsigned int flag)
{
int i = 0;
for (i = 0; i < tabSize; ++i) {
if (tab[i].flag == flag) {
return i;
}
}
return -1;
}
int PokerDetect(int M, int n, BitSequence *epsilon)
{
int ret = 0;
int i = 0, j = 0, N = n / M, index = 0, c = 0;
int maxElements = (int) pow(2, M);
double p_value = 0.0, sum_ni = 0.0, mp = 0.0, V = 0.0;
unsigned int flag = 0;
PokerNi *tab = NULL;
if (M > 8) {
return 0;
}
tab = (PokerNi *)calloc(maxElements, sizeof(PokerNi));
if (NULL == tab) {
return 0;
}
for (i = 0; i < maxElements; ++i) {
tab[i].flag = (unsigned int) i;
tab[i].count = 0;
}
for (i = 0, j = 0; j < N; ++j, i += M) {
flag = toByte(epsilon + i, M);
index = findIndex(tab, maxElements, flag);
if (-1 == index) {
goto end;
}
tab[index].count += 1;
}
for (i = 0; i < maxElements; ++i) {
sum_ni += pow(tab[i].count, 2);
}
mp = (double)maxElements / N;
V = mp * sum_ni - N;
p_value = cephes_igamc((double)(maxElements - 1) / 2, V / 2);
if (p_value < ALPHA) {
goto end;
}
ret = 1;
end:
free(tab);
return ret;
}

View File

@@ -0,0 +1,116 @@
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "include/externs.h"
#include "include/cephes.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
R A N D O M E X C U R S I O N S T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
RandomExcursions(int n, BitSequence *epsilon)
{
int ret = 0;
int b, i, j, k, J, x;
int cycleStart, cycleStop, *cycle = NULL, *S_k = NULL;
const int stateX[8] = { -4, -3, -2, -1, 1, 2, 3, 4 };
int counter[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
double p_value, sum, constraint, nu[6][8];
double pi[5][6] = { {0.0000000000, 0.00000000000, 0.00000000000, 0.00000000000, 0.00000000000, 0.0000000000},
{0.5000000000, 0.25000000000, 0.12500000000, 0.06250000000, 0.03125000000, 0.0312500000},
{0.7500000000, 0.06250000000, 0.04687500000, 0.03515625000, 0.02636718750, 0.0791015625},
{0.8333333333, 0.02777777778, 0.02314814815, 0.01929012346, 0.01607510288, 0.0803755143},
{0.8750000000, 0.01562500000, 0.01367187500, 0.01196289063, 0.01046752930, 0.0732727051} };
if ( ((S_k = (int *)calloc(n, sizeof(int))) == NULL) ||
((cycle = (int *)calloc(MAX(1000, n/100), sizeof(int))) == NULL) ) {
printf("Random Excursions Test: Insufficent Work Space Allocated.\n");
if ( S_k != NULL )
free(S_k);
if ( cycle != NULL )
free(cycle);
return 0;
}
J = 0; /* DETERMINE CYCLES */
S_k[0] = 2*(int)epsilon[0] - 1;
for( i=1; i<n; i++ ) {
S_k[i] = S_k[i-1] + 2*epsilon[i] - 1;
if ( S_k[i] == 0 ) {
J++;
if ( J > MAX(1000, n/100) ) {
printf("ERROR IN FUNCTION randomExcursions: EXCEEDING THE MAX NUMBER OF CYCLES EXPECTED\n.");
goto end;
}
cycle[J] = i;
}
}
if ( S_k[n-1] != 0 )
J++;
cycle[J] = n;
constraint = MAX(0.005*pow(n, 0.5), 500);
if (J < constraint) {
ret = 1; //TODO
goto end;
}
else {
cycleStart = 0;
cycleStop = cycle[1];
for ( k=0; k<6; k++ )
for ( i=0; i<8; i++ )
nu[k][i] = 0.;
for ( j=1; j<=J; j++ ) { /* FOR EACH CYCLE */
for ( i=0; i<8; i++ )
counter[i] = 0;
for ( i=cycleStart; i<cycleStop; i++ ) {
if ( (S_k[i] >= 1 && S_k[i] <= 4) || (S_k[i] >= -4 && S_k[i] <= -1) ) {
if ( S_k[i] < 0 )
b = 4;
else
b = 3;
counter[S_k[i]+b]++;
}
}
cycleStart = cycle[j]+1;
if ( j < J )
cycleStop = cycle[j+1];
for ( i=0; i<8; i++ ) {
if ( (counter[i] >= 0) && (counter[i] <= 4) )
nu[counter[i]][i]++;
else if ( counter[i] >= 5 )
nu[5][i]++;
}
}
for ( i=0; i<8; i++ ) {
x = stateX[i];
sum = 0.;
for ( k=0; k<6; k++ )
sum += pow(nu[k][i] - J*pi[(int)fabs(x)][k], 2) / (J*pi[(int)fabs(x)][k]);
p_value = cephes_igamc(2.5, sum/2.0);
if ( isNegative(p_value) || isGreaterThanOne(p_value) ) {
// fprintf(stats[TEST_RND_EXCURSION], "WARNING: P_VALUE IS OUT OF RANGE.\n");
goto end;
}
// fprintf(stats[TEST_RND_EXCURSION], "%s\t\tx = %2d chi^2 = %9.6f p_value = %f\n",
// p_value < ALPHA ? "FAILURE" : "SUCCESS", x, sum, p_value);
// fprintf(results[TEST_RND_EXCURSION], "%f\n", p_value); fflush(results[TEST_RND_EXCURSION]);
if (p_value < ALPHA) {
goto end;
}
}
}
// fprintf(stats[TEST_RND_EXCURSION], "\n"); fflush(stats[TEST_RND_EXCURSION]);
ret = 1;
end:
free(S_k);
free(cycle);
return ret;
}

View File

@@ -0,0 +1,61 @@
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "include/externs.h"
#include "include/cephes.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
R A N D O M E X C U R S I O N S V A R I A N T T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
RandomExcursionsVariant(int n, BitSequence *epsilon)
{
int ret = 0;
int i, p, J, x, constraint, count, *S_k = NULL;
const int stateX[18] = { -9, -8, -7, -6, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
double p_value;
if ( (S_k = (int *)calloc(n, sizeof(int))) == NULL ) {
return 0;
}
J = 0;
S_k[0] = 2*(int)epsilon[0] - 1;
for ( i=1; i<n; i++ ) {
S_k[i] = S_k[i-1] + 2*epsilon[i] - 1;
if ( S_k[i] == 0 )
J++;
}
if ( S_k[n-1] != 0 )
J++;
constraint = (int)MAX(0.005*pow(n, 0.5), 500);
if (J < constraint) {
ret = 1; //TODO
goto end;
}
else {
for ( p=0; p<=17; p++ ) {
x = stateX[p];
count = 0;
for ( i=0; i<n; i++ )
if ( S_k[i] == x )
count++;
p_value = erfc(fabs(count-J)/(sqrt(2.0*J*(4.0*fabs(x)-2))));
if ( isNegative(p_value) || isGreaterThanOne(p_value) ) {
goto end;
}
if (p_value < ALPHA) {
goto end;
}
}
}
ret = 1;
end:
free(S_k);
return ret;
}

View File

@@ -0,0 +1,76 @@
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "include/externs.h"
#include "include/cephes.h"
#include "include/matrix.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
R A N K T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
Rank(int n, BitSequence *epsilon)
{
int ret = 0;
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) ) {
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, epsilon);
#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;
p_value = exp(arg1);
if ( isNegative(p_value) || isGreaterThanOne(p_value) ) {
goto end;
}
}
if (p_value < ALPHA) {
goto end;
}
ret = 1;
end:
delete_matrix(32, matrix);
return ret;
}

View File

@@ -0,0 +1,46 @@
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "include/externs.h"
#include "include/cephes.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
R U N S T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
Runs(int n, BitSequence *epsilon)
{
int S, k;
double pi, V, erfc_arg, p_value;
S = 0;
for ( k=0; k<n; k++ )
if ( epsilon[k] )
S++;
pi = (double)S / (double)n;
if ( fabs(pi - 0.5) > (2.0 / sqrt(n)) ) {
p_value = 0.0;
}
else {
V = 1;
for ( k=1; k<n; k++ )
if ( epsilon[k] != epsilon[k-1] )
V++;
erfc_arg = fabs(V - 2.0 * n * pi * (1-pi)) / (2.0 * pi * (1-pi) * sqrt(2*n));
p_value = erfc(erfc_arg);
if ( isNegative(p_value) || isGreaterThanOne(p_value) ) {
return 0;
}
}
if (p_value < ALPHA) {
return 0;
} else {
return 1;
}
}

View File

@@ -0,0 +1,82 @@
#include <stdlib.h>
#include <math.h>
#include "include/stat_fncs.h"
#include "include/cephes.h"
int RunsDistribution(int n, BitSequence *epsilon)
{
int ret = 0;
int i = 0, j = 0, k = 0;
unsigned char runFlag = 0x00;
double p_value = 0.0, sum_bi = 0.0, sum_gi = 0.0, V = 0.0;
double *bi = NULL, *gi = NULL, *e = NULL;
double bit = 0.0, git = 0.0, et = 0.0;
bi = (double *)calloc(n, sizeof(double));
if (NULL == bi) {
goto end;
}
gi = (double *)calloc(n, sizeof(double));
if (NULL == gi) {
goto end;
}
e = (double *)calloc(n, sizeof(double));
if (NULL == e) {
goto end;
}
for (i = 1; i <= n; ++i) {
e[i - 1] = (double)(n - i + 3) / pow(2, i + 2);
if (e[i - 1] >= 5) {
k = i;
}
}
runFlag = epsilon[0];
j = 1;
for (i = 1; i < n; ++i) {
if (epsilon[i] != runFlag) {
if (runFlag == 0x00) {
gi[j - 1] += 1;
} else if (runFlag == 0x01) {
bi[j - 1] += 1;
}
runFlag = epsilon[i];
j = 1;
} else {
++j;
}
}
for (i = 0; i < k; ++i) {
bit = bi[i];
et = e[i];
sum_bi += pow(bit - et, 2) / et;
}
for (i = 0; i < k; ++i) {
git = gi[i];
et = e[i];
sum_gi += pow(git - et, 2) / et;
}
V = sum_bi + sum_gi;
p_value = cephes_igamc(k - 1, V / 2);
if (p_value < ALPHA) {
goto end;
}
ret = 1;
end:
if (NULL != bi) {
free(bi);
}
if (NULL != gi) {
free(gi);
}
if (NULL != e) {
free(e);
}
return ret;
}

View File

@@ -0,0 +1,25 @@
#include <math.h>
#include "include/stat_fncs.h"
int SelfCorrelation(int d, int n, BitSequence *epsilon)
{
int i = 0;
int n_d = n - d;
int Ad = 0;
double V = 0.0, p_value = 0.0, sqrt2 = 1.41421356237309504880;
for (i = 0; i < n_d - 1; ++i) {
Ad += (epsilon[i] ^ epsilon[i + d]);
}
V = 2 * ((double)Ad - ((double)n_d / 2)) / sqrt(n_d);
p_value = erfc(fabs(V) / sqrt2);
if (p_value < ALPHA) {
return 0;
} else {
return 1;
}
}

View File

@@ -0,0 +1,65 @@
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "include/externs.h"
#include "include/cephes.h"
double psi2(int m, int n, BitSequence *epsilon);
int
Serial(int m, int n, BitSequence *epsilon)
{
double p_value1, p_value2, psim0, psim1, psim2, del1, del2;
psim0 = psi2(m, n, epsilon);
psim1 = psi2(m - 1, n, epsilon);
psim2 = psi2(m - 2, n, epsilon);
del1 = psim0 - psim1;
del2 = psim0 - 2.0*psim1 + psim2;
p_value1 = cephes_igamc(pow(2, m-1)/2, del1/2.0);
p_value2 = cephes_igamc(pow(2, m-2)/2, del2/2.0);
if (p_value1 < ALPHA || p_value2 < ALPHA) {
return 0;
} else {
return 1;
}
}
double
psi2(int m, int n, BitSequence *epsilon)
{
int i, j, k, powLen;
double sum, numOfBlocks;
unsigned int *P;
if ( (m == 0) || (m == -1) )
return 0.0;
numOfBlocks = n;
powLen = (int)pow(2, m+1)-1;
if ( (P = (unsigned int*)calloc(powLen,sizeof(unsigned int)))== NULL ) {
// fprintf(stats[TEST_SERIAL], "Serial Test: Insufficient memory available.\n");
// fflush(stats[TEST_SERIAL]);
return 0.0;
}
for ( i=1; i<powLen-1; i++ )
P[i] = 0; /* INITIALIZE NODES */
for ( i=0; i<numOfBlocks; i++ ) { /* COMPUTE FREQUENCY */
k = 1;
for ( j=0; j<m; j++ ) {
if ( epsilon[(i+j)%n] == 0 )
k *= 2;
else if ( epsilon[(i+j)%n] == 1 )
k = 2*k+1;
}
P[k-1]++;
}
sum = 0.0;
for ( i=(int)pow(2, m)-1; i<(int)pow(2, m+1)-1; i++ )
sum += pow(P[i], 2);
sum = (sum * pow(2, m)/(double)n) - (double)n;
free(P);
return sum;
}

View File

@@ -0,0 +1,88 @@
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "include/externs.h"
#include "include/cephes.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
U N I V E R S A L T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
Universal(int n, BitSequence *epsilon)
{
int ret = 0;
int i, j, p, L, Q, K;
double arg, sqrt2, sigma, phi, sum, p_value, c;
long *T, decRep;
const 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 };
const 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) ) {
return 0;
}
/* 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);
arg = fabs(phi-expected_value[L])/(sqrt2 * sigma);
p_value = erfc(arg);
if ( isNegative(p_value) || isGreaterThanOne(p_value) ) {
goto end;
}
if (p_value < ALPHA) {
goto end;
}
ret = 1;
end:
free(T);
return ret;
}

View File

@@ -0,0 +1,45 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
U T I L I T I E S
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "include/utilities.h"
int
convertToBits(BYTE *x, int xBitLength, int bitsNeeded, int *num_0s, int *num_1s, int *bitsRead, BitSequence* epsilon)
{
int i, j, count, bit;
BYTE mask;
int zeros, ones;
count = 0;
zeros = ones = 0;
for ( i=0; i<(xBitLength+7)/8; i++ ) {
mask = 0x80;
for ( j=0; j<8; j++ ) {
if ( *(x+i) & mask ) {
bit = 1;
(*num_1s)++;
ones++;
}
else {
bit = 0;
(*num_0s)++;
zeros++;
}
mask >>= 1;
epsilon[*bitsRead] = bit;
(*bitsRead)++;
if ( *bitsRead == bitsNeeded )
return 1;
if ( ++count == xBitLength )
return 0;
}
}
return 0;
}

View File

@@ -0,0 +1,6 @@
{
global:
statistical_test_suite;
GIT_VERSION*;
local: *;
};

View File

@@ -0,0 +1,6 @@
cmake_minimum_required (VERSION 3.5)
add_executable(gtest_mesa gtest_mesa_sts.cpp)
target_link_libraries(gtest_mesa gtest pcap pthread libmesa_sts)
file(COPY pcap DESTINATION ./)

View File

@@ -0,0 +1,256 @@
#include <netinet/ip6.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <pcap/pcap.h>
#include "gtest/gtest.h"
#include "mesa_sts.h"
#define MAX_PKT_CNT 1
static int read_pcap_and_judge_randomness(const char* pcap_file, struct sts_result* result)
{
pcap_t *handle;
struct pcap_pkthdr *header; // pcap报文头部结构
const u_char *packet; // 报文数据指针
char errbuf[PCAP_ERRBUF_SIZE];
char content[2048] = {0};
int content_len = 0;
int payload_len;
char *payload;
int pkt_cnt = 0;
handle = pcap_open_offline(pcap_file, errbuf);
while (pcap_next_ex(handle, &header, &packet) > 0) {
unsigned short eth_type = ntohs(*(unsigned short *)(packet + 12));
if (eth_type == ETH_P_IP) {
int l4_proto = *(unsigned char *)(packet + sizeof(struct ethhdr) + 9);
if (l4_proto == IPPROTO_TCP) {
int tcp_header_len = (*(unsigned char *)(packet + sizeof(struct ethhdr) + sizeof(struct iphdr) + 12) & 0xf0) >> 2;
payload_len = header->caplen - sizeof(struct ethhdr) - sizeof(struct iphdr) - tcp_header_len;
payload = (char *)packet + sizeof(struct ethhdr) + sizeof(struct iphdr) + tcp_header_len;
} else if (l4_proto == IPPROTO_UDP) {
payload_len = header->caplen - sizeof(struct ethhdr) - sizeof(struct iphdr) - sizeof(struct udphdr);
payload = (char *)packet + sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr);
} else {
continue;
}
} else if (eth_type == ETH_P_IPV6) {
int l4_proto = *(unsigned char *)(packet + sizeof(struct ethhdr) + 6);
if (l4_proto == IPPROTO_TCP) {
int tcp_header_len = (*(unsigned char *)(packet + sizeof(struct ethhdr) + sizeof(struct ip6_hdr) + 12) & 0xf0) >> 2;
payload_len = header->caplen - sizeof(struct ethhdr) - sizeof(struct ip6_hdr) - tcp_header_len;
payload = (char *)packet + sizeof(struct ethhdr) + sizeof(struct ip6_hdr) + tcp_header_len;
} else if (l4_proto == IPPROTO_UDP) {
payload_len = header->caplen - sizeof(struct ethhdr) - sizeof(struct ip6_hdr) - sizeof(struct udphdr);
payload = (char *)packet + sizeof(struct ethhdr) + sizeof(struct ip6_hdr) + sizeof(struct udphdr);
} else {
continue;
}
}
if (payload_len < 100) {
continue;
}
memcpy(content + content_len, payload, payload_len);
content_len += payload_len;
pkt_cnt++;
if (pkt_cnt == MAX_PKT_CNT) {
break;
}
}
mesa_statistical_test_suite(content, content_len, result, 0xffffffff);
pcap_close(handle);
return 0;
}
TEST(random_looking, telegram_mtproto_ipv4_key1)
{
struct sts_result result;
read_pcap_and_judge_randomness("pcap/telegram_mtproto_ipv4_key_1.pcap", &result);
EXPECT_EQ(result.frequency, 1);
EXPECT_EQ(result.block_frequency, 1);
EXPECT_EQ(result.cumulative_sums, 1);
EXPECT_EQ(result.runs, 1);
EXPECT_EQ(result.longest_run, 1);
EXPECT_EQ(result.rank, 0);
EXPECT_EQ(result.non_overlapping_template_matching, 0);
EXPECT_EQ(result.overlapping_template_matching, 1);
EXPECT_EQ(result.universal, 0);
EXPECT_EQ(result.random_excursions, 1);
EXPECT_EQ(result.random_excursions_variant, 1);
EXPECT_EQ(result.poker_detect, 1);
EXPECT_EQ(result.runs_distribution, 1);
EXPECT_EQ(result.self_correlation, 1);
EXPECT_EQ(result.binary_derivative, 1);
}
TEST(random_looking, telegram_mtproto_ipv4_key2)
{
struct sts_result result;
read_pcap_and_judge_randomness("pcap/telegram_mtproto_ipv4_key_2_dd.pcap", &result);
EXPECT_EQ(result.frequency, 1);
EXPECT_EQ(result.block_frequency, 1);
EXPECT_EQ(result.cumulative_sums, 1);
EXPECT_EQ(result.runs, 1);
EXPECT_EQ(result.longest_run, 1);
EXPECT_EQ(result.rank, 0);
EXPECT_EQ(result.non_overlapping_template_matching, 0);
EXPECT_EQ(result.overlapping_template_matching, 1);
EXPECT_EQ(result.universal, 0);
EXPECT_EQ(result.random_excursions, 1);
EXPECT_EQ(result.random_excursions_variant, 1);
EXPECT_EQ(result.poker_detect, 1);
EXPECT_EQ(result.runs_distribution, 1);
EXPECT_EQ(result.self_correlation, 1);
EXPECT_EQ(result.binary_derivative, 1);
}
TEST(random_looking, telegram_mtproto_ipv4_key3)
{
struct sts_result result;
read_pcap_and_judge_randomness("pcap/telegram_mtproto_ipv4_key_3_ee.pcap", &result);
EXPECT_EQ(result.frequency, 1);
EXPECT_EQ(result.block_frequency, 0);
EXPECT_EQ(result.cumulative_sums, 1);
EXPECT_EQ(result.runs, 0);
EXPECT_EQ(result.longest_run, 1);
EXPECT_EQ(result.rank, 0);
EXPECT_EQ(result.non_overlapping_template_matching, 0);
EXPECT_EQ(result.overlapping_template_matching, 1);
EXPECT_EQ(result.universal, 0);
EXPECT_EQ(result.random_excursions, 1);
EXPECT_EQ(result.random_excursions_variant, 1);
EXPECT_EQ(result.poker_detect, 0);
EXPECT_EQ(result.runs_distribution, 1);
EXPECT_EQ(result.self_correlation, 1);
EXPECT_EQ(result.binary_derivative, 1);
}
TEST(random_looking, telegram_mtproto_ipv6_key1)
{
struct sts_result result;
read_pcap_and_judge_randomness("pcap/telegram_mtproto_ipv6_key_1.pcap", &result);
EXPECT_EQ(result.frequency, 1);
EXPECT_EQ(result.block_frequency, 1);
EXPECT_EQ(result.cumulative_sums, 1);
EXPECT_EQ(result.runs, 1);
EXPECT_EQ(result.longest_run, 1);
EXPECT_EQ(result.rank, 0);
EXPECT_EQ(result.non_overlapping_template_matching, 0);
EXPECT_EQ(result.overlapping_template_matching, 1);
EXPECT_EQ(result.universal, 0);
EXPECT_EQ(result.random_excursions, 1);
EXPECT_EQ(result.random_excursions_variant, 1);
EXPECT_EQ(result.poker_detect, 1);
EXPECT_EQ(result.runs_distribution, 1);
EXPECT_EQ(result.self_correlation, 1);
EXPECT_EQ(result.binary_derivative, 1);
}
TEST(random_looking, telegram_mtproto_ipv6_key2)
{
struct sts_result result;
read_pcap_and_judge_randomness("pcap/telegram_mtproto_ipv6_key_2_dd.pcap", &result);
EXPECT_EQ(result.frequency, 1);
EXPECT_EQ(result.block_frequency, 1);
EXPECT_EQ(result.cumulative_sums, 1);
EXPECT_EQ(result.runs, 1);
EXPECT_EQ(result.longest_run, 1);
EXPECT_EQ(result.rank, 0);
EXPECT_EQ(result.non_overlapping_template_matching, 0);
EXPECT_EQ(result.overlapping_template_matching, 1);
EXPECT_EQ(result.universal, 0);
EXPECT_EQ(result.random_excursions, 1);
EXPECT_EQ(result.random_excursions_variant, 1);
EXPECT_EQ(result.poker_detect, 1);
EXPECT_EQ(result.runs_distribution, 1);
EXPECT_EQ(result.self_correlation, 1);
EXPECT_EQ(result.binary_derivative, 1);
}
TEST(random_looking, telegram_mtproto_ipv6_key3)
{
struct sts_result result;
read_pcap_and_judge_randomness("pcap/telegram_mtproto_ipv6_key_3_ee.pcap", &result);
EXPECT_EQ(result.frequency, 1);
EXPECT_EQ(result.block_frequency, 0);
EXPECT_EQ(result.cumulative_sums, 1);
EXPECT_EQ(result.runs, 1);
EXPECT_EQ(result.longest_run, 1);
EXPECT_EQ(result.rank, 0);
EXPECT_EQ(result.non_overlapping_template_matching, 0);
EXPECT_EQ(result.overlapping_template_matching, 1);
EXPECT_EQ(result.universal, 0);
EXPECT_EQ(result.random_excursions, 1);
EXPECT_EQ(result.random_excursions_variant, 1);
EXPECT_EQ(result.poker_detect, 0);
EXPECT_EQ(result.runs_distribution, 1);
EXPECT_EQ(result.self_correlation, 1);
EXPECT_EQ(result.binary_derivative, 1);
}
TEST(non_random_looking, wechat_voice_call)
{
struct sts_result result;
read_pcap_and_judge_randomness("pcap/202202161604_win_wifi_30M_pure_wechat_wechat3.5.0.46_voice-call_120s_2_multinat.pcap", &result);
EXPECT_EQ(result.frequency, 0);
EXPECT_EQ(result.block_frequency, 1);
EXPECT_EQ(result.cumulative_sums, 0);
EXPECT_EQ(result.runs, 0);
EXPECT_EQ(result.longest_run, 0);
EXPECT_EQ(result.rank, 0);
EXPECT_EQ(result.non_overlapping_template_matching, 0);
EXPECT_EQ(result.overlapping_template_matching, 1);
EXPECT_EQ(result.universal, 0);
EXPECT_EQ(result.random_excursions, 1);
EXPECT_EQ(result.random_excursions_variant, 1);
EXPECT_EQ(result.poker_detect, 1);
EXPECT_EQ(result.runs_distribution, 0);
EXPECT_EQ(result.self_correlation, 0);
EXPECT_EQ(result.binary_derivative, 1);
}
TEST(non_random_looking, http)
{
struct sts_result result;
read_pcap_and_judge_randomness("pcap/xingongsuo_kouling_http_C2S.pcap", &result);
EXPECT_EQ(result.frequency, 0);
EXPECT_EQ(result.block_frequency, 0);
EXPECT_EQ(result.cumulative_sums, 0);
EXPECT_EQ(result.runs, 1);
EXPECT_EQ(result.longest_run, 0);
EXPECT_EQ(result.rank, 1);
EXPECT_EQ(result.non_overlapping_template_matching, 0);
EXPECT_EQ(result.overlapping_template_matching, 1);
EXPECT_EQ(result.universal, 0);
EXPECT_EQ(result.random_excursions, 1);
EXPECT_EQ(result.random_excursions_variant, 1);
EXPECT_EQ(result.poker_detect, 0);
EXPECT_EQ(result.runs_distribution, 0);
EXPECT_EQ(result.self_correlation, 0);
EXPECT_EQ(result.binary_derivative, 1);
}
int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
//testing::GTEST_FLAG(filter) = "random_looking.telegram_mtproto_ipv6_key1";
return RUN_ALL_TESTS();
}