| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 | var randomBytes = require('randombytes');module.exports = findPrime;findPrime.simpleSieve = simpleSieve;findPrime.fermatTest = fermatTest;var BN = require('bn.js');var TWENTYFOUR = new BN(24);var MillerRabin = require('miller-rabin');var millerRabin = new MillerRabin();var ONE = new BN(1);var TWO = new BN(2);var FIVE = new BN(5);var SIXTEEN = new BN(16);var EIGHT = new BN(8);var TEN = new BN(10);var THREE = new BN(3);var SEVEN = new BN(7);var ELEVEN = new BN(11);var FOUR = new BN(4);var TWELVE = new BN(12);var primes = null;function _getPrimes() {  if (primes !== null)    return primes;  var limit = 0x100000;  var res = [];  res[0] = 2;  for (var i = 1, k = 3; k < limit; k += 2) {    var sqrt = Math.ceil(Math.sqrt(k));    for (var j = 0; j < i && res[j] <= sqrt; j++)      if (k % res[j] === 0)        break;    if (i !== j && res[j] <= sqrt)      continue;    res[i++] = k;  }  primes = res;  return res;}function simpleSieve(p) {  var primes = _getPrimes();  for (var i = 0; i < primes.length; i++)    if (p.modn(primes[i]) === 0) {      if (p.cmpn(primes[i]) === 0) {        return true;      } else {        return false;      }    }  return true;}function fermatTest(p) {  var red = BN.mont(p);  return TWO.toRed(red).redPow(p.subn(1)).fromRed().cmpn(1) === 0;}function findPrime(bits, gen) {  if (bits < 16) {    // this is what openssl does    if (gen === 2 || gen === 5) {      return new BN([0x8c, 0x7b]);    } else {      return new BN([0x8c, 0x27]);    }  }  gen = new BN(gen);  var num, n2;  while (true) {    num = new BN(randomBytes(Math.ceil(bits / 8)));    while (num.bitLength() > bits) {      num.ishrn(1);    }    if (num.isEven()) {      num.iadd(ONE);    }    if (!num.testn(1)) {      num.iadd(TWO);    }    if (!gen.cmp(TWO)) {      while (num.mod(TWENTYFOUR).cmp(ELEVEN)) {        num.iadd(FOUR);      }    } else if (!gen.cmp(FIVE)) {      while (num.mod(TEN).cmp(THREE)) {        num.iadd(FOUR);      }    }    n2 = num.shrn(1);    if (simpleSieve(n2) && simpleSieve(num) &&      fermatTest(n2) && fermatTest(num) &&      millerRabin.test(n2) && millerRabin.test(num)) {      return num;    }  }}
 |