Failed Conditions
Push — v7 ( a687dc...e264c8 )
by Florent
02:28
created

GmpMath::leftShift()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
1
<?php
2
3
namespace Jose\Component\Core\Util\Ecc\Math;
4
5
use Jose\Component\Core\Util\Ecc\Util\BinaryString;
6
7
final class GmpMath
8
{
9
    /**
10
     * {@inheritDoc}
11
     * @see GmpMath::cmp()
12
     */
13
    public function cmp(\GMP $first, \GMP $other)
14
    {
15
        return gmp_cmp($first, $other);
16
    }
17
18
    /**
19
     * @param \GMP $first
20
     * @param \GMP $other
21
     * @return bool
22
     */
23
    public function equals(\GMP $first, \GMP $other)
24
    {
25
        return gmp_cmp($first, $other) === 0;
26
    }
27
    
28
    /**
29
     * {@inheritDoc}
30
     * @see GmpMath::mod()
31
     */
32
    public function mod(\GMP $number, \GMP $modulus)
33
    {
34
        return gmp_mod($number, $modulus);
35
    }
36
37
    /**
38
     * {@inheritDoc}
39
     * @see GmpMath::add()
40
     */
41
    public function add(\GMP $augend, \GMP $addend)
42
    {
43
        return gmp_add($augend, $addend);
44
    }
45
46
    /**
47
     * {@inheritDoc}
48
     * @see GmpMath::sub()
49
     */
50
    public function sub(\GMP $minuend, \GMP $subtrahend)
51
    {
52
        return gmp_sub($minuend, $subtrahend);
53
    }
54
55
    /**
56
     * {@inheritDoc}
57
     * @see GmpMath::mul()
58
     */
59
    public function mul(\GMP $multiplier, \GMP $multiplicand)
60
    {
61
        return gmp_mul($multiplier, $multiplicand);
62
    }
63
64
    /**
65
     * {@inheritDoc}
66
     * @see GmpMath::div()
67
     */
68
    public function div(\GMP $dividend, \GMP $divisor)
69
    {
70
        return gmp_div($dividend, $divisor);
71
    }
72
73
    /**
74
     * {@inheritDoc}
75
     * @see GmpMath::pow()
76
     */
77
    public function pow(\GMP $base, $exponent)
78
    {
79
        return gmp_pow($base, $exponent);
80
    }
81
82
    /**
83
     * {@inheritDoc}
84
     * @see GmpMath::bitwiseAnd()
85
     */
86
    public function bitwiseAnd(\GMP $first, \GMP $other)
87
    {
88
        return gmp_and($first, $other);
89
    }
90
91
    /**
92
     * {@inheritDoc}
93
     * @see GmpMath::rightShift()
94
     */
95
    public function rightShift(\GMP $number, $positions)
96
    {
97
        // Shift 1 right = div / 2
98
        return gmp_div($number, gmp_pow(gmp_init(2, 10), $positions));
99
    }
100
101
    /**
102
     * {@inheritDoc}
103
     * @see GmpMath::bitwiseXor()
104
     */
105
    public function bitwiseXor(\GMP $first, \GMP $other)
106
    {
107
        return gmp_xor($first, $other);
108
    }
109
110
    /**
111
     * {@inheritDoc}
112
     * @see GmpMath::leftShift()
113
     */
114
    public function leftShift(\GMP $number, $positions)
115
    {
116
        // Shift 1 left = mul by 2
117
        return gmp_mul($number, gmp_pow(2, $positions));
118
    }
119
120
    /**
121
     * {@inheritDoc}
122
     * @see GmpMath::toString()
123
     */
124
    public function toString(\GMP $value)
125
    {
126
        return gmp_strval($value);
127
    }
128
129
    /**
130
     * {@inheritDoc}
131
     * @see GmpMath::hexDec()
132
     */
133
    public function hexDec($hex)
134
    {
135
        return gmp_strval(gmp_init($hex, 16), 10);
136
    }
137
138
    /**
139
     * {@inheritDoc}
140
     * @see GmpMath::decHex()
141
     */
142
    public function decHex($dec)
143
    {
144
        $dec = gmp_init($dec, 10);
145
146
        if (gmp_cmp($dec, 0) < 0) {
147
            throw new \InvalidArgumentException('Unable to convert negative integer to string');
148
        }
149
150
        $hex = gmp_strval($dec, 16);
151
152
        if (BinaryString::length($hex) % 2 != 0) {
153
            $hex = '0'.$hex;
154
        }
155
156
        return $hex;
157
    }
158
159
    /**
160
     * {@inheritDoc}
161
     * @see GmpMath::powmod()
162
     */
163
    public function powmod(\GMP $base, \GMP $exponent, \GMP $modulus)
164
    {
165
        if ($this->cmp($exponent, gmp_init(0, 10)) < 0) {
166
            throw new \InvalidArgumentException("Negative exponents (" . $this->toString($exponent) . ") not allowed.");
167
        }
168
169
        return gmp_powm($base, $exponent, $modulus);
170
    }
171
172
    /**
173
     * {@inheritDoc}
174
     * @see GmpMath::isPrime()
175
     */
176
    public function isPrime(\GMP $n)
177
    {
178
        $prob = gmp_prob_prime($n);
179
180
        if ($prob > 0) {
181
            return true;
182
        }
183
184
        return false;
185
    }
186
187
    /**
188
     * {@inheritDoc}
189
     * @see GmpMath::nextPrime()
190
     */
191
    public function nextPrime(\GMP $starting_value)
192
    {
193
        return gmp_nextprime($starting_value);
194
    }
195
196
    /**
197
     * {@inheritDoc}
198
     * @see GmpMath::inverseMod()
199
     */
200
    public function inverseMod(\GMP $a, \GMP $m)
201
    {
202
        return gmp_invert($a, $m);
203
    }
204
205
    /**
206
     * {@inheritDoc}
207
     * @see GmpMath::jacobi()
208
     */
209
    public function jacobi(\GMP $a, \GMP $n)
210
    {
211
        return gmp_jacobi($a, $n);
212
    }
213
214
    /**
215
     * {@inheritDoc}
216
     * @see GmpMath::intToString()
217
     */
218
    public function intToString(\GMP $x)
219
    {
220
        if (gmp_cmp($x, 0) < 0) {
221
            throw new \InvalidArgumentException('Unable to convert negative integer to string');
222
        }
223
224
        $hex = gmp_strval($x, 16);
225
226
        if (BinaryString::length($hex) % 2 != 0) {
227
            $hex = '0'.$hex;
228
        }
229
230
        return pack('H*', $hex);
231
    }
232
233
    /**
234
     * {@inheritDoc}
235
     * @see GmpMath::stringToInt()
236
     */
237
    public function stringToInt($s)
238
    {
239
        $result = gmp_init(0, 10);
240
        $sLen = BinaryString::length($s);
241
242
        for ($c = 0; $c < $sLen; $c ++) {
243
            $result = gmp_add(gmp_mul(256, $result), gmp_init(ord($s[$c]), 10));
244
        }
245
246
        return $result;
247
    }
248
249
    /**
250
     * {@inheritDoc}
251
     * @see GmpMath::digestInteger()
252
     */
253
    public function digestInteger(\GMP $m)
254
    {
255
        return $this->stringToInt(hash('sha1', $this->intToString($m), true));
256
    }
257
258
    /**
259
     * {@inheritDoc}
260
     * @see GmpMath::gcd2()
261
     */
262
    public function gcd2(\GMP $a, \GMP $b)
263
    {
264
        while ($this->cmp($a, gmp_init(0)) > 0) {
1 ignored issue
show
Bug introduced by
It seems like $a defined by $this->mod($b, $a) on line 266 can also be of type resource; however, Jose\Component\Core\Util\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...
265
            $temp = $a;
266
            $a = $this->mod($b, $a);
2 ignored issues
show
Bug introduced by
It seems like $b defined by $temp on line 267 can also be of type resource; however, Jose\Component\Core\Util\Ecc\Math\GmpMath::mod() 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...
Bug introduced by
It seems like $a defined by $this->mod($b, $a) on line 266 can also be of type resource; however, Jose\Component\Core\Util\Ecc\Math\GmpMath::mod() 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...
267
            $b = $temp;
268
        }
269
270
        return $b;
271
    }
272
273
    /**
274
     * {@inheritDoc}
275
     * @see GmpMath::baseConvert()
276
     */
277
    public function baseConvert($number, $from, $to)
278
    {
279
        return gmp_strval(gmp_init($number, $from), $to);
280
    }
281
282
    /**
283
     * {@inheritDoc}
284
     * @see GmpMath::getNumberTheory()
285
     */
286
    public function getNumberTheory()
287
    {
288
        return new NumberTheory($this);
289
    }
290
291
    /**
292
     * @param \GMP $modulus
293
     * @return ModularArithmetic
294
     */
295
    public function getModularArithmetic(\GMP $modulus)
296
    {
297
        return new ModularArithmetic($this, $modulus);
298
    }
299
}
300