pri_test.c 4.9 KB

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