PluginProbe ʕ •ᴥ•ʔ
JetBackup – Backup, Restore & Migrate / trunk
JetBackup – Backup, Restore & Migrate vtrunk
3.1.22.3 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.8.1 1.4.9 1.5.0 1.5.1 1.5.1.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.10 1.6.11 1.6.12 1.6.13 1.6.15 1.6.5.1 1.6.8.8 1.6.9 1.6.9.1 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7.5 2.0.8.7 2.0.9.11 2.0.9.14 2.0.9.15 2.0.9.6 2.0.9.7 2.0.9.9 3.1.10.7 3.1.11.1 3.1.12.3 3.1.13.4 3.1.14.17 3.1.15.4 3.1.16.1 3.1.17.5 3.1.18.10 3.1.18.8 3.1.18.9 3.1.19.8 3.1.20.3 3.1.21.3 3.1.7.9 3.1.9.2 trunk 1.1.90 1.1.91 1.2.0 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2
backup / src / JetBackup / 3rdparty / phpseclib3 / Math / PrimeField / Integer.php
backup / src / JetBackup / 3rdparty / phpseclib3 / Math / PrimeField Last commit date
.htaccess 1 year ago Integer.php 1 year ago index.html 1 year ago web.config 1 year ago
Integer.php
396 lines
1 <?php
2
3 declare(strict_types=1);
4
5 /**
6 * Prime Finite Fields
7 *
8 * PHP version 5 and 7
9 *
10 * @author Jim Wigginton <terrafrost@php.net>
11 * @copyright 2017 Jim Wigginton
12 * @license http://www.opensource.org/licenses/mit-license.html MIT License
13 */
14
15 namespace phpseclib3\Math\PrimeField;
16
17 use phpseclib3\Common\Functions\Strings;
18 use phpseclib3\Exception\UnexpectedValueException;
19 use phpseclib3\Math\BigInteger;
20 use phpseclib3\Math\Common\FiniteField\Integer as Base;
21
22 /**
23 * Prime Finite Fields
24 *
25 * @author Jim Wigginton <terrafrost@php.net>
26 */
27 class Integer extends Base
28 {
29 /**
30 * Holds the PrimeField's value
31 *
32 * @var BigInteger
33 */
34 protected $value;
35
36 /**
37 * Keeps track of current instance
38 *
39 * @var int
40 */
41 protected $instanceID;
42
43 /**
44 * Holds the PrimeField's modulo
45 *
46 * @var array<int, BigInteger>
47 */
48 protected static $modulo;
49
50 /**
51 * Holds a pre-generated function to perform modulo reductions
52 *
53 * @var array<int, callable(BigInteger):BigInteger>
54 */
55 protected static $reduce;
56
57 /**
58 * Zero
59 *
60 * @var BigInteger
61 */
62 protected static $zero;
63
64 /**
65 * Default constructor
66 */
67 public function __construct(int $instanceID, BigInteger $num = null)
68 {
69 $this->instanceID = $instanceID;
70 if (!isset($num)) {
71 $this->value = clone static::$zero[static::class];
72 } else {
73 $reduce = static::$reduce[$instanceID];
74 $this->value = $reduce($num);
75 }
76 }
77
78 /**
79 * Set the modulo for a given instance
80 */
81 public static function setModulo(int $instanceID, BigInteger $modulo): void
82 {
83 static::$modulo[$instanceID] = $modulo;
84 }
85
86 /**
87 * Set the modulo for a given instance
88 */
89 public static function setRecurringModuloFunction(int $instanceID, callable $function): void
90 {
91 static::$reduce[$instanceID] = $function;
92 if (!isset(static::$zero[static::class])) {
93 static::$zero[static::class] = new BigInteger();
94 }
95 }
96
97 /**
98 * Delete the modulo for a given instance
99 */
100 public static function cleanupCache(int $instanceID): void
101 {
102 unset(static::$modulo[$instanceID]);
103 unset(static::$reduce[$instanceID]);
104 }
105
106 /**
107 * Returns the modulo
108 */
109 public static function getModulo(int $instanceID): BigInteger
110 {
111 return static::$modulo[$instanceID];
112 }
113
114 /**
115 * Tests a parameter to see if it's of the right instance
116 *
117 * Throws an exception if the incorrect class is being utilized
118 */
119 public static function checkInstance(self $x, self $y): void
120 {
121 if ($x->instanceID != $y->instanceID) {
122 throw new UnexpectedValueException('The instances of the two PrimeField\Integer objects do not match');
123 }
124 }
125
126 /**
127 * Tests the equality of two numbers.
128 */
129 public function equals(self $x): bool
130 {
131 static::checkInstance($this, $x);
132
133 return $this->value->equals($x->value);
134 }
135
136 /**
137 * Compares two numbers.
138 */
139 public function compare(self $x): int
140 {
141 static::checkInstance($this, $x);
142
143 return $this->value->compare($x->value);
144 }
145
146 /**
147 * Adds two PrimeFieldIntegers.
148 *
149 * @return static
150 */
151 public function add(self $x): Integer
152 {
153 static::checkInstance($this, $x);
154
155 $temp = new static($this->instanceID);
156 $temp->value = $this->value->add($x->value);
157 if ($temp->value->compare(static::$modulo[$this->instanceID]) >= 0) {
158 $temp->value = $temp->value->subtract(static::$modulo[$this->instanceID]);
159 }
160
161 return $temp;
162 }
163
164 /**
165 * Subtracts two PrimeFieldIntegers.
166 *
167 * @return static
168 */
169 public function subtract(self $x): Integer
170 {
171 static::checkInstance($this, $x);
172
173 $temp = new static($this->instanceID);
174 $temp->value = $this->value->subtract($x->value);
175 if ($temp->value->isNegative()) {
176 $temp->value = $temp->value->add(static::$modulo[$this->instanceID]);
177 }
178
179 return $temp;
180 }
181
182 /**
183 * Multiplies two PrimeFieldIntegers.
184 *
185 * @return static
186 */
187 public function multiply(self $x): Integer
188 {
189 static::checkInstance($this, $x);
190
191 return new static($this->instanceID, $this->value->multiply($x->value));
192 }
193
194 /**
195 * Divides two PrimeFieldIntegers.
196 *
197 * @return static
198 */
199 public function divide(self $x): Integer
200 {
201 static::checkInstance($this, $x);
202
203 $denominator = $x->value->modInverse(static::$modulo[$this->instanceID]);
204 return new static($this->instanceID, $this->value->multiply($denominator));
205 }
206
207 /**
208 * Performs power operation on a PrimeFieldInteger.
209 *
210 * @return static
211 */
212 public function pow(BigInteger $x): Integer
213 {
214 $temp = new static($this->instanceID);
215 $temp->value = $this->value->powMod($x, static::$modulo[$this->instanceID]);
216
217 return $temp;
218 }
219
220 /**
221 * Calculates the square root
222 *
223 * @link https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm
224 * @return static|false
225 */
226 public function squareRoot()
227 {
228 static $one, $two;
229 if (!isset($one)) {
230 $one = new BigInteger(1);
231 $two = new BigInteger(2);
232 }
233 $reduce = static::$reduce[$this->instanceID];
234 $p_1 = static::$modulo[$this->instanceID]->subtract($one);
235 $q = clone $p_1;
236 $s = BigInteger::scan1divide($q);
237 [$pow] = $p_1->divide($two);
238 for ($z = $one; !$z->equals(static::$modulo[$this->instanceID]); $z = $z->add($one)) {
239 $temp = $z->powMod($pow, static::$modulo[$this->instanceID]);
240 if ($temp->equals($p_1)) {
241 break;
242 }
243 }
244
245 $m = new BigInteger($s);
246 $c = $z->powMod($q, static::$modulo[$this->instanceID]);
247 $t = $this->value->powMod($q, static::$modulo[$this->instanceID]);
248 [$temp] = $q->add($one)->divide($two);
249 $r = $this->value->powMod($temp, static::$modulo[$this->instanceID]);
250
251 while (!$t->equals($one)) {
252 for ($i = clone $one; $i->compare($m) < 0; $i = $i->add($one)) {
253 if ($t->powMod($two->pow($i), static::$modulo[$this->instanceID])->equals($one)) {
254 break;
255 }
256 }
257
258 if ($i->compare($m) == 0) {
259 return false;
260 }
261 $b = $c->powMod($two->pow($m->subtract($i)->subtract($one)), static::$modulo[$this->instanceID]);
262 $m = $i;
263 $c = $reduce($b->multiply($b));
264 $t = $reduce($t->multiply($c));
265 $r = $reduce($r->multiply($b));
266 }
267
268 return new static($this->instanceID, $r);
269 }
270
271 /**
272 * Is Odd?
273 */
274 public function isOdd(): bool
275 {
276 return $this->value->isOdd();
277 }
278
279 /**
280 * Negate
281 *
282 * A negative number can be written as 0-12. With modulos, 0 is the same thing as the modulo
283 * so 0-12 is the same thing as modulo-12
284 *
285 * @return static
286 */
287 public function negate(): Integer
288 {
289 return new static($this->instanceID, static::$modulo[$this->instanceID]->subtract($this->value));
290 }
291
292 /**
293 * Converts an Integer to a byte string (eg. base-256).
294 */
295 public function toBytes(): string
296 {
297 if (isset(static::$modulo[$this->instanceID])) {
298 $length = static::$modulo[$this->instanceID]->getLengthInBytes();
299 return str_pad($this->value->toBytes(), $length, "\0", STR_PAD_LEFT);
300 }
301 return $this->value->toBytes();
302 }
303
304 /**
305 * Converts an Integer to a hex string (eg. base-16).
306 */
307 public function toHex(): string
308 {
309 return Strings::bin2hex($this->toBytes());
310 }
311
312 /**
313 * Converts an Integer to a bit string (eg. base-2).
314 */
315 public function toBits(): string
316 {
317 // return $this->value->toBits();
318 static $length;
319 if (!isset($length)) {
320 $length = static::$modulo[$this->instanceID]->getLength();
321 }
322
323 return str_pad($this->value->toBits(), $length, '0', STR_PAD_LEFT);
324 }
325
326 /**
327 * Returns the w-ary non-adjacent form (wNAF)
328 *
329 * @param int $w optional
330 * @return array<int, int>
331 */
332 public function getNAF(int $w = 1): array
333 {
334 $w++;
335
336 $mask = new BigInteger((1 << $w) - 1);
337 $sub = new BigInteger(1 << $w);
338 //$sub = new BigInteger(1 << ($w - 1));
339 $d = $this->toBigInteger();
340 $d_i = [];
341
342 $i = 0;
343 while ($d->compare(static::$zero[static::class]) > 0) {
344 if ($d->isOdd()) {
345 // start mods
346
347 $bigInteger = $d->testBit($w - 1) ?
348 $d->bitwise_and($mask)->subtract($sub) :
349 //$sub->subtract($d->bitwise_and($mask)) :
350 $d->bitwise_and($mask);
351 // end mods
352 $d = $d->subtract($bigInteger);
353 $d_i[$i] = (int) $bigInteger->toString();
354 } else {
355 $d_i[$i] = 0;
356 }
357 $shift = !$d->equals(static::$zero[static::class]) && $d->bitwise_and($mask)->equals(static::$zero[static::class]) ? $w : 1; // $w or $w + 1?
358 $d = $d->bitwise_rightShift($shift);
359 while (--$shift > 0) {
360 $d_i[++$i] = 0;
361 }
362 $i++;
363 }
364
365 return $d_i;
366 }
367
368 /**
369 * Converts an Integer to a BigInteger
370 */
371 public function toBigInteger(): BigInteger
372 {
373 return clone $this->value;
374 }
375
376 /**
377 * __toString() magic method
378 *
379 * @return string
380 */
381 public function __toString()
382 {
383 return (string) $this->value;
384 }
385
386 /**
387 * __debugInfo() magic method
388 *
389 * @return array
390 */
391 public function __debugInfo()
392 {
393 return ['value' => $this->toHex()];
394 }
395 }
396