blob: 77da0ae0a77e0ed5512e290a086e7e915ba6b272 [file] [log] [blame]
Cullen Jennings235513a2005-09-21 22:51:36 +00001/*
2 * stats.c
3 *
jfigusfb838412014-12-04 10:15:47 -05004 * statistical tests
Cullen Jennings235513a2005-09-21 22:51:36 +00005 *
6 * David A. McGrew
7 * Cisco Systems, Inc.
8 */
9
Teerapap Changwichukarn6cffe242014-09-24 11:24:07 +080010#ifdef HAVE_CONFIG_H
11 #include <config.h>
12#endif
13
Cullen Jennings235513a2005-09-21 22:51:36 +000014#include "stat.h"
15
jfigus02d6f032014-11-21 10:56:42 -050016srtp_debug_module_t mod_stat = {
Cullen Jennings235513a2005-09-21 22:51:36 +000017 0, /* debugging is off by default */
David McGrewfec49dd2005-09-23 19:34:11 +000018 (char *)"stat test" /* printable module name */
Cullen Jennings235513a2005-09-21 22:51:36 +000019};
20
21/*
22 * each test assumes that 20,000 bits (2500 octets) of data is
23 * provided as input
24 */
25
26#define STAT_TEST_DATA_LEN 2500
27
jfigus857009c2014-11-05 11:17:43 -050028srtp_err_status_t
Marcus Sundberg410faaa2005-09-29 12:36:43 +000029stat_test_monobit(uint8_t *data) {
30 uint8_t *data_end = data + STAT_TEST_DATA_LEN;
Cullen Jennings235513a2005-09-21 22:51:36 +000031 uint16_t ones_count;
32
33 ones_count = 0;
34 while (data < data_end) {
35 ones_count += octet_get_weight(*data);
36 data++;
37 }
38
39 debug_print(mod_stat, "bit count: %d", ones_count);
40
41 if ((ones_count < 9725) || (ones_count > 10275))
jfigus857009c2014-11-05 11:17:43 -050042 return srtp_err_status_algo_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +000043
jfigus857009c2014-11-05 11:17:43 -050044 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +000045}
46
jfigus857009c2014-11-05 11:17:43 -050047srtp_err_status_t
Marcus Sundberg410faaa2005-09-29 12:36:43 +000048stat_test_poker(uint8_t *data) {
Cullen Jennings235513a2005-09-21 22:51:36 +000049 int i;
Marcus Sundberg410faaa2005-09-29 12:36:43 +000050 uint8_t *data_end = data + STAT_TEST_DATA_LEN;
Cullen Jennings235513a2005-09-21 22:51:36 +000051 double poker;
52 uint16_t f[16] = {
53 0, 0, 0, 0, 0, 0, 0, 0,
54 0, 0, 0, 0, 0, 0, 0, 0
55 };
56
57 while (data < data_end) {
58 f[*data & 0x0f]++; /* increment freq. count for low nibble */
59 f[(*data) >> 4]++; /* increment freq. count for high nibble */
60 data++;
61 }
62
63 poker = 0.0;
64 for (i=0; i < 16; i++)
65 poker += (double) f[i] * f[i];
66
67 poker *= (16.0 / 5000.0);
68 poker -= 5000.0;
69
70 debug_print(mod_stat, "poker test: %f\n", poker);
71
72 if ((poker < 2.16) || (poker > 46.17))
jfigus857009c2014-11-05 11:17:43 -050073 return srtp_err_status_algo_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +000074
jfigus857009c2014-11-05 11:17:43 -050075 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +000076}
77
78
79/*
80 * runs[i] holds the number of runs of size (i-1)
81 */
82
jfigus857009c2014-11-05 11:17:43 -050083srtp_err_status_t
Marcus Sundberg410faaa2005-09-29 12:36:43 +000084stat_test_runs(uint8_t *data) {
85 uint8_t *data_end = data + STAT_TEST_DATA_LEN;
Cullen Jennings235513a2005-09-21 22:51:36 +000086 uint16_t runs[6] = { 0, 0, 0, 0, 0, 0 };
87 uint16_t gaps[6] = { 0, 0, 0, 0, 0, 0 };
88 uint16_t lo_value[6] = { 2315, 1114, 527, 240, 103, 103 };
89 uint16_t hi_value[6] = { 2685, 1386, 723, 384, 209, 209 };
David McGrewc7805762006-07-11 23:37:10 +000090 int state = 0;
Cullen Jennings235513a2005-09-21 22:51:36 +000091 uint16_t mask;
92 int i;
93
94 /*
95 * the state variable holds the number of bits in the
96 * current run (or gap, if negative)
97 */
98
99 while (data < data_end) {
100
101 /* loop over the bits of this byte */
102 for (mask = 1; mask < 256; mask <<= 1) {
103 if (*data & mask) {
104
105 /* next bit is a one */
106 if (state > 0) {
107
108 /* prefix is a run, so increment the run-count */
109 state++;
110
111 /* check for long runs */
112 if (state > 25) {
113 debug_print(mod_stat, ">25 runs: %d", state);
jfigus857009c2014-11-05 11:17:43 -0500114 return srtp_err_status_algo_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000115 }
116
117 } else if (state < 0) {
118
119 /* prefix is a gap */
120 if (state < -25) {
121 debug_print(mod_stat, ">25 gaps: %d", state);
jfigus857009c2014-11-05 11:17:43 -0500122 return srtp_err_status_algo_fail; /* long-runs test failed */
Cullen Jennings235513a2005-09-21 22:51:36 +0000123 }
124 if (state < -6) {
125 state = -6; /* group together gaps > 5 */
126 }
127 gaps[-1-state]++; /* increment gap count */
128 state = 1; /* set state at one set bit */
129 } else {
130
131 /* state is zero; this happens only at initialization */
132 state = 1;
133 }
134 } else {
135
136 /* next bit is a zero */
137 if (state > 0) {
138
139 /* prefix is a run */
140 if (state > 25) {
141 debug_print(mod_stat, ">25 runs (2): %d", state);
jfigus857009c2014-11-05 11:17:43 -0500142 return srtp_err_status_algo_fail; /* long-runs test failed */
Cullen Jennings235513a2005-09-21 22:51:36 +0000143 }
144 if (state > 6) {
145 state = 6; /* group together runs > 5 */
146 }
147 runs[state-1]++; /* increment run count */
148 state = -1; /* set state at one zero bit */
149 } else if (state < 0) {
150
151 /* prefix is a gap, so increment gap-count (decrement state) */
152 state--;
153
154 /* check for long gaps */
155 if (state < -25) {
156 debug_print(mod_stat, ">25 gaps (2): %d", state);
jfigus857009c2014-11-05 11:17:43 -0500157 return srtp_err_status_algo_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000158 }
159
160 } else {
161
162 /* state is zero; this happens only at initialization */
163 state = -1;
164 }
165 }
166 }
167
168 /* move along to next octet */
169 data++;
170 }
171
172 if (mod_stat.on) {
173 debug_print(mod_stat, "runs test", NULL);
174 for (i=0; i < 6; i++)
175 debug_print(mod_stat, " runs[]: %d", runs[i]);
176 for (i=0; i < 6; i++)
177 debug_print(mod_stat, " gaps[]: %d", gaps[i]);
178 }
179
180 /* check run and gap counts against the fixed limits */
181 for (i=0; i < 6; i++)
182 if ( (runs[i] < lo_value[i] ) || (runs[i] > hi_value[i])
183 || (gaps[i] < lo_value[i] ) || (gaps[i] > hi_value[i]))
jfigus857009c2014-11-05 11:17:43 -0500184 return srtp_err_status_algo_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000185
186
jfigus857009c2014-11-05 11:17:43 -0500187 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000188}
189
190