NumberSize::bnNumBits()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 8
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 14
rs 10
1
<?php
2
declare(strict_types=1);
3
4
namespace Mdanter\Ecc\Util;
5
6
use Mdanter\Ecc\Math\GmpMathInterface;
7
8
class NumberSize
9
{
10
11
    /**
12
     * @param GmpMathInterface $adapter
13
     * @param \GMP             $x
14
     * @return float
15
     */
16
    public static function getCeiledByteSize(GmpMathInterface $adapter, \GMP $x): float
17
    {
18
        $log2 = self::bnNumBits($adapter, $x);
19
        return ceil($log2 / 8);
20
    }
21
22
    /**
23
     * @param GmpMathInterface $adapter
24
     * @param \GMP             $x
25
     * @return float
26
     */
27
    public static function getFlooredByteSize(GmpMathInterface $adapter, \GMP $x): float
28
    {
29
        $log2 = self::bnNumBits($adapter, $x);
30
        return floor($log2 / 8) + 1;
31
    }
32
33
    /**
34
     * Returns the number of minimum required bytes to store a given number. Non-significant upper bits are not counted.
35
     *
36
     * @param  GmpMathInterface $adapter
37
     * @param  \GMP             $x
38
     * @return int
39
     *
40
     * @link https://www.openssl.org/docs/crypto/BN_num_bytes.html
41
     */
42
    public static function bnNumBytes(GmpMathInterface $adapter, \GMP $x): int
43
    {
44
        // https://github.com/luvit/openssl/blob/master/openssl/crypto/bn/bn.h#L402
45
        return (int) floor((self::bnNumBits($adapter, $x) + 7) / 8);
46
    }
47
48
    /**
49
     * Returns the number of bits used to store this number. Non-significant upper bits are not counted.
50
     *
51
     * @param  GmpMathInterface $adapter
52
     * @param  \GMP             $x
53
     * @return int
54
     *
55
     * @link https://www.openssl.org/docs/crypto/BN_num_bytes.html
56
     */
57
    public static function bnNumBits(GmpMathInterface $adapter, \GMP $x): int
58
    {
59
        $zero = gmp_init(0, 10);
60
        if ($adapter->equals($x, $zero)) {
0 ignored issues
show
Bug introduced by
It seems like $zero can also be of type resource; however, parameter $other of Mdanter\Ecc\Math\GmpMathInterface::equals() 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 ignore-type  annotation

60
        if ($adapter->equals($x, /** @scrutinizer ignore-type */ $zero)) {
Loading history...
61
            return 0;
62
        }
63
64
        $log2 = 0;
65
        while (false === $adapter->equals($x, $zero)) {
66
            $x = $adapter->rightShift($x, 1);
67
            $log2++;
68
        }
69
70
        return $log2 ;
71
    }
72
}
73