PluginProbe ʕ •ᴥ•ʔ
JetBackup – Backup, Restore & Migrate / 3.1.13.4
JetBackup – Backup, Restore & Migrate v3.1.13.4
3.1.22.4 3.1.22.3 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.8.1 1.4.9 1.5.0 1.5.1 1.5.1.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.10 1.6.11 1.6.12 1.6.13 1.6.15 1.6.5.1 1.6.8.8 1.6.9 1.6.9.1 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7.5 2.0.8.7 2.0.9.11 2.0.9.14 2.0.9.15 2.0.9.6 2.0.9.7 2.0.9.9 3.1.10.7 3.1.11.1 3.1.12.3 3.1.13.4 3.1.14.17 3.1.15.4 3.1.16.1 3.1.17.5 3.1.18.10 3.1.18.8 3.1.18.9 3.1.19.8 3.1.20.3 3.1.21.3 3.1.7.9 3.1.9.2 trunk 1.1.90 1.1.91 1.2.0 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2
backup / src / JetBackup / 3rdparty / phpseclib3 / Crypt / EC / BaseCurves / Binary.php
backup / src / JetBackup / 3rdparty / phpseclib3 / Crypt / EC / BaseCurves Last commit date
.htaccess 9 months ago Base.php 9 months ago Binary.php 9 months ago KoblitzPrime.php 9 months ago Montgomery.php 9 months ago Prime.php 9 months ago TwistedEdwards.php 9 months ago index.html 9 months ago web.config 9 months ago
Binary.php
372 lines
1 <?php
2
3 /**
4 * Curves over y^2 + x*y = x^3 + a*x^2 + b
5 *
6 * These are curves used in SEC 2 over prime fields: http://www.secg.org/SEC2-Ver-1.0.pdf
7 * The curve is a weierstrass curve with a[3] and a[2] set to 0.
8 *
9 * Uses Jacobian Coordinates for speed if able:
10 *
11 * https://en.wikipedia.org/wiki/Jacobian_curve
12 * https://en.wikibooks.org/wiki/Cryptography/Prime_Curve/Jacobian_Coordinates
13 *
14 * PHP version 5 and 7
15 *
16 * @author Jim Wigginton <terrafrost@php.net>
17 * @copyright 2017 Jim Wigginton
18 * @license http://www.opensource.org/licenses/mit-license.html MIT License
19 * @link http://pear.php.net/package/Math_BigInteger
20 */
21
22 declare(strict_types=1);
23
24 namespace phpseclib3\Crypt\EC\BaseCurves;
25
26 use phpseclib3\Exception\RuntimeException;
27 use phpseclib3\Exception\UnexpectedValueException;
28 use phpseclib3\Math\BigInteger;
29 use phpseclib3\Math\BinaryField;
30 use phpseclib3\Math\BinaryField\Integer as BinaryInteger;
31 use phpseclib3\Math\PrimeField\Integer;
32
33 /**
34 * Curves over y^2 + x*y = x^3 + a*x^2 + b
35 *
36 * @author Jim Wigginton <terrafrost@php.net>
37 */
38 class Binary extends Base
39 {
40 /**
41 * Binary Field Integer factory
42 *
43 * @var BinaryField
44 */
45 protected $factory;
46
47 /**
48 * Cofficient for x^1
49 *
50 * @var object
51 */
52 protected $a;
53
54 /**
55 * Cofficient for x^0
56 *
57 * @var object
58 */
59 protected $b;
60
61 /**
62 * Base Point
63 *
64 * @var object
65 */
66 protected $p;
67
68 /**
69 * The number one over the specified finite field
70 *
71 * @var object
72 */
73 protected $one;
74
75 /**
76 * The modulo
77 *
78 * @var array
79 */
80 protected $modulo;
81
82 /**
83 * The Order
84 *
85 * @var BigInteger
86 */
87 protected $order;
88
89 /**
90 * Sets the modulo
91 */
92 public function setModulo(int ...$modulo): void
93 {
94 $this->modulo = $modulo;
95 $this->factory = new BinaryField(...$modulo);
96
97 $this->one = $this->factory->newInteger("\1");
98 }
99
100 /**
101 * Set coefficients a and b
102 */
103 public function setCoefficients(string $a, string $b): void
104 {
105 if (!isset($this->factory)) {
106 throw new RuntimeException('setModulo needs to be called before this method');
107 }
108 $this->a = $this->factory->newInteger(pack('H*', $a));
109 $this->b = $this->factory->newInteger(pack('H*', $b));
110 }
111
112 /**
113 * Set x and y coordinates for the base point
114 *
115 * @param string|BinaryInteger $x
116 * @param string|BinaryInteger $y
117 */
118 public function setBasePoint($x, $y): void
119 {
120 switch (true) {
121 case !is_string($x) && !$x instanceof BinaryInteger:
122 throw new UnexpectedValueException('Argument 1 passed to Binary::setBasePoint() must be a string or an instance of BinaryField\Integer');
123 case !is_string($y) && !$y instanceof BinaryInteger:
124 throw new UnexpectedValueException('Argument 2 passed to Binary::setBasePoint() must be a string or an instance of BinaryField\Integer');
125 }
126 if (!isset($this->factory)) {
127 throw new RuntimeException('setModulo needs to be called before this method');
128 }
129 $this->p = [
130 is_string($x) ? $this->factory->newInteger(pack('H*', $x)) : $x,
131 is_string($y) ? $this->factory->newInteger(pack('H*', $y)) : $y,
132 ];
133 }
134
135 /**
136 * Retrieve the base point as an array
137 *
138 * @return array
139 */
140 public function getBasePoint()
141 {
142 if (!isset($this->factory)) {
143 throw new RuntimeException('setModulo needs to be called before this method');
144 }
145 /*
146 if (!isset($this->p)) {
147 throw new \phpseclib3\Exception\RuntimeException('setBasePoint needs to be called before this method');
148 }
149 */
150 return $this->p;
151 }
152
153 /**
154 * Adds two points on the curve
155 *
156 * @return FiniteField[]
157 */
158 public function addPoint(array $p, array $q): array
159 {
160 if (!isset($this->factory)) {
161 throw new RuntimeException('setModulo needs to be called before this method');
162 }
163
164 if (!count($p) || !count($q)) {
165 if (count($q)) {
166 return $q;
167 }
168 if (count($p)) {
169 return $p;
170 }
171 return [];
172 }
173
174 if (!isset($p[2]) || !isset($q[2])) {
175 throw new RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa');
176 }
177
178 if ($p[0]->equals($q[0])) {
179 return !$p[1]->equals($q[1]) ? [] : $this->doublePoint($p);
180 }
181
182 // formulas from http://hyperelliptic.org/EFD/g12o/auto-shortw-jacobian.html
183
184 [$x1, $y1, $z1] = $p;
185 [$x2, $y2, $z2] = $q;
186
187 $o1 = $z1->multiply($z1);
188 $b = $x2->multiply($o1);
189
190 if ($z2->equals($this->one)) {
191 $d = $y2->multiply($o1)->multiply($z1);
192 $e = $x1->add($b);
193 $f = $y1->add($d);
194 $z3 = $e->multiply($z1);
195 $h = $f->multiply($x2)->add($z3->multiply($y2));
196 $i = $f->add($z3);
197 $g = $z3->multiply($z3);
198 $p1 = $this->a->multiply($g);
199 $p2 = $f->multiply($i);
200 $p3 = $e->multiply($e)->multiply($e);
201 $x3 = $p1->add($p2)->add($p3);
202 $y3 = $i->multiply($x3)->add($g->multiply($h));
203
204 return [$x3, $y3, $z3];
205 }
206
207 $o2 = $z2->multiply($z2);
208 $a = $x1->multiply($o2);
209 $c = $y1->multiply($o2)->multiply($z2);
210 $d = $y2->multiply($o1)->multiply($z1);
211 $e = $a->add($b);
212 $f = $c->add($d);
213 $g = $e->multiply($z1);
214 $h = $f->multiply($x2)->add($g->multiply($y2));
215 $z3 = $g->multiply($z2);
216 $i = $f->add($z3);
217 $p1 = $this->a->multiply($z3->multiply($z3));
218 $p2 = $f->multiply($i);
219 $p3 = $e->multiply($e)->multiply($e);
220 $x3 = $p1->add($p2)->add($p3);
221 $y3 = $i->multiply($x3)->add($g->multiply($g)->multiply($h));
222
223 return [$x3, $y3, $z3];
224 }
225
226 /**
227 * Doubles a point on a curve
228 *
229 * @return FiniteField[]
230 */
231 public function doublePoint(array $p): array
232 {
233 if (!isset($this->factory)) {
234 throw new RuntimeException('setModulo needs to be called before this method');
235 }
236
237 if (!count($p)) {
238 return [];
239 }
240
241 if (!isset($p[2])) {
242 throw new RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa');
243 }
244
245 // formulas from http://hyperelliptic.org/EFD/g12o/auto-shortw-jacobian.html
246
247 [$x1, $y1, $z1] = $p;
248
249 $a = $x1->multiply($x1);
250 $b = $a->multiply($a);
251
252 if ($z1->equals($this->one)) {
253 $x3 = $b->add($this->b);
254 $z3 = clone $x1;
255 $p1 = $a->add($y1)->add($z3)->multiply($this->b);
256 $p2 = $a->add($y1)->multiply($b);
257 $y3 = $p1->add($p2);
258
259 return [$x3, $y3, $z3];
260 }
261
262 $c = $z1->multiply($z1);
263 $d = $c->multiply($c);
264 $x3 = $b->add($this->b->multiply($d->multiply($d)));
265 $z3 = $x1->multiply($c);
266 $p1 = $b->multiply($z3);
267 $p2 = $a->add($y1->multiply($z1))->add($z3)->multiply($x3);
268 $y3 = $p1->add($p2);
269
270 return [$x3, $y3, $z3];
271 }
272
273 /**
274 * Returns the X coordinate and the derived Y coordinate
275 *
276 * Not supported because it is covered by patents.
277 * Quoting https://www.openssl.org/docs/man1.1.0/apps/ecparam.html ,
278 *
279 * "Due to patent issues the compressed option is disabled by default for binary curves
280 * and can be enabled by defining the preprocessor macro OPENSSL_EC_BIN_PT_COMP at
281 * compile time."
282 */
283 public function derivePoint($m): array
284 {
285 throw new RuntimeException('Point compression on binary finite field elliptic curves is not supported');
286 }
287
288 /**
289 * Tests whether or not the x / y values satisfy the equation
290 *
291 * @return boolean
292 */
293 public function verifyPoint(array $p): bool
294 {
295 [$x, $y] = $p;
296 $lhs = $y->multiply($y);
297 $lhs = $lhs->add($x->multiply($y));
298 $x2 = $x->multiply($x);
299 $x3 = $x2->multiply($x);
300 $rhs = $x3->add($this->a->multiply($x2))->add($this->b);
301
302 return $lhs->equals($rhs);
303 }
304
305 /**
306 * Returns the modulo
307 */
308 public function getModulo(): array
309 {
310 return $this->modulo;
311 }
312
313 /**
314 * Returns the a coefficient
315 *
316 * @return Integer
317 */
318 public function getA()
319 {
320 return $this->a;
321 }
322
323 /**
324 * Returns the a coefficient
325 *
326 * @return Integer
327 */
328 public function getB()
329 {
330 return $this->b;
331 }
332
333 /**
334 * Returns the affine point
335 *
336 * A Jacobian Coordinate is of the form (x, y, z).
337 * To convert a Jacobian Coordinate to an Affine Point
338 * you do (x / z^2, y / z^3)
339 *
340 * @return Integer[]
341 */
342 public function convertToAffine(array $p): array
343 {
344 if (!isset($p[2])) {
345 return $p;
346 }
347 [$x, $y, $z] = $p;
348 $z = $this->one->divide($z);
349 $z2 = $z->multiply($z);
350 return [
351 $x->multiply($z2),
352 $y->multiply($z2)->multiply($z),
353 ];
354 }
355
356 /**
357 * Converts an affine point to a jacobian coordinate
358 *
359 * @return Integer[]
360 */
361 public function convertToInternal(array $p): array
362 {
363 if (isset($p[2])) {
364 return $p;
365 }
366
367 $p[2] = clone $this->one;
368 $p['fresh'] = true;
369 return $p;
370 }
371 }
372