From fced0ddc0ffc70361eff2db5aa60d9c60b023ac3 Mon Sep 17 00:00:00 2001 From: danogentili Date: Mon, 18 Jul 2016 18:43:50 +0200 Subject: [PATCH] Update --- mtproto.php | 6 +- mtproto.py | 3 +- prime.php | 335 ++++++++++++++++++++++------------------------------ prime.py | 3 +- 4 files changed, 149 insertions(+), 198 deletions(-) diff --git a/mtproto.php b/mtproto.php index 43c19879..9f6f8dd4 100755 --- a/mtproto.php +++ b/mtproto.php @@ -174,6 +174,7 @@ class Session $this->MAX_RETRY = 5; $this->AUTH_MAX_RETRY = 5; $this->struct = new \danog\PHP\Struct(); + $this->PrimeModule = new PrimeModule(); try { $this->tl = new TL('https://core.telegram.org/schema/mtproto-json'); } catch (Exception $e) { @@ -273,7 +274,8 @@ class Session $public_key_fingerprint = $ResPQ['server_public_key_fingerprints'][0]; $pq_bytes = $ResPQ['pq']; $pq = bytes_to_long($pq_bytes); - list($p, $q) = primefactors($pq); + var_dump($this->PrimeModule->primefactors($pq)); + list($p, $q) = $this->PrimeModule->primefactors($pq); if ($p > $q) { list($p, $q) = [$q, $p]; } @@ -310,7 +312,7 @@ class Session pyjslib_printnl(sprintf('Server-client time delta = %.1f s', $this->timedelta)); $dh_prime = new bytes_to_long($dh_prime_str); $g_a = new bytes_to_long($g_a_str); - assert(prime::isprime($dh_prime)); + assert($this->PrimeModule->isprime($dh_prime)); $retry_id = 0; $b_str = random_bytes(256); $b = new bytes_to_long($b_str); diff --git a/mtproto.py b/mtproto.py index 4e6b932c..0d8f26b0 100644 --- a/mtproto.py +++ b/mtproto.py @@ -145,8 +145,9 @@ class Session: public_key_fingerprint = ResPQ['server_public_key_fingerprints'][0] pq_bytes = ResPQ['pq'] - vis(pq_bytes) pq = bytes_to_long(pq_bytes) + print(prime.primefactors(2118588165281151121)) + exit() [p, q] = prime.primefactors(pq) if p > q: (p, q) = (q, p) assert p*q == pq and p < q diff --git a/prime.php b/prime.php index 98296003..4f2d51c9 100644 --- a/prime.php +++ b/prime.php @@ -2,228 +2,177 @@ set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php'); require_once 'libpy2php.php'; -function everynth($array, $n) -{ - $result = []; - $i = -1; - foreach ($array as $key => $value) { - if ($i++ == $n) { - $i = 0; - } - if ($i == 0) { - $result[$key] = $value; +class PrimeModule { + function __construct() { + $this->smallprimeset = array_unique($this->primesbelow(100000)); + $this->_smallprimeset = 100000; + $this->smallprimes = $this->primesbelow(10000); + } + function primesbelow($N) { + $res = []; + for ($i = 2; $i <= $N; $i++) + { + if($i % 2 != 1) continue; + $d = 3; + $x = sqrt($i); + while ($i % $d != 0 && $d < $x) $d += 2; + if((($i % $d == 0 && $i != $d) * 1) == 0) $res[] = $i; } + return $res; } - return $result; -} -function array_merge_ignore_keys($array1, $array2) -{ - if (count($array1) == count($array2)) { - $i = -1; - foreach ($array1 as $key => $val) { - $array1[$key] = $array2[$i++]; + function isprime($n, $precision = 7) + { + if (($n == 1) || (($n % 2) == 0)) { + return false; + } elseif (($n < 1)) { + throw new Exception('Out of bounds, first argument must be > 0'); + } elseif (($n < $this->_smallprimeset)) { + return in_array($n, $this->smallprimeset); } - } else { - return; - } - - return $array1; -} -function primesbelow($N) -{ - $correction = (($N % 6) > 1); - $N = [0 => $N, 1 => ($N - 1), 2 => ($N + 4), 3 => ($N + 3), 4 => ($N + 2), 5 => ($N + 1)][($N % 6)]; - $sieve = array_fill(0, floor($N / 3), true); - $sieve[0] = false; - foreach (pyjslib_range(floor((int)(pow($N, 0.5)) / 3) + 1) as $i) { - if ($sieve[$i]) { - $k = ((3 * $i) + 1) | 1; - foreach (pyjslib_range(floor(($k*$k) / 3), 2*$k) as $key) { - + $d = ($n - 1); + $s = 0; + while (($d % 2) == 0) { + $d = floor($d / 2); + $s += 1; + } + foreach (pyjslib_range($precision) as $repeat) { + $a = rand(2, ($n - 2)); + $x = posmod(pow($a, $d), $n); + if (($x == 1) || ($x == ($n - 1))) { + continue; } - array_fill(0, floor((floor($N / 6) - floor(($k * $k) / 6) - 1) / $k) + 1, false) - $sieve = array_merge( - $sieve, array_merge( - everynth( - array_splice( - $sieve, floor( - ( - $k * $k + 4 * $k - 2 * $k * ($i % 2) - ) / 3 - ) - ), 2 * $k - ), - ( - - ) - ) - ); - } - } - var_dump($sieve); - - return [2, 3] + array_map(function ($i, $sieve) { - if ($sieve[$i]) { - return (3 * $i + 1) | 1; - } - }, pyjslib_range(1, (($N / 3) - $correction)), $sieve); -} -$smallprimeset = array_unique(primesbelow(100000)); -$_smallprimeset = 100000; -function isprime($n, $precision = 7) -{ - if (($n == 1) || (($n % 2) == 0)) { - return false; - } elseif (($n < 1)) { - throw new $ValueError('Out of bounds, first argument must be > 0'); - } elseif (($n < $_smallprimeset)) { - return in_array($n, $smallprimeset); - } - $d = ($n - 1); - $s = 0; - while ((($d % 2) == 0)) { - $d = floor($d / 2); - $s += 1; - } - foreach (pyjslib_range($precision) as $repeat) { - $a = random::randrange(2, ($n - 2)); - $x = pow($a, $d, $n); - if (($x == 1) || ($x == ($n - 1))) { - continue; - } - foreach (pyjslib_range(($s - 1)) as $r) { - $x = pow($x, 2, $n); - if (($x == 1)) { - return false; - } - if (($x == ($n - 1))) { - break; + foreach (pyjslib_range(($s - 1)) as $r) { + $x = posmod(pow($x, 2), $n); + if (($x == 1)) { + return false; + } + if (($x == ($n - 1))) { + break; + } } } - } - return true; -} -function pollard_brent($n) -{ - if ((($n % 2) == 0)) { - return 2; + return true; } - if ((($n % 3) == 0)) { - return 3; - } - list($y, $c, $m) = [random::randint(1, ($n - 1)), random::randint(1, ($n - 1)), random::randint(1, ($n - 1))]; - list($g, $r, $q) = [1, 1, 1]; - while (($g == 1)) { - $x = $y; - foreach (pyjslib_range($r) as $i) { - $y = ((pow($y, 2, $n) + $c) % $n); + function pollard_brent($n) + { + if ((($n % 2) == 0)) { + return 2; } - $k = 0; - while (($k < $r) && ($g == 1)) { - $ys = $y; - foreach (pyjslib_range(min($m, ($r - $k))) as $i) { + if ((($n % 3) == 0)) { + return 3; + } + list($y, $c, $m) = [rand(1, ($n - 1)), rand(1, ($n - 1)), rand(1, ($n - 1))]; + list($g, $r, $q) = [1, 1, 1]; + while (($g == 1)) { + $x = $y; + foreach (pyjslib_range($r) as $i) { $y = ((pow($y, 2, $n) + $c) % $n); - $q = (($q * abs(($x - $y))) % $n); } - $g = gcd($q, $n); - $k += $m; + $k = 0; + while (($k < $r) && ($g == 1)) { + $ys = $y; + foreach (pyjslib_range(min($m, ($r - $k))) as $i) { + $y = ((pow($y, 2, $n) + $c) % $n); + $q = (($q * abs(($x - $y))) % $n); + } + $g = gcd($q, $n); + $k += $m; + } + $r *= 2; } - $r *= 2; - } - if (($g == $n)) { - while (true) { - $ys = ((pow($ys, 2, $n) + $c) % $n); - $g = gcd(abs(($x - $ys)), $n); - if (($g > 1)) { - break; + if (($g == $n)) { + while (true) { + $ys = ((pow($ys, 2, $n) + $c) % $n); + $g = gcd(abs(($x - $ys)), $n); + if (($g > 1)) { + break; + } } } - } - return $g; -} -$smallprimes = primesbelow(10000); -function primefactors($n, $sort = false) -{ - global $smallprimes; - $factors = []; - $limit = (pyjslib_int(pow($n, 0.5)) + 1); - foreach ($smallprimes as $checker) { - if (($checker > $limit)) { - break; - } - while ((($n % $checker) == 0)) { - $factors[] = $checker; - $n = floor($n / $checker); - $limit = (pyjslib_int(pow($n, 0.5)) + 1); + return $g; + } + function primefactors($n, $sort = false) + { + $factors = []; + $limit = ((int)(pow($n, 0.5)) + 1); + foreach ($this->smallprimes as $checker) { if (($checker > $limit)) { break; } + while (($n % $checker) == 0) { + $factors[] = $checker; + $n = floor($n / $checker); + $limit = ((int)(pow($n, 0.5)) + 1); + if (($checker > $limit)) { + break; + } + } } - } - if (($n < 2)) { + if (($n < 2)) { + return $factors; + } + while (($n > 1)) { + if ($this->isprime($n)) { + $factors[] = $n; + break; + } + $factor = $this->pollard_brent($n); + $factors[] = $this->primefactors($factor); + $n = floor($n / $factor); + } + if ($sort) { + $factors = sort($factors); + } + return $factors; } - while (($n > 1)) { - if (isprime($n)) { - $factors[] = $n; - break; + function factorization($n) + { + $factors = []; + foreach (primefactors($n) as $p1) { + if(isset($factors[$p1])) { + $factors[$p1] += 1; + } else { + $factors[$p1] = 1; + } } - $factor = pollard_brent($n); - $factors->extend(primefactors($factor)); - $n = floor($n / $factor); - } - if ($sort) { - $factors->sort(); - } - return $factors; -} -function factorization($n) -{ - $factors = []; - foreach (primefactors($n) as $p1) { - try { - $factors[$p1] += 1; - } catch (KeyError $e) { - $factors[$p1] = 1; + return $factors; + } + function totient($n) + { + $totients = []; + if (($n == 0)) { + return 1; } - } + if(isset($totients[$n])) { + return $totients[$n]; + } + $tot = 1; + foreach (factorization($n) as $p => $exp) { + $tot *= (($p - 1) * pow($p, ($exp - 1))); + } + $totients[$n] = $tot; - return $factors; -} -$totients = []; -function totient($n) -{ - if (($n == 0)) { - return 1; + return $tot; } - try { - return $totients[$n]; - } catch (KeyError $e) { - } - $tot = 1; - foreach (factorization($n)->items() as list($p, $exp)) { - $tot *= (($p - 1) * pow($p, ($exp - 1))); - } - $totients[$n] = $tot; + function gcd($a, $b) + { + if (($a == $b)) { + return $a; + } + while (($b > 0)) { + list($a, $b) = [$b, ($a % $b)]; + } - return $tot; -} -function gcd($a, $b) -{ - if (($a == $b)) { return $a; } - while (($b > 0)) { - list($a, $b) = [$b, ($a % $b)]; + function lcm($a, $b) + { + return floor(abs(($a * $b)) / gcd($a, $b)); } - return $a; -} -function lcm($a, $b) -{ - return floor(abs(($a * $b)) / gcd($a, $b)); -} +} \ No newline at end of file diff --git a/prime.py b/prime.py index e1e1ceed..051179f6 100644 --- a/prime.py +++ b/prime.py @@ -14,7 +14,6 @@ def primesbelow(N): k = (3 * i + 1) | 1 sieve[k*k // 3::2*k] = [False] * ((N//6 - (k*k)//6 - 1)//k + 1) sieve[(k*k + 4*k - 2*k*(i%2)) // 3::2*k] = [False] * ((N // 6 - (k*k + 4*k - 2*k*(i%2))//6 - 1) // k + 1) - exit() return [2, 3] + [(3 * i + 1) | 1 for i in range(1, N//3 - correction) if sieve[i]] smallprimeset = set(primesbelow(100000)) @@ -94,11 +93,11 @@ def primefactors(n, sort=False): if checker > limit: break if n < 2: return factors - while n > 1: if isprime(n): factors.append(n) break + print(pollard_brent(n)) factor = pollard_brent(n) # trial division did not fully factor, switch to pollard-brent factors.extend(primefactors(factor)) # recurse to factor the not necessarily prime factor returned by pollard-brent n //= factor