• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

famoser / elliptic / 16437972044

22 Jul 2025 07:42AM UTC coverage: 95.58% (+0.1%) from 95.437%
16437972044

Pull #12

github

web-flow
Merge 90594b1b9 into 85d13e57a
Pull Request #12: WIP: Add montgomery

567 of 589 new or added lines in 35 files covered. (96.26%)

1211 of 1267 relevant lines covered (95.58%)

22.1 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.92
/src/Serializer/Decoder/RFC7784Decoder.php
1
<?php
2

3
namespace Famoser\Elliptic\Serializer\Decoder;
4

5
/**
6
 * implements the decoding described in RFC 7784
7
 */
8
class RFC7784Decoder
9
{
10
    /**
11
     * @return int[]
12
     */
13
    private function decodeHexToBytes(string $hex): array
10✔
14
    {
15
        $cleanedHex = preg_replace('/\s+/', '', $hex);
10✔
16

17
        /** @phpstan-ignore-next-line */
18
        $list = unpack('C*', hex2bin($cleanedHex));
10✔
19

20
        /** @var int[]|false $list */
21
        if (!$list) {
10✔
NEW
22
            throw new \InvalidArgumentException('Invalid hex string');
×
23
        }
24

25
        return array_values($list);
10✔
26
    }
27

28
    /**
29
     * @param int[] $b
30
     */
31
    private function encodeBytesToHex(array $b): string
10✔
32
    {
33
        $result = '';
10✔
34
        foreach ($b as $entry) {
10✔
35
            $result .= bin2hex(pack('C', $entry));
10✔
36
        }
37

38
        return $result;
10✔
39
    }
40

41
    /**
42
     * @param int[] $b
43
     */
44
    private function decodeLittleEndian(array $b, int $bits): \GMP
10✔
45
    {
46
        $sum = gmp_init(0);
10✔
47
        $bytes = intdiv($bits + 7, 8);
10✔
48

49
        for ($i = 0; $i < $bytes; $i++) {
10✔
50
            $value = gmp_mul(gmp_init($b[$i]), gmp_pow(2, 8 * $i));
10✔
51
            $sum = gmp_add($sum, $value);
10✔
52
        }
53

54
        return $sum;
10✔
55
    }
56

57
    /**
58
     * @return int[]
59
     */
60
    private function encodeLittleEndian(\GMP $b, int $bits): array
10✔
61
    {
62
        $result = [];
10✔
63

64
        $mask = gmp_init(0xFF);
10✔
65
        $number = $b;
10✔
66
        $bytes = intdiv($bits + 7, 8);
10✔
67
        for ($i = 0; $i < $bytes; $i++) {
10✔
68
            $result[] = gmp_intval(gmp_and($number, $mask));
10✔
69
            $number = gmp_div($number, gmp_pow(2, 8));
10✔
70
        }
71

72
        return $result;
10✔
73
    }
74

75
    public function decodeUCoordinate(string $uHex, int $bits): \GMP
10✔
76
    {
77
        $u_list = $this->decodeHexToBytes($uHex);
10✔
78

79
        // Ignore any unused bits
80
        if ($bits % 8) {
10✔
81
            $u_list[count($u_list) - 1] &= (1 << ($bits % 8)) - 1;
5✔
82
        }
83

84
        return $this->decodeLittleEndian($u_list, $bits);
10✔
85
    }
86

87
    public function encodeUCoordinate(\GMP $b, int $bits): string
10✔
88
    {
89
        $u_list = $this->encodeLittleEndian($b, $bits);
10✔
90

91
        // Ignore any unused bits
92
        if ($bits % 8) {
10✔
93
            $u_list[count($u_list) - 1] &= (1 << ($bits % 8)) - 1;
5✔
94
        }
95

96
        return $this->encodeBytesToHex($u_list);
10✔
97
    }
98

99
    public function decodeScalar25519(string $k): \GMP
5✔
100
    {
101
        $k_list = $this->decodeHexToBytes($k);
5✔
102

103
        // Apply the bit masks
104
        $k_list[0] &= 248;
5✔
105
        $k_list[31] &= 127;
5✔
106
        $k_list[31] |= 64;
5✔
107

108
        return $this->decodeLittleEndian($k_list, 255);
5✔
109
    }
110

111
    public function decodeScalar448(string $k): \GMP
5✔
112
    {
113
        $k_list = $this->decodeHexToBytes($k);
5✔
114

115
        // Apply the bit masks
116
        $k_list[0] &= 252;
5✔
117
        $k_list[55] |= 128;
5✔
118

119
        return $this->decodeLittleEndian($k_list, 448);
5✔
120
    }
121
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc