CurveFp   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 202
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 53
c 2
b 0
f 0
dl 0
loc 202
rs 10
wmc 18

15 Methods

Rating   Name   Duplication   Size   Complexity  
A getInfinity() 0 3 1
A getPrime() 0 3 1
A getA() 0 3 1
A getPoint() 0 3 1
A __toString() 0 3 1
A getB() 0 3 1
A equals() 0 3 1
A recoverYfromX() 0 24 3
A getSize() 0 3 1
A getGenerator() 0 3 1
A cmp() 0 9 2
A __debugInfo() 0 6 1
A contains() 0 19 1
A __construct() 0 5 1
A getModAdapter() 0 3 1
1
<?php
2
declare(strict_types=1);
3
4
/***********************************************************************
5
Copyright (C) 2012 Matyas Danter
6
7
Permission is hereby granted, free of charge, to any person obtaining
8
a copy of this software and associated documentation files (the "Software"),
9
to deal in the Software without restriction, including without limitation
10
the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
and/or sell copies of the Software, and to permit persons to whom the
12
Software is furnished to do so, subject to the following conditions:
13
14
The above copyright notice and this permission notice shall be included
15
in all copies or substantial portions of the Software.
16
17
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
21
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
OTHER DEALINGS IN THE SOFTWARE.
24
 *************************************************************************/
25
namespace Mdanter\Ecc\Primitives;
26
27
use Mdanter\Ecc\Exception\PointRecoveryException;
28
use Mdanter\Ecc\Exception\SquareRootException;
29
use Mdanter\Ecc\Math\GmpMathInterface;
30
use Mdanter\Ecc\Math\ModularArithmetic;
31
use Mdanter\Ecc\Random\RandomNumberGeneratorInterface;
32
33
/**
34
 * This class is a representation of an EC over a field modulo a prime number
35
 *
36
 * Important objectives for this class are:
37
 * - Does the curve contain a point?
38
 * - Comparison of two curves.
39
 */
40
class CurveFp implements CurveFpInterface
41
{
42
43
    /**
44
     * @var CurveParameters
45
     */
46
    protected $parameters;
47
48
    /**
49
     *
50
     * @var GmpMathInterface
51
     */
52
    protected $adapter = null;
53
54
    /**
55
     *
56
     * @var ModularArithmetic
57
     */
58
    protected $modAdapter = null;
59
60
    /**
61
     * Constructor that sets up the instance variables.
62
     *
63
     * @param CurveParameters $parameters
64
     * @param GmpMathInterface $adapter
65
     */
66
    public function __construct(CurveParameters $parameters, GmpMathInterface $adapter)
67
    {
68
        $this->parameters = $parameters;
69
        $this->adapter = $adapter;
70
        $this->modAdapter = new ModularArithmetic($this->adapter, $this->parameters->getPrime());
71
    }
72
73
    /**
74
     * {@inheritDoc}
75
     * @see \Mdanter\Ecc\Primitives\CurveFpInterface::getModAdapter()
76
     */
77
    public function getModAdapter(): ModularArithmetic
78
    {
79
        return $this->modAdapter;
80
    }
81
82
    /**
83
     * {@inheritDoc}
84
     * @see \Mdanter\Ecc\Primitives\CurveFpInterface::getPoint()
85
     */
86
    public function getPoint(\GMP $x, \GMP $y, \GMP $order = null): PointInterface
87
    {
88
        return new Point($this->adapter, $this, $x, $y, $order);
89
    }
90
    
91
    /**
92
     * {@inheritDoc}
93
     * @see \Mdanter\Ecc\Primitives\CurveFpInterface::getInfinity()
94
     */
95
    public function getInfinity(): PointInterface
96
    {
97
        return new Point($this->adapter, $this, gmp_init(0, 10), gmp_init(0, 10), null, true);
0 ignored issues
show
Bug introduced by
It seems like gmp_init(0, 10) can also be of type resource; however, parameter $x of Mdanter\Ecc\Primitives\Point::__construct() 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

97
        return new Point($this->adapter, $this, /** @scrutinizer ignore-type */ gmp_init(0, 10), gmp_init(0, 10), null, true);
Loading history...
Bug introduced by
It seems like gmp_init(0, 10) can also be of type resource; however, parameter $y of Mdanter\Ecc\Primitives\Point::__construct() 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

97
        return new Point($this->adapter, $this, gmp_init(0, 10), /** @scrutinizer ignore-type */ gmp_init(0, 10), null, true);
Loading history...
98
    }
99
100
    /**
101
     * {@inheritDoc}
102
     * @see \Mdanter\Ecc\Primitives\CurveFpInterface::getGenerator()
103
     */
104
    public function getGenerator(\GMP $x, \GMP $y, \GMP $order, RandomNumberGeneratorInterface $randomGenerator = null): GeneratorPoint
105
    {
106
        return new GeneratorPoint($this->adapter, $this, $x, $y, $order, $randomGenerator);
107
    }
108
109
    /**
110
     * @param bool $wasOdd
111
     * @param \GMP $xCoord
112
     * @return \GMP
113
     */
114
    public function recoverYfromX(bool $wasOdd, \GMP $xCoord): \GMP
115
    {
116
        $math = $this->adapter;
117
        $prime = $this->getPrime();
118
119
        try {
120
            $root = $this->adapter->getNumberTheory()->squareRootModP(
121
                $math->add(
122
                    $math->add(
123
                        $this->modAdapter->pow($xCoord, gmp_init(3, 10)),
0 ignored issues
show
Bug introduced by
It seems like gmp_init(3, 10) can also be of type resource; however, parameter $exponent of Mdanter\Ecc\Math\ModularArithmetic::pow() 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

123
                        $this->modAdapter->pow($xCoord, /** @scrutinizer ignore-type */ gmp_init(3, 10)),
Loading history...
124
                        $math->mul($this->getA(), $xCoord)
125
                    ),
126
                    $this->getB()
127
                ),
128
                $prime
129
            );
130
        } catch (SquareRootException $e) {
131
            throw new PointRecoveryException("Failed to recover y coordinate for point", 0, $e);
132
        }
133
134
        if ($math->equals($math->mod($root, gmp_init(2, 10)), gmp_init(1)) === $wasOdd) {
0 ignored issues
show
Bug introduced by
It seems like gmp_init(1) 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

134
        if ($math->equals($math->mod($root, gmp_init(2, 10)), /** @scrutinizer ignore-type */ gmp_init(1)) === $wasOdd) {
Loading history...
Bug introduced by
It seems like gmp_init(2, 10) can also be of type resource; however, parameter $modulus of Mdanter\Ecc\Math\GmpMathInterface::mod() 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

134
        if ($math->equals($math->mod($root, /** @scrutinizer ignore-type */ gmp_init(2, 10)), gmp_init(1)) === $wasOdd) {
Loading history...
135
            return $root;
136
        } else {
137
            return $math->sub($prime, $root);
138
        }
139
    }
140
    /**
141
     * {@inheritDoc}
142
     * @see \Mdanter\Ecc\Primitives\CurveFpInterface::contains()
143
     */
144
    public function contains(\GMP $x, \GMP $y): bool
145
    {
146
        $math = $this->adapter;
147
148
        $eq_zero = $math->equals(
149
            $this->modAdapter->sub(
150
                $math->pow($y, 2),
151
                $math->add(
152
                    $math->add(
153
                        $math->pow($x, 3),
154
                        $math->mul($this->getA(), $x)
155
                    ),
156
                    $this->getB()
157
                )
158
            ),
159
            gmp_init(0, 10)
0 ignored issues
show
Bug introduced by
It seems like gmp_init(0, 10) 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

159
            /** @scrutinizer ignore-type */ gmp_init(0, 10)
Loading history...
160
        );
161
162
        return $eq_zero;
163
    }
164
165
    /**
166
     * {@inheritDoc}
167
     * @see \Mdanter\Ecc\Primitives\CurveFpInterface::getA()
168
     */
169
    public function getA(): \GMP
170
    {
171
        return $this->parameters->getA();
172
    }
173
174
    /**
175
     * {@inheritDoc}
176
     * @see \Mdanter\Ecc\Primitives\CurveFpInterface::getB()
177
     */
178
    public function getB(): \GMP
179
    {
180
        return $this->parameters->getB();
181
    }
182
183
    /**
184
     * {@inheritDoc}
185
     * @see \Mdanter\Ecc\Primitives\CurveFpInterface::getPrime()
186
     */
187
    public function getPrime(): \GMP
188
    {
189
        return $this->parameters->getPrime();
190
    }
191
192
    /**
193
     * @return int
194
     */
195
    public function getSize(): int
196
    {
197
        return $this->parameters->getSize();
198
    }
199
200
    /**
201
     * {@inheritDoc}
202
     * @see \Mdanter\Ecc\Primitives\CurveFpInterface::cmp()
203
     */
204
    public function cmp(CurveFpInterface $other): int
205
    {
206
        $math = $this->adapter;
207
208
        $equal  = $math->equals($this->getA(), $other->getA());
209
        $equal &= $math->equals($this->getB(), $other->getB());
210
        $equal &= $math->equals($this->getPrime(), $other->getPrime());
211
212
        return ($equal) ? 0 : 1;
213
    }
214
215
    /**
216
     * {@inheritDoc}
217
     * @see \Mdanter\Ecc\Primitives\CurveFpInterface::equals()
218
     */
219
    public function equals(CurveFpInterface $other): bool
220
    {
221
        return $this->cmp($other) == 0;
222
    }
223
224
    /**
225
     * {@inheritDoc}
226
     * @see \Mdanter\Ecc\Primitives\CurveFpInterface::__toString()
227
     */
228
    public function __toString(): string
229
    {
230
        return 'curve(' . $this->adapter->toString($this->getA()) . ', ' . $this->adapter->toString($this->getB()) . ', ' . $this->adapter->toString($this->getPrime()) . ')';
231
    }
232
233
    /**
234
     * @return array
235
     */
236
    public function __debugInfo()
237
    {
238
        return [
239
            'a' => $this->adapter->toString($this->getA()),
240
            'b' => $this->adapter->toString($this->getB()),
241
            'prime' => $this->adapter->toString($this->getPrime())
242
        ];
243
    }
244
}
245