Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80551 views
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
22
function _getPrimes() {
23
if (primes !== null)
24
return primes;
25
26
var limit = 0x100000;
27
var res = [];
28
res[0] = 2;
29
for (var i = 1, k = 3; k < limit; k += 2) {
30
var sqrt = Math.ceil(Math.sqrt(k));
31
for (var j = 0; j < i && res[j] <= sqrt; j++)
32
if (k % res[j] === 0)
33
break;
34
35
if (i !== j && res[j] <= sqrt)
36
continue;
37
38
res[i++] = k;
39
}
40
primes = res;
41
return res;
42
}
43
44
function simpleSieve(p) {
45
var primes = _getPrimes();
46
47
for (var i = 0; i < primes.length; i++)
48
if (p.modn(primes[i]) === 0) {
49
if (p.cmpn(primes[i]) === 0) {
50
return true;
51
} else {
52
return false;
53
}
54
}
55
56
return true;
57
}
58
59
function fermatTest(p) {
60
var red = BN.mont(p);
61
return TWO.toRed(red).redPow(p.subn(1)).fromRed().cmpn(1) === 0;
62
}
63
64
function findPrime(bits, gen) {
65
if (bits < 16) {
66
// this is what openssl does
67
if (gen === 2 || gen === 5) {
68
return new BN([0x8c, 0x7b]);
69
} else {
70
return new BN([0x8c, 0x27]);
71
}
72
}
73
gen = new BN(gen);
74
var runs, comp;
75
function generateRandom(bits) {
76
runs = -1;
77
var out = new BN(randomBytes(Math.ceil(bits / 8)));
78
while (out.bitLength() > bits) {
79
out.ishrn(1);
80
}
81
if (out.isEven()) {
82
out.iadd(ONE);
83
}
84
if (!out.testn(1)) {
85
out.iadd(TWO);
86
}
87
if (!gen.cmp(TWO)) {
88
while (out.mod(TWENTYFOUR).cmp(ELEVEN)) {
89
out.iadd(FOUR);
90
}
91
comp = {
92
major: [TWENTYFOUR],
93
minor: [TWELVE]
94
};
95
} else if (!gen.cmp(FIVE)) {
96
rem = out.mod(TEN);
97
while (rem.cmp(THREE)) {
98
out.iadd(FOUR);
99
rem = out.mod(TEN);
100
}
101
comp = {
102
major: [FOUR, SIXTEEN],
103
minor: [TWO, EIGHT]
104
};
105
} else {
106
comp = {
107
major: [FOUR],
108
minor: [TWO]
109
};
110
}
111
return out;
112
}
113
var num = generateRandom(bits);
114
115
var n2 = num.shrn(1);
116
117
while (true) {
118
while (num.bitLength() > bits) {
119
num = generateRandom(bits);
120
n2 = num.shrn(1);
121
}
122
runs++;
123
if (simpleSieve(n2) && simpleSieve(num) &&
124
fermatTest(n2) && fermatTest(num) &&
125
millerRabin.test(n2) && millerRabin.test(num)) {
126
return num;
127
}
128
num.iadd(comp.major[runs%comp.major.length]);
129
n2.iadd(comp.minor[runs%comp.minor.length]);
130
}
131
132
}
133