* @function ShorsAlgorithm * @description Classical implementation of Shor's Algorithm. * @param {Integer} num - Find a non-trivial factor of this number. * @returns {Integer} - A non-trivial factor of num. * @see https://en.wikipedia.org/wiki/Shor%27s_algorithm * @see https://www.youtube.com/w
(num)
| 23 | * factor with N, which can then be found using Euclid's GCD algorithm. |
| 24 | */ |
| 25 | function ShorsAlgorithm(num) { |
| 26 | const N = BigInt(num) |
| 27 | |
| 28 | while (true) { |
| 29 | // generate random g such that 1 < g < N |
| 30 | const g = BigInt(Math.floor(Math.random() * (num - 1)) + 2) |
| 31 | |
| 32 | // check if g shares a factor with N |
| 33 | // if it does, find and return the factor |
| 34 | let K = gcd(g, N) |
| 35 | if (K !== 1) return K |
| 36 | |
| 37 | // find p such that g^p = mN + 1 |
| 38 | const p = findP(g, N) |
| 39 | |
| 40 | // p needs to be even for it's half to be an integer |
| 41 | if (p % 2n === 1n) continue |
| 42 | |
| 43 | const base = g ** (p / 2n) // g^(p/2) |
| 44 | const upper = base + 1n // g^(p/2) + 1 |
| 45 | const lower = base - 1n // g^(p/2) - 1 |
| 46 | |
| 47 | // upper and lower can't be a multiple of N |
| 48 | if (upper % N === 0n || lower % N === 0n) continue |
| 49 | |
| 50 | // either upper or lower must share a factor with N |
| 51 | K = gcd(upper, N) |
| 52 | if (K !== 1) return K // upper shares a factor |
| 53 | return gcd(lower, N) // otherwise lower shares a factor |
| 54 | } |
| 55 | } |
| 56 | |
| 57 | /** |
| 58 | * @function findP |
no test coverage detected