You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

generatePrime.js 2.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. var randomBytes = require('randombytes');
  2. module.exports = findPrime;
  3. findPrime.simpleSieve = simpleSieve;
  4. findPrime.fermatTest = fermatTest;
  5. var BN = require('bn.js');
  6. var TWENTYFOUR = new BN(24);
  7. var MillerRabin = require('miller-rabin');
  8. var millerRabin = new MillerRabin();
  9. var ONE = new BN(1);
  10. var TWO = new BN(2);
  11. var FIVE = new BN(5);
  12. var SIXTEEN = new BN(16);
  13. var EIGHT = new BN(8);
  14. var TEN = new BN(10);
  15. var THREE = new BN(3);
  16. var SEVEN = new BN(7);
  17. var ELEVEN = new BN(11);
  18. var FOUR = new BN(4);
  19. var TWELVE = new BN(12);
  20. var primes = null;
  21. function _getPrimes() {
  22. if (primes !== null)
  23. return primes;
  24. var limit = 0x100000;
  25. var res = [];
  26. res[0] = 2;
  27. for (var i = 1, k = 3; k < limit; k += 2) {
  28. var sqrt = Math.ceil(Math.sqrt(k));
  29. for (var j = 0; j < i && res[j] <= sqrt; j++)
  30. if (k % res[j] === 0)
  31. break;
  32. if (i !== j && res[j] <= sqrt)
  33. continue;
  34. res[i++] = k;
  35. }
  36. primes = res;
  37. return res;
  38. }
  39. function simpleSieve(p) {
  40. var primes = _getPrimes();
  41. for (var i = 0; i < primes.length; i++)
  42. if (p.modn(primes[i]) === 0) {
  43. if (p.cmpn(primes[i]) === 0) {
  44. return true;
  45. } else {
  46. return false;
  47. }
  48. }
  49. return true;
  50. }
  51. function fermatTest(p) {
  52. var red = BN.mont(p);
  53. return TWO.toRed(red).redPow(p.subn(1)).fromRed().cmpn(1) === 0;
  54. }
  55. function findPrime(bits, gen) {
  56. if (bits < 16) {
  57. // this is what openssl does
  58. if (gen === 2 || gen === 5) {
  59. return new BN([0x8c, 0x7b]);
  60. } else {
  61. return new BN([0x8c, 0x27]);
  62. }
  63. }
  64. gen = new BN(gen);
  65. var num, n2;
  66. while (true) {
  67. num = new BN(randomBytes(Math.ceil(bits / 8)));
  68. while (num.bitLength() > bits) {
  69. num.ishrn(1);
  70. }
  71. if (num.isEven()) {
  72. num.iadd(ONE);
  73. }
  74. if (!num.testn(1)) {
  75. num.iadd(TWO);
  76. }
  77. if (!gen.cmp(TWO)) {
  78. while (num.mod(TWENTYFOUR).cmp(ELEVEN)) {
  79. num.iadd(FOUR);
  80. }
  81. } else if (!gen.cmp(FIVE)) {
  82. while (num.mod(TEN).cmp(THREE)) {
  83. num.iadd(FOUR);
  84. }
  85. }
  86. n2 = num.shrn(1);
  87. if (simpleSieve(n2) && simpleSieve(num) &&
  88. fermatTest(n2) && fermatTest(num) &&
  89. millerRabin.test(n2) && millerRabin.test(num)) {
  90. return num;
  91. }
  92. }
  93. }