Failed Conditions
Push — master ( 1edcb4...1e22a0 )
by Florent
02:06
created

Point::getY()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * The MIT License (MIT)
7
 *
8
 * Copyright (c) 2014-2017 Spomky-Labs
9
 *
10
 * This software may be modified and distributed under the terms
11
 * of the MIT license.  See the LICENSE file for details.
12
 */
13
14
namespace Jose\Component\Core\Util\Ecc;
15
16
/**
17
 * *********************************************************************
18
 * Copyright (C) 2012 Matyas Danter.
19
 *
20
 * Permission is hereby granted, free of charge, to any person obtaining
21
 * a copy of this software and associated documentation files (the "Software"),
22
 * to deal in the Software without restriction, including without limitation
23
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
24
 * and/or sell copies of the Software, and to permit persons to whom the
25
 * Software is furnished to do so, subject to the following conditions:
26
 *
27
 * The above copyright notice and this permission notice shall be included
28
 * in all copies or substantial portions of the Software.
29
 *
30
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
31
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
33
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
34
 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
35
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
36
 * OTHER DEALINGS IN THE SOFTWARE.
37
 * ***********************************************************************
38
 */
39
40
/**
41
 * This class is where the elliptic curve arithmetic takes place.
42
 * The important methods are:
43
 * - add: adds two points according to ec arithmetic
44
 * - double: doubles a point on the ec field mod p
45
 * - mul: uses double and add to achieve multiplication The rest of the methods are there for supporting the ones above.
46
 */
47
final class Point
48
{
49
    /**
50
     * @var \GMP
51
     */
52
    private $x;
53
54
    /**
55
     * @var \GMP
56
     */
57
    private $y;
58
59
    /**
60
     * @var \GMP
61
     */
62
    private $order;
63
64
    /**
65
     * @var bool
66
     */
67
    private $infinity = false;
68
69
    /**
70
     * Initialize a new instance.
71
     *
72
     * @param \GMP $x
73
     * @param \GMP $y
74
     * @param \GMP $order
75
     * @param bool $infinity
76
     *
77
     * @throws \RuntimeException when either the curve does not contain the given coordinates or
78
     *                           when order is not null and P(x, y) * order is not equal to infinity
79
     */
80
    private function __construct(\GMP $x, \GMP $y, \GMP $order, bool $infinity = false)
81
    {
82
        $this->x = $x;
83
        $this->y = $y;
84
        $this->order = null === $order ? gmp_init(0, 10) : $order;
85
        $this->infinity = $infinity;
86
    }
87
88
    /**
89
     * @param \GMP      $x
90
     * @param \GMP      $y
91
     * @param \GMP|null $order
92
     *
93
     * @return Point
94
     */
95
    public static function create(\GMP $x, \GMP $y, ?\GMP $order = null): Point
96
    {
97
        return new self($x, $y, null === $order ? gmp_init(0, 10) : $order);
98
    }
99
100
    /**
101
     * @return Point
102
     */
103
    public static function infinity(): Point
104
    {
105
        $zero = gmp_init(0, 10);
106
107
        return new self($zero, $zero, $zero, true);
108
    }
109
110
    /**
111
     * @return bool
112
     */
113
    public function isInfinity(): bool
114
    {
115
        return $this->infinity;
116
    }
117
118
    /**
119
     * @return \GMP
120
     */
121
    public function getOrder(): \GMP
122
    {
123
        return $this->order;
124
    }
125
126
    /**
127
     * @return \GMP
128
     */
129
    public function getX(): \GMP
130
    {
131
        return $this->x;
132
    }
133
134
    /**
135
     * @return \GMP
136
     */
137
    public function getY(): \GMP
138
    {
139
        return $this->y;
140
    }
141
142
    /**
143
     * @param Point $a
144
     * @param Point $b
145
     * @param int   $cond
146
     */
147
    public static function cswap(Point $a, Point $b, int $cond)
148
    {
149
        self::cswapGMP($a->x, $b->x, $cond);
150
        self::cswapGMP($a->y, $b->y, $cond);
151
        self::cswapGMP($a->order, $b->order, $cond);
152
        self::cswapBoolean($a->infinity, $b->infinity, $cond);
153
    }
154
155
    /**
156
     * @param $a
157
     * @param $b
158
     * @param $cond
159
     */
160
    private static function cswapBoolean(bool &$a, bool &$b, int $cond)
161
    {
162
        $sa = gmp_init(intval($a), 10);
163
        $sb = gmp_init(intval($b), 10);
164
165
        self::cswapGMP($sa, $sb, $cond);
166
167
        $a = (bool) gmp_strval($sa, 10);
168
        $b = (bool) gmp_strval($sb, 10);
169
    }
170
171
    /**
172
     * @param \GMP $sa
173
     * @param \GMP $sb
174
     * @param int  $cond
175
     */
176
    private static function cswapGMP(\GMP &$sa, \GMP &$sb, int $cond)
177
    {
178
        $size = max(mb_strlen(gmp_strval($sa, 2), '8bit'), mb_strlen(gmp_strval($sb, 2), '8bit'));
179
        $mask = strval(1 - intval($cond));
180
        $mask = str_pad('', $size, $mask, STR_PAD_LEFT);
181
        $mask = gmp_init($mask, 2);
182
        $taA = Math::bitwiseAnd($sa, $mask);
183
        $taB = Math::bitwiseAnd($sb, $mask);
184
        $sa = Math::bitwiseXor(Math::bitwiseXor($sa, $sb), $taB);
185
        $sb = Math::bitwiseXor(Math::bitwiseXor($sa, $sb), $taA);
186
        $sa = Math::bitwiseXor(Math::bitwiseXor($sa, $sb), $taB);
187
    }
188
}
189