/* * This taken from the source code of tgnet library v. 1.0 * It is licensed under GNU GPL v. 2 or later. * You should have received a copy of the license in this archive (see LICENSE). * * Copyright Nikolai Kudashov, 2015. */ #include inline uint64_t gcd(uint64_t a, uint64_t b) { while (a != 0 && b != 0) { while ((b & 1) == 0) { b >>= 1; } while ((a & 1) == 0) { a >>= 1; } if (a > b) { a -= b; } else { b -= a; } } return b == 0 ? a : b; } inline Php::Value factorize(Php::Parameters ¶meters) { uint64_t what = (int64_t) parameters[0]; uint32_t p; uint32_t q; int32_t it = 0, i, j; uint64_t g = 0; for (i = 0; i < 3 || it < 1000; i++) { uint64_t t = ((lrand48() & 15) + 17) % what; uint64_t x = (long long) lrand48() % (what - 1) + 1, y = x; int32_t lim = 1 << (i + 18); for (j = 1; j < lim; j++) { ++it; uint64_t a = x, b = x, c = t; while (b) { if (b & 1) { c += a; if (c >= what) { c -= what; } } a += a; if (a >= what) { a -= what; } b >>= 1; } x = c; uint64_t z = x < y ? what + x - y : x - y; g = gcd(z, what); if (g != 1) { break; } if (!(j & (j - 1))) { y = x; } } if (g > 1 && g < what) { break; } } if (g > 1 && g < what) { p = (uint32_t) g; q = (uint32_t) (what / g); if (p > q) { uint32_t tmp = p; p = q; q = tmp; } Php::Value result; result[0] = (int32_t) p; result[1] = (int32_t) q; return result; } else { throw Php::Exception("Factorization failed!"); return false; } } extern "C" { PHPCPP_EXPORT void *get_module() { static Php::Extension extension("primemodule", "1.0"); extension.add("factorize", { Php::ByVal("pq") }); return extension; } }