Subversion Repositories oidplus

Rev

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
        }