| 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; |
| } |
| } |
| |
| } |