mirror of
https://github.com/danog/MadelineProto.git
synced 2024-11-30 10:38:59 +01:00
Modifying prime function to make use of BigInteger functino
This commit is contained in:
parent
9e08e6fe8f
commit
f524ae1121
@ -230,6 +230,7 @@ class Session
|
||||
$server_nonce = $ResPQ['server_nonce'];
|
||||
$public_key_fingerprint = $ResPQ['server_public_key_fingerprints'][0];
|
||||
$pq_bytes = $ResPQ['pq'];
|
||||
|
||||
$pq = new \phpseclib\Math\BigInteger($pq_bytes, 256);
|
||||
var_dump($this->PrimeModule->primefactors($pq));
|
||||
die;
|
||||
|
@ -146,9 +146,8 @@ class Session:
|
||||
|
||||
pq_bytes = ResPQ['pq']
|
||||
pq = bytes_to_long(pq_bytes)
|
||||
print(prime.pollard_brent(15))
|
||||
exit()
|
||||
print(prime.primefactors(1724114033281923457))
|
||||
exit()
|
||||
[p, q] = prime.primefactors(pq)
|
||||
if p > q: (p, q) = (q, p)
|
||||
assert p*q == pq and p < q
|
||||
|
73
prime.php
73
prime.php
@ -75,40 +75,47 @@ class PrimeModule
|
||||
|
||||
public function pollard_brent($n)
|
||||
{
|
||||
if ((($n % 2) == 0)) {
|
||||
$zero = new \phpseclib\Math\BigInteger(0);
|
||||
$one = new \phpseclib\Math\BigInteger(1);
|
||||
$two = new \phpseclib\Math\BigInteger(2);
|
||||
$three = new \phpseclib\Math\BigInteger(3);
|
||||
if ($n->powMod($one, $two)->toString() == "0") {
|
||||
return 2;
|
||||
}
|
||||
if ((($n % 3) == 0)) {
|
||||
if ($n->powMod($one, $three)->toString() == "0") {
|
||||
return 3;
|
||||
}
|
||||
$big = new \phpseclib\Math\BigInteger();
|
||||
$max = new \phpseclib\Math\BigInteger($n - 1);
|
||||
|
||||
$min = new \phpseclib\Math\BigInteger(1);
|
||||
list($y, $c, $m) = [(int) $big->random($min, $max)->toString(), (int) $big->random($min, $max)->toString(), (int) $big->random($min, $max)->toString()];
|
||||
list($g, $r, $q) = [1, 1, 1];
|
||||
while ($g == 1) {
|
||||
$max = $n->subtract($one);
|
||||
list($y, $c, $m) = [new \phpseclib\Math\BigInteger(87552211475113995), new \phpseclib\Math\BigInteger(330422027228888537), new \phpseclib\Math\BigInteger(226866727920975483)];
|
||||
//[$big->random($one, $max), $big->random($one, $max), $big->random($one, $max)];
|
||||
list($g, $r, $q) = [$one, $one, $one];
|
||||
while ($g->equals($one)) {
|
||||
$x = $y;
|
||||
foreach (pyjslib_range($r) as $i) {
|
||||
$y = posmod((posmod(pow($y, 2), $n) + $c), $n);
|
||||
$range = $r;
|
||||
while (!$range->equals($zero)) {
|
||||
$y = $y->powMod($two, $n)->add($c)->powMod($one, $n);
|
||||
$range = $range->subtract($one);
|
||||
}
|
||||
$k = 0;
|
||||
while (($k < $r) && ($g == 1)) {
|
||||
$k = $zero;
|
||||
while ($k->compare($r) == -1 && $g->equals($one)) {
|
||||
$ys = $y;
|
||||
foreach (pyjslib_range(min($m, ($r - $k))) as $i) {
|
||||
$y = posmod((posmod(pow($y, 2), $n) + $c), $n);
|
||||
$q = posmod(($q * abs($x - $y)), $n);
|
||||
$range = $big->min($m, $r->subtract($k));
|
||||
while (!$range->equals($zero)) {
|
||||
$y = $y->powMod($two, $n)->add($c)->powMod($one, $n);
|
||||
$q = $q->multiply($x->subtract($y)->abs())->powMod($one, $n);
|
||||
$range = $range->subtract($one);
|
||||
}
|
||||
$g = $this->gcd($q, $n);
|
||||
$k += $m;
|
||||
$g = $q->gcd($n);
|
||||
$k = $k->add($m);
|
||||
}
|
||||
$r *= 2;
|
||||
$r = $r->multiply($two);
|
||||
}
|
||||
if (($g == $n)) {
|
||||
if ($g->equals($n)) {
|
||||
while (true) {
|
||||
$ys = posmod((posmod(pow($ys, 2), $n) + $c), $n);
|
||||
$g = $this->gcd(abs($x - $ys), $n);
|
||||
if ($g > 1) {
|
||||
$ys = $ys->powMod($two, $n)->add($c)->powMod($one, $n);
|
||||
$g = $x->subtract($ys)->abs()->gcd($n);
|
||||
if ($g->compare($one) == 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -120,25 +127,29 @@ class PrimeModule
|
||||
public function primefactors($n, $sort = false)
|
||||
{
|
||||
$factors = [];
|
||||
$limit = $n->root()->add(1);
|
||||
$n = new \phpseclib\Math\BigInteger(1724114033281923457);
|
||||
$one = new \phpseclib\Math\BigInteger(1);
|
||||
$two = new \phpseclib\Math\BigInteger(2);
|
||||
$limit = $n->root()->add($one);
|
||||
foreach ($this->smallprimes as $checker) {
|
||||
if (($limit < $checker)) {
|
||||
$checker = new \phpseclib\Math\BigInteger($checker);
|
||||
if ($limit->compare($checker) == -1) {
|
||||
break;
|
||||
}
|
||||
while (($n % $checker) == 0) {
|
||||
while ($n->modPow($one, $checker)->toString() == "0") {
|
||||
$factors[] = $checker;
|
||||
$n = floor($n / $checker);
|
||||
$limit = ((int) (pow($n, 0.5)) + 1);
|
||||
if (($checker > $limit)) {
|
||||
$n = $n->divide($checker)[0];
|
||||
$limit = $n->root()->add($one);
|
||||
if ($limit->compare($checker) == -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($n < 2) {
|
||||
if ($n->compare($two) == -1) {
|
||||
return $factors;
|
||||
}
|
||||
while ($n > 1) {
|
||||
if ($this->isprime($n)) {
|
||||
while ($n->compare($two) == 1) {
|
||||
if ($n->isprime()) {
|
||||
$factors[] = $n;
|
||||
break;
|
||||
}
|
||||
|
26
prime.py
26
prime.py
@ -14,14 +14,7 @@ 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)
|
||||
result = []
|
||||
|
||||
for i in range(1, N//3 - correction):
|
||||
if sieve[i]:
|
||||
result.append((3 * i + 1) | 1)
|
||||
return [2, 3] + result
|
||||
|
||||
smallprimes = primesbelow(10000) # might seem low, but 1000*1000 = 1000000, so this will fully factor every composite < 1000000
|
||||
return [2, 3] + [(3 * i + 1) | 1 for i in range(1, N//3 - correction) if sieve[i]]
|
||||
|
||||
smallprimeset = set(primesbelow(100000))
|
||||
_smallprimeset = 100000
|
||||
@ -47,12 +40,12 @@ def isprime(n, precision=7):
|
||||
x = pow(a, d, n)
|
||||
|
||||
if x == 1 or x == n - 1: continue
|
||||
|
||||
for r in range(s - 1):
|
||||
x = pow(x, 2, n)
|
||||
if x == 1: return False
|
||||
if x == n - 1: break
|
||||
else:
|
||||
return False
|
||||
else: return False
|
||||
|
||||
return True
|
||||
|
||||
@ -61,19 +54,24 @@ def pollard_brent(n):
|
||||
if n % 2 == 0: return 2
|
||||
if n % 3 == 0: return 3
|
||||
|
||||
y, c, m = random.randint(1, n-1), random.randint(1, n-1), random.randint(1, n-1)
|
||||
y, c, m = 87552211475113995, 330422027228888537, 226866727920975483
|
||||
#random.randint(1, n-1), random.randint(1, n-1), random.randint(1, n-1)
|
||||
|
||||
g, r, q = 1, 1, 1
|
||||
while g == 1:
|
||||
x = y
|
||||
for i in range(r):
|
||||
y = (pow(y, 2, n) + c) % n
|
||||
print(y)
|
||||
|
||||
k = 0
|
||||
while k < r and g==1:
|
||||
ys = y
|
||||
print(min(m, r-k))
|
||||
for i in range(min(m, r-k)):
|
||||
y = (pow(y, 2, n) + c) % n
|
||||
q = q * abs(x-y) % n
|
||||
exit()
|
||||
g = gcd(q, n)
|
||||
k += m
|
||||
r *= 2
|
||||
@ -86,7 +84,7 @@ def pollard_brent(n):
|
||||
|
||||
return g
|
||||
|
||||
|
||||
smallprimes = primesbelow(10000) # might seem low, but 1000*1000 = 1000000, so this will fully factor every composite < 1000000
|
||||
def primefactors(n, sort=False):
|
||||
factors = []
|
||||
|
||||
@ -100,15 +98,17 @@ 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
|
||||
|
||||
if sort: factors.sort()
|
||||
|
||||
return factors
|
||||
|
||||
def factorization(n):
|
||||
|
@ -1733,6 +1733,37 @@ class BigInteger
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the minimum BigInteger between two BigIntegers.
|
||||
*
|
||||
*
|
||||
* @param \phpseclib\Math\BigInteger $a
|
||||
* @param \phpseclib\Math\BigInteger $b
|
||||
* @return \phpseclib\Math\BigInteger
|
||||
* @access public
|
||||
*/
|
||||
function min($a, $b) {
|
||||
if($a->compare($b) == "1") {
|
||||
return $b;
|
||||
}
|
||||
return $a;
|
||||
}
|
||||
/**
|
||||
* Return the maximum BigInteger between two BigIntegers.
|
||||
*
|
||||
*
|
||||
* @param \phpseclib\Math\BigInteger $a
|
||||
* @param \phpseclib\Math\BigInteger $b
|
||||
* @return \phpseclib\Math\BigInteger
|
||||
* @access public
|
||||
*/
|
||||
function max($a, $b) {
|
||||
if($a->compare($b) == "1") {
|
||||
return $a;
|
||||
}
|
||||
return $b;
|
||||
}
|
||||
/**
|
||||
* Divides a BigInteger by a regular integer
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user