Completed
Pull Request — master (#318)
by thomas
36:24 queued 32:26
created

Math::getBinaryMath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace BitWasp\Bitcoin\Math;
4
5
use \Mdanter\Ecc\Math\GmpMath;
6
use Mdanter\Ecc\Util\NumberSize;
7
8
class Math extends GmpMath
9
{
10
11
    /**
12
     * @param $integer
13
     * @return bool
14
     */
15 131
    public function isEven($integer)
16
    {
17 131
        return $this->cmp($this->mod($integer, gmp_init(2)), gmp_init(0)) === 0;
18
    }
19
20
    /**
21
     * @param \GMP $int
22
     * @param \GMP $otherInt
23
     * @return \GMP
24
     */
25 186
    public function bitwiseOr(\GMP $int, \GMP $otherInt)
26
    {
27 186
        return gmp_or($int, $otherInt);
28
    }
29
30
    /**
31
     * Similar to gmp_div_qr, return a tuple containing the
32
     * result and the remainder
33
     *
34
     * @param \GMP $dividend
35
     * @param \GMP $divisor
36
     * @return array
37
     */
38 156
    public function divQr(\GMP $dividend, \GMP $divisor)
39
    {
40
        // $div = n / q
41 156
        $div = $this->div($dividend, $divisor);
42
        // $remainder = n - (n / q) * q
43 156
        $remainder = $this->sub($dividend, $this->mul($div, $divisor));
44 156
        return array($div, $remainder);
45
    }
46
47
    /**
48
     * @param int $compact
49
     * @param bool|false $isNegative
50
     * @param bool|false $isOverflow
51
     * @return \GMP
52
     */
53 630
    public function decodeCompact($compact, &$isNegative, &$isOverflow)
54
    {
55 630
        $compact = gmp_init($compact, 10);
56 630
        $size = $this->rightShift($compact, 24);
57 630
        $word = $this->bitwiseAnd($compact, gmp_init(0x007fffff));
58 630
        if ($this->cmp($size, gmp_init(3)) <= 0) {
59 39
            $positions = $this->toString($this->mul(gmp_init(8), $this->sub(gmp_init(3), $size)));
60 39
            $word = $this->rightShift($word, $positions);
61 26
        } else {
62 591
            $positions = $this->toString($this->mul(gmp_init(8), $this->sub($size, gmp_init(3))));
63 591
            $word = $this->leftShift($word, $positions);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->leftShift($word, $positions); of type resource adds the type resource to the return on line 76 which is incompatible with the return type documented by BitWasp\Bitcoin\Math\Math::decodeCompact of type GMP.
Loading history...
64
        }
65
66
        // isNegative: $word != 0 && $uint32 & 0x00800000 != 0
67
        // isOverflow: $word != 0 && (($size > 34) || ($word > 0xff && $size > 33) || ($word > 0xffff && $size  >32))
68 630
        $zero = gmp_init(0);
69 630
        $isNegative = ($this->cmp($word, $zero) !== 0) && ($this->cmp($this->bitwiseAnd($compact, gmp_init(0x00800000)), $zero) === 1);
0 ignored issues
show
Bug introduced by
It seems like $word defined by $this->leftShift($word, $positions) on line 63 can also be of type resource; however, Mdanter\Ecc\Math\GmpMath::cmp() does only seem to accept object<GMP>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
70 630
        $isOverflow = $this->cmp($word, $zero) !== 0 && (
0 ignored issues
show
Bug introduced by
It seems like $word defined by $this->leftShift($word, $positions) on line 63 can also be of type resource; however, Mdanter\Ecc\Math\GmpMath::cmp() does only seem to accept object<GMP>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
71 597
                ($this->cmp($size, gmp_init(34)) > 0)
72 594
                || ($this->cmp($word, gmp_init(0xff)) > 0 && $this->cmp($size, gmp_init(33)) > 0)
0 ignored issues
show
Bug introduced by
It seems like $word defined by $this->leftShift($word, $positions) on line 63 can also be of type resource; however, Mdanter\Ecc\Math\GmpMath::cmp() does only seem to accept object<GMP>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
73 606
                || ($this->cmp($word, gmp_init(0xffff)) > 0 && $this->cmp($size, gmp_init(32)) > 0)
0 ignored issues
show
Bug introduced by
It seems like $word defined by $this->leftShift($word, $positions) on line 63 can also be of type resource; however, Mdanter\Ecc\Math\GmpMath::cmp() does only seem to accept object<GMP>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
74 420
            );
75
76 630
        return $word;
77
    }
78
79
    /**
80
     * @param \GMP $integer
81
     * @return \GMP
82
     */
83 54
    public function getLow64(\GMP $integer)
84
    {
85 54
        $bits = gmp_strval($integer, 2);
86 54
        $bits = substr($bits, 0, 64);
87 54
        $bits = str_pad($bits, 64, '0', STR_PAD_LEFT);
88 54
        return gmp_init($bits, 2);
89
    }
90
91
    /**
92
     * @param \GMP $integer
93
     * @param bool $fNegative
94
     * @return \GMP
95
     */
96 57
    public function encodeCompact(\GMP $integer, $fNegative)
97
    {
98 57
        if (!is_bool($fNegative)) {
99 3
            throw new \InvalidArgumentException('CompactInteger::read() - flag must be boolean!');
100
        }
101
102 54
        $size = (int) NumberSize::bnNumBytes($this, $integer);
103 54
        if ($size <= 3) {
104 42
            $compact = $this->leftShift($this->getLow64($integer), (8 * (3 - $size)));
105 28
        } else {
106 12
            $compact = $this->rightShift($integer, 8 * ($size - 3));
107 12
            $compact = $this->getLow64($compact);
108
        }
109
110 54
        if ($this->cmp($this->bitwiseAnd($compact, gmp_init(0x00800000, 10)), gmp_init(0)) > 0) {
111 3
            $compact = $this->rightShift($compact, 8);
112 3
            $size = $size + 1;
113 2
        }
114
115 54
        $compact = $this->bitwiseOr($compact, $this->leftShift(gmp_init($size, 10), 24));
0 ignored issues
show
Bug introduced by
It seems like $compact defined by $this->bitwiseOr($compac...p_init($size, 10), 24)) on line 115 can also be of type resource; however, BitWasp\Bitcoin\Math\Math::bitwiseOr() does only seem to accept object<GMP>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
116 54
        if ($fNegative && $this->cmp($this->bitwiseAnd($compact, gmp_init(0x007fffff)), gmp_init(0)) > 0) { /// ?
117 6
            $compact = $this->bitwiseOr($compact, gmp_init(0x00800000));
118 4
        }
119
120 54
        return $compact;
121
    }
122
}
123