Bit-Wasp /
bitcoin-php
| 1 | <?php |
||||||
| 2 | |||||||
| 3 | declare(strict_types=1); |
||||||
| 4 | |||||||
| 5 | namespace BitWasp\Bitcoin\Math; |
||||||
| 6 | |||||||
| 7 | use Mdanter\Ecc\Math\GmpMath; |
||||||
| 8 | use Mdanter\Ecc\Util\NumberSize; |
||||||
| 9 | |||||||
| 10 | class Math extends GmpMath |
||||||
| 11 | { |
||||||
| 12 | |||||||
| 13 | /** |
||||||
| 14 | * @param \GMP $integer |
||||||
| 15 | * @return bool |
||||||
| 16 | */ |
||||||
| 17 | 54 | public function isEven(\GMP $integer): bool |
|||||
| 18 | { |
||||||
| 19 | 54 | return $this->cmp($this->mod($integer, gmp_init(2)), gmp_init(0)) === 0; |
|||||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
It seems like
gmp_init(0) can also be of type resource; however, parameter $other of Mdanter\Ecc\Math\GmpMath::cmp() does only seem to accept GMP, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 20 | } |
||||||
| 21 | |||||||
| 22 | /** |
||||||
| 23 | * @param \GMP $int |
||||||
| 24 | * @param \GMP $otherInt |
||||||
| 25 | * @return \GMP |
||||||
| 26 | */ |
||||||
| 27 | 1695 | public function bitwiseOr(\GMP $int, \GMP $otherInt): \GMP |
|||||
| 28 | { |
||||||
| 29 | 1695 | return gmp_or($int, $otherInt); |
|||||
|
0 ignored issues
–
show
|
|||||||
| 30 | } |
||||||
| 31 | |||||||
| 32 | /** |
||||||
| 33 | * Similar to gmp_div_qr, return a tuple containing the |
||||||
| 34 | * result and the remainder |
||||||
| 35 | * |
||||||
| 36 | * @param \GMP $dividend |
||||||
| 37 | * @param \GMP $divisor |
||||||
| 38 | * @return array |
||||||
| 39 | */ |
||||||
| 40 | public function divQr(\GMP $dividend, \GMP $divisor): array |
||||||
| 41 | { |
||||||
| 42 | // $div = n / q |
||||||
| 43 | $div = $this->div($dividend, $divisor); |
||||||
| 44 | // $remainder = n - (n / q) * q |
||||||
| 45 | $remainder = $this->sub($dividend, $this->mul($div, $divisor)); |
||||||
| 46 | return [$div, $remainder]; |
||||||
| 47 | } |
||||||
| 48 | |||||||
| 49 | /** |
||||||
| 50 | * @param int $compact |
||||||
| 51 | * @param bool|false $isNegative |
||||||
| 52 | * @param bool|false $isOverflow |
||||||
| 53 | * @return \GMP |
||||||
| 54 | */ |
||||||
| 55 | 210 | public function decodeCompact($compact, &$isNegative, &$isOverflow): \GMP |
|||||
| 56 | { |
||||||
| 57 | 210 | if ($compact < 0 || $compact > pow(2, 32) - 1) { |
|||||
| 58 | throw new \RuntimeException('Compact integer must be 32bit'); |
||||||
| 59 | } |
||||||
| 60 | |||||||
| 61 | 210 | $compact = gmp_init($compact, 10); |
|||||
| 62 | 210 | $size = $this->rightShift($compact, 24); |
|||||
|
0 ignored issues
–
show
It seems like
$compact can also be of type resource; however, parameter $number of Mdanter\Ecc\Math\GmpMath::rightShift() does only seem to accept GMP, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 63 | 210 | $word = $this->bitwiseAnd($compact, gmp_init(0x007fffff, 10)); |
|||||
|
0 ignored issues
–
show
It seems like
$compact can also be of type resource; however, parameter $first of Mdanter\Ecc\Math\GmpMath::bitwiseAnd() does only seem to accept GMP, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
It seems like
gmp_init(8388607, 10) can also be of type resource; however, parameter $other of Mdanter\Ecc\Math\GmpMath::bitwiseAnd() does only seem to accept GMP, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 64 | 210 | if ($this->cmp($size, gmp_init(3)) <= 0) { |
|||||
|
0 ignored issues
–
show
It seems like
gmp_init(3) can also be of type resource; however, parameter $other of Mdanter\Ecc\Math\GmpMath::cmp() does only seem to accept GMP, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 65 | 13 | $positions = (int) $this->toString($this->mul(gmp_init(8, 10), $this->sub(gmp_init(3, 10), $size))); |
|||||
|
0 ignored issues
–
show
It seems like
gmp_init(8, 10) can also be of type resource; however, parameter $multiplier of Mdanter\Ecc\Math\GmpMath::mul() does only seem to accept GMP, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
It seems like
gmp_init(3, 10) can also be of type resource; however, parameter $minuend of Mdanter\Ecc\Math\GmpMath::sub() does only seem to accept GMP, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 66 | 13 | $word = $this->rightShift($word, $positions); |
|||||
| 67 | } else { |
||||||
| 68 | 197 | $positions = (int) $this->toString($this->mul(gmp_init(8, 10), $this->sub($size, gmp_init(3, 10)))); |
|||||
|
0 ignored issues
–
show
It seems like
gmp_init(3, 10) can also be of type resource; however, parameter $subtrahend of Mdanter\Ecc\Math\GmpMath::sub() does only seem to accept GMP, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 69 | 197 | $word = $this->leftShift($word, $positions); |
|||||
| 70 | } |
||||||
| 71 | |||||||
| 72 | // isNegative: $word !== 0 && $uint32 & 0x00800000 !== 0 |
||||||
| 73 | // isOverflow: $word !== 0 && (($size > 34) || ($word > 0xff && $size > 33) || ($word > 0xffff && $size > 32)) |
||||||
| 74 | 210 | $zero = gmp_init(0); |
|||||
| 75 | 210 | $isNegative = ($this->cmp($word, $zero) !== 0) && ($this->cmp($this->bitwiseAnd($compact, gmp_init(0x00800000)), $zero) === 1); |
|||||
| 76 | 210 | $isOverflow = $this->cmp($word, $zero) !== 0 && ( |
|||||
| 77 | 199 | ($this->cmp($size, gmp_init(34, 10)) > 0) |
|||||
| 78 | 198 | || ($this->cmp($word, gmp_init(0xff, 10)) > 0 && $this->cmp($size, gmp_init(33, 10)) > 0) |
|||||
| 79 | 210 | || ($this->cmp($word, gmp_init(0xffff, 10)) > 0 && $this->cmp($size, gmp_init(32, 10)) > 0) |
|||||
| 80 | ); |
||||||
| 81 | |||||||
| 82 | 210 | return $word; |
|||||
| 83 | } |
||||||
| 84 | |||||||
| 85 | /** |
||||||
| 86 | * @param \GMP $integer |
||||||
| 87 | * @return \GMP |
||||||
| 88 | */ |
||||||
| 89 | 18 | public function getLow64(\GMP $integer): \GMP |
|||||
| 90 | { |
||||||
| 91 | 18 | $bits = gmp_strval($integer, 2); |
|||||
| 92 | 18 | $bits = substr($bits, 0, 64); |
|||||
| 93 | 18 | $bits = str_pad($bits, 64, '0', STR_PAD_LEFT); |
|||||
| 94 | 18 | return gmp_init($bits, 2); |
|||||
|
0 ignored issues
–
show
|
|||||||
| 95 | } |
||||||
| 96 | |||||||
| 97 | /** |
||||||
| 98 | * @param \GMP $int |
||||||
| 99 | * @param int $byteSize |
||||||
| 100 | * @return string |
||||||
| 101 | */ |
||||||
| 102 | public function fixedSizeInt(\GMP $int, int $byteSize): string |
||||||
| 103 | { |
||||||
| 104 | $two = gmp_init(2); |
||||||
| 105 | $maskShift = gmp_pow($two, 8); |
||||||
| 106 | $mask = gmp_mul(gmp_init(255), gmp_pow($two, 256)); |
||||||
| 107 | |||||||
| 108 | $x = ''; |
||||||
| 109 | for ($i = $byteSize - 1; $i >= 0; $i--) { |
||||||
| 110 | $mask = gmp_div($mask, $maskShift); |
||||||
| 111 | $x .= pack('C', gmp_strval(gmp_div(gmp_and($int, $mask), gmp_pow($two, $i * 8)), 10)); |
||||||
| 112 | } |
||||||
| 113 | |||||||
| 114 | return $x; |
||||||
| 115 | } |
||||||
| 116 | |||||||
| 117 | /** |
||||||
| 118 | * @param \GMP $integer |
||||||
| 119 | * @param bool $fNegative |
||||||
| 120 | * @return \GMP |
||||||
| 121 | */ |
||||||
| 122 | 18 | public function encodeCompact(\GMP $integer, bool $fNegative): \GMP |
|||||
| 123 | { |
||||||
| 124 | 18 | if (!is_bool($fNegative)) { |
|||||
|
0 ignored issues
–
show
|
|||||||
| 125 | throw new \InvalidArgumentException('CompactInteger::read() - flag must be boolean!'); |
||||||
| 126 | } |
||||||
| 127 | |||||||
| 128 | 18 | $size = (int) NumberSize::bnNumBytes($this, $integer); |
|||||
| 129 | 18 | if ($size <= 3) { |
|||||
| 130 | 14 | $compact = $this->leftShift($this->getLow64($integer), (8 * (3 - $size))); |
|||||
| 131 | } else { |
||||||
| 132 | 4 | $compact = $this->rightShift($integer, 8 * ($size - 3)); |
|||||
| 133 | 4 | $compact = $this->getLow64($compact); |
|||||
| 134 | } |
||||||
| 135 | |||||||
| 136 | 18 | if ($this->cmp($this->bitwiseAnd($compact, gmp_init(0x00800000, 10)), gmp_init(0, 10)) > 0) { |
|||||
|
0 ignored issues
–
show
It seems like
gmp_init(0, 10) can also be of type resource; however, parameter $other of Mdanter\Ecc\Math\GmpMath::cmp() does only seem to accept GMP, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
It seems like
gmp_init(8388608, 10) can also be of type resource; however, parameter $other of Mdanter\Ecc\Math\GmpMath::bitwiseAnd() does only seem to accept GMP, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 137 | 1 | $compact = $this->rightShift($compact, 8); |
|||||
| 138 | 1 | $size = $size + 1; |
|||||
| 139 | } |
||||||
| 140 | |||||||
| 141 | 18 | $compact = $this->bitwiseOr($compact, $this->leftShift(gmp_init($size, 10), 24)); |
|||||
|
0 ignored issues
–
show
It seems like
gmp_init($size, 10) can also be of type resource; however, parameter $number of Mdanter\Ecc\Math\GmpMath::leftShift() does only seem to accept GMP, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 142 | 18 | if ($fNegative && $this->cmp($this->bitwiseAnd($compact, gmp_init(0x007fffff, 10)), gmp_init(0, 10)) > 0) { /// ? |
|||||
| 143 | 2 | $compact = $this->bitwiseOr($compact, gmp_init(0x00800000, 10)); |
|||||
|
0 ignored issues
–
show
It seems like
gmp_init(8388608, 10) can also be of type resource; however, parameter $otherInt of BitWasp\Bitcoin\Math\Math::bitwiseOr() does only seem to accept GMP, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 144 | } |
||||||
| 145 | |||||||
| 146 | 18 | return $compact; |
|||||
| 147 | } |
||||||
| 148 | } |
||||||
| 149 |