Rev 291 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 291 | Rev 386 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | <?php |
1 | <?php |
2 | 2 | ||
3 | /* |
3 | /* |
4 | * PHP GMP-Supplement implemented using BCMath |
4 | * PHP GMP-Supplement implemented using BCMath |
5 | * Copyright 2020 Daniel Marschall, ViaThinkSoft |
5 | * Copyright 2020 Daniel Marschall, ViaThinkSoft |
6 | * Version 2020-04-07 |
6 | * Version 2020-09-12 |
7 | * |
7 | * |
8 | * Licensed under the Apache License, Version 2.0 (the "License"); |
8 | * Licensed under the Apache License, Version 2.0 (the "License"); |
9 | * you may not use this file except in compliance with the License. |
9 | * you may not use this file except in compliance with the License. |
10 | * You may obtain a copy of the License at |
10 | * You may obtain a copy of the License at |
11 | * |
11 | * |
Line 154... | Line 154... | ||
154 | 154 | ||
155 | // gmp_divexact ( GMP $n , GMP $d ) : GMP |
155 | // gmp_divexact ( GMP $n , GMP $d ) : GMP |
156 | // Exact division of numbers |
156 | // Exact division of numbers |
157 | function gmp_divexact($n, $d) { |
157 | function gmp_divexact($n, $d) { |
158 | bcscale(0); |
158 | bcscale(0); |
159 | return bcdiv($a, $b); |
159 | return bcdiv($n, $d); |
160 | } |
160 | } |
161 | 161 | ||
162 | // gmp_export ( GMP $gmpnumber [, int $word_size = 1 [, int $options = GMP_MSW_FIRST | GMP_NATIVE_ENDIAN ]] ) : string |
162 | // gmp_export ( GMP $gmpnumber [, int $word_size = 1 [, int $options = GMP_MSW_FIRST | GMP_NATIVE_ENDIAN ]] ) : string |
163 | // Export to a binary string |
163 | // Export to a binary string |
164 | function gmp_export($gmpnumber, $word_size = 1, $options = GMP_MSW_FIRST | GMP_NATIVE_ENDIAN) { |
164 | function gmp_export($gmpnumber, $word_size = 1, $options = GMP_MSW_FIRST | GMP_NATIVE_ENDIAN) { |
Line 212... | Line 212... | ||
212 | $t = $t_; |
212 | $t = $t_; |
213 | $t_ = bcsub($temp, bcmul($t, $q, 0), 0); |
213 | $t_ = bcsub($temp, bcmul($t, $q, 0), 0); |
214 | } |
214 | } |
215 | 215 | ||
216 | return [ |
216 | return [ |
217 | 'g' => $this->normalize($a), |
217 | 'g' => /*$this->normalize*/($a), |
218 | 's' => $this->normalize($s), |
218 | 's' => /*$this->normalize*/($s), |
219 | 't' => $this->normalize($t) |
219 | 't' => /*$this->normalize*/($t) |
220 | ]; |
220 | ]; |
221 | } |
221 | } |
222 | 222 | ||
223 | // gmp_hamdist ( GMP $a , GMP $b ) : int |
223 | // gmp_hamdist ( GMP $a , GMP $b ) : int |
224 | // Hamming distance |
224 | // Hamming distance |
Line 276... | Line 276... | ||
276 | bcscale(0); |
276 | bcscale(0); |
277 | 277 | ||
278 | // Source: https://github.com/CityOfZion/neo-php/blob/master/src/Crypto/NumberTheory.php#L246 |
278 | // Source: https://github.com/CityOfZion/neo-php/blob/master/src/Crypto/NumberTheory.php#L246 |
279 | 279 | ||
280 | while (bccomp($a, 0)==-1) { |
280 | while (bccomp($a, 0)==-1) { |
281 | $a=bcadd($m, $a); |
281 | $a=bcadd($b, $a); |
282 | } |
282 | } |
283 | while (bccomp($m, $a)==-1) { |
283 | while (bccomp($b, $a)==-1) { |
284 | $a=bcmod($a, $m); |
284 | $a=bcmod($a, $b); |
285 | } |
285 | } |
286 | $c=$a; |
286 | $c=$a; |
287 | $d=$m; |
287 | $d=$b; |
288 | $uc=1; |
288 | $uc=1; |
289 | $vc=0; |
289 | $vc=0; |
290 | $ud=0; |
290 | $ud=0; |
291 | $vd=1; |
291 | $vd=1; |
292 | while (bccomp($c, 0)!=0) { |
292 | while (bccomp($c, 0)!=0) { |
Line 304... | Line 304... | ||
304 | $result=''; |
304 | $result=''; |
305 | if (bccomp($d, 1)==0) { |
305 | if (bccomp($d, 1)==0) { |
306 | if (bccomp($ud, 0)==1) { |
306 | if (bccomp($ud, 0)==1) { |
307 | $result=$ud; |
307 | $result=$ud; |
308 | } else { |
308 | } else { |
309 | $result=bcadd($ud, $m); |
309 | $result=bcadd($ud, $b); |
310 | } |
310 | } |
311 | } else { |
311 | } else { |
312 | throw new ErrorException("ERROR: $a and $m are NOT relatively prime."); |
312 | throw new ErrorException("ERROR: $a and $b are NOT relatively prime."); |
313 | } |
313 | } |
314 | return $result; |
314 | return $result; |
315 | } |
315 | } |
316 | 316 | ||
317 | // gmp_jacobi ( GMP $a , GMP $p ) : int |
317 | // gmp_jacobi ( GMP $a , GMP $p ) : int |
Line 319... | Line 319... | ||
319 | function gmp_jacobi($a, $p) { |
319 | function gmp_jacobi($a, $p) { |
320 | bcscale(0); |
320 | bcscale(0); |
321 | 321 | ||
322 | // Source: https://github.com/CityOfZion/neo-php/blob/master/src/Crypto/NumberTheory.php#L136 |
322 | // Source: https://github.com/CityOfZion/neo-php/blob/master/src/Crypto/NumberTheory.php#L136 |
323 | 323 | ||
324 | if ($n>=3 && $n%2==1) { |
324 | if ($p>=3 && $p%2==1) { |
325 | $a = bcmod($a, $n); |
325 | $a = bcmod($a, $p); |
326 | if ($a == 0) return 0; |
326 | if ($a == 0) return 0; |
327 | if ($a == 1) return 1; |
327 | if ($a == 1) return 1; |
328 | $a1 = $a; |
328 | $a1 = $a; |
329 | $e = 0; |
329 | $e = 0; |
330 | while (bcmod($a1, 2) == 0) { |
330 | while (bcmod($a1, 2) == 0) { |
331 | $a1 = bcdiv($a1, 2); |
331 | $a1 = bcdiv($a1, 2); |
332 | $e = bcadd($e, 1); |
332 | $e = bcadd($e, 1); |
333 | } |
333 | } |
334 | $s = (bcmod($e, 2)==0 || bcmod($n, 8)==1 || bcmod($n, 8)==7) ? 1 : -1; |
334 | $s = (bcmod($e, 2)==0 || bcmod($p, 8)==1 || bcmod($p, 8)==7) ? 1 : -1; |
335 | if ($a1 == 1) return $s; |
335 | if ($a1 == 1) return $s; |
336 | if (bcmod($n, 4)==3 && bcmod($a1, 4)==3) $s = -$s; |
336 | if (bcmod($p, 4)==3 && bcmod($a1, 4)==3) $s = -$s; |
337 | return bcmul($s, gmp_jacobi(bcmod($n, $a1), $a1)); |
337 | return bcmul($s, gmp_jacobi(bcmod($p, $a1), $a1)); |
338 | } else { |
338 | } else { |
339 | return false; |
339 | return false; |
340 | } |
340 | } |
341 | } |
341 | } |
342 | 342 | ||
Line 396... | Line 396... | ||
396 | function gmp_nextprime($a) { |
396 | function gmp_nextprime($a) { |
397 | bcscale(0); |
397 | bcscale(0); |
398 | 398 | ||
399 | // Source: https://github.com/CityOfZion/neo-php/blob/master/src/Crypto/NumberTheory.php#L692 |
399 | // Source: https://github.com/CityOfZion/neo-php/blob/master/src/Crypto/NumberTheory.php#L692 |
400 | 400 | ||
401 | if (bccomp($starting_value, 2) == -1) { |
401 | if (bccomp($a, 2) == -1) { |
402 | return 2; |
402 | return 2; |
403 | } |
403 | } |
404 | $result = gmp_or(bcadd($starting_value, 1), 1); |
404 | $result = gmp_or(bcadd($a, 1), 1); |
405 | while (!gmp_prob_prime($result)) { |
405 | while (!gmp_prob_prime($result)) { |
406 | $result = bcadd($result, 2); |
406 | $result = bcadd($result, 2); |
407 | } |
407 | } |
408 | return $result; |
408 | return $result; |
409 | } |
409 | } |
Line 476... | Line 476... | ||
476 | 476 | ||
477 | // Source: https://github.com/CityOfZion/neo-php/blob/master/src/Crypto/NumberTheory.php#L655 |
477 | // Source: https://github.com/CityOfZion/neo-php/blob/master/src/Crypto/NumberTheory.php#L655 |
478 | 478 | ||
479 | $t = 40; |
479 | $t = 40; |
480 | $k = 0; |
480 | $k = 0; |
481 | $m = bcsub($n, 1); |
481 | $m = bcsub($reps, 1); |
482 | while (bcmod($m, 2) == 0) { |
482 | while (bcmod($m, 2) == 0) { |
483 | $k = bcadd($k, 1); |
483 | $k = bcadd($k, 1); |
484 | $m = bcdiv($m, 2); |
484 | $m = bcdiv($m, 2); |
485 | } |
485 | } |
486 | for ($i=0; $i<$t; $i++) { |
486 | for ($i=0; $i<$t; $i++) { |
487 | $a = bcrand(1, bcsub($n, 1)); |
487 | $a = bcrand(1, bcsub($reps, 1)); |
488 | if ($m < 0) { |
488 | if ($m < 0) { |
489 | return new ErrorException("Negative exponents ($m) not allowed"); |
489 | return new ErrorException("Negative exponents ($m) not allowed"); |
490 | } else { |
490 | } else { |
491 | $b0 = bcpowmod($a, $m, $n); |
491 | $b0 = bcpowmod($a, $m, $reps); |
492 | } |
492 | } |
493 | if ($b0!=1 && $b0!=bcsub($n, 1)) { |
493 | if ($b0!=1 && $b0!=bcsub($reps, 1)) { |
494 | $j = 1; |
494 | $j = 1; |
495 | while ($j<=$k-1 && $b0!=bcsub($n, 1)) { |
495 | while ($j<=$k-1 && $b0!=bcsub($reps, 1)) { |
496 | $b0 = bcpowmod($b0, 2, $n); |
496 | $b0 = bcpowmod($b0, 2, $reps); |
497 | if ($b0 == 1) { |
497 | if ($b0 == 1) { |
498 | return false; |
498 | return false; |
499 | } |
499 | } |
500 | $j++; |
500 | $j++; |
501 | } |
501 | } |
502 | if ($b0 != bcsub($n, 1)) { |
502 | if ($b0 != bcsub($reps, 1)) { |
503 | return false; |
503 | return false; |
504 | } |
504 | } |
505 | } |
505 | } |
506 | } |
506 | } |
507 | return true; |
507 | return true; |
Line 752... | Line 752... | ||
752 | // ----------------- New functions ----------------- |
752 | // ----------------- New functions ----------------- |
753 | 753 | ||
754 | // Newly added: gmp_not / bcnot |
754 | // Newly added: gmp_not / bcnot |
755 | function bcnot($a) { |
755 | function bcnot($a) { |
756 | bcscale(0); |
756 | bcscale(0); |
757 | // Convert $a and $b to a binary string |
757 | // Convert $a to a binary string |
758 | $ab = bc_dec2bin($a); |
758 | $ab = bc_dec2bin($a); |
759 | $bb = bc_dec2bin($b); |
- | |
760 | $length = max(strlen($ab), strlen($bb)); |
759 | $length = strlen($ab); |
761 | $ab = str_pad($ab, $length, "0", STR_PAD_LEFT); |
- | |
762 | $bb = str_pad($bb, $length, "0", STR_PAD_LEFT); |
- | |
- | 760 | ||
763 | // Do the bitwise binary operation |
761 | // Do the bitwise binary operation |
764 | $cb = ''; |
762 | $cb = ''; |
765 | for ($i=0; $i<$length; $i++) { |
763 | for ($i=0; $i<$length; $i++) { |
766 | if ($ab[$i] == 1) return false; |
764 | $cb .= ($ab[$i] == 1) ? '0' : '1'; |
767 | } |
765 | } |
768 | 766 | ||
- | 767 | // Convert back to a decimal number |
|
769 | return true; |
768 | return bc_bin2dec($cb); |
770 | } |
769 | } |
771 | function gmp_not($a) { |
770 | function gmp_not($a) { |
772 | bcscale(0); |
771 | bcscale(0); |
773 | return bcnot($a); |
772 | return bcnot($a); |
774 | } |
773 | } |