-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgenerate_primes.js
61 lines (57 loc) · 1.43 KB
/
generate_primes.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
'use strict'
const {bitLength, isProbablyPrime, randBetween} = require('bigint-crypto-utils')
const tf = require('typeforce')
const delta = [6n, 4n, 2n, 4n, 2n, 4n, 6n, 2n]
/**
* Generates a random prime with specific number of bits.
* @param {Number} bits The number of bits the prime with contain.
* @returns {BigInteger} The generated prime.
* @private
*/
function randomPrime(bits) {
tf(tf.tuple(tf.Number), arguments)
const minPrime = 1n << BigInt(bits - 1)
const maxPrime = (1n << BigInt(bits)) - 1n
let p
while (true) {
p = randBetween(maxPrime, minPrime)
p += 31n - (p % 30n)
let deltaIdx = 0
while (bitLength(p) !== bits) {
if (isProbablyPrime(p, 1)) {
break
}
p += delta[deltaIdx++ % delta.length]
}
if (bitLength(p) !== bits) {
continue
}
if (isProbablyPrime(p, 24)) {
return p
}
}
}
/**
* Generates two primes suitable for an RSA private key.
* @param {Number} modulusBits The bits in the key's modulus.
* @returns {Primes} The generated primes.
* @private
*/
function generatePrimes(modulusBits) {
tf(tf.tuple(tf.Number), arguments)
const pBits = Math.ceil(modulusBits / 2)
const qBits = modulusBits - pBits
let p, q
let n
do {
n = 0n
p = randomPrime(pBits)
q = randomPrime(qBits)
n = p * q
} while (bitLength(n) !== modulusBits)
if (p < q) {
return {p: q, q: p}
}
return {p, q}
}
module.exports = generatePrimes