|
@@ -4,25 +4,25 @@ class Factorizator {
|
|
|
|
|
|
/**
|
|
|
* Finds the small multiplier by using Lopatin's method
|
|
|
- * @param what
|
|
|
- * @return {number}
|
|
|
+ * @param what {BigInt}
|
|
|
+ * @return {BigInt}
|
|
|
*/
|
|
|
static findSmallMultiplierLopatin(what) {
|
|
|
- let g = 0;
|
|
|
- for (let i = 0; i < 3; i++) {
|
|
|
- let q = 30 || (helper.getRandomInt(0, 127) & 15) + 17;
|
|
|
- let x = 40 || helper.getRandomInt(0, 1000000000) + 1;
|
|
|
+ let g = 0n;
|
|
|
+ for (let i = 0n; i < 3n; i++) {
|
|
|
+ let q = 30n || (helper.getRandomInt(0, 127) & 15) + 17;
|
|
|
+ let x = 40n || helper.getRandomInt(0, 1000000000) + 1;
|
|
|
|
|
|
|
|
|
let y = x;
|
|
|
- let lim = 1 << (i + 18);
|
|
|
- for (let j = 1; j < lim; j++) {
|
|
|
+ let lim = 1n << (i + 18n);
|
|
|
+ for (let j = 1n; j < lim; j++) {
|
|
|
let a = x;
|
|
|
let b = x;
|
|
|
|
|
|
let c = q;
|
|
|
- while (b !== 0) {
|
|
|
- if ((b & 1) !== 0) {
|
|
|
+ while (b !== 0n) {
|
|
|
+ if (BigInt(b & 1n) !== 0n) {
|
|
|
c += a;
|
|
|
if (c >= what) {
|
|
|
c -= what;
|
|
@@ -32,18 +32,19 @@ class Factorizator {
|
|
|
if (a >= what) {
|
|
|
a -= what;
|
|
|
}
|
|
|
- b >>= 1;
|
|
|
+ b >>= 1n;
|
|
|
}
|
|
|
|
|
|
x = c;
|
|
|
- let z = ((x < y) ? (y - x) : (x - y));
|
|
|
-
|
|
|
+ let z = BigInt((x < y) ? (y - x) : (x - y));
|
|
|
g = this.gcd(z, what);
|
|
|
- if (g !== 1) {
|
|
|
+
|
|
|
+
|
|
|
+ if (g !== 1n) {
|
|
|
break
|
|
|
}
|
|
|
|
|
|
- if ((j & (j - 1)) === 0) {
|
|
|
+ if ((j & (j - 1n)) === 0n) {
|
|
|
y = x;
|
|
|
}
|
|
|
|
|
@@ -52,41 +53,43 @@ class Factorizator {
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
- let p = Math.floor(what / g);
|
|
|
- return Math.min(p, g);
|
|
|
+ let p = what / g;
|
|
|
+
|
|
|
+ return p < g ? p : g;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Calculates the greatest common divisor
|
|
|
- * @param a
|
|
|
- * @param b
|
|
|
- * @returns {number}
|
|
|
+ * @param a {BigInt}
|
|
|
+ * @param b {BigInt}
|
|
|
+ * @returns {BigInt}
|
|
|
*/
|
|
|
static gcd(a, b) {
|
|
|
- while (((a !== 0) && (b !== 0))) {
|
|
|
- while (((b & 1) === 0)) {
|
|
|
- b >>= 1;
|
|
|
+
|
|
|
+ while (((a !== 0n) && (b !== 0n))) {
|
|
|
+ while ((b & 1n) === 0n) {
|
|
|
+ b >>= 1n;
|
|
|
}
|
|
|
- while (((a & 1) === 0)) {
|
|
|
- a >>= 1;
|
|
|
+ while ((a & 1n) === 0n) {
|
|
|
+ a >>= 1n;
|
|
|
}
|
|
|
- if ((a > b)) {
|
|
|
+ if (a > b) {
|
|
|
a -= b;
|
|
|
} else {
|
|
|
b -= a;
|
|
|
}
|
|
|
}
|
|
|
- return ((b === 0) ? a : b);
|
|
|
+ return ((b === 0n) ? a : b);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Factorizes the given number and returns both the divisor and the number divided by the divisor
|
|
|
- * @param pq
|
|
|
- * @returns {{divisor: number, divided: number}}
|
|
|
+ * @param pq {BigInt}
|
|
|
+ * @returns {{p: BigInt, q: BigInt}}
|
|
|
*/
|
|
|
static factorize(pq) {
|
|
|
let divisor = this.findSmallMultiplierLopatin(pq);
|
|
|
- return {divisor: divisor, divided: Math.floor(pq / divisor)}
|
|
|
+ return {p: divisor, q: pq / divisor}
|
|
|
}
|
|
|
}
|
|
|
|