stat.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * stats.c
  3. *
  4. * statistical tests
  5. *
  6. * David A. McGrew
  7. * Cisco Systems, Inc.
  8. */
  9. /*
  10. *
  11. * Copyright (c) 2001-2017, Cisco Systems, Inc.
  12. * All rights reserved.
  13. *
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions
  16. * are met:
  17. *
  18. * Redistributions of source code must retain the above copyright
  19. * notice, this list of conditions and the following disclaimer.
  20. *
  21. * Redistributions in binary form must reproduce the above
  22. * copyright notice, this list of conditions and the following
  23. * disclaimer in the documentation and/or other materials provided
  24. * with the distribution.
  25. *
  26. * Neither the name of the Cisco Systems, Inc. nor the names of its
  27. * contributors may be used to endorse or promote products derived
  28. * from this software without specific prior written permission.
  29. *
  30. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  31. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  32. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  33. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  34. * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  35. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  36. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  37. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  40. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  41. * OF THE POSSIBILITY OF SUCH DAMAGE.
  42. *
  43. */
  44. #ifdef HAVE_CONFIG_H
  45. #include <config.h>
  46. #endif
  47. #include "stat.h"
  48. srtp_debug_module_t srtp_mod_stat = {
  49. 0, /* debugging is off by default */
  50. (char *)"stat test" /* printable module name */
  51. };
  52. /*
  53. * each test assumes that 20,000 bits (2500 octets) of data is
  54. * provided as input
  55. */
  56. #define STAT_TEST_DATA_LEN 2500
  57. srtp_err_status_t stat_test_monobit(uint8_t *data)
  58. {
  59. uint8_t *data_end = data + STAT_TEST_DATA_LEN;
  60. uint16_t ones_count;
  61. ones_count = 0;
  62. while (data < data_end) {
  63. ones_count += octet_get_weight(*data);
  64. data++;
  65. }
  66. debug_print(srtp_mod_stat, "bit count: %d", ones_count);
  67. if ((ones_count < 9725) || (ones_count > 10275))
  68. return srtp_err_status_algo_fail;
  69. return srtp_err_status_ok;
  70. }
  71. srtp_err_status_t stat_test_poker(uint8_t *data)
  72. {
  73. int i;
  74. uint8_t *data_end = data + STAT_TEST_DATA_LEN;
  75. double poker;
  76. uint16_t f[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  77. while (data < data_end) {
  78. f[*data & 0x0f]++; /* increment freq. count for low nibble */
  79. f[(*data) >> 4]++; /* increment freq. count for high nibble */
  80. data++;
  81. }
  82. poker = 0.0;
  83. for (i = 0; i < 16; i++)
  84. poker += (double)f[i] * f[i];
  85. poker *= (16.0 / 5000.0);
  86. poker -= 5000.0;
  87. debug_print(srtp_mod_stat, "poker test: %f\n", poker);
  88. if ((poker < 2.16) || (poker > 46.17))
  89. return srtp_err_status_algo_fail;
  90. return srtp_err_status_ok;
  91. }
  92. /*
  93. * runs[i] holds the number of runs of size (i-1)
  94. */
  95. srtp_err_status_t stat_test_runs(uint8_t *data)
  96. {
  97. uint8_t *data_end = data + STAT_TEST_DATA_LEN;
  98. uint16_t runs[6] = { 0, 0, 0, 0, 0, 0 };
  99. uint16_t gaps[6] = { 0, 0, 0, 0, 0, 0 };
  100. uint16_t lo_value[6] = { 2315, 1114, 527, 240, 103, 103 };
  101. uint16_t hi_value[6] = { 2685, 1386, 723, 384, 209, 209 };
  102. int state = 0;
  103. uint16_t mask;
  104. int i;
  105. /*
  106. * the state variable holds the number of bits in the
  107. * current run (or gap, if negative)
  108. */
  109. while (data < data_end) {
  110. /* loop over the bits of this byte */
  111. for (mask = 1; mask < 256; mask <<= 1) {
  112. if (*data & mask) {
  113. /* next bit is a one */
  114. if (state > 0) {
  115. /* prefix is a run, so increment the run-count */
  116. state++;
  117. /* check for long runs */
  118. if (state > 25) {
  119. debug_print(srtp_mod_stat, ">25 runs: %d", state);
  120. return srtp_err_status_algo_fail;
  121. }
  122. } else if (state < 0) {
  123. /* prefix is a gap */
  124. if (state < -25) {
  125. debug_print(srtp_mod_stat, ">25 gaps: %d", state);
  126. return srtp_err_status_algo_fail; /* long-runs test
  127. failed */
  128. }
  129. if (state < -6) {
  130. state = -6; /* group together gaps > 5 */
  131. }
  132. gaps[-1 - state]++; /* increment gap count */
  133. state = 1; /* set state at one set bit */
  134. } else {
  135. /* state is zero; this happens only at initialization */
  136. state = 1;
  137. }
  138. } else {
  139. /* next bit is a zero */
  140. if (state > 0) {
  141. /* prefix is a run */
  142. if (state > 25) {
  143. debug_print(srtp_mod_stat, ">25 runs (2): %d", state);
  144. return srtp_err_status_algo_fail; /* long-runs test
  145. failed */
  146. }
  147. if (state > 6) {
  148. state = 6; /* group together runs > 5 */
  149. }
  150. runs[state - 1]++; /* increment run count */
  151. state = -1; /* set state at one zero bit */
  152. } else if (state < 0) {
  153. /* prefix is a gap, so increment gap-count (decrement state)
  154. */
  155. state--;
  156. /* check for long gaps */
  157. if (state < -25) {
  158. debug_print(srtp_mod_stat, ">25 gaps (2): %d", state);
  159. return srtp_err_status_algo_fail;
  160. }
  161. } else {
  162. /* state is zero; this happens only at initialization */
  163. state = -1;
  164. }
  165. }
  166. }
  167. /* move along to next octet */
  168. data++;
  169. }
  170. if (srtp_mod_stat.on) {
  171. debug_print0(srtp_mod_stat, "runs test");
  172. for (i = 0; i < 6; i++)
  173. debug_print(srtp_mod_stat, " runs[]: %d", runs[i]);
  174. for (i = 0; i < 6; i++)
  175. debug_print(srtp_mod_stat, " gaps[]: %d", gaps[i]);
  176. }
  177. /* check run and gap counts against the fixed limits */
  178. for (i = 0; i < 6; i++)
  179. if ((runs[i] < lo_value[i]) || (runs[i] > hi_value[i]) ||
  180. (gaps[i] < lo_value[i]) || (gaps[i] > hi_value[i]))
  181. return srtp_err_status_algo_fail;
  182. return srtp_err_status_ok;
  183. }