Factorizator.ts 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import bigInt from "big-integer";
  2. import {modExp} from "../Helpers";
  3. export class Factorizator {
  4. /**
  5. * Calculates the greatest common divisor
  6. * @param a {BigInteger}
  7. * @param b {BigInteger}
  8. * @returns {BigInteger}
  9. */
  10. static gcd(a:bigInt.BigInteger, b:bigInt.BigInteger) {
  11. while (b.neq(bigInt.zero)) {
  12. const temp = b;
  13. b = a.remainder(b);
  14. a = temp
  15. }
  16. return a
  17. }
  18. /**
  19. * Factorizes the given number and returns both the divisor and the number divided by the divisor
  20. * @param pq {BigInteger}
  21. * @returns {{p: *, q: *}}
  22. */
  23. static factorize(pq:bigInt.BigInteger) {
  24. if (pq.remainder(2).equals(bigInt.zero)) {
  25. return { p: bigInt(2), q: pq.divide(bigInt(2)) }
  26. }
  27. let y = bigInt.randBetween(bigInt(1),pq.minus(1));
  28. const c = bigInt.randBetween(bigInt(1),pq.minus(1));
  29. const m = bigInt.randBetween(bigInt(1),pq.minus(1));
  30. let g = bigInt.one;
  31. let r = bigInt.one;
  32. let q = bigInt.one;
  33. let x = bigInt.zero;
  34. let ys = bigInt.zero;
  35. let k;
  36. while (g.eq(bigInt.one)) {
  37. x = y;
  38. for (let i = 0; bigInt(i).lesser(r); i++) {
  39. y = (modExp(y, bigInt(2), pq)).add(c).remainder(pq)
  40. }
  41. k = bigInt.zero;
  42. while (k.lesser(r) && g.eq(bigInt.one)) {
  43. ys = y;
  44. const condition = bigInt.min(m, r.minus(k));
  45. for (let i = 0; bigInt(i).lesser(condition); i++) {
  46. y = (modExp(y, bigInt(2), pq)).add(c).remainder(pq);
  47. q = q.multiply(x.minus(y).abs()).remainder(pq)
  48. }
  49. g = Factorizator.gcd(q, pq);
  50. k = k.add(m)
  51. }
  52. r = r.multiply(2)
  53. }
  54. if (g.eq(pq)) {
  55. while (true) {
  56. ys = (modExp(ys, bigInt(2), pq)).add(c).remainder(pq);
  57. g = Factorizator.gcd(x.minus(ys).abs(), pq);
  58. if (g.greater(1)) {
  59. break
  60. }
  61. }
  62. }
  63. const p = g;
  64. q = pq.divide(g);
  65. return p < q ? { p: p, q: q } : { p: q, q: p }
  66. }
  67. }