pri_test.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. *******************************************************************************
  3. \file pri_test.c
  4. \brief Tests for prime numbers
  5. \project bee2/test
  6. \author (C) Sergey Agievich [agievich@{bsu.by|gmail.com}]
  7. \created 2014.07.07
  8. \version 2016.07.15
  9. \license This program is released under the GNU General Public License
  10. version 3. See Copyright Notices in bee2/info.h.
  11. *******************************************************************************
  12. */
  13. #include <bee2/core/mem.h>
  14. #include <bee2/core/prng.h>
  15. #include <bee2/core/util.h>
  16. #include <bee2/core/word.h>
  17. #include <bee2/math/pri.h>
  18. #include <bee2/math/ww.h>
  19. /*
  20. *******************************************************************************
  21. Тестирование
  22. *******************************************************************************
  23. */
  24. bool_t priTest()
  25. {
  26. size_t i;
  27. word a[W_OF_B(521)];
  28. word p[W_OF_B(289)];
  29. word mods[1024];
  30. octet combo_state[32];
  31. octet stack[4096];
  32. // инициализировать генератор COMBO
  33. ASSERT(prngCOMBO_keep() <= sizeof(combo_state));
  34. prngCOMBOStart(combo_state, utilNonce32());
  35. // проверить простоту элементов факторной базы
  36. ASSERT(priIsPrimeW_deep() <= sizeof(stack));
  37. ASSERT(priIsPrime_deep(1) <= sizeof(stack));
  38. for (i = 0; i < priBaseSize(); ++i)
  39. {
  40. a[0] = priBasePrime(i);
  41. if (!priIsPrimeW(a[0], stack) || !priIsPrime(a, 1, stack))
  42. return FALSE;
  43. }
  44. // проверить простоту числа Ферма 2^{2^5} + 1
  45. ASSERT(priIsPrime_deep(W_OF_B(32)) <= sizeof(stack));
  46. wwSetZero(a, W_OF_B(32));
  47. wwSetBit(a, 32, 1);
  48. zzAddW2(a, W_OF_B(32), 1);
  49. if (priIsPrime(a, W_OF_B(32), stack) != FALSE)
  50. return FALSE;
  51. // проверить простоту 13-го числа Мерсенна 2^521 - 1
  52. ASSERT(priRMTest_deep(W_OF_B(521)) <= sizeof(stack));
  53. wwSetZero(a, W_OF_B(521));
  54. wwSetBit(a, 521, 1);
  55. zzSubW2(a, W_OF_B(521), 1);
  56. if (priRMTest(a, W_OF_B(521), 20, stack) != TRUE)
  57. return FALSE;
  58. // остатки по простым из факторной базы
  59. i = MIN2(COUNT_OF(mods), priBaseSize());
  60. priBaseMod(mods, a, W_OF_B(521), i);
  61. while (i--)
  62. if (mods[i] != zzModW(a, W_OF_B(521), priBasePrime(i)) ||
  63. priBasePrime(i) < WORD_BIT_HALF &&
  64. mods[i] != zzModW2(a, W_OF_B(521), priBasePrime(i)))
  65. return FALSE;
  66. // найти 2-битовое нечетное простое число
  67. ASSERT(priNextPrime_deep(1, 0) <= sizeof(stack));
  68. a[0] = 2;
  69. if (!priNextPrime(a, a, 1, SIZE_MAX, 0, B_PER_IMPOSSIBLE, stack) ||
  70. a[0] != 3)
  71. return FALSE;
  72. // найти 10-битовое нечетное простое число
  73. a[0] = 512;
  74. if (!priNextPrime(a, a, 1, SIZE_MAX, 0, B_PER_IMPOSSIBLE, stack) ||
  75. a[0] != 521)
  76. return FALSE;
  77. // найти следующее 10-битовое нечетное простое число
  78. ASSERT(priNextPrimeW_deep() <= sizeof(stack));
  79. if (!priNextPrimeW(a, ++a[0], stack) || a[0] != 523)
  80. return FALSE;
  81. // убедиться, что 2^256 - 400 не является гладким
  82. ASSERT(priIsSmooth_deep(W_OF_B(256)) <= sizeof(stack));
  83. memSet(a, 0xFF, O_OF_B(256));
  84. zzSubW2(a, W_OF_B(256), 400);
  85. if (priIsSmooth(a, W_OF_B(256), priBaseSize(), stack))
  86. return FALSE;
  87. // найти простое число 2^256 - 357
  88. ASSERT(priBaseSize() >= 10);
  89. ASSERT(priNextPrime_deep(W_OF_B(256), 10) <= sizeof(stack));
  90. if (!priNextPrime(a, a, W_OF_B(256), 50, 10, B_PER_IMPOSSIBLE, stack) ||
  91. a[0] != WORD_MAX - 356 ||
  92. !wwIsRepW(a + 1, W_OF_B(256) - 1, WORD_MAX))
  93. return FALSE;
  94. // найти простое число 2^256 - 189
  95. zzAddW2(a, W_OF_B(256), 1);
  96. if (!priNextPrime(a, a, W_OF_B(256), 200, 10, B_PER_IMPOSSIBLE, stack) ||
  97. a[0] != WORD_MAX - 188 ||
  98. !wwIsRepW(a + 1, W_OF_B(256) - 1, WORD_MAX))
  99. return FALSE;
  100. // построить 289-битовое простое вида 2r(2^256 - 189) + 1
  101. ASSERT(priBaseSize() >= 10);
  102. ASSERT(priExtendPrime_deep(289, W_OF_B(256), 0) <= sizeof(stack));
  103. ASSERT(priIsPrime_deep(W_OF_B(256)) <= sizeof(stack));
  104. if (!priExtendPrime(p, 289, a, W_OF_B(256), SIZE_MAX, 0, prngCOMBOStepR,
  105. combo_state, stack) || !priIsPrime(p, W_OF_B(289), stack))
  106. return FALSE;
  107. // удостовериться, что в интервале (2^256 - 188, 2^256 - 1) нет простых
  108. zzAddW2(a, W_OF_B(256), 1);
  109. if (priNextPrime(a, a, W_OF_B(256), 200, 0, B_PER_IMPOSSIBLE, stack))
  110. return FALSE;
  111. // проверить, что 2^256 - 29237 является простым Жермен
  112. ASSERT(priIsSieved_deep(10) <= sizeof(stack));
  113. ASSERT(priIsSGPrime_deep(W_OF_B(256)) <= sizeof(stack));
  114. memSet(a, 0xFF, O_OF_B(256));
  115. a[0] = WORD_MAX - 29236;
  116. if (!priIsSieved(a, W_OF_B(256), 10, stack) ||
  117. !priIsSGPrime(a, W_OF_B(256), stack) != 0)
  118. return FALSE;
  119. // построить простое 23 = 2 * 11 + 1 (за одну попытку)
  120. ASSERT(priExtendPrime_deep(5, 1, 10) <= sizeof(stack));
  121. a[0] = 11;
  122. if (!priExtendPrime(p, 5, a, 1, SIZE_MAX, 0,
  123. prngCOMBOStepR, combo_state, stack) || p[0] != 23)
  124. return FALSE;
  125. // все нормально
  126. return TRUE;
  127. }