Failed Conditions
Push — v7 ( d5cb12...d36fb1 )
by Florent
02:58
created

Point::cswapGMP()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

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