Failed Conditions
Push — PHPSecLib_Rid ( 3a3eb8...805f0f )
by Florent
06:23
created

src/Util/BigInteger.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/*
4
 * The MIT License (MIT)
5
 *
6
 * Copyright (c) 2014-2016 Spomky-Labs
7
 *
8
 * This software may be modified and distributed under the terms
9
 * of the MIT license.  See the LICENSE file for details.
10
 */
11
12
namespace Jose\Util;
13
14
use Assert\Assertion;
15
16
final class BigInteger
17
{
18
    /**
19
     * Holds the BigInteger's value.
20
     *
21
     * @var resource
22
     */
23
    private $value;
24
25
    /**
26
     * Converts base-10 and binary strings (base-256) to BigIntegers.
27
     *
28
     * @param \GMP|string $value
29
     * @param int         $base
30
     */
31
    private function __construct($value, $base)
32
    {
33
        if ($value instanceof \GMP) {
34
            $this->value = $value;
0 ignored issues
show
Documentation Bug introduced by
It seems like $value of type object<GMP> is incompatible with the declared type resource of property $value.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
35
36
            return;
37
        }
38
39
        $this->value = gmp_init($value, $base);
40
    }
41
42
    /**
43
     * @param \GMP $value
44
     *
45
     * @return \Jose\Util\BigInteger
46
     */
47
    public static function createFromGMPResource($value)
48
    {
49
        Assertion::isInstanceOf($value, \GMP::class);
50
51
        return new self($value, 0);
52
    }
53
54
    /**
55
     * @param string $value
56
     *
57
     * @return \Jose\Util\BigInteger
58
     */
59
    public static function createFromBinaryString($value)
60
    {
61
        Assertion::string($value);
62
        $value = '0x'.bin2hex($value);
63
64
        return new self($value, 16);
65
    }
66
67
    /**
68
     * @param string $value
69
     *
70
     * @return \Jose\Util\BigInteger
71
     */
72
    public static function createFromDecimalString($value)
73
    {
74
        Assertion::string($value);
75
76
        return new self($value, 10);
77
    }
78
79
    /**
80
     * Converts a BigInteger to a byte string (eg. base-256).
81
     *
82
     * @return string
83
     */
84
    public function toBytes()
85
    {
86
        if (gmp_cmp($this->value, gmp_init(0)) === 0) {
87
            return '';
88
        }
89
90
        $temp = gmp_strval(gmp_abs($this->value), 16);
91
        $temp = (strlen($temp) & 1) ? '0'.$temp : $temp;
92
        $temp = hex2bin($temp);
93
94
        return ltrim($temp, chr(0));
95
    }
96
97
    /**
98
     * Divides two BigIntegers.
99
     *
100
     * @param \Jose\Util\BigInteger $y
101
     *
102
     * @return \Jose\Util\BigInteger[]
103
     */
104
    public function divide(BigInteger $y)
105
    {
106
        list($quotient_value, $remainder_value) = gmp_div_qr($this->value, $y->value);
107
108
        if (gmp_sign($remainder_value) < 0) {
109
            $remainder_value = gmp_add($remainder_value, gmp_abs($y->value));
110
        }
111
112
        return [self::createFromGMPResource($quotient_value), self::createFromGMPResource($remainder_value)];
113
    }
114
115
    /**
116
     * Performs modular exponentiation.
117
     *
118
     * @param \Jose\Util\BigInteger $e
119
     * @param \Jose\Util\BigInteger $n
120
     *
121
     * @return \Jose\Util\BigInteger|bool
122
     */
123
    public function modPow(BigInteger $e, BigInteger $n)
124
    {
125
        $value = gmp_powm($this->value, $e->value, $n->value);
126
127
        return self::createFromGMPResource($value);
128
    }
129
130
    /**
131
     * Absolute value.
132
     *
133
     * @return \Jose\Util\BigInteger
134
     */
135
    public function abs()
136
    {
137
        $value = gmp_abs($this->value);
138
139
        return self::createFromGMPResource($value);
140
    }
141
142
    /**
143
     * Compares two numbers.
144
     *
145
     * @param \Jose\Util\BigInteger $y
146
     *
147
     * @return int < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal.
148
     */
149
    public function compare(BigInteger $y)
150
    {
151
        return gmp_cmp($this->value, $y->value);
152
    }
153
}
154