1
0
mirror of https://github.com/danog/MadelineProto.git synced 2024-11-27 08:54:44 +01:00

Improve factorization

This commit is contained in:
Daniil Gentili 2021-12-13 14:07:27 +01:00
parent 4b459d083c
commit df03038f15

View File

@ -134,10 +134,9 @@ trait AuthKeyHandler
* ***********************************************************************
* Compute p and q
*/
$pq = new BigInteger((string) $pq_bytes, 256);
$pqStr = (string) $pq;
$ok = false;
$pq = Tools::unpackSignedLong(\strrev($pq_bytes));
foreach ([
'auto_single',
'native_single_cpp',
'python_single_alt',
'python_single',
@ -145,37 +144,43 @@ trait AuthKeyHandler
'wolfram'
] as $method) {
$this->logger->logger("Factorizing with $method (please wait, might take a while)");
if ($method !== 'native_single_cpp') {
$this->logger->logger("Install https://prime.madelineproto.xyz to speed this up!");
}
$q = new BigInteger(0);
$p = 0;
$q = 0;
try {
if ($method === 'wolfram') {
$p = new BigInteger(yield from $this->wolframSingle($pqStr));
$p = yield from $this->wolframSingle($pq);
} else {
$p = new BigInteger(@PrimeModule::$method($pqStr));
$p = PrimeModule::$method($pq);
}
} catch (\Throwable $e) {
$this->logger->logger("While factorizing with $method: $e");
}
if (!$p->equals(\danog\MadelineProto\Magic::$zero)) {
$q = $pq->divide($p)[0];
if ($p->compare($q) > 0) {
if ($p) {
$q = $pq / $p;
if ($p > $q) {
list($p, $q) = [$q, $p];
}
}
if ($pq->equals($p->multiply($q))) {
if ($pq === $p*$q) {
$ok = true;
break;
}
}
if (!$pq->equals($p->multiply($q))) {
throw new \danog\MadelineProto\SecurityException("Couldn't compute p and q, install prime.madelineproto.xyz to fix. Original pq: {$pq}, computed p: {$p}, computed q: {$q}, computed pq: ".$p->multiply($q));
}
if (!$ok) {
throw new \danog\MadelineProto\SecurityException("Couldn't compute p and q, install prime.madelineproto.xyz to fix. Original pq: {$pq}, computed p: {$p}, computed q: {$q}, computed pq: ".$p*$q);
}
$this->logger->logger('Factorization '.$pq.' = '.$p.' * '.$q, \danog\MadelineProto\Logger::VERBOSE);
/*
* ***********************************************************************
* Serialize object for req_DH_params
*/
$p_bytes = $p->toBytes();
$q_bytes = $q->toBytes();
$p_bytes = \strrev(Tools::packUnsignedInt($p));
$q_bytes = \strrev(Tools::packUnsignedInt($q));
$new_nonce = \danog\MadelineProto\Tools::random(32);
$data_unserialized = ['_' => 'p_q_inner_data'.($expires_in < 0 ? '' : '_temp').'_dc', 'pq' => $pq_bytes, 'p' => $p_bytes, 'q' => $q_bytes, 'nonce' => $nonce, 'server_nonce' => $server_nonce, 'new_nonce' => $new_nonce, 'expires_in' => $expires_in, 'dc' => $datacenter_id];
$p_q_inner_data = (yield from $this->TL->serializeObject(['type' => ''], $data_unserialized, 'p_q_inner_data'));