97 lines
2.5 KiB
JavaScript
97 lines
2.5 KiB
JavaScript
const BigInt = require('big-integer');
|
|
const { modExp } = require('../Helpers');
|
|
|
|
class Factorizator {
|
|
/**
|
|
* Calculates the greatest common divisor
|
|
* @param a {BigInteger}
|
|
* @param b {BigInteger}
|
|
* @returns {BigInteger}
|
|
*/
|
|
static gcd(a, b) {
|
|
while (b.neq(BigInt.zero)) {
|
|
const temp = b;
|
|
b = a.remainder(b);
|
|
a = temp;
|
|
}
|
|
return a;
|
|
}
|
|
|
|
/**
|
|
* Factorizes the given number and returns both the divisor and the number divided by the divisor
|
|
* @param pq {BigInteger}
|
|
* @returns {{p: *, q: *}}
|
|
*/
|
|
static factorize(pq) {
|
|
if (pq.remainder(2)
|
|
.equals(BigInt.zero)) {
|
|
return {
|
|
p: BigInt(2),
|
|
q: pq.divide(BigInt(2)),
|
|
};
|
|
}
|
|
let y = BigInt.randBetween(BigInt(1), pq.minus(1));
|
|
const c = BigInt.randBetween(BigInt(1), pq.minus(1));
|
|
const m = BigInt.randBetween(BigInt(1), pq.minus(1));
|
|
|
|
let g = BigInt.one;
|
|
let r = BigInt.one;
|
|
let q = BigInt.one;
|
|
let x = BigInt.zero;
|
|
let ys = BigInt.zero;
|
|
let k;
|
|
|
|
while (g.eq(BigInt.one)) {
|
|
x = y;
|
|
for (let i = 0; BigInt(i)
|
|
.lesser(r); i++) {
|
|
y = (modExp(y, BigInt(2), pq)).add(c)
|
|
.remainder(pq);
|
|
}
|
|
k = BigInt.zero;
|
|
|
|
while (k.lesser(r) && g.eq(BigInt.one)) {
|
|
ys = y;
|
|
const condition = BigInt.min(m, r.minus(k));
|
|
for (let i = 0; BigInt(i)
|
|
.lesser(condition); i++) {
|
|
y = (modExp(y, BigInt(2), pq)).add(c)
|
|
.remainder(pq);
|
|
q = q.multiply(x.minus(y)
|
|
.abs())
|
|
.remainder(pq);
|
|
}
|
|
g = Factorizator.gcd(q, pq);
|
|
k = k.add(m);
|
|
}
|
|
|
|
r = r.multiply(2);
|
|
}
|
|
|
|
if (g.eq(pq)) {
|
|
// eslint-disable-next-line no-constant-condition
|
|
while (true) {
|
|
ys = (modExp(ys, BigInt(2), pq)).add(c)
|
|
.remainder(pq);
|
|
g = Factorizator.gcd(x.minus(ys)
|
|
.abs(), pq);
|
|
|
|
if (g.greater(1)) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
const p = g;
|
|
q = pq.divide(g);
|
|
return p < q ? {
|
|
p,
|
|
q,
|
|
} : {
|
|
p: q,
|
|
q: p,
|
|
};
|
|
}
|
|
}
|
|
|
|
module.exports = Factorizator;
|