Update
This commit is contained in:
parent
b808531197
commit
fced0ddc0f
@ -174,6 +174,7 @@ class Session
|
|||||||
$this->MAX_RETRY = 5;
|
$this->MAX_RETRY = 5;
|
||||||
$this->AUTH_MAX_RETRY = 5;
|
$this->AUTH_MAX_RETRY = 5;
|
||||||
$this->struct = new \danog\PHP\Struct();
|
$this->struct = new \danog\PHP\Struct();
|
||||||
|
$this->PrimeModule = new PrimeModule();
|
||||||
try {
|
try {
|
||||||
$this->tl = new TL('https://core.telegram.org/schema/mtproto-json');
|
$this->tl = new TL('https://core.telegram.org/schema/mtproto-json');
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
@ -273,7 +274,8 @@ class Session
|
|||||||
$public_key_fingerprint = $ResPQ['server_public_key_fingerprints'][0];
|
$public_key_fingerprint = $ResPQ['server_public_key_fingerprints'][0];
|
||||||
$pq_bytes = $ResPQ['pq'];
|
$pq_bytes = $ResPQ['pq'];
|
||||||
$pq = bytes_to_long($pq_bytes);
|
$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) {
|
if ($p > $q) {
|
||||||
list($p, $q) = [$q, $p];
|
list($p, $q) = [$q, $p];
|
||||||
}
|
}
|
||||||
@ -310,7 +312,7 @@ class Session
|
|||||||
pyjslib_printnl(sprintf('Server-client time delta = %.1f s', $this->timedelta));
|
pyjslib_printnl(sprintf('Server-client time delta = %.1f s', $this->timedelta));
|
||||||
$dh_prime = new bytes_to_long($dh_prime_str);
|
$dh_prime = new bytes_to_long($dh_prime_str);
|
||||||
$g_a = new bytes_to_long($g_a_str);
|
$g_a = new bytes_to_long($g_a_str);
|
||||||
assert(prime::isprime($dh_prime));
|
assert($this->PrimeModule->isprime($dh_prime));
|
||||||
$retry_id = 0;
|
$retry_id = 0;
|
||||||
$b_str = random_bytes(256);
|
$b_str = random_bytes(256);
|
||||||
$b = new bytes_to_long($b_str);
|
$b = new bytes_to_long($b_str);
|
||||||
|
@ -145,8 +145,9 @@ class Session:
|
|||||||
public_key_fingerprint = ResPQ['server_public_key_fingerprints'][0]
|
public_key_fingerprint = ResPQ['server_public_key_fingerprints'][0]
|
||||||
|
|
||||||
pq_bytes = ResPQ['pq']
|
pq_bytes = ResPQ['pq']
|
||||||
vis(pq_bytes)
|
|
||||||
pq = bytes_to_long(pq_bytes)
|
pq = bytes_to_long(pq_bytes)
|
||||||
|
print(prime.primefactors(2118588165281151121))
|
||||||
|
exit()
|
||||||
[p, q] = prime.primefactors(pq)
|
[p, q] = prime.primefactors(pq)
|
||||||
if p > q: (p, q) = (q, p)
|
if p > q: (p, q) = (q, p)
|
||||||
assert p*q == pq and p < q
|
assert p*q == pq and p < q
|
||||||
|
127
prime.php
127
prime.php
@ -2,98 +2,48 @@
|
|||||||
|
|
||||||
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
|
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
|
||||||
require_once 'libpy2php.php';
|
require_once 'libpy2php.php';
|
||||||
function everynth($array, $n)
|
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++)
|
||||||
{
|
{
|
||||||
$result = [];
|
if($i % 2 != 1) continue;
|
||||||
$i = -1;
|
$d = 3;
|
||||||
foreach ($array as $key => $value) {
|
$x = sqrt($i);
|
||||||
if ($i++ == $n) {
|
while ($i % $d != 0 && $d < $x) $d += 2;
|
||||||
$i = 0;
|
if((($i % $d == 0 && $i != $d) * 1) == 0) $res[] = $i;
|
||||||
}
|
|
||||||
if ($i == 0) {
|
|
||||||
$result[$key] = $value;
|
|
||||||
}
|
}
|
||||||
|
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++];
|
|
||||||
}
|
|
||||||
} 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) {
|
|
||||||
|
|
||||||
}
|
|
||||||
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)
|
function isprime($n, $precision = 7)
|
||||||
{
|
{
|
||||||
if (($n == 1) || (($n % 2) == 0)) {
|
if (($n == 1) || (($n % 2) == 0)) {
|
||||||
return false;
|
return false;
|
||||||
} elseif (($n < 1)) {
|
} elseif (($n < 1)) {
|
||||||
throw new $ValueError('Out of bounds, first argument must be > 0');
|
throw new Exception('Out of bounds, first argument must be > 0');
|
||||||
} elseif (($n < $_smallprimeset)) {
|
} elseif (($n < $this->_smallprimeset)) {
|
||||||
return in_array($n, $smallprimeset);
|
return in_array($n, $this->smallprimeset);
|
||||||
}
|
}
|
||||||
$d = ($n - 1);
|
$d = ($n - 1);
|
||||||
$s = 0;
|
$s = 0;
|
||||||
while ((($d % 2) == 0)) {
|
while (($d % 2) == 0) {
|
||||||
$d = floor($d / 2);
|
$d = floor($d / 2);
|
||||||
$s += 1;
|
$s += 1;
|
||||||
}
|
}
|
||||||
foreach (pyjslib_range($precision) as $repeat) {
|
foreach (pyjslib_range($precision) as $repeat) {
|
||||||
$a = random::randrange(2, ($n - 2));
|
$a = rand(2, ($n - 2));
|
||||||
$x = pow($a, $d, $n);
|
$x = posmod(pow($a, $d), $n);
|
||||||
if (($x == 1) || ($x == ($n - 1))) {
|
if (($x == 1) || ($x == ($n - 1))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
foreach (pyjslib_range(($s - 1)) as $r) {
|
foreach (pyjslib_range(($s - 1)) as $r) {
|
||||||
$x = pow($x, 2, $n);
|
$x = posmod(pow($x, 2), $n);
|
||||||
if (($x == 1)) {
|
if (($x == 1)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -113,7 +63,7 @@ function pollard_brent($n)
|
|||||||
if ((($n % 3) == 0)) {
|
if ((($n % 3) == 0)) {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
list($y, $c, $m) = [random::randint(1, ($n - 1)), random::randint(1, ($n - 1)), random::randint(1, ($n - 1))];
|
list($y, $c, $m) = [rand(1, ($n - 1)), rand(1, ($n - 1)), rand(1, ($n - 1))];
|
||||||
list($g, $r, $q) = [1, 1, 1];
|
list($g, $r, $q) = [1, 1, 1];
|
||||||
while (($g == 1)) {
|
while (($g == 1)) {
|
||||||
$x = $y;
|
$x = $y;
|
||||||
@ -144,20 +94,18 @@ function pollard_brent($n)
|
|||||||
|
|
||||||
return $g;
|
return $g;
|
||||||
}
|
}
|
||||||
$smallprimes = primesbelow(10000);
|
|
||||||
function primefactors($n, $sort = false)
|
function primefactors($n, $sort = false)
|
||||||
{
|
{
|
||||||
global $smallprimes;
|
|
||||||
$factors = [];
|
$factors = [];
|
||||||
$limit = (pyjslib_int(pow($n, 0.5)) + 1);
|
$limit = ((int)(pow($n, 0.5)) + 1);
|
||||||
foreach ($smallprimes as $checker) {
|
foreach ($this->smallprimes as $checker) {
|
||||||
if (($checker > $limit)) {
|
if (($checker > $limit)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
while ((($n % $checker) == 0)) {
|
while (($n % $checker) == 0) {
|
||||||
$factors[] = $checker;
|
$factors[] = $checker;
|
||||||
$n = floor($n / $checker);
|
$n = floor($n / $checker);
|
||||||
$limit = (pyjslib_int(pow($n, 0.5)) + 1);
|
$limit = ((int)(pow($n, 0.5)) + 1);
|
||||||
if (($checker > $limit)) {
|
if (($checker > $limit)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -167,16 +115,16 @@ function primefactors($n, $sort = false)
|
|||||||
return $factors;
|
return $factors;
|
||||||
}
|
}
|
||||||
while (($n > 1)) {
|
while (($n > 1)) {
|
||||||
if (isprime($n)) {
|
if ($this->isprime($n)) {
|
||||||
$factors[] = $n;
|
$factors[] = $n;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$factor = pollard_brent($n);
|
$factor = $this->pollard_brent($n);
|
||||||
$factors->extend(primefactors($factor));
|
$factors[] = $this->primefactors($factor);
|
||||||
$n = floor($n / $factor);
|
$n = floor($n / $factor);
|
||||||
}
|
}
|
||||||
if ($sort) {
|
if ($sort) {
|
||||||
$factors->sort();
|
$factors = sort($factors);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $factors;
|
return $factors;
|
||||||
@ -185,27 +133,26 @@ function factorization($n)
|
|||||||
{
|
{
|
||||||
$factors = [];
|
$factors = [];
|
||||||
foreach (primefactors($n) as $p1) {
|
foreach (primefactors($n) as $p1) {
|
||||||
try {
|
if(isset($factors[$p1])) {
|
||||||
$factors[$p1] += 1;
|
$factors[$p1] += 1;
|
||||||
} catch (KeyError $e) {
|
} else {
|
||||||
$factors[$p1] = 1;
|
$factors[$p1] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $factors;
|
return $factors;
|
||||||
}
|
}
|
||||||
$totients = [];
|
|
||||||
function totient($n)
|
function totient($n)
|
||||||
{
|
{
|
||||||
|
$totients = [];
|
||||||
if (($n == 0)) {
|
if (($n == 0)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
try {
|
if(isset($totients[$n])) {
|
||||||
return $totients[$n];
|
return $totients[$n];
|
||||||
} catch (KeyError $e) {
|
|
||||||
}
|
}
|
||||||
$tot = 1;
|
$tot = 1;
|
||||||
foreach (factorization($n)->items() as list($p, $exp)) {
|
foreach (factorization($n) as $p => $exp) {
|
||||||
$tot *= (($p - 1) * pow($p, ($exp - 1)));
|
$tot *= (($p - 1) * pow($p, ($exp - 1)));
|
||||||
}
|
}
|
||||||
$totients[$n] = $tot;
|
$totients[$n] = $tot;
|
||||||
@ -227,3 +174,5 @@ function lcm($a, $b)
|
|||||||
{
|
{
|
||||||
return floor(abs(($a * $b)) / gcd($a, $b));
|
return floor(abs(($a * $b)) / gcd($a, $b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
3
prime.py
3
prime.py
@ -14,7 +14,6 @@ def primesbelow(N):
|
|||||||
k = (3 * i + 1) | 1
|
k = (3 * i + 1) | 1
|
||||||
sieve[k*k // 3::2*k] = [False] * ((N//6 - (k*k)//6 - 1)//k + 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)
|
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]]
|
return [2, 3] + [(3 * i + 1) | 1 for i in range(1, N//3 - correction) if sieve[i]]
|
||||||
|
|
||||||
smallprimeset = set(primesbelow(100000))
|
smallprimeset = set(primesbelow(100000))
|
||||||
@ -94,11 +93,11 @@ def primefactors(n, sort=False):
|
|||||||
if checker > limit: break
|
if checker > limit: break
|
||||||
|
|
||||||
if n < 2: return factors
|
if n < 2: return factors
|
||||||
|
|
||||||
while n > 1:
|
while n > 1:
|
||||||
if isprime(n):
|
if isprime(n):
|
||||||
factors.append(n)
|
factors.append(n)
|
||||||
break
|
break
|
||||||
|
print(pollard_brent(n))
|
||||||
factor = pollard_brent(n) # trial division did not fully factor, switch to pollard-brent
|
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
|
factors.extend(primefactors(factor)) # recurse to factor the not necessarily prime factor returned by pollard-brent
|
||||||
n //= factor
|
n //= factor
|
||||||
|
Loading…
Reference in New Issue
Block a user