Modifying prime function to make use of BigInteger functino

This commit is contained in:
danogentili 2016-07-30 17:16:54 +02:00
parent 9e08e6fe8f
commit f524ae1121
5 changed files with 88 additions and 46 deletions

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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):

View File

@ -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
*