Completed
Pull Request — master (#379)
by thomas
73:29
created

Math::bitwiseOr()   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 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
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 150
    public function isEven($integer)
16
    {
17 150
        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 1674
    public function bitwiseOr(\GMP $int, \GMP $otherInt)
26
    {
27 1674
        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 312
    public function divQr(\GMP $dividend, \GMP $divisor)
39
    {
40
        // $div = n / q
41 312
        $div = $this->div($dividend, $divisor);
42
        // $remainder = n - (n / q) * q
43 312
        $remainder = $this->sub($dividend, $this->mul($div, $divisor));
44 312
        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 1260
    public function decodeCompact($compact, &$isNegative, &$isOverflow)
54
    {
55 1260
        $compact = gmp_init($compact, 10);
56 1260
        $size = $this->rightShift($compact, 24);
57 1260
        $word = $this->bitwiseAnd($compact, gmp_init(0x007fffff));
58 1260
        if ($this->cmp($size, gmp_init(3)) <= 0) {
59 78
            $positions = $this->toString($this->mul(gmp_init(8), $this->sub(gmp_init(3), $size)));
60 78
            $word = $this->rightShift($word, $positions);
61 26
        } else {
62 1182
            $positions = $this->toString($this->mul(gmp_init(8), $this->sub($size, gmp_init(3))));
63 1182
            $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 1260
        $zero = gmp_init(0);
69 1260
        $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 1260
        $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 1194
                ($this->cmp($size, gmp_init(34)) > 0)
72 1188
                || ($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 1236
                || ($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 1260
        return $word;
77
    }
78
79
    /**
80
     * @param \GMP $integer
81
     * @return \GMP
82
     */
83 108
    public function getLow64(\GMP $integer)
84
    {
85 108
        $bits = gmp_strval($integer, 2);
86 108
        $bits = substr($bits, 0, 64);
87 108
        $bits = str_pad($bits, 64, '0', STR_PAD_LEFT);
88 108
        return gmp_init($bits, 2);
89
    }
90
91
    /**
92
     * @param \GMP $int
93
     * @param int $byteSize
94
     * @return string
95
     */
96 114
    public function fixedSizeInt(\GMP $int, $byteSize)
97
    {
98 114
        $two = gmp_init(2);
99 6
        $maskShift = gmp_pow($two, 8);
100
        $mask = gmp_mul(gmp_init(255), gmp_pow($two, 256));
101
102 108
        $x = '';
103 108
        for ($i = $byteSize - 1; $i >= 0; $i--) {
104 84
            $mask = gmp_div($mask, $maskShift);
105 28
            $x .= pack('C', gmp_strval(gmp_div(gmp_and($int, $mask), gmp_pow($two, $i * 8)), 10));
106 24
        }
107 24
108
        return $x;
109
    }
110 108
111 6
    /**
112 6
     * @param \GMP $integer
113 2
     * @param bool $fNegative
114
     * @return \GMP
115 108
     */
116 108
    public function encodeCompact(\GMP $integer, $fNegative)
117 12
    {
118 4
        if (!is_bool($fNegative)) {
119
            throw new \InvalidArgumentException('CompactInteger::read() - flag must be boolean!');
120 108
        }
121
122
        $size = (int) NumberSize::bnNumBytes($this, $integer);
123
        if ($size <= 3) {
124
            $compact = $this->leftShift($this->getLow64($integer), (8 * (3 - $size)));
125
        } else {
126
            $compact = $this->rightShift($integer, 8 * ($size - 3));
127
            $compact = $this->getLow64($compact);
128
        }
129
130
        if ($this->cmp($this->bitwiseAnd($compact, gmp_init(0x00800000, 10)), gmp_init(0)) > 0) {
0 ignored issues
show
Bug introduced by
It seems like $compact defined by $this->leftShift($this->...eger), 8 * (3 - $size)) on line 124 can also be of type resource; however, Mdanter\Ecc\Math\GmpMath::bitwiseAnd() 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...
131
            $compact = $this->rightShift($compact, 8);
0 ignored issues
show
Bug introduced by
It seems like $compact can also be of type resource; however, Mdanter\Ecc\Math\GmpMath::rightShift() 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...
132
            $size = $size + 1;
133
        }
134
135
        $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 135 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...
136
        if ($fNegative && $this->cmp($this->bitwiseAnd($compact, gmp_init(0x007fffff)), gmp_init(0)) > 0) { /// ?
137
            $compact = $this->bitwiseOr($compact, gmp_init(0x00800000));
138
        }
139
140
        return $compact;
141
    }
142
}
143