Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/tutor-pro/vendor/web-token/jwt-util-ecc/Curve.php
Keine Baseline-Datei – Diff nur gegen leer.
1
-
1
+
<?php
2
+
3
+
declare(strict_types=1);
4
+
5
+
/*
6
+
* The MIT License (MIT)
7
+
*
8
+
* Copyright (c) 2014-2020 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
+
use Brick\Math\BigInteger;
17
+
use function is_null;
18
+
use RuntimeException;
19
+
20
+
/**
21
+
* @internal
22
+
*/
23
+
class Curve
24
+
{
25
+
/**
26
+
* Elliptic curve over the field of integers modulo a prime.
27
+
*
28
+
* @var BigInteger
29
+
*/
30
+
private $a;
31
+
32
+
/**
33
+
* @var BigInteger
34
+
*/
35
+
private $b;
36
+
37
+
/**
38
+
* @var BigInteger
39
+
*/
40
+
private $prime;
41
+
42
+
/**
43
+
* Binary length of keys associated with these curve parameters.
44
+
*
45
+
* @var int
46
+
*/
47
+
private $size;
48
+
49
+
/**
50
+
* @var Point
51
+
*/
52
+
private $generator;
53
+
54
+
public function __construct(int $size, BigInteger $prime, BigInteger $a, BigInteger $b, Point $generator)
55
+
{
56
+
$this->size = $size;
57
+
$this->prime = $prime;
58
+
$this->a = $a;
59
+
$this->b = $b;
60
+
$this->generator = $generator;
61
+
}
62
+
63
+
public function __toString(): string
64
+
{
65
+
return 'curve('.Math::toString($this->getA()).', '.Math::toString($this->getB()).', '.Math::toString($this->getPrime()).')';
66
+
}
67
+
68
+
public function getA(): BigInteger
69
+
{
70
+
return $this->a;
71
+
}
72
+
73
+
public function getB(): BigInteger
74
+
{
75
+
return $this->b;
76
+
}
77
+
78
+
public function getPrime(): BigInteger
79
+
{
80
+
return $this->prime;
81
+
}
82
+
83
+
public function getSize(): int
84
+
{
85
+
return $this->size;
86
+
}
87
+
88
+
/**
89
+
* @throws RuntimeException if the curve does not contain the point
90
+
*/
91
+
public function getPoint(BigInteger $x, BigInteger $y, ?BigInteger $order = null): Point
92
+
{
93
+
if (!$this->contains($x, $y)) {
94
+
throw new RuntimeException('Curve '.$this->__toString().' does not contain point ('.Math::toString($x).', '.Math::toString($y).')');
95
+
}
96
+
$point = Point::create($x, $y, $order);
97
+
if (!is_null($order)) {
98
+
$mul = $this->mul($point, $order);
99
+
if (!$mul->isInfinity()) {
100
+
throw new RuntimeException('SELF * ORDER MUST EQUAL INFINITY.');
101
+
}
102
+
}
103
+
104
+
return $point;
105
+
}
106
+
107
+
/**
108
+
* @throws RuntimeException if the coordinates are out of range
109
+
*/
110
+
public function getPublicKeyFrom(BigInteger $x, BigInteger $y): PublicKey
111
+
{
112
+
$zero = BigInteger::zero();
113
+
if ($x->compareTo($zero) < 0 || $y->compareTo($zero) < 0 || $this->generator->getOrder()->compareTo($x) <= 0 || $this->generator->getOrder()->compareTo($y) <= 0) {
114
+
throw new RuntimeException('Generator point has x and y out of range.');
115
+
}
116
+
$point = $this->getPoint($x, $y);
117
+
118
+
return new PublicKey($point);
119
+
}
120
+
121
+
public function contains(BigInteger $x, BigInteger $y): bool
122
+
{
123
+
return Math::equals(
124
+
ModularArithmetic::sub(
125
+
$y->power(2),
126
+
Math::add(
127
+
Math::add(
128
+
$x->power(3),
129
+
$this->getA()->multipliedBy($x)
130
+
),
131
+
$this->getB()
132
+
),
133
+
$this->getPrime()
134
+
),
135
+
BigInteger::zero()
136
+
);
137
+
}
138
+
139
+
public function add(Point $one, Point $two): Point
140
+
{
141
+
if ($two->isInfinity()) {
142
+
return clone $one;
143
+
}
144
+
145
+
if ($one->isInfinity()) {
146
+
return clone $two;
147
+
}
148
+
149
+
if ($two->getX()->isEqualTo($one->getX())) {
150
+
if ($two->getY()->isEqualTo($one->getY())) {
151
+
return $this->getDouble($one);
152
+
}
153
+
154
+
return Point::infinity();
155
+
}
156
+
157
+
$slope = ModularArithmetic::div(
158
+
$two->getY()->minus($one->getY()),
159
+
$two->getX()->minus($one->getX()),
160
+
$this->getPrime()
161
+
);
162
+
163
+
$xR = ModularArithmetic::sub(
164
+
$slope->power(2)->minus($one->getX()),
165
+
$two->getX(),
166
+
$this->getPrime()
167
+
);
168
+
169
+
$yR = ModularArithmetic::sub(
170
+
$slope->multipliedBy($one->getX()->minus($xR)),
171
+
$one->getY(),
172
+
$this->getPrime()
173
+
);
174
+
175
+
return $this->getPoint($xR, $yR, $one->getOrder());
176
+
}
177
+
178
+
public function mul(Point $one, BigInteger $n): Point
179
+
{
180
+
if ($one->isInfinity()) {
181
+
return Point::infinity();
182
+
}
183
+
184
+
/** @var BigInteger $zero */
185
+
$zero = BigInteger::zero();
186
+
if ($one->getOrder()->compareTo($zero) > 0) {
187
+
$n = $n->mod($one->getOrder());
188
+
}
189
+
190
+
if ($n->isEqualTo($zero)) {
191
+
return Point::infinity();
192
+
}
193
+
194
+
/** @var Point[] $r */
195
+
$r = [
196
+
Point::infinity(),
197
+
clone $one,
198
+
];
199
+
200
+
$k = $this->getSize();
201
+
$n1 = str_pad(Math::baseConvert(Math::toString($n), 10, 2), $k, '0', STR_PAD_LEFT);
202
+
203
+
for ($i = 0; $i < $k; ++$i) {
204
+
$j = $n1[$i];
205
+
Point::cswap($r[0], $r[1], $j ^ 1);
206
+
$r[0] = $this->add($r[0], $r[1]);
207
+
$r[1] = $this->getDouble($r[1]);
208
+
Point::cswap($r[0], $r[1], $j ^ 1);
209
+
}
210
+
211
+
$this->validate($r[0]);
212
+
213
+
return $r[0];
214
+
}
215
+
216
+
/**
217
+
* @param Curve $other
218
+
*/
219
+
public function cmp(self $other): int
220
+
{
221
+
$equal = $this->getA()->isEqualTo($other->getA())
222
+
&& $this->getB()->isEqualTo($other->getB())
223
+
&& $this->getPrime()->isEqualTo($other->getPrime());
224
+
225
+
return $equal ? 0 : 1;
226
+
}
227
+
228
+
/**
229
+
* @param Curve $other
230
+
*/
231
+
public function equals(self $other): bool
232
+
{
233
+
return 0 === $this->cmp($other);
234
+
}
235
+
236
+
public function getDouble(Point $point): Point
237
+
{
238
+
if ($point->isInfinity()) {
239
+
return Point::infinity();
240
+
}
241
+
242
+
$a = $this->getA();
243
+
$threeX2 = BigInteger::of(3)->multipliedBy($point->getX()->power(2));
244
+
245
+
$tangent = ModularArithmetic::div(
246
+
$threeX2->plus($a),
247
+
BigInteger::of(2)->multipliedBy($point->getY()),
248
+
$this->getPrime()
249
+
);
250
+
251
+
$x3 = ModularArithmetic::sub(
252
+
$tangent->power(2),
253
+
BigInteger::of(2)->multipliedBy($point->getX()),
254
+
$this->getPrime()
255
+
);
256
+
257
+
$y3 = ModularArithmetic::sub(
258
+
$tangent->multipliedBy($point->getX()->minus($x3)),
259
+
$point->getY(),
260
+
$this->getPrime()
261
+
);
262
+
263
+
return $this->getPoint($x3, $y3, $point->getOrder());
264
+
}
265
+
266
+
public function createPrivateKey(): PrivateKey
267
+
{
268
+
return PrivateKey::create($this->generate());
269
+
}
270
+
271
+
public function createPublicKey(PrivateKey $privateKey): PublicKey
272
+
{
273
+
$point = $this->mul($this->generator, $privateKey->getSecret());
274
+
275
+
return new PublicKey($point);
276
+
}
277
+
278
+
public function getGenerator(): Point
279
+
{
280
+
return $this->generator;
281
+
}
282
+
283
+
/**
284
+
* @throws RuntimeException if the point is invalid
285
+
*/
286
+
private function validate(Point $point): void
287
+
{
288
+
if (!$point->isInfinity() && !$this->contains($point->getX(), $point->getY())) {
289
+
throw new RuntimeException('Invalid point');
290
+
}
291
+
}
292
+
293
+
private function generate(): BigInteger
294
+
{
295
+
$max = $this->generator->getOrder();
296
+
$numBits = $this->bnNumBits($max);
297
+
$numBytes = (int) ceil($numBits / 8);
298
+
// Generate an integer of size >= $numBits
299
+
$bytes = BigInteger::randomBits($numBytes);
300
+
$mask = BigInteger::of(2)->power($numBits)->minus(1);
301
+
302
+
return $bytes->and($mask);
303
+
}
304
+
305
+
/**
306
+
* Returns the number of bits used to store this number. Non-significant upper bits are not counted.
307
+
*
308
+
* @see https://www.openssl.org/docs/crypto/BN_num_bytes.html
309
+
*/
310
+
private function bnNumBits(BigInteger $x): int
311
+
{
312
+
$zero = BigInteger::of(0);
313
+
if ($x->isEqualTo($zero)) {
314
+
return 0;
315
+
}
316
+
$log2 = 0;
317
+
while (!$x->isEqualTo($zero)) {
318
+
$x = $x->shiftedRight(1);
319
+
++$log2;
320
+
}
321
+
322
+
return $log2;
323
+
}
324
+
}
325
+