Diff: STRATO-apps/wordpress_03/app/wp-includes/sodium_compat/src/Core32/Curve25519.php

Keine Baseline-Datei – Diff nur gegen leer.
Zur Liste
1 -
1 + <?php
2 +
3 + if (class_exists('ParagonIE_Sodium_Core32_Curve25519', false)) {
4 + return;
5 + }
6 +
7 + /**
8 + * Class ParagonIE_Sodium_Core32_Curve25519
9 + *
10 + * Implements Curve25519 core functions
11 + *
12 + * Based on the ref10 curve25519 code provided by libsodium
13 + *
14 + * @ref https://github.com/jedisct1/libsodium/blob/master/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c
15 + */
16 + abstract class ParagonIE_Sodium_Core32_Curve25519 extends ParagonIE_Sodium_Core32_Curve25519_H
17 + {
18 + /**
19 + * Get a field element of size 10 with a value of 0
20 + *
21 + * @internal You should not use this directly from another application
22 + *
23 + * @return ParagonIE_Sodium_Core32_Curve25519_Fe
24 + * @throws SodiumException
25 + * @throws TypeError
26 + */
27 + public static function fe_0()
28 + {
29 + return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
30 + array(
31 + new ParagonIE_Sodium_Core32_Int32(),
32 + new ParagonIE_Sodium_Core32_Int32(),
33 + new ParagonIE_Sodium_Core32_Int32(),
34 + new ParagonIE_Sodium_Core32_Int32(),
35 + new ParagonIE_Sodium_Core32_Int32(),
36 + new ParagonIE_Sodium_Core32_Int32(),
37 + new ParagonIE_Sodium_Core32_Int32(),
38 + new ParagonIE_Sodium_Core32_Int32(),
39 + new ParagonIE_Sodium_Core32_Int32(),
40 + new ParagonIE_Sodium_Core32_Int32()
41 + )
42 + );
43 + }
44 +
45 + /**
46 + * Get a field element of size 10 with a value of 1
47 + *
48 + * @internal You should not use this directly from another application
49 + *
50 + * @return ParagonIE_Sodium_Core32_Curve25519_Fe
51 + * @throws SodiumException
52 + * @throws TypeError
53 + */
54 + public static function fe_1()
55 + {
56 + return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
57 + array(
58 + ParagonIE_Sodium_Core32_Int32::fromInt(1),
59 + new ParagonIE_Sodium_Core32_Int32(),
60 + new ParagonIE_Sodium_Core32_Int32(),
61 + new ParagonIE_Sodium_Core32_Int32(),
62 + new ParagonIE_Sodium_Core32_Int32(),
63 + new ParagonIE_Sodium_Core32_Int32(),
64 + new ParagonIE_Sodium_Core32_Int32(),
65 + new ParagonIE_Sodium_Core32_Int32(),
66 + new ParagonIE_Sodium_Core32_Int32(),
67 + new ParagonIE_Sodium_Core32_Int32()
68 + )
69 + );
70 + }
71 +
72 + /**
73 + * Add two field elements.
74 + *
75 + * @internal You should not use this directly from another application
76 + *
77 + * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
78 + * @param ParagonIE_Sodium_Core32_Curve25519_Fe $g
79 + * @return ParagonIE_Sodium_Core32_Curve25519_Fe
80 + * @throws SodiumException
81 + * @throws TypeError
82 + * @psalm-suppress MixedAssignment
83 + * @psalm-suppress MixedMethodCall
84 + */
85 + public static function fe_add(
86 + ParagonIE_Sodium_Core32_Curve25519_Fe $f,
87 + ParagonIE_Sodium_Core32_Curve25519_Fe $g
88 + ) {
89 + $arr = array();
90 + for ($i = 0; $i < 10; ++$i) {
91 + $arr[$i] = $f[$i]->addInt32($g[$i]);
92 + }
93 + /** @var array<int, ParagonIE_Sodium_Core32_Int32> $arr */
94 + return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray($arr);
95 + }
96 +
97 + /**
98 + * Constant-time conditional move.
99 + *
100 + * @internal You should not use this directly from another application
101 + *
102 + * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
103 + * @param ParagonIE_Sodium_Core32_Curve25519_Fe $g
104 + * @param int $b
105 + * @return ParagonIE_Sodium_Core32_Curve25519_Fe
106 + * @throws SodiumException
107 + * @throws TypeError
108 + * @psalm-suppress MixedAssignment
109 + * @psalm-suppress MixedMethodCall
110 + */
111 + public static function fe_cmov(
112 + ParagonIE_Sodium_Core32_Curve25519_Fe $f,
113 + ParagonIE_Sodium_Core32_Curve25519_Fe $g,
114 + $b = 0
115 + ) {
116 + /** @var array<int, ParagonIE_Sodium_Core32_Int32> $h */
117 + $h = array();
118 + for ($i = 0; $i < 10; ++$i) {
119 + if (!($f[$i] instanceof ParagonIE_Sodium_Core32_Int32)) {
120 + throw new TypeError('Expected Int32');
121 + }
122 + if (!($g[$i] instanceof ParagonIE_Sodium_Core32_Int32)) {
123 + throw new TypeError('Expected Int32');
124 + }
125 + $h[$i] = $f[$i]->xorInt32(
126 + $f[$i]->xorInt32($g[$i])->mask($b)
127 + );
128 + }
129 + /** @var array<int, ParagonIE_Sodium_Core32_Int32> $h */
130 + return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray($h);
131 + }
132 +
133 + /**
134 + * Create a copy of a field element.
135 + *
136 + * @internal You should not use this directly from another application
137 + *
138 + * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
139 + * @return ParagonIE_Sodium_Core32_Curve25519_Fe
140 + */
141 + public static function fe_copy(ParagonIE_Sodium_Core32_Curve25519_Fe $f)
142 + {
143 + $h = clone $f;
144 + return $h;
145 + }
146 +
147 + /**
148 + * Give: 32-byte string.
149 + * Receive: A field element object to use for internal calculations.
150 + *
151 + * @internal You should not use this directly from another application
152 + *
153 + * @param string $s
154 + * @return ParagonIE_Sodium_Core32_Curve25519_Fe
155 + * @throws RangeException
156 + * @throws SodiumException
157 + * @throws TypeError
158 + * @psalm-suppress MixedMethodCall
159 + */
160 + public static function fe_frombytes($s)
161 + {
162 + if (self::strlen($s) !== 32) {
163 + throw new RangeException('Expected a 32-byte string.');
164 + }
165 + /** @var ParagonIE_Sodium_Core32_Int32 $h0 */
166 + $h0 = ParagonIE_Sodium_Core32_Int32::fromInt(
167 + self::load_4($s)
168 + );
169 + /** @var ParagonIE_Sodium_Core32_Int32 $h1 */
170 + $h1 = ParagonIE_Sodium_Core32_Int32::fromInt(
171 + self::load_3(self::substr($s, 4, 3)) << 6
172 + );
173 + /** @var ParagonIE_Sodium_Core32_Int32 $h2 */
174 + $h2 = ParagonIE_Sodium_Core32_Int32::fromInt(
175 + self::load_3(self::substr($s, 7, 3)) << 5
176 + );
177 + /** @var ParagonIE_Sodium_Core32_Int32 $h3 */
178 + $h3 = ParagonIE_Sodium_Core32_Int32::fromInt(
179 + self::load_3(self::substr($s, 10, 3)) << 3
180 + );
181 + /** @var ParagonIE_Sodium_Core32_Int32 $h4 */
182 + $h4 = ParagonIE_Sodium_Core32_Int32::fromInt(
183 + self::load_3(self::substr($s, 13, 3)) << 2
184 + );
185 + /** @var ParagonIE_Sodium_Core32_Int32 $h5 */
186 + $h5 = ParagonIE_Sodium_Core32_Int32::fromInt(
187 + self::load_4(self::substr($s, 16, 4))
188 + );
189 + /** @var ParagonIE_Sodium_Core32_Int32 $h6 */
190 + $h6 = ParagonIE_Sodium_Core32_Int32::fromInt(
191 + self::load_3(self::substr($s, 20, 3)) << 7
192 + );
193 + /** @var ParagonIE_Sodium_Core32_Int32 $h7 */
194 + $h7 = ParagonIE_Sodium_Core32_Int32::fromInt(
195 + self::load_3(self::substr($s, 23, 3)) << 5
196 + );
197 + /** @var ParagonIE_Sodium_Core32_Int32 $h8 */
198 + $h8 = ParagonIE_Sodium_Core32_Int32::fromInt(
199 + self::load_3(self::substr($s, 26, 3)) << 4
200 + );
201 + /** @var ParagonIE_Sodium_Core32_Int32 $h9 */
202 + $h9 = ParagonIE_Sodium_Core32_Int32::fromInt(
203 + (self::load_3(self::substr($s, 29, 3)) & 8388607) << 2
204 + );
205 +
206 + $carry9 = $h9->addInt(1 << 24)->shiftRight(25);
207 + $h0 = $h0->addInt32($carry9->mulInt(19, 5));
208 + $h9 = $h9->subInt32($carry9->shiftLeft(25));
209 +
210 + $carry1 = $h1->addInt(1 << 24)->shiftRight(25);
211 + $h2 = $h2->addInt32($carry1);
212 + $h1 = $h1->subInt32($carry1->shiftLeft(25));
213 +
214 + $carry3 = $h3->addInt(1 << 24)->shiftRight(25);
215 + $h4 = $h4->addInt32($carry3);
216 + $h3 = $h3->subInt32($carry3->shiftLeft(25));
217 +
218 + $carry5 = $h5->addInt(1 << 24)->shiftRight(25);
219 + $h6 = $h6->addInt32($carry5);
220 + $h5 = $h5->subInt32($carry5->shiftLeft(25));
221 +
222 + $carry7 = $h7->addInt(1 << 24)->shiftRight(25);
223 + $h8 = $h8->addInt32($carry7);
224 + $h7 = $h7->subInt32($carry7->shiftLeft(25));
225 +
226 + $carry0 = $h0->addInt(1 << 25)->shiftRight(26);
227 + $h1 = $h1->addInt32($carry0);
228 + $h0 = $h0->subInt32($carry0->shiftLeft(26));
229 +
230 + $carry2 = $h2->addInt(1 << 25)->shiftRight(26);
231 + $h3 = $h3->addInt32($carry2);
232 + $h2 = $h2->subInt32($carry2->shiftLeft(26));
233 +
234 + $carry4 = $h4->addInt(1 << 25)->shiftRight(26);
235 + $h5 = $h5->addInt32($carry4);
236 + $h4 = $h4->subInt32($carry4->shiftLeft(26));
237 +
238 + $carry6 = $h6->addInt(1 << 25)->shiftRight(26);
239 + $h7 = $h7->addInt32($carry6);
240 + $h6 = $h6->subInt32($carry6->shiftLeft(26));
241 +
242 + $carry8 = $h8->addInt(1 << 25)->shiftRight(26);
243 + $h9 = $h9->addInt32($carry8);
244 + $h8 = $h8->subInt32($carry8->shiftLeft(26));
245 +
246 + return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
247 + array($h0, $h1, $h2,$h3, $h4, $h5, $h6, $h7, $h8, $h9)
248 + );
249 + }
250 +
251 + /**
252 + * Convert a field element to a byte string.
253 + *
254 + * @internal You should not use this directly from another application
255 + *
256 + * @param ParagonIE_Sodium_Core32_Curve25519_Fe $h
257 + * @return string
258 + * @throws SodiumException
259 + * @throws TypeError
260 + * @psalm-suppress MixedAssignment
261 + * @psalm-suppress MixedMethodCall
262 + */
263 + public static function fe_tobytes(ParagonIE_Sodium_Core32_Curve25519_Fe $h)
264 + {
265 + /**
266 + * @var ParagonIE_Sodium_Core32_Int64[] $f
267 + * @var ParagonIE_Sodium_Core32_Int64 $q
268 + */
269 + $f = array();
270 +
271 + for ($i = 0; $i < 10; ++$i) {
272 + $f[$i] = $h[$i]->toInt64();
273 + }
274 +
275 + $q = $f[9]->mulInt(19, 5)->addInt(1 << 14)->shiftRight(25)
276 + ->addInt64($f[0])->shiftRight(26)
277 + ->addInt64($f[1])->shiftRight(25)
278 + ->addInt64($f[2])->shiftRight(26)
279 + ->addInt64($f[3])->shiftRight(25)
280 + ->addInt64($f[4])->shiftRight(26)
281 + ->addInt64($f[5])->shiftRight(25)
282 + ->addInt64($f[6])->shiftRight(26)
283 + ->addInt64($f[7])->shiftRight(25)
284 + ->addInt64($f[8])->shiftRight(26)
285 + ->addInt64($f[9])->shiftRight(25);
286 +
287 + $f[0] = $f[0]->addInt64($q->mulInt(19, 5));
288 +
289 + $carry0 = $f[0]->shiftRight(26);
290 + $f[1] = $f[1]->addInt64($carry0);
291 + $f[0] = $f[0]->subInt64($carry0->shiftLeft(26));
292 +
293 + $carry1 = $f[1]->shiftRight(25);
294 + $f[2] = $f[2]->addInt64($carry1);
295 + $f[1] = $f[1]->subInt64($carry1->shiftLeft(25));
296 +
297 + $carry2 = $f[2]->shiftRight(26);
298 + $f[3] = $f[3]->addInt64($carry2);
299 + $f[2] = $f[2]->subInt64($carry2->shiftLeft(26));
300 +
301 + $carry3 = $f[3]->shiftRight(25);
302 + $f[4] = $f[4]->addInt64($carry3);
303 + $f[3] = $f[3]->subInt64($carry3->shiftLeft(25));
304 +
305 + $carry4 = $f[4]->shiftRight(26);
306 + $f[5] = $f[5]->addInt64($carry4);
307 + $f[4] = $f[4]->subInt64($carry4->shiftLeft(26));
308 +
309 + $carry5 = $f[5]->shiftRight(25);
310 + $f[6] = $f[6]->addInt64($carry5);
311 + $f[5] = $f[5]->subInt64($carry5->shiftLeft(25));
312 +
313 + $carry6 = $f[6]->shiftRight(26);
314 + $f[7] = $f[7]->addInt64($carry6);
315 + $f[6] = $f[6]->subInt64($carry6->shiftLeft(26));
316 +
317 + $carry7 = $f[7]->shiftRight(25);
318 + $f[8] = $f[8]->addInt64($carry7);
319 + $f[7] = $f[7]->subInt64($carry7->shiftLeft(25));
320 +
321 + $carry8 = $f[8]->shiftRight(26);
322 + $f[9] = $f[9]->addInt64($carry8);
323 + $f[8] = $f[8]->subInt64($carry8->shiftLeft(26));
324 +
325 + $carry9 = $f[9]->shiftRight(25);
326 + $f[9] = $f[9]->subInt64($carry9->shiftLeft(25));
327 +
328 + $h0 = $f[0]->toInt32()->toInt();
329 + $h1 = $f[1]->toInt32()->toInt();
330 + $h2 = $f[2]->toInt32()->toInt();
331 + $h3 = $f[3]->toInt32()->toInt();
332 + $h4 = $f[4]->toInt32()->toInt();
333 + $h5 = $f[5]->toInt32()->toInt();
334 + $h6 = $f[6]->toInt32()->toInt();
335 + $h7 = $f[7]->toInt32()->toInt();
336 + $h8 = $f[8]->toInt32()->toInt();
337 + $h9 = $f[9]->toInt32()->toInt();
338 +
339 + /**
340 + * @var array<int, int>
341 + */
342 + $s = array(
343 + (int) (($h0 >> 0) & 0xff),
344 + (int) (($h0 >> 8) & 0xff),
345 + (int) (($h0 >> 16) & 0xff),
346 + (int) ((($h0 >> 24) | ($h1 << 2)) & 0xff),
347 + (int) (($h1 >> 6) & 0xff),
348 + (int) (($h1 >> 14) & 0xff),
349 + (int) ((($h1 >> 22) | ($h2 << 3)) & 0xff),
350 + (int) (($h2 >> 5) & 0xff),
351 + (int) (($h2 >> 13) & 0xff),
352 + (int) ((($h2 >> 21) | ($h3 << 5)) & 0xff),
353 + (int) (($h3 >> 3) & 0xff),
354 + (int) (($h3 >> 11) & 0xff),
355 + (int) ((($h3 >> 19) | ($h4 << 6)) & 0xff),
356 + (int) (($h4 >> 2) & 0xff),
357 + (int) (($h4 >> 10) & 0xff),
358 + (int) (($h4 >> 18) & 0xff),
359 + (int) (($h5 >> 0) & 0xff),
360 + (int) (($h5 >> 8) & 0xff),
361 + (int) (($h5 >> 16) & 0xff),
362 + (int) ((($h5 >> 24) | ($h6 << 1)) & 0xff),
363 + (int) (($h6 >> 7) & 0xff),
364 + (int) (($h6 >> 15) & 0xff),
365 + (int) ((($h6 >> 23) | ($h7 << 3)) & 0xff),
366 + (int) (($h7 >> 5) & 0xff),
367 + (int) (($h7 >> 13) & 0xff),
368 + (int) ((($h7 >> 21) | ($h8 << 4)) & 0xff),
369 + (int) (($h8 >> 4) & 0xff),
370 + (int) (($h8 >> 12) & 0xff),
371 + (int) ((($h8 >> 20) | ($h9 << 6)) & 0xff),
372 + (int) (($h9 >> 2) & 0xff),
373 + (int) (($h9 >> 10) & 0xff),
374 + (int) (($h9 >> 18) & 0xff)
375 + );
376 + return self::intArrayToString($s);
377 + }
378 +
379 + /**
380 + * Is a field element negative? (1 = yes, 0 = no. Used in calculations.)
381 + *
382 + * @internal You should not use this directly from another application
383 + *
384 + * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
385 + * @return int
386 + * @throws SodiumException
387 + * @throws TypeError
388 + */
389 + public static function fe_isnegative(ParagonIE_Sodium_Core32_Curve25519_Fe $f)
390 + {
391 + $str = self::fe_tobytes($f);
392 + return (int) (self::chrToInt($str[0]) & 1);
393 + }
394 +
395 + /**
396 + * Returns 0 if this field element results in all NUL bytes.
397 + *
398 + * @internal You should not use this directly from another application
399 + *
400 + * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
401 + * @return bool
402 + * @throws SodiumException
403 + * @throws TypeError
404 + */
405 + public static function fe_isnonzero(ParagonIE_Sodium_Core32_Curve25519_Fe $f)
406 + {
407 + static $zero;
408 + if ($zero === null) {
409 + $zero = str_repeat("\x00", 32);
410 + }
411 + $str = self::fe_tobytes($f);
412 + /** @var string $zero */
413 + return !self::verify_32($str, $zero);
414 + }
415 +
416 + /**
417 + * Multiply two field elements
418 + *
419 + * h = f * g
420 + *
421 + * @internal You should not use this directly from another application
422 + *
423 + * @security Is multiplication a source of timing leaks? If so, can we do
424 + * anything to prevent that from happening?
425 + *
426 + * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
427 + * @param ParagonIE_Sodium_Core32_Curve25519_Fe $g
428 + * @return ParagonIE_Sodium_Core32_Curve25519_Fe
429 + * @throws SodiumException
430 + * @throws TypeError
431 + */
432 + public static function fe_mul(
433 + ParagonIE_Sodium_Core32_Curve25519_Fe $f,
434 + ParagonIE_Sodium_Core32_Curve25519_Fe $g
435 + ) {
436 + /**
437 + * @var ParagonIE_Sodium_Core32_Int32[] $f
438 + * @var ParagonIE_Sodium_Core32_Int32[] $g
439 + * @var ParagonIE_Sodium_Core32_Int64 $f0
440 + * @var ParagonIE_Sodium_Core32_Int64 $f1
441 + * @var ParagonIE_Sodium_Core32_Int64 $f2
442 + * @var ParagonIE_Sodium_Core32_Int64 $f3
443 + * @var ParagonIE_Sodium_Core32_Int64 $f4
444 + * @var ParagonIE_Sodium_Core32_Int64 $f5
445 + * @var ParagonIE_Sodium_Core32_Int64 $f6
446 + * @var ParagonIE_Sodium_Core32_Int64 $f7
447 + * @var ParagonIE_Sodium_Core32_Int64 $f8
448 + * @var ParagonIE_Sodium_Core32_Int64 $f9
449 + * @var ParagonIE_Sodium_Core32_Int64 $g0
450 + * @var ParagonIE_Sodium_Core32_Int64 $g1
451 + * @var ParagonIE_Sodium_Core32_Int64 $g2
452 + * @var ParagonIE_Sodium_Core32_Int64 $g3
453 + * @var ParagonIE_Sodium_Core32_Int64 $g4
454 + * @var ParagonIE_Sodium_Core32_Int64 $g5
455 + * @var ParagonIE_Sodium_Core32_Int64 $g6
456 + * @var ParagonIE_Sodium_Core32_Int64 $g7
457 + * @var ParagonIE_Sodium_Core32_Int64 $g8
458 + * @var ParagonIE_Sodium_Core32_Int64 $g9
459 + */
460 + $f0 = $f[0]->toInt64();
461 + $f1 = $f[1]->toInt64();
462 + $f2 = $f[2]->toInt64();
463 + $f3 = $f[3]->toInt64();
464 + $f4 = $f[4]->toInt64();
465 + $f5 = $f[5]->toInt64();
466 + $f6 = $f[6]->toInt64();
467 + $f7 = $f[7]->toInt64();
468 + $f8 = $f[8]->toInt64();
469 + $f9 = $f[9]->toInt64();
470 + $g0 = $g[0]->toInt64();
471 + $g1 = $g[1]->toInt64();
472 + $g2 = $g[2]->toInt64();
473 + $g3 = $g[3]->toInt64();
474 + $g4 = $g[4]->toInt64();
475 + $g5 = $g[5]->toInt64();
476 + $g6 = $g[6]->toInt64();
477 + $g7 = $g[7]->toInt64();
478 + $g8 = $g[8]->toInt64();
479 + $g9 = $g[9]->toInt64();
480 + $g1_19 = $g1->mulInt(19, 5); /* 2^4 <= 19 <= 2^5, but we only want 5 bits */
481 + $g2_19 = $g2->mulInt(19, 5);
482 + $g3_19 = $g3->mulInt(19, 5);
483 + $g4_19 = $g4->mulInt(19, 5);
484 + $g5_19 = $g5->mulInt(19, 5);
485 + $g6_19 = $g6->mulInt(19, 5);
486 + $g7_19 = $g7->mulInt(19, 5);
487 + $g8_19 = $g8->mulInt(19, 5);
488 + $g9_19 = $g9->mulInt(19, 5);
489 + $f1_2 = $f1->shiftLeft(1);
490 + $f3_2 = $f3->shiftLeft(1);
491 + $f5_2 = $f5->shiftLeft(1);
492 + $f7_2 = $f7->shiftLeft(1);
493 + $f9_2 = $f9->shiftLeft(1);
494 + $f0g0 = $f0->mulInt64($g0, 27);
495 + $f0g1 = $f0->mulInt64($g1, 27);
496 + $f0g2 = $f0->mulInt64($g2, 27);
497 + $f0g3 = $f0->mulInt64($g3, 27);
498 + $f0g4 = $f0->mulInt64($g4, 27);
499 + $f0g5 = $f0->mulInt64($g5, 27);
500 + $f0g6 = $f0->mulInt64($g6, 27);
501 + $f0g7 = $f0->mulInt64($g7, 27);
502 + $f0g8 = $f0->mulInt64($g8, 27);
503 + $f0g9 = $f0->mulInt64($g9, 27);
504 + $f1g0 = $f1->mulInt64($g0, 27);
505 + $f1g1_2 = $f1_2->mulInt64($g1, 27);
506 + $f1g2 = $f1->mulInt64($g2, 27);
507 + $f1g3_2 = $f1_2->mulInt64($g3, 27);
508 + $f1g4 = $f1->mulInt64($g4, 30);
509 + $f1g5_2 = $f1_2->mulInt64($g5, 30);
510 + $f1g6 = $f1->mulInt64($g6, 30);
511 + $f1g7_2 = $f1_2->mulInt64($g7, 30);
512 + $f1g8 = $f1->mulInt64($g8, 30);
513 + $f1g9_38 = $g9_19->mulInt64($f1_2, 30);
514 + $f2g0 = $f2->mulInt64($g0, 30);
515 + $f2g1 = $f2->mulInt64($g1, 29);
516 + $f2g2 = $f2->mulInt64($g2, 30);
517 + $f2g3 = $f2->mulInt64($g3, 29);
518 + $f2g4 = $f2->mulInt64($g4, 30);
519 + $f2g5 = $f2->mulInt64($g5, 29);
520 + $f2g6 = $f2->mulInt64($g6, 30);
521 + $f2g7 = $f2->mulInt64($g7, 29);
522 + $f2g8_19 = $g8_19->mulInt64($f2, 30);
523 + $f2g9_19 = $g9_19->mulInt64($f2, 30);
524 + $f3g0 = $f3->mulInt64($g0, 30);
525 + $f3g1_2 = $f3_2->mulInt64($g1, 30);
526 + $f3g2 = $f3->mulInt64($g2, 30);
527 + $f3g3_2 = $f3_2->mulInt64($g3, 30);
528 + $f3g4 = $f3->mulInt64($g4, 30);
529 + $f3g5_2 = $f3_2->mulInt64($g5, 30);
530 + $f3g6 = $f3->mulInt64($g6, 30);
531 + $f3g7_38 = $g7_19->mulInt64($f3_2, 30);
532 + $f3g8_19 = $g8_19->mulInt64($f3, 30);
533 + $f3g9_38 = $g9_19->mulInt64($f3_2, 30);
534 + $f4g0 = $f4->mulInt64($g0, 30);
535 + $f4g1 = $f4->mulInt64($g1, 30);
536 + $f4g2 = $f4->mulInt64($g2, 30);
537 + $f4g3 = $f4->mulInt64($g3, 30);
538 + $f4g4 = $f4->mulInt64($g4, 30);
539 + $f4g5 = $f4->mulInt64($g5, 30);
540 + $f4g6_19 = $g6_19->mulInt64($f4, 30);
541 + $f4g7_19 = $g7_19->mulInt64($f4, 30);
542 + $f4g8_19 = $g8_19->mulInt64($f4, 30);
543 + $f4g9_19 = $g9_19->mulInt64($f4, 30);
544 + $f5g0 = $f5->mulInt64($g0, 30);
545 + $f5g1_2 = $f5_2->mulInt64($g1, 30);
546 + $f5g2 = $f5->mulInt64($g2, 30);
547 + $f5g3_2 = $f5_2->mulInt64($g3, 30);
548 + $f5g4 = $f5->mulInt64($g4, 30);
549 + $f5g5_38 = $g5_19->mulInt64($f5_2, 30);
550 + $f5g6_19 = $g6_19->mulInt64($f5, 30);
551 + $f5g7_38 = $g7_19->mulInt64($f5_2, 30);
552 + $f5g8_19 = $g8_19->mulInt64($f5, 30);
553 + $f5g9_38 = $g9_19->mulInt64($f5_2, 30);
554 + $f6g0 = $f6->mulInt64($g0, 30);
555 + $f6g1 = $f6->mulInt64($g1, 30);
556 + $f6g2 = $f6->mulInt64($g2, 30);
557 + $f6g3 = $f6->mulInt64($g3, 30);
558 + $f6g4_19 = $g4_19->mulInt64($f6, 30);
559 + $f6g5_19 = $g5_19->mulInt64($f6, 30);
560 + $f6g6_19 = $g6_19->mulInt64($f6, 30);
561 + $f6g7_19 = $g7_19->mulInt64($f6, 30);
562 + $f6g8_19 = $g8_19->mulInt64($f6, 30);
563 + $f6g9_19 = $g9_19->mulInt64($f6, 30);
564 + $f7g0 = $f7->mulInt64($g0, 30);
565 + $f7g1_2 = $g1->mulInt64($f7_2, 30);
566 + $f7g2 = $f7->mulInt64($g2, 30);
567 + $f7g3_38 = $g3_19->mulInt64($f7_2, 30);
568 + $f7g4_19 = $g4_19->mulInt64($f7, 30);
569 + $f7g5_38 = $g5_19->mulInt64($f7_2, 30);
570 + $f7g6_19 = $g6_19->mulInt64($f7, 30);
571 + $f7g7_38 = $g7_19->mulInt64($f7_2, 30);
572 + $f7g8_19 = $g8_19->mulInt64($f7, 30);
573 + $f7g9_38 = $g9_19->mulInt64($f7_2, 30);
574 + $f8g0 = $f8->mulInt64($g0, 30);
575 + $f8g1 = $f8->mulInt64($g1, 29);
576 + $f8g2_19 = $g2_19->mulInt64($f8, 30);
577 + $f8g3_19 = $g3_19->mulInt64($f8, 30);
578 + $f8g4_19 = $g4_19->mulInt64($f8, 30);
579 + $f8g5_19 = $g5_19->mulInt64($f8, 30);
580 + $f8g6_19 = $g6_19->mulInt64($f8, 30);
581 + $f8g7_19 = $g7_19->mulInt64($f8, 30);
582 + $f8g8_19 = $g8_19->mulInt64($f8, 30);
583 + $f8g9_19 = $g9_19->mulInt64($f8, 30);
584 + $f9g0 = $f9->mulInt64($g0, 30);
585 + $f9g1_38 = $g1_19->mulInt64($f9_2, 30);
586 + $f9g2_19 = $g2_19->mulInt64($f9, 30);
587 + $f9g3_38 = $g3_19->mulInt64($f9_2, 30);
588 + $f9g4_19 = $g4_19->mulInt64($f9, 30);
589 + $f9g5_38 = $g5_19->mulInt64($f9_2, 30);
590 + $f9g6_19 = $g6_19->mulInt64($f9, 30);
591 + $f9g7_38 = $g7_19->mulInt64($f9_2, 30);
592 + $f9g8_19 = $g8_19->mulInt64($f9, 30);
593 + $f9g9_38 = $g9_19->mulInt64($f9_2, 30);
594 +
595 + // $h0 = $f0g0 + $f1g9_38 + $f2g8_19 + $f3g7_38 + $f4g6_19 + $f5g5_38 + $f6g4_19 + $f7g3_38 + $f8g2_19 + $f9g1_38;
596 + $h0 = $f0g0->addInt64($f1g9_38)->addInt64($f2g8_19)->addInt64($f3g7_38)
597 + ->addInt64($f4g6_19)->addInt64($f5g5_38)->addInt64($f6g4_19)
598 + ->addInt64($f7g3_38)->addInt64($f8g2_19)->addInt64($f9g1_38);
599 +
600 + // $h1 = $f0g1 + $f1g0 + $f2g9_19 + $f3g8_19 + $f4g7_19 + $f5g6_19 + $f6g5_19 + $f7g4_19 + $f8g3_19 + $f9g2_19;
601 + $h1 = $f0g1->addInt64($f1g0)->addInt64($f2g9_19)->addInt64($f3g8_19)
602 + ->addInt64($f4g7_19)->addInt64($f5g6_19)->addInt64($f6g5_19)
603 + ->addInt64($f7g4_19)->addInt64($f8g3_19)->addInt64($f9g2_19);
604 +
605 + // $h2 = $f0g2 + $f1g1_2 + $f2g0 + $f3g9_38 + $f4g8_19 + $f5g7_38 + $f6g6_19 + $f7g5_38 + $f8g4_19 + $f9g3_38;
606 + $h2 = $f0g2->addInt64($f1g1_2)->addInt64($f2g0)->addInt64($f3g9_38)
607 + ->addInt64($f4g8_19)->addInt64($f5g7_38)->addInt64($f6g6_19)
608 + ->addInt64($f7g5_38)->addInt64($f8g4_19)->addInt64($f9g3_38);
609 +
610 + // $h3 = $f0g3 + $f1g2 + $f2g1 + $f3g0 + $f4g9_19 + $f5g8_19 + $f6g7_19 + $f7g6_19 + $f8g5_19 + $f9g4_19;
611 + $h3 = $f0g3->addInt64($f1g2)->addInt64($f2g1)->addInt64($f3g0)
612 + ->addInt64($f4g9_19)->addInt64($f5g8_19)->addInt64($f6g7_19)
613 + ->addInt64($f7g6_19)->addInt64($f8g5_19)->addInt64($f9g4_19);
614 +
615 + // $h4 = $f0g4 + $f1g3_2 + $f2g2 + $f3g1_2 + $f4g0 + $f5g9_38 + $f6g8_19 + $f7g7_38 + $f8g6_19 + $f9g5_38;
616 + $h4 = $f0g4->addInt64($f1g3_2)->addInt64($f2g2)->addInt64($f3g1_2)
617 + ->addInt64($f4g0)->addInt64($f5g9_38)->addInt64($f6g8_19)
618 + ->addInt64($f7g7_38)->addInt64($f8g6_19)->addInt64($f9g5_38);
619 +
620 + // $h5 = $f0g5 + $f1g4 + $f2g3 + $f3g2 + $f4g1 + $f5g0 + $f6g9_19 + $f7g8_19 + $f8g7_19 + $f9g6_19;
621 + $h5 = $f0g5->addInt64($f1g4)->addInt64($f2g3)->addInt64($f3g2)
622 + ->addInt64($f4g1)->addInt64($f5g0)->addInt64($f6g9_19)
623 + ->addInt64($f7g8_19)->addInt64($f8g7_19)->addInt64($f9g6_19);
624 +
625 + // $h6 = $f0g6 + $f1g5_2 + $f2g4 + $f3g3_2 + $f4g2 + $f5g1_2 + $f6g0 + $f7g9_38 + $f8g8_19 + $f9g7_38;
626 + $h6 = $f0g6->addInt64($f1g5_2)->addInt64($f2g4)->addInt64($f3g3_2)
627 + ->addInt64($f4g2)->addInt64($f5g1_2)->addInt64($f6g0)
628 + ->addInt64($f7g9_38)->addInt64($f8g8_19)->addInt64($f9g7_38);
629 +
630 + // $h7 = $f0g7 + $f1g6 + $f2g5 + $f3g4 + $f4g3 + $f5g2 + $f6g1 + $f7g0 + $f8g9_19 + $f9g8_19;
631 + $h7 = $f0g7->addInt64($f1g6)->addInt64($f2g5)->addInt64($f3g4)
632 + ->addInt64($f4g3)->addInt64($f5g2)->addInt64($f6g1)
633 + ->addInt64($f7g0)->addInt64($f8g9_19)->addInt64($f9g8_19);
634 +
635 + // $h8 = $f0g8 + $f1g7_2 + $f2g6 + $f3g5_2 + $f4g4 + $f5g3_2 + $f6g2 + $f7g1_2 + $f8g0 + $f9g9_38;
636 + $h8 = $f0g8->addInt64($f1g7_2)->addInt64($f2g6)->addInt64($f3g5_2)
637 + ->addInt64($f4g4)->addInt64($f5g3_2)->addInt64($f6g2)
638 + ->addInt64($f7g1_2)->addInt64($f8g0)->addInt64($f9g9_38);
639 +
640 + // $h9 = $f0g9 + $f1g8 + $f2g7 + $f3g6 + $f4g5 + $f5g4 + $f6g3 + $f7g2 + $f8g1 + $f9g0 ;
641 + $h9 = $f0g9->addInt64($f1g8)->addInt64($f2g7)->addInt64($f3g6)
642 + ->addInt64($f4g5)->addInt64($f5g4)->addInt64($f6g3)
643 + ->addInt64($f7g2)->addInt64($f8g1)->addInt64($f9g0);
644 +
645 + /**
646 + * @var ParagonIE_Sodium_Core32_Int64 $h0
647 + * @var ParagonIE_Sodium_Core32_Int64 $h1
648 + * @var ParagonIE_Sodium_Core32_Int64 $h2
649 + * @var ParagonIE_Sodium_Core32_Int64 $h3
650 + * @var ParagonIE_Sodium_Core32_Int64 $h4
651 + * @var ParagonIE_Sodium_Core32_Int64 $h5
652 + * @var ParagonIE_Sodium_Core32_Int64 $h6
653 + * @var ParagonIE_Sodium_Core32_Int64 $h7
654 + * @var ParagonIE_Sodium_Core32_Int64 $h8
655 + * @var ParagonIE_Sodium_Core32_Int64 $h9
656 + * @var ParagonIE_Sodium_Core32_Int64 $carry0
657 + * @var ParagonIE_Sodium_Core32_Int64 $carry1
658 + * @var ParagonIE_Sodium_Core32_Int64 $carry2
659 + * @var ParagonIE_Sodium_Core32_Int64 $carry3
660 + * @var ParagonIE_Sodium_Core32_Int64 $carry4
661 + * @var ParagonIE_Sodium_Core32_Int64 $carry5
662 + * @var ParagonIE_Sodium_Core32_Int64 $carry6
663 + * @var ParagonIE_Sodium_Core32_Int64 $carry7
664 + * @var ParagonIE_Sodium_Core32_Int64 $carry8
665 + * @var ParagonIE_Sodium_Core32_Int64 $carry9
666 + */
667 + $carry0 = $h0->addInt(1 << 25)->shiftRight(26);
668 + $h1 = $h1->addInt64($carry0);
669 + $h0 = $h0->subInt64($carry0->shiftLeft(26));
670 + $carry4 = $h4->addInt(1 << 25)->shiftRight(26);
671 + $h5 = $h5->addInt64($carry4);
672 + $h4 = $h4->subInt64($carry4->shiftLeft(26));
673 +
674 + $carry1 = $h1->addInt(1 << 24)->shiftRight(25);
675 + $h2 = $h2->addInt64($carry1);
676 + $h1 = $h1->subInt64($carry1->shiftLeft(25));
677 + $carry5 = $h5->addInt(1 << 24)->shiftRight(25);
678 + $h6 = $h6->addInt64($carry5);
679 + $h5 = $h5->subInt64($carry5->shiftLeft(25));
680 +
681 + $carry2 = $h2->addInt(1 << 25)->shiftRight(26);
682 + $h3 = $h3->addInt64($carry2);
683 + $h2 = $h2->subInt64($carry2->shiftLeft(26));
684 + $carry6 = $h6->addInt(1 << 25)->shiftRight(26);
685 + $h7 = $h7->addInt64($carry6);
686 + $h6 = $h6->subInt64($carry6->shiftLeft(26));
687 +
688 + $carry3 = $h3->addInt(1 << 24)->shiftRight(25);
689 + $h4 = $h4->addInt64($carry3);
690 + $h3 = $h3->subInt64($carry3->shiftLeft(25));
691 + $carry7 = $h7->addInt(1 << 24)->shiftRight(25);
692 + $h8 = $h8->addInt64($carry7);
693 + $h7 = $h7->subInt64($carry7->shiftLeft(25));
694 +
695 + $carry4 = $h4->addInt(1 << 25)->shiftRight(26);
696 + $h5 = $h5->addInt64($carry4);
697 + $h4 = $h4->subInt64($carry4->shiftLeft(26));
698 + $carry8 = $h8->addInt(1 << 25)->shiftRight(26);
699 + $h9 = $h9->addInt64($carry8);
700 + $h8 = $h8->subInt64($carry8->shiftLeft(26));
701 +
702 + $carry9 = $h9->addInt(1 << 24)->shiftRight(25);
703 + $h0 = $h0->addInt64($carry9->mulInt(19, 5));
704 + $h9 = $h9->subInt64($carry9->shiftLeft(25));
705 +
706 + $carry0 = $h0->addInt(1 << 25)->shiftRight(26);
707 + $h1 = $h1->addInt64($carry0);
708 + $h0 = $h0->subInt64($carry0->shiftLeft(26));
709 +
710 + return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
711 + array(
712 + $h0->toInt32(),
713 + $h1->toInt32(),
714 + $h2->toInt32(),
715 + $h3->toInt32(),
716 + $h4->toInt32(),
717 + $h5->toInt32(),
718 + $h6->toInt32(),
719 + $h7->toInt32(),
720 + $h8->toInt32(),
721 + $h9->toInt32()
722 + )
723 + );
724 + }
725 +
726 + /**
727 + * Get the negative values for each piece of the field element.
728 + *
729 + * h = -f
730 + *
731 + * @internal You should not use this directly from another application
732 + *
733 + * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
734 + * @return ParagonIE_Sodium_Core32_Curve25519_Fe
735 + * @psalm-suppress MixedAssignment
736 + * @psalm-suppress MixedMethodCall
737 + */
738 + public static function fe_neg(ParagonIE_Sodium_Core32_Curve25519_Fe $f)
739 + {
740 + $h = new ParagonIE_Sodium_Core32_Curve25519_Fe();
741 + for ($i = 0; $i < 10; ++$i) {
742 + $h[$i] = $h[$i]->subInt32($f[$i]);
743 + }
744 + return $h;
745 + }
746 +
747 + /**
748 + * Square a field element
749 + *
750 + * h = f * f
751 + *
752 + * @internal You should not use this directly from another application
753 + *
754 + * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
755 + * @return ParagonIE_Sodium_Core32_Curve25519_Fe
756 + * @throws SodiumException
757 + * @throws TypeError
758 + * @psalm-suppress MixedMethodCall
759 + */
760 + public static function fe_sq(ParagonIE_Sodium_Core32_Curve25519_Fe $f)
761 + {
762 + $f0 = $f[0]->toInt64();
763 + $f1 = $f[1]->toInt64();
764 + $f2 = $f[2]->toInt64();
765 + $f3 = $f[3]->toInt64();
766 + $f4 = $f[4]->toInt64();
767 + $f5 = $f[5]->toInt64();
768 + $f6 = $f[6]->toInt64();
769 + $f7 = $f[7]->toInt64();
770 + $f8 = $f[8]->toInt64();
771 + $f9 = $f[9]->toInt64();
772 +
773 + $f0_2 = $f0->shiftLeft(1);
774 + $f1_2 = $f1->shiftLeft(1);
775 + $f2_2 = $f2->shiftLeft(1);
776 + $f3_2 = $f3->shiftLeft(1);
777 + $f4_2 = $f4->shiftLeft(1);
778 + $f5_2 = $f5->shiftLeft(1);
779 + $f6_2 = $f6->shiftLeft(1);
780 + $f7_2 = $f7->shiftLeft(1);
781 + $f5_38 = $f5->mulInt(38, 6);
782 + $f6_19 = $f6->mulInt(19, 5);
783 + $f7_38 = $f7->mulInt(38, 6);
784 + $f8_19 = $f8->mulInt(19, 5);
785 + $f9_38 = $f9->mulInt(38, 6);
786 +
787 + $f0f0 = $f0->mulInt64($f0, 28);
788 + $f0f1_2 = $f0_2->mulInt64($f1, 28);
789 + $f0f2_2 = $f0_2->mulInt64($f2, 28);
790 + $f0f3_2 = $f0_2->mulInt64($f3, 28);
791 + $f0f4_2 = $f0_2->mulInt64($f4, 28);
792 + $f0f5_2 = $f0_2->mulInt64($f5, 28);
793 + $f0f6_2 = $f0_2->mulInt64($f6, 28);
794 + $f0f7_2 = $f0_2->mulInt64($f7, 28);
795 + $f0f8_2 = $f0_2->mulInt64($f8, 28);
796 + $f0f9_2 = $f0_2->mulInt64($f9, 28);
797 +
798 + $f1f1_2 = $f1_2->mulInt64($f1, 28);
799 + $f1f2_2 = $f1_2->mulInt64($f2, 28);
800 + $f1f3_4 = $f1_2->mulInt64($f3_2, 28);
801 + $f1f4_2 = $f1_2->mulInt64($f4, 28);
802 + $f1f5_4 = $f1_2->mulInt64($f5_2, 30);
803 + $f1f6_2 = $f1_2->mulInt64($f6, 28);
804 + $f1f7_4 = $f1_2->mulInt64($f7_2, 28);
805 + $f1f8_2 = $f1_2->mulInt64($f8, 28);
806 + $f1f9_76 = $f9_38->mulInt64($f1_2, 30);
807 +
808 + $f2f2 = $f2->mulInt64($f2, 28);
809 + $f2f3_2 = $f2_2->mulInt64($f3, 28);
810 + $f2f4_2 = $f2_2->mulInt64($f4, 28);
811 + $f2f5_2 = $f2_2->mulInt64($f5, 28);
812 + $f2f6_2 = $f2_2->mulInt64($f6, 28);
813 + $f2f7_2 = $f2_2->mulInt64($f7, 28);
814 + $f2f8_38 = $f8_19->mulInt64($f2_2, 30);
815 + $f2f9_38 = $f9_38->mulInt64($f2, 30);
816 +
817 + $f3f3_2 = $f3_2->mulInt64($f3, 28);
818 + $f3f4_2 = $f3_2->mulInt64($f4, 28);
819 + $f3f5_4 = $f3_2->mulInt64($f5_2, 30);
820 + $f3f6_2 = $f3_2->mulInt64($f6, 28);
821 + $f3f7_76 = $f7_38->mulInt64($f3_2, 30);
822 + $f3f8_38 = $f8_19->mulInt64($f3_2, 30);
823 + $f3f9_76 = $f9_38->mulInt64($f3_2, 30);
824 +
825 + $f4f4 = $f4->mulInt64($f4, 28);
826 + $f4f5_2 = $f4_2->mulInt64($f5, 28);
827 + $f4f6_38 = $f6_19->mulInt64($f4_2, 30);
828 + $f4f7_38 = $f7_38->mulInt64($f4, 30);
829 + $f4f8_38 = $f8_19->mulInt64($f4_2, 30);
830 + $f4f9_38 = $f9_38->mulInt64($f4, 30);
831 +
832 + $f5f5_38 = $f5_38->mulInt64($f5, 30);
833 + $f5f6_38 = $f6_19->mulInt64($f5_2, 30);
834 + $f5f7_76 = $f7_38->mulInt64($f5_2, 30);
835 + $f5f8_38 = $f8_19->mulInt64($f5_2, 30);
836 + $f5f9_76 = $f9_38->mulInt64($f5_2, 30);
837 +
838 + $f6f6_19 = $f6_19->mulInt64($f6, 30);
839 + $f6f7_38 = $f7_38->mulInt64($f6, 30);
840 + $f6f8_38 = $f8_19->mulInt64($f6_2, 30);
841 + $f6f9_38 = $f9_38->mulInt64($f6, 30);
842 +
843 + $f7f7_38 = $f7_38->mulInt64($f7, 28);
844 + $f7f8_38 = $f8_19->mulInt64($f7_2, 30);
845 + $f7f9_76 = $f9_38->mulInt64($f7_2, 30);
846 +
847 + $f8f8_19 = $f8_19->mulInt64($f8, 30);
848 + $f8f9_38 = $f9_38->mulInt64($f8, 30);
849 +
850 + $f9f9_38 = $f9_38->mulInt64($f9, 28);
851 +
852 + $h0 = $f0f0->addInt64($f1f9_76)->addInt64($f2f8_38)->addInt64($f3f7_76)->addInt64($f4f6_38)->addInt64($f5f5_38);
853 + $h1 = $f0f1_2->addInt64($f2f9_38)->addInt64($f3f8_38)->addInt64($f4f7_38)->addInt64($f5f6_38);
854 + $h2 = $f0f2_2->addInt64($f1f1_2)->addInt64($f3f9_76)->addInt64($f4f8_38)->addInt64($f5f7_76)->addInt64($f6f6_19);
855 + $h3 = $f0f3_2->addInt64($f1f2_2)->addInt64($f4f9_38)->addInt64($f5f8_38)->addInt64($f6f7_38);
856 + $h4 = $f0f4_2->addInt64($f1f3_4)->addInt64($f2f2)->addInt64($f5f9_76)->addInt64($f6f8_38)->addInt64($f7f7_38);
857 + $h5 = $f0f5_2->addInt64($f1f4_2)->addInt64($f2f3_2)->addInt64($f6f9_38)->addInt64($f7f8_38);
858 + $h6 = $f0f6_2->addInt64($f1f5_4)->addInt64($f2f4_2)->addInt64($f3f3_2)->addInt64($f7f9_76)->addInt64($f8f8_19);
859 + $h7 = $f0f7_2->addInt64($f1f6_2)->addInt64($f2f5_2)->addInt64($f3f4_2)->addInt64($f8f9_38);
860 + $h8 = $f0f8_2->addInt64($f1f7_4)->addInt64($f2f6_2)->addInt64($f3f5_4)->addInt64($f4f4)->addInt64($f9f9_38);
861 + $h9 = $f0f9_2->addInt64($f1f8_2)->addInt64($f2f7_2)->addInt64($f3f6_2)->addInt64($f4f5_2);
862 +
863 + /**
864 + * @var ParagonIE_Sodium_Core32_Int64 $h0
865 + * @var ParagonIE_Sodium_Core32_Int64 $h1
866 + * @var ParagonIE_Sodium_Core32_Int64 $h2
867 + * @var ParagonIE_Sodium_Core32_Int64 $h3
868 + * @var ParagonIE_Sodium_Core32_Int64 $h4
869 + * @var ParagonIE_Sodium_Core32_Int64 $h5
870 + * @var ParagonIE_Sodium_Core32_Int64 $h6
871 + * @var ParagonIE_Sodium_Core32_Int64 $h7
872 + * @var ParagonIE_Sodium_Core32_Int64 $h8
873 + * @var ParagonIE_Sodium_Core32_Int64 $h9
874 + */
875 +
876 + $carry0 = $h0->addInt(1 << 25)->shiftRight(26);
877 + $h1 = $h1->addInt64($carry0);
878 + $h0 = $h0->subInt64($carry0->shiftLeft(26));
879 +
880 + $carry4 = $h4->addInt(1 << 25)->shiftRight(26);
881 + $h5 = $h5->addInt64($carry4);
882 + $h4 = $h4->subInt64($carry4->shiftLeft(26));
883 +
884 + $carry1 = $h1->addInt(1 << 24)->shiftRight(25);
885 + $h2 = $h2->addInt64($carry1);
886 + $h1 = $h1->subInt64($carry1->shiftLeft(25));
887 +
888 + $carry5 = $h5->addInt(1 << 24)->shiftRight(25);
889 + $h6 = $h6->addInt64($carry5);
890 + $h5 = $h5->subInt64($carry5->shiftLeft(25));
891 +
892 + $carry2 = $h2->addInt(1 << 25)->shiftRight(26);
893 + $h3 = $h3->addInt64($carry2);
894 + $h2 = $h2->subInt64($carry2->shiftLeft(26));
895 +
896 + $carry6 = $h6->addInt(1 << 25)->shiftRight(26);
897 + $h7 = $h7->addInt64($carry6);
898 + $h6 = $h6->subInt64($carry6->shiftLeft(26));
899 +
900 + $carry3 = $h3->addInt(1 << 24)->shiftRight(25);
901 + $h4 = $h4->addInt64($carry3);
902 + $h3 = $h3->subInt64($carry3->shiftLeft(25));
903 +
904 + $carry7 = $h7->addInt(1 << 24)->shiftRight(25);
905 + $h8 = $h8->addInt64($carry7);
906 + $h7 = $h7->subInt64($carry7->shiftLeft(25));
907 +
908 + $carry4 = $h4->addInt(1 << 25)->shiftRight(26);
909 + $h5 = $h5->addInt64($carry4);
910 + $h4 = $h4->subInt64($carry4->shiftLeft(26));
911 +
912 + $carry8 = $h8->addInt(1 << 25)->shiftRight(26);
913 + $h9 = $h9->addInt64($carry8);
914 + $h8 = $h8->subInt64($carry8->shiftLeft(26));
915 +
916 + $carry9 = $h9->addInt(1 << 24)->shiftRight(25);
917 + $h0 = $h0->addInt64($carry9->mulInt(19, 5));
918 + $h9 = $h9->subInt64($carry9->shiftLeft(25));
919 +
920 + $carry0 = $h0->addInt(1 << 25)->shiftRight(26);
921 + $h1 = $h1->addInt64($carry0);
922 + $h0 = $h0->subInt64($carry0->shiftLeft(26));
923 +
924 + return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
925 + array(
926 + $h0->toInt32(),
927 + $h1->toInt32(),
928 + $h2->toInt32(),
929 + $h3->toInt32(),
930 + $h4->toInt32(),
931 + $h5->toInt32(),
932 + $h6->toInt32(),
933 + $h7->toInt32(),
934 + $h8->toInt32(),
935 + $h9->toInt32()
936 + )
937 + );
938 + }
939 +
940 + /**
941 + * Square and double a field element
942 + *
943 + * h = 2 * f * f
944 + *
945 + * @internal You should not use this directly from another application
946 + *
947 + * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
948 + * @return ParagonIE_Sodium_Core32_Curve25519_Fe
949 + * @throws SodiumException
950 + * @throws TypeError
951 + * @psalm-suppress MixedMethodCall
952 + */
953 + public static function fe_sq2(ParagonIE_Sodium_Core32_Curve25519_Fe $f)
954 + {
955 + $f0 = $f[0]->toInt64();
956 + $f1 = $f[1]->toInt64();
957 + $f2 = $f[2]->toInt64();
958 + $f3 = $f[3]->toInt64();
959 + $f4 = $f[4]->toInt64();
960 + $f5 = $f[5]->toInt64();
961 + $f6 = $f[6]->toInt64();
962 + $f7 = $f[7]->toInt64();
963 + $f8 = $f[8]->toInt64();
964 + $f9 = $f[9]->toInt64();
965 +
966 + $f0_2 = $f0->shiftLeft(1);
967 + $f1_2 = $f1->shiftLeft(1);
968 + $f2_2 = $f2->shiftLeft(1);
969 + $f3_2 = $f3->shiftLeft(1);
970 + $f4_2 = $f4->shiftLeft(1);
971 + $f5_2 = $f5->shiftLeft(1);
972 + $f6_2 = $f6->shiftLeft(1);
973 + $f7_2 = $f7->shiftLeft(1);
974 + $f5_38 = $f5->mulInt(38, 6); /* 1.959375*2^30 */
975 + $f6_19 = $f6->mulInt(19, 5); /* 1.959375*2^30 */
976 + $f7_38 = $f7->mulInt(38, 6); /* 1.959375*2^30 */
977 + $f8_19 = $f8->mulInt(19, 5); /* 1.959375*2^30 */
978 + $f9_38 = $f9->mulInt(38, 6); /* 1.959375*2^30 */
979 + $f0f0 = $f0->mulInt64($f0, 28);
980 + $f0f1_2 = $f0_2->mulInt64($f1, 28);
981 + $f0f2_2 = $f0_2->mulInt64($f2, 28);
982 + $f0f3_2 = $f0_2->mulInt64($f3, 28);
983 + $f0f4_2 = $f0_2->mulInt64($f4, 28);
984 + $f0f5_2 = $f0_2->mulInt64($f5, 28);
985 + $f0f6_2 = $f0_2->mulInt64($f6, 28);
986 + $f0f7_2 = $f0_2->mulInt64($f7, 28);
987 + $f0f8_2 = $f0_2->mulInt64($f8, 28);
988 + $f0f9_2 = $f0_2->mulInt64($f9, 28);
989 + $f1f1_2 = $f1_2->mulInt64($f1, 28);
990 + $f1f2_2 = $f1_2->mulInt64($f2, 28);
991 + $f1f3_4 = $f1_2->mulInt64($f3_2, 29);
992 + $f1f4_2 = $f1_2->mulInt64($f4, 28);
993 + $f1f5_4 = $f1_2->mulInt64($f5_2, 29);
994 + $f1f6_2 = $f1_2->mulInt64($f6, 28);
995 + $f1f7_4 = $f1_2->mulInt64($f7_2, 29);
996 + $f1f8_2 = $f1_2->mulInt64($f8, 28);
997 + $f1f9_76 = $f9_38->mulInt64($f1_2, 29);
998 + $f2f2 = $f2->mulInt64($f2, 28);
999 + $f2f3_2 = $f2_2->mulInt64($f3, 28);
1000 + $f2f4_2 = $f2_2->mulInt64($f4, 28);
1001 + $f2f5_2 = $f2_2->mulInt64($f5, 28);
1002 + $f2f6_2 = $f2_2->mulInt64($f6, 28);
1003 + $f2f7_2 = $f2_2->mulInt64($f7, 28);
1004 + $f2f8_38 = $f8_19->mulInt64($f2_2, 29);
1005 + $f2f9_38 = $f9_38->mulInt64($f2, 29);
1006 + $f3f3_2 = $f3_2->mulInt64($f3, 28);
1007 + $f3f4_2 = $f3_2->mulInt64($f4, 28);
1008 + $f3f5_4 = $f3_2->mulInt64($f5_2, 28);
1009 + $f3f6_2 = $f3_2->mulInt64($f6, 28);
1010 + $f3f7_76 = $f7_38->mulInt64($f3_2, 29);
1011 + $f3f8_38 = $f8_19->mulInt64($f3_2, 29);
1012 + $f3f9_76 = $f9_38->mulInt64($f3_2, 29);
1013 + $f4f4 = $f4->mulInt64($f4, 28);
1014 + $f4f5_2 = $f4_2->mulInt64($f5, 28);
1015 + $f4f6_38 = $f6_19->mulInt64($f4_2, 29);
1016 + $f4f7_38 = $f7_38->mulInt64($f4, 29);
1017 + $f4f8_38 = $f8_19->mulInt64($f4_2, 29);
1018 + $f4f9_38 = $f9_38->mulInt64($f4, 29);
1019 + $f5f5_38 = $f5_38->mulInt64($f5, 29);
1020 + $f5f6_38 = $f6_19->mulInt64($f5_2, 29);
1021 + $f5f7_76 = $f7_38->mulInt64($f5_2, 29);
1022 + $f5f8_38 = $f8_19->mulInt64($f5_2, 29);
1023 + $f5f9_76 = $f9_38->mulInt64($f5_2, 29);
1024 + $f6f6_19 = $f6_19->mulInt64($f6, 29);
1025 + $f6f7_38 = $f7_38->mulInt64($f6, 29);
1026 + $f6f8_38 = $f8_19->mulInt64($f6_2, 29);
1027 + $f6f9_38 = $f9_38->mulInt64($f6, 29);
1028 + $f7f7_38 = $f7_38->mulInt64($f7, 29);
1029 + $f7f8_38 = $f8_19->mulInt64($f7_2, 29);
1030 + $f7f9_76 = $f9_38->mulInt64($f7_2, 29);
1031 + $f8f8_19 = $f8_19->mulInt64($f8, 29);
1032 + $f8f9_38 = $f9_38->mulInt64($f8, 29);
1033 + $f9f9_38 = $f9_38->mulInt64($f9, 29);
1034 +
1035 + $h0 = $f0f0->addInt64($f1f9_76)->addInt64($f2f8_38)->addInt64($f3f7_76)->addInt64($f4f6_38)->addInt64($f5f5_38);
1036 + $h1 = $f0f1_2->addInt64($f2f9_38)->addInt64($f3f8_38)->addInt64($f4f7_38)->addInt64($f5f6_38);
1037 + $h2 = $f0f2_2->addInt64($f1f1_2)->addInt64($f3f9_76)->addInt64($f4f8_38)->addInt64($f5f7_76)->addInt64($f6f6_19);
1038 + $h3 = $f0f3_2->addInt64($f1f2_2)->addInt64($f4f9_38)->addInt64($f5f8_38)->addInt64($f6f7_38);
1039 + $h4 = $f0f4_2->addInt64($f1f3_4)->addInt64($f2f2)->addInt64($f5f9_76)->addInt64($f6f8_38)->addInt64($f7f7_38);
1040 + $h5 = $f0f5_2->addInt64($f1f4_2)->addInt64($f2f3_2)->addInt64($f6f9_38)->addInt64($f7f8_38);
1041 + $h6 = $f0f6_2->addInt64($f1f5_4)->addInt64($f2f4_2)->addInt64($f3f3_2)->addInt64($f7f9_76)->addInt64($f8f8_19);
1042 + $h7 = $f0f7_2->addInt64($f1f6_2)->addInt64($f2f5_2)->addInt64($f3f4_2)->addInt64($f8f9_38);
1043 + $h8 = $f0f8_2->addInt64($f1f7_4)->addInt64($f2f6_2)->addInt64($f3f5_4)->addInt64($f4f4)->addInt64($f9f9_38);
1044 + $h9 = $f0f9_2->addInt64($f1f8_2)->addInt64($f2f7_2)->addInt64($f3f6_2)->addInt64($f4f5_2);
1045 +
1046 + /**
1047 + * @var ParagonIE_Sodium_Core32_Int64 $h0
1048 + * @var ParagonIE_Sodium_Core32_Int64 $h1
1049 + * @var ParagonIE_Sodium_Core32_Int64 $h2
1050 + * @var ParagonIE_Sodium_Core32_Int64 $h3
1051 + * @var ParagonIE_Sodium_Core32_Int64 $h4
1052 + * @var ParagonIE_Sodium_Core32_Int64 $h5
1053 + * @var ParagonIE_Sodium_Core32_Int64 $h6
1054 + * @var ParagonIE_Sodium_Core32_Int64 $h7
1055 + * @var ParagonIE_Sodium_Core32_Int64 $h8
1056 + * @var ParagonIE_Sodium_Core32_Int64 $h9
1057 + */
1058 + $h0 = $h0->shiftLeft(1);
1059 + $h1 = $h1->shiftLeft(1);
1060 + $h2 = $h2->shiftLeft(1);
1061 + $h3 = $h3->shiftLeft(1);
1062 + $h4 = $h4->shiftLeft(1);
1063 + $h5 = $h5->shiftLeft(1);
1064 + $h6 = $h6->shiftLeft(1);
1065 + $h7 = $h7->shiftLeft(1);
1066 + $h8 = $h8->shiftLeft(1);
1067 + $h9 = $h9->shiftLeft(1);
1068 +
1069 + $carry0 = $h0->addInt(1 << 25)->shiftRight(26);
1070 + $h1 = $h1->addInt64($carry0);
1071 + $h0 = $h0->subInt64($carry0->shiftLeft(26));
1072 + $carry4 = $h4->addInt(1 << 25)->shiftRight(26);
1073 + $h5 = $h5->addInt64($carry4);
1074 + $h4 = $h4->subInt64($carry4->shiftLeft(26));
1075 +
1076 + $carry1 = $h1->addInt(1 << 24)->shiftRight(25);
1077 + $h2 = $h2->addInt64($carry1);
1078 + $h1 = $h1->subInt64($carry1->shiftLeft(25));
1079 + $carry5 = $h5->addInt(1 << 24)->shiftRight(25);
1080 + $h6 = $h6->addInt64($carry5);
1081 + $h5 = $h5->subInt64($carry5->shiftLeft(25));
1082 +
1083 + $carry2 = $h2->addInt(1 << 25)->shiftRight(26);
1084 + $h3 = $h3->addInt64($carry2);
1085 + $h2 = $h2->subInt64($carry2->shiftLeft(26));
1086 + $carry6 = $h6->addInt(1 << 25)->shiftRight(26);
1087 + $h7 = $h7->addInt64($carry6);
1088 + $h6 = $h6->subInt64($carry6->shiftLeft(26));
1089 +
1090 + $carry3 = $h3->addInt(1 << 24)->shiftRight(25);
1091 + $h4 = $h4->addInt64($carry3);
1092 + $h3 = $h3->subInt64($carry3->shiftLeft(25));
1093 + $carry7 = $h7->addInt(1 << 24)->shiftRight(25);
1094 + $h8 = $h8->addInt64($carry7);
1095 + $h7 = $h7->subInt64($carry7->shiftLeft(25));
1096 +
1097 + $carry4 = $h4->addInt(1 << 25)->shiftRight(26);
1098 + $h5 = $h5->addInt64($carry4);
1099 + $h4 = $h4->subInt64($carry4->shiftLeft(26));
1100 + $carry8 = $h8->addInt(1 << 25)->shiftRight(26);
1101 + $h9 = $h9->addInt64($carry8);
1102 + $h8 = $h8->subInt64($carry8->shiftLeft(26));
1103 +
1104 + $carry9 = $h9->addInt(1 << 24)->shiftRight(25);
1105 + $h0 = $h0->addInt64($carry9->mulInt(19, 5));
1106 + $h9 = $h9->subInt64($carry9->shiftLeft(25));
1107 +
1108 + $carry0 = $h0->addInt(1 << 25)->shiftRight(26);
1109 + $h1 = $h1->addInt64($carry0);
1110 + $h0 = $h0->subInt64($carry0->shiftLeft(26));
1111 +
1112 + return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
1113 + array(
1114 + $h0->toInt32(),
1115 + $h1->toInt32(),
1116 + $h2->toInt32(),
1117 + $h3->toInt32(),
1118 + $h4->toInt32(),
1119 + $h5->toInt32(),
1120 + $h6->toInt32(),
1121 + $h7->toInt32(),
1122 + $h8->toInt32(),
1123 + $h9->toInt32()
1124 + )
1125 + );
1126 + }
1127 +
1128 + /**
1129 + * @internal You should not use this directly from another application
1130 + *
1131 + * @param ParagonIE_Sodium_Core32_Curve25519_Fe $Z
1132 + * @return ParagonIE_Sodium_Core32_Curve25519_Fe
1133 + * @throws SodiumException
1134 + * @throws TypeError
1135 + */
1136 + public static function fe_invert(ParagonIE_Sodium_Core32_Curve25519_Fe $Z)
1137 + {
1138 + $z = clone $Z;
1139 + $t0 = self::fe_sq($z);
1140 + $t1 = self::fe_sq($t0);
1141 + $t1 = self::fe_sq($t1);
1142 + $t1 = self::fe_mul($z, $t1);
1143 + $t0 = self::fe_mul($t0, $t1);
1144 + $t2 = self::fe_sq($t0);
1145 + $t1 = self::fe_mul($t1, $t2);
1146 + $t2 = self::fe_sq($t1);
1147 + for ($i = 1; $i < 5; ++$i) {
1148 + $t2 = self::fe_sq($t2);
1149 + }
1150 + $t1 = self::fe_mul($t2, $t1);
1151 + $t2 = self::fe_sq($t1);
1152 + for ($i = 1; $i < 10; ++$i) {
1153 + $t2 = self::fe_sq($t2);
1154 + }
1155 + $t2 = self::fe_mul($t2, $t1);
1156 + $t3 = self::fe_sq($t2);
1157 + for ($i = 1; $i < 20; ++$i) {
1158 + $t3 = self::fe_sq($t3);
1159 + }
1160 + $t2 = self::fe_mul($t3, $t2);
1161 + $t2 = self::fe_sq($t2);
1162 + for ($i = 1; $i < 10; ++$i) {
1163 + $t2 = self::fe_sq($t2);
1164 + }
1165 + $t1 = self::fe_mul($t2, $t1);
1166 + $t2 = self::fe_sq($t1);
1167 + for ($i = 1; $i < 50; ++$i) {
1168 + $t2 = self::fe_sq($t2);
1169 + }
1170 + $t2 = self::fe_mul($t2, $t1);
1171 + $t3 = self::fe_sq($t2);
1172 + for ($i = 1; $i < 100; ++$i) {
1173 + $t3 = self::fe_sq($t3);
1174 + }
1175 + $t2 = self::fe_mul($t3, $t2);
1176 + $t2 = self::fe_sq($t2);
1177 + for ($i = 1; $i < 50; ++$i) {
1178 + $t2 = self::fe_sq($t2);
1179 + }
1180 + $t1 = self::fe_mul($t2, $t1);
1181 + $t1 = self::fe_sq($t1);
1182 + for ($i = 1; $i < 5; ++$i) {
1183 + $t1 = self::fe_sq($t1);
1184 + }
1185 + return self::fe_mul($t1, $t0);
1186 + }
1187 +
1188 + /**
1189 + * @internal You should not use this directly from another application
1190 + *
1191 + * @ref https://github.com/jedisct1/libsodium/blob/68564326e1e9dc57ef03746f85734232d20ca6fb/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c#L1054-L1106
1192 + *
1193 + * @param ParagonIE_Sodium_Core32_Curve25519_Fe $z
1194 + * @return ParagonIE_Sodium_Core32_Curve25519_Fe
1195 + * @throws SodiumException
1196 + * @throws TypeError
1197 + */
1198 + public static function fe_pow22523(ParagonIE_Sodium_Core32_Curve25519_Fe $z)
1199 + {
1200 + # fe_sq(t0, z);
1201 + # fe_sq(t1, t0);
1202 + # fe_sq(t1, t1);
1203 + # fe_mul(t1, z, t1);
1204 + # fe_mul(t0, t0, t1);
1205 + # fe_sq(t0, t0);
1206 + # fe_mul(t0, t1, t0);
1207 + # fe_sq(t1, t0);
1208 + $t0 = self::fe_sq($z);
1209 + $t1 = self::fe_sq($t0);
1210 + $t1 = self::fe_sq($t1);
1211 + $t1 = self::fe_mul($z, $t1);
1212 + $t0 = self::fe_mul($t0, $t1);
1213 + $t0 = self::fe_sq($t0);
1214 + $t0 = self::fe_mul($t1, $t0);
1215 + $t1 = self::fe_sq($t0);
1216 +
1217 + # for (i = 1; i < 5; ++i) {
1218 + # fe_sq(t1, t1);
1219 + # }
1220 + for ($i = 1; $i < 5; ++$i) {
1221 + $t1 = self::fe_sq($t1);
1222 + }
1223 +
1224 + # fe_mul(t0, t1, t0);
1225 + # fe_sq(t1, t0);
1226 + $t0 = self::fe_mul($t1, $t0);
1227 + $t1 = self::fe_sq($t0);
1228 +
1229 + # for (i = 1; i < 10; ++i) {
1230 + # fe_sq(t1, t1);
1231 + # }
1232 + for ($i = 1; $i < 10; ++$i) {
1233 + $t1 = self::fe_sq($t1);
1234 + }
1235 +
1236 + # fe_mul(t1, t1, t0);
1237 + # fe_sq(t2, t1);
1238 + $t1 = self::fe_mul($t1, $t0);
1239 + $t2 = self::fe_sq($t1);
1240 +
1241 + # for (i = 1; i < 20; ++i) {
1242 + # fe_sq(t2, t2);
1243 + # }
1244 + for ($i = 1; $i < 20; ++$i) {
1245 + $t2 = self::fe_sq($t2);
1246 + }
1247 +
1248 + # fe_mul(t1, t2, t1);
1249 + # fe_sq(t1, t1);
1250 + $t1 = self::fe_mul($t2, $t1);
1251 + $t1 = self::fe_sq($t1);
1252 +
1253 + # for (i = 1; i < 10; ++i) {
1254 + # fe_sq(t1, t1);
1255 + # }
1256 + for ($i = 1; $i < 10; ++$i) {
1257 + $t1 = self::fe_sq($t1);
1258 + }
1259 +
1260 + # fe_mul(t0, t1, t0);
1261 + # fe_sq(t1, t0);
1262 + $t0 = self::fe_mul($t1, $t0);
1263 + $t1 = self::fe_sq($t0);
1264 +
1265 + # for (i = 1; i < 50; ++i) {
1266 + # fe_sq(t1, t1);
1267 + # }
1268 + for ($i = 1; $i < 50; ++$i) {
1269 + $t1 = self::fe_sq($t1);
1270 + }
1271 +
1272 + # fe_mul(t1, t1, t0);
1273 + # fe_sq(t2, t1);
1274 + $t1 = self::fe_mul($t1, $t0);
1275 + $t2 = self::fe_sq($t1);
1276 +
1277 + # for (i = 1; i < 100; ++i) {
1278 + # fe_sq(t2, t2);
1279 + # }
1280 + for ($i = 1; $i < 100; ++$i) {
1281 + $t2 = self::fe_sq($t2);
1282 + }
1283 +
1284 + # fe_mul(t1, t2, t1);
1285 + # fe_sq(t1, t1);
1286 + $t1 = self::fe_mul($t2, $t1);
1287 + $t1 = self::fe_sq($t1);
1288 +
1289 + # for (i = 1; i < 50; ++i) {
1290 + # fe_sq(t1, t1);
1291 + # }
1292 + for ($i = 1; $i < 50; ++$i) {
1293 + $t1 = self::fe_sq($t1);
1294 + }
1295 +
1296 + # fe_mul(t0, t1, t0);
1297 + # fe_sq(t0, t0);
1298 + # fe_sq(t0, t0);
1299 + # fe_mul(out, t0, z);
1300 + $t0 = self::fe_mul($t1, $t0);
1301 + $t0 = self::fe_sq($t0);
1302 + $t0 = self::fe_sq($t0);
1303 + return self::fe_mul($t0, $z);
1304 + }
1305 +
1306 + /**
1307 + * Subtract two field elements.
1308 + *
1309 + * h = f - g
1310 + *
1311 + * Preconditions:
1312 + * |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
1313 + * |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
1314 + *
1315 + * Postconditions:
1316 + * |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
1317 + *
1318 + * @internal You should not use this directly from another application
1319 + *
1320 + * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
1321 + * @param ParagonIE_Sodium_Core32_Curve25519_Fe $g
1322 + * @return ParagonIE_Sodium_Core32_Curve25519_Fe
1323 + * @throws SodiumException
1324 + * @throws TypeError
1325 + * @psalm-suppress MixedMethodCall
1326 + * @psalm-suppress MixedTypeCoercion
1327 + */
1328 + public static function fe_sub(ParagonIE_Sodium_Core32_Curve25519_Fe $f, ParagonIE_Sodium_Core32_Curve25519_Fe $g)
1329 + {
1330 + return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
1331 + array(
1332 + $f[0]->subInt32($g[0]),
1333 + $f[1]->subInt32($g[1]),
1334 + $f[2]->subInt32($g[2]),
1335 + $f[3]->subInt32($g[3]),
1336 + $f[4]->subInt32($g[4]),
1337 + $f[5]->subInt32($g[5]),
1338 + $f[6]->subInt32($g[6]),
1339 + $f[7]->subInt32($g[7]),
1340 + $f[8]->subInt32($g[8]),
1341 + $f[9]->subInt32($g[9])
1342 + )
1343 + );
1344 + }
1345 +
1346 + /**
1347 + * Add two group elements.
1348 + *
1349 + * r = p + q
1350 + *
1351 + * @internal You should not use this directly from another application
1352 + *
1353 + * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p
1354 + * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Cached $q
1355 + * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1
1356 + * @throws SodiumException
1357 + * @throws TypeError
1358 + */
1359 + public static function ge_add(
1360 + ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p,
1361 + ParagonIE_Sodium_Core32_Curve25519_Ge_Cached $q
1362 + ) {
1363 + $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1();
1364 + $r->X = self::fe_add($p->Y, $p->X);
1365 + $r->Y = self::fe_sub($p->Y, $p->X);
1366 + $r->Z = self::fe_mul($r->X, $q->YplusX);
1367 + $r->Y = self::fe_mul($r->Y, $q->YminusX);
1368 + $r->T = self::fe_mul($q->T2d, $p->T);
1369 + $r->X = self::fe_mul($p->Z, $q->Z);
1370 + $t0 = self::fe_add($r->X, $r->X);
1371 + $r->X = self::fe_sub($r->Z, $r->Y);
1372 + $r->Y = self::fe_add($r->Z, $r->Y);
1373 + $r->Z = self::fe_add($t0, $r->T);
1374 + $r->T = self::fe_sub($t0, $r->T);
1375 + return $r;
1376 + }
1377 +
1378 + /**
1379 + * @internal You should not use this directly from another application
1380 + *
1381 + * @ref https://github.com/jedisct1/libsodium/blob/157c4a80c13b117608aeae12178b2d38825f9f8f/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c#L1185-L1215
1382 + * @param string $a
1383 + * @return array<int, mixed>
1384 + * @throws SodiumException
1385 + * @throws TypeError
1386 + * @psalm-suppress MixedArrayOffset
1387 + */
1388 + public static function slide($a)
1389 + {
1390 + if (self::strlen($a) < 256) {
1391 + if (self::strlen($a) < 16) {
1392 + $a = str_pad($a, 256, '0', STR_PAD_RIGHT);
1393 + }
1394 + }
1395 + /** @var array<int, int> $r */
1396 + $r = array();
1397 + for ($i = 0; $i < 256; ++$i) {
1398 + $r[$i] = (int) (1 &
1399 + (
1400 + self::chrToInt($a[$i >> 3])
1401 + >>
1402 + ($i & 7)
1403 + )
1404 + );
1405 + }
1406 +
1407 + for ($i = 0;$i < 256;++$i) {
1408 + if ($r[$i]) {
1409 + for ($b = 1;$b <= 6 && $i + $b < 256;++$b) {
1410 + if ($r[$i + $b]) {
1411 + if ($r[$i] + ($r[$i + $b] << $b) <= 15) {
1412 + $r[$i] += $r[$i + $b] << $b;
1413 + $r[$i + $b] = 0;
1414 + } elseif ($r[$i] - ($r[$i + $b] << $b) >= -15) {
1415 + $r[$i] -= $r[$i + $b] << $b;
1416 + for ($k = $i + $b; $k < 256; ++$k) {
1417 + if (!$r[$k]) {
1418 + $r[$k] = 1;
1419 + break;
1420 + }
1421 + $r[$k] = 0;
1422 + }
1423 + } else {
1424 + break;
1425 + }
1426 + }
1427 + }
1428 + }
1429 + }
1430 + return $r;
1431 + }
1432 +
1433 + /**
1434 + * @internal You should not use this directly from another application
1435 + *
1436 + * @param string $s
1437 + * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P3
1438 + * @throws SodiumException
1439 + * @throws TypeError
1440 + */
1441 + public static function ge_frombytes_negate_vartime($s)
1442 + {
1443 + static $d = null;
1444 + if (!$d) {
1445 + $d = ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
1446 + array(
1447 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[0]),
1448 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[1]),
1449 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[2]),
1450 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[3]),
1451 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[4]),
1452 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[5]),
1453 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[6]),
1454 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[7]),
1455 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[8]),
1456 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[9])
1457 + )
1458 + );
1459 + }
1460 + /** @var ParagonIE_Sodium_Core32_Curve25519_Fe $d */
1461 +
1462 + # fe_frombytes(h->Y,s);
1463 + # fe_1(h->Z);
1464 + $h = new ParagonIE_Sodium_Core32_Curve25519_Ge_P3(
1465 + self::fe_0(),
1466 + self::fe_frombytes($s),
1467 + self::fe_1()
1468 + );
1469 +
1470 + # fe_sq(u,h->Y);
1471 + # fe_mul(v,u,d);
1472 + # fe_sub(u,u,h->Z); /* u = y^2-1 */
1473 + # fe_add(v,v,h->Z); /* v = dy^2+1 */
1474 + $u = self::fe_sq($h->Y);
1475 + /** @var ParagonIE_Sodium_Core32_Curve25519_Fe $d */
1476 + $v = self::fe_mul($u, $d);
1477 + $u = self::fe_sub($u, $h->Z); /* u = y^2 - 1 */
1478 + $v = self::fe_add($v, $h->Z); /* v = dy^2 + 1 */
1479 +
1480 + # fe_sq(v3,v);
1481 + # fe_mul(v3,v3,v); /* v3 = v^3 */
1482 + # fe_sq(h->X,v3);
1483 + # fe_mul(h->X,h->X,v);
1484 + # fe_mul(h->X,h->X,u); /* x = uv^7 */
1485 + $v3 = self::fe_sq($v);
1486 + $v3 = self::fe_mul($v3, $v); /* v3 = v^3 */
1487 + $h->X = self::fe_sq($v3);
1488 + $h->X = self::fe_mul($h->X, $v);
1489 + $h->X = self::fe_mul($h->X, $u); /* x = uv^7 */
1490 +
1491 + # fe_pow22523(h->X,h->X); /* x = (uv^7)^((q-5)/8) */
1492 + # fe_mul(h->X,h->X,v3);
1493 + # fe_mul(h->X,h->X,u); /* x = uv^3(uv^7)^((q-5)/8) */
1494 + $h->X = self::fe_pow22523($h->X); /* x = (uv^7)^((q-5)/8) */
1495 + $h->X = self::fe_mul($h->X, $v3);
1496 + $h->X = self::fe_mul($h->X, $u); /* x = uv^3(uv^7)^((q-5)/8) */
1497 +
1498 + # fe_sq(vxx,h->X);
1499 + # fe_mul(vxx,vxx,v);
1500 + # fe_sub(check,vxx,u); /* vx^2-u */
1501 + $vxx = self::fe_sq($h->X);
1502 + $vxx = self::fe_mul($vxx, $v);
1503 + $check = self::fe_sub($vxx, $u); /* vx^2 - u */
1504 +
1505 + # if (fe_isnonzero(check)) {
1506 + # fe_add(check,vxx,u); /* vx^2+u */
1507 + # if (fe_isnonzero(check)) {
1508 + # return -1;
1509 + # }
1510 + # fe_mul(h->X,h->X,sqrtm1);
1511 + # }
1512 + if (self::fe_isnonzero($check)) {
1513 + $check = self::fe_add($vxx, $u); /* vx^2 + u */
1514 + if (self::fe_isnonzero($check)) {
1515 + throw new RangeException('Internal check failed.');
1516 + }
1517 + $h->X = self::fe_mul(
1518 + $h->X,
1519 + ParagonIE_Sodium_Core32_Curve25519_Fe::fromIntArray(self::$sqrtm1)
1520 + );
1521 + }
1522 +
1523 + # if (fe_isnegative(h->X) == (s[31] >> 7)) {
1524 + # fe_neg(h->X,h->X);
1525 + # }
1526 + $i = self::chrToInt($s[31]);
1527 + if (self::fe_isnegative($h->X) === ($i >> 7)) {
1528 + $h->X = self::fe_neg($h->X);
1529 + }
1530 +
1531 + # fe_mul(h->T,h->X,h->Y);
1532 + $h->T = self::fe_mul($h->X, $h->Y);
1533 + return $h;
1534 + }
1535 +
1536 + /**
1537 + * @internal You should not use this directly from another application
1538 + *
1539 + * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $R
1540 + * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p
1541 + * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $q
1542 + * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1
1543 + * @throws SodiumException
1544 + * @throws TypeError
1545 + */
1546 + public static function ge_madd(
1547 + ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $R,
1548 + ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p,
1549 + ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $q
1550 + ) {
1551 + $r = clone $R;
1552 + $r->X = self::fe_add($p->Y, $p->X);
1553 + $r->Y = self::fe_sub($p->Y, $p->X);
1554 + $r->Z = self::fe_mul($r->X, $q->yplusx);
1555 + $r->Y = self::fe_mul($r->Y, $q->yminusx);
1556 + $r->T = self::fe_mul($q->xy2d, $p->T);
1557 + $t0 = self::fe_add(clone $p->Z, clone $p->Z);
1558 + $r->X = self::fe_sub($r->Z, $r->Y);
1559 + $r->Y = self::fe_add($r->Z, $r->Y);
1560 + $r->Z = self::fe_add($t0, $r->T);
1561 + $r->T = self::fe_sub($t0, $r->T);
1562 +
1563 + return $r;
1564 + }
1565 +
1566 + /**
1567 + * @internal You should not use this directly from another application
1568 + *
1569 + * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $R
1570 + * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p
1571 + * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $q
1572 + * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1
1573 + * @throws SodiumException
1574 + * @throws TypeError
1575 + */
1576 + public static function ge_msub(
1577 + ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $R,
1578 + ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p,
1579 + ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $q
1580 + ) {
1581 + $r = clone $R;
1582 +
1583 + $r->X = self::fe_add($p->Y, $p->X);
1584 + $r->Y = self::fe_sub($p->Y, $p->X);
1585 + $r->Z = self::fe_mul($r->X, $q->yminusx);
1586 + $r->Y = self::fe_mul($r->Y, $q->yplusx);
1587 + $r->T = self::fe_mul($q->xy2d, $p->T);
1588 + $t0 = self::fe_add($p->Z, $p->Z);
1589 + $r->X = self::fe_sub($r->Z, $r->Y);
1590 + $r->Y = self::fe_add($r->Z, $r->Y);
1591 + $r->Z = self::fe_sub($t0, $r->T);
1592 + $r->T = self::fe_add($t0, $r->T);
1593 +
1594 + return $r;
1595 + }
1596 +
1597 + /**
1598 + * @internal You should not use this directly from another application
1599 + *
1600 + * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $p
1601 + * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P2
1602 + * @throws SodiumException
1603 + * @throws TypeError
1604 + */
1605 + public static function ge_p1p1_to_p2(ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $p)
1606 + {
1607 + $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P2();
1608 + $r->X = self::fe_mul($p->X, $p->T);
1609 + $r->Y = self::fe_mul($p->Y, $p->Z);
1610 + $r->Z = self::fe_mul($p->Z, $p->T);
1611 + return $r;
1612 + }
1613 +
1614 + /**
1615 + * @internal You should not use this directly from another application
1616 + *
1617 + * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $p
1618 + * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P3
1619 + * @throws SodiumException
1620 + * @throws TypeError
1621 + */
1622 + public static function ge_p1p1_to_p3(ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $p)
1623 + {
1624 + $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P3();
1625 + $r->X = self::fe_mul($p->X, $p->T);
1626 + $r->Y = self::fe_mul($p->Y, $p->Z);
1627 + $r->Z = self::fe_mul($p->Z, $p->T);
1628 + $r->T = self::fe_mul($p->X, $p->Y);
1629 + return $r;
1630 + }
1631 +
1632 + /**
1633 + * @internal You should not use this directly from another application
1634 + *
1635 + * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P2
1636 + * @throws SodiumException
1637 + * @throws TypeError
1638 + */
1639 + public static function ge_p2_0()
1640 + {
1641 + return new ParagonIE_Sodium_Core32_Curve25519_Ge_P2(
1642 + self::fe_0(),
1643 + self::fe_1(),
1644 + self::fe_1()
1645 + );
1646 + }
1647 +
1648 + /**
1649 + * @internal You should not use this directly from another application
1650 + *
1651 + * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $p
1652 + * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1
1653 + * @throws SodiumException
1654 + * @throws TypeError
1655 + */
1656 + public static function ge_p2_dbl(ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $p)
1657 + {
1658 + $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1();
1659 +
1660 + $r->X = self::fe_sq($p->X);
1661 + $r->Z = self::fe_sq($p->Y);
1662 + $r->T = self::fe_sq2($p->Z);
1663 + $r->Y = self::fe_add($p->X, $p->Y);
1664 + $t0 = self::fe_sq($r->Y);
1665 + $r->Y = self::fe_add($r->Z, $r->X);
1666 + $r->Z = self::fe_sub($r->Z, $r->X);
1667 + $r->X = self::fe_sub($t0, $r->Y);
1668 + $r->T = self::fe_sub($r->T, $r->Z);
1669 +
1670 + return $r;
1671 + }
1672 +
1673 + /**
1674 + * @internal You should not use this directly from another application
1675 + *
1676 + * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P3
1677 + * @throws SodiumException
1678 + * @throws TypeError
1679 + */
1680 + public static function ge_p3_0()
1681 + {
1682 + return new ParagonIE_Sodium_Core32_Curve25519_Ge_P3(
1683 + self::fe_0(),
1684 + self::fe_1(),
1685 + self::fe_1(),
1686 + self::fe_0()
1687 + );
1688 + }
1689 +
1690 + /**
1691 + * @internal You should not use this directly from another application
1692 + *
1693 + * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p
1694 + * @return ParagonIE_Sodium_Core32_Curve25519_Ge_Cached
1695 + * @throws SodiumException
1696 + * @throws TypeError
1697 + */
1698 + public static function ge_p3_to_cached(ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p)
1699 + {
1700 + static $d2 = null;
1701 + if ($d2 === null) {
1702 + $d2 = ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
1703 + array(
1704 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[0]),
1705 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[1]),
1706 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[2]),
1707 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[3]),
1708 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[4]),
1709 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[5]),
1710 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[6]),
1711 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[7]),
1712 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[8]),
1713 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[9])
1714 + )
1715 + );
1716 + }
1717 + /** @var ParagonIE_Sodium_Core32_Curve25519_Fe $d2 */
1718 + $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_Cached();
1719 + $r->YplusX = self::fe_add($p->Y, $p->X);
1720 + $r->YminusX = self::fe_sub($p->Y, $p->X);
1721 + $r->Z = self::fe_copy($p->Z);
1722 + $r->T2d = self::fe_mul($p->T, $d2);
1723 + return $r;
1724 + }
1725 +
1726 + /**
1727 + * @internal You should not use this directly from another application
1728 + *
1729 + * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p
1730 + * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P2
1731 + */
1732 + public static function ge_p3_to_p2(ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p)
1733 + {
1734 + return new ParagonIE_Sodium_Core32_Curve25519_Ge_P2(
1735 + $p->X,
1736 + $p->Y,
1737 + $p->Z
1738 + );
1739 + }
1740 +
1741 + /**
1742 + * @internal You should not use this directly from another application
1743 + *
1744 + * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $h
1745 + * @return string
1746 + * @throws SodiumException
1747 + * @throws TypeError
1748 + */
1749 + public static function ge_p3_tobytes(ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $h)
1750 + {
1751 + $recip = self::fe_invert($h->Z);
1752 + $x = self::fe_mul($h->X, $recip);
1753 + $y = self::fe_mul($h->Y, $recip);
1754 + $s = self::fe_tobytes($y);
1755 + $s[31] = self::intToChr(
1756 + self::chrToInt($s[31]) ^ (self::fe_isnegative($x) << 7)
1757 + );
1758 + return $s;
1759 + }
1760 +
1761 + /**
1762 + * @internal You should not use this directly from another application
1763 + *
1764 + * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p
1765 + * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1
1766 + * @throws SodiumException
1767 + * @throws TypeError
1768 + */
1769 + public static function ge_p3_dbl(ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p)
1770 + {
1771 + $q = self::ge_p3_to_p2($p);
1772 + return self::ge_p2_dbl($q);
1773 + }
1774 +
1775 + /**
1776 + * @return ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp
1777 + * @throws SodiumException
1778 + * @throws TypeError
1779 + */
1780 + public static function ge_precomp_0()
1781 + {
1782 + return new ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp(
1783 + self::fe_1(),
1784 + self::fe_1(),
1785 + self::fe_0()
1786 + );
1787 + }
1788 +
1789 + /**
1790 + * @internal You should not use this directly from another application
1791 + *
1792 + * @param int $b
1793 + * @param int $c
1794 + * @return int
1795 + * @psalm-suppress MixedReturnStatement
1796 + */
1797 + public static function equal($b, $c)
1798 + {
1799 + $b0 = $b & 0xffff;
1800 + $b1 = ($b >> 16) & 0xffff;
1801 + $c0 = $c & 0xffff;
1802 + $c1 = ($c >> 16) & 0xffff;
1803 +
1804 + $d0 = (($b0 ^ $c0) - 1) >> 31;
1805 + $d1 = (($b1 ^ $c1) - 1) >> 31;
1806 + return ($d0 & $d1) & 1;
1807 + }
1808 +
1809 + /**
1810 + * @internal You should not use this directly from another application
1811 + *
1812 + * @param string|int $char
1813 + * @return int (1 = yes, 0 = no)
1814 + * @throws SodiumException
1815 + * @throws TypeError
1816 + */
1817 + public static function negative($char)
1818 + {
1819 + if (is_int($char)) {
1820 + return $char < 0 ? 1 : 0;
1821 + }
1822 + /** @var string $char */
1823 + $x = self::chrToInt(self::substr($char, 0, 1));
1824 + return (int) ($x >> 31);
1825 + }
1826 +
1827 + /**
1828 + * Conditional move
1829 + *
1830 + * @internal You should not use this directly from another application
1831 + *
1832 + * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $t
1833 + * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $u
1834 + * @param int $b
1835 + * @return ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp
1836 + * @throws SodiumException
1837 + * @throws TypeError
1838 + */
1839 + public static function cmov(
1840 + ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $t,
1841 + ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $u,
1842 + $b
1843 + ) {
1844 + if (!is_int($b)) {
1845 + throw new InvalidArgumentException('Expected an integer.');
1846 + }
1847 + return new ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp(
1848 + self::fe_cmov($t->yplusx, $u->yplusx, $b),
1849 + self::fe_cmov($t->yminusx, $u->yminusx, $b),
1850 + self::fe_cmov($t->xy2d, $u->xy2d, $b)
1851 + );
1852 + }
1853 +
1854 + /**
1855 + * @internal You should not use this directly from another application
1856 + *
1857 + * @param int $pos
1858 + * @param int $b
1859 + * @return ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp
1860 + * @throws SodiumException
1861 + * @throws TypeError
1862 + * @psalm-suppress MixedArrayAccess
1863 + * @psalm-suppress MixedArrayOffset
1864 + * @psalm-suppress MixedArgument
1865 + */
1866 + public static function ge_select($pos = 0, $b = 0)
1867 + {
1868 + static $base = null;
1869 + if ($base === null) {
1870 + $base = array();
1871 + foreach (self::$base as $i => $bas) {
1872 + for ($j = 0; $j < 8; ++$j) {
1873 + $base[$i][$j] = new ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp(
1874 + ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
1875 + array(
1876 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][0]),
1877 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][1]),
1878 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][2]),
1879 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][3]),
1880 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][4]),
1881 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][5]),
1882 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][6]),
1883 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][7]),
1884 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][8]),
1885 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][9])
1886 + )
1887 + ),
1888 + ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
1889 + array(
1890 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][0]),
1891 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][1]),
1892 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][2]),
1893 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][3]),
1894 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][4]),
1895 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][5]),
1896 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][6]),
1897 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][7]),
1898 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][8]),
1899 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][9])
1900 + )
1901 + ),
1902 + ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
1903 + array(
1904 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][0]),
1905 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][1]),
1906 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][2]),
1907 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][3]),
1908 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][4]),
1909 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][5]),
1910 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][6]),
1911 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][7]),
1912 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][8]),
1913 + ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][9])
1914 + )
1915 + )
1916 + );
1917 + }
1918 + }
1919 + }
1920 + if (!is_int($pos)) {
1921 + throw new InvalidArgumentException('Position must be an integer');
1922 + }
1923 + if ($pos < 0 || $pos > 31) {
1924 + throw new RangeException('Position is out of range [0, 31]');
1925 + }
1926 +
1927 + $bnegative = self::negative($b);
1928 + $babs = $b - (((-$bnegative) & $b) << 1);
1929 +
1930 + $t = self::ge_precomp_0();
1931 + for ($i = 0; $i < 8; ++$i) {
1932 + $t = self::cmov(
1933 + $t,
1934 + $base[$pos][$i],
1935 + -self::equal($babs, $i + 1)
1936 + );
1937 + }
1938 + $minusT = new ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp(
1939 + self::fe_copy($t->yminusx),
1940 + self::fe_copy($t->yplusx),
1941 + self::fe_neg($t->xy2d)
1942 + );
1943 + return self::cmov($t, $minusT, -$bnegative);
1944 + }
1945 +
1946 + /**
1947 + * Subtract two group elements.
1948 + *
1949 + * r = p - q
1950 + *
1951 + * @internal You should not use this directly from another application
1952 + *
1953 + * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p
1954 + * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Cached $q
1955 + * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1
1956 + * @throws SodiumException
1957 + * @throws TypeError
1958 + */
1959 + public static function ge_sub(
1960 + ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p,
1961 + ParagonIE_Sodium_Core32_Curve25519_Ge_Cached $q
1962 + ) {
1963 + $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1();
1964 +
1965 + $r->X = self::fe_add($p->Y, $p->X);
1966 + $r->Y = self::fe_sub($p->Y, $p->X);
1967 + $r->Z = self::fe_mul($r->X, $q->YminusX);
1968 + $r->Y = self::fe_mul($r->Y, $q->YplusX);
1969 + $r->T = self::fe_mul($q->T2d, $p->T);
1970 + $r->X = self::fe_mul($p->Z, $q->Z);
1971 + $t0 = self::fe_add($r->X, $r->X);
1972 + $r->X = self::fe_sub($r->Z, $r->Y);
1973 + $r->Y = self::fe_add($r->Z, $r->Y);
1974 + $r->Z = self::fe_sub($t0, $r->T);
1975 + $r->T = self::fe_add($t0, $r->T);
1976 +
1977 + return $r;
1978 + }
1979 +
1980 + /**
1981 + * Convert a group element to a byte string.
1982 + *
1983 + * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $h
1984 + * @return string
1985 + * @throws SodiumException
1986 + * @throws TypeError
1987 + */
1988 + public static function ge_tobytes(ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $h)
1989 + {
1990 + $recip = self::fe_invert($h->Z);
1991 + $x = self::fe_mul($h->X, $recip);
1992 + $y = self::fe_mul($h->Y, $recip);
1993 + $s = self::fe_tobytes($y);
1994 + $s[31] = self::intToChr(
1995 + self::chrToInt($s[31]) ^ (self::fe_isnegative($x) << 7)
1996 + );
1997 + return $s;
1998 + }
1999 +
2000 + /**
2001 + * @internal You should not use this directly from another application
2002 + *
2003 + * @param string $a
2004 + * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A
2005 + * @param string $b
2006 + * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P2
2007 + * @throws SodiumException
2008 + * @throws TypeError
2009 + * @psalm-suppress MixedArrayAccess
2010 + */
2011 + public static function ge_double_scalarmult_vartime(
2012 + $a,
2013 + ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A,
2014 + $b
2015 + ) {
2016 + /** @var array<int, ParagonIE_Sodium_Core32_Curve25519_Ge_Cached> $Ai */
2017 + $Ai = array();
2018 +
2019 + static $Bi = array();
2020 + /** @var array<int, ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp> $Bi */
2021 + if (!$Bi) {
2022 + for ($i = 0; $i < 8; ++$i) {
2023 + $Bi[$i] = new ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp(
2024 + ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
2025 + array(
2026 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][0]),
2027 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][1]),
2028 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][2]),
2029 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][3]),
2030 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][4]),
2031 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][5]),
2032 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][6]),
2033 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][7]),
2034 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][8]),
2035 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][9])
2036 + )
2037 + ),
2038 + ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
2039 + array(
2040 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][0]),
2041 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][1]),
2042 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][2]),
2043 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][3]),
2044 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][4]),
2045 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][5]),
2046 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][6]),
2047 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][7]),
2048 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][8]),
2049 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][9])
2050 + )
2051 + ),
2052 + ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
2053 + array(
2054 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][0]),
2055 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][1]),
2056 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][2]),
2057 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][3]),
2058 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][4]),
2059 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][5]),
2060 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][6]),
2061 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][7]),
2062 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][8]),
2063 + ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][9])
2064 + )
2065 + )
2066 + );
2067 + }
2068 + }
2069 +
2070 + for ($i = 0; $i < 8; ++$i) {
2071 + $Ai[$i] = new ParagonIE_Sodium_Core32_Curve25519_Ge_Cached(
2072 + self::fe_0(),
2073 + self::fe_0(),
2074 + self::fe_0(),
2075 + self::fe_0()
2076 + );
2077 + }
2078 + /** @var array<int, ParagonIE_Sodium_Core32_Curve25519_Ge_Cached> $Ai */
2079 +
2080 + # slide(aslide,a);
2081 + # slide(bslide,b);
2082 + /** @var array<int, int> $aslide */
2083 + $aslide = self::slide($a);
2084 + /** @var array<int, int> $bslide */
2085 + $bslide = self::slide($b);
2086 +
2087 + # ge_p3_to_cached(&Ai[0],A);
2088 + # ge_p3_dbl(&t,A); ge_p1p1_to_p3(&A2,&t);
2089 + $Ai[0] = self::ge_p3_to_cached($A);
2090 + $t = self::ge_p3_dbl($A);
2091 + $A2 = self::ge_p1p1_to_p3($t);
2092 +
2093 + # ge_add(&t,&A2,&Ai[0]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[1],&u);
2094 + # ge_add(&t,&A2,&Ai[1]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[2],&u);
2095 + # ge_add(&t,&A2,&Ai[2]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[3],&u);
2096 + # ge_add(&t,&A2,&Ai[3]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[4],&u);
2097 + # ge_add(&t,&A2,&Ai[4]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[5],&u);
2098 + # ge_add(&t,&A2,&Ai[5]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[6],&u);
2099 + # ge_add(&t,&A2,&Ai[6]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[7],&u);
2100 + for ($i = 0; $i < 7; ++$i) {
2101 + $t = self::ge_add($A2, $Ai[$i]);
2102 + $u = self::ge_p1p1_to_p3($t);
2103 + $Ai[$i + 1] = self::ge_p3_to_cached($u);
2104 + }
2105 +
2106 + # ge_p2_0(r);
2107 + $r = self::ge_p2_0();
2108 +
2109 + # for (i = 255;i >= 0;--i) {
2110 + # if (aslide[i] || bslide[i]) break;
2111 + # }
2112 + $i = 255;
2113 + for (; $i >= 0; --$i) {
2114 + if ($aslide[$i] || $bslide[$i]) {
2115 + break;
2116 + }
2117 + }
2118 +
2119 + # for (;i >= 0;--i) {
2120 + for (; $i >= 0; --$i) {
2121 + # ge_p2_dbl(&t,r);
2122 + $t = self::ge_p2_dbl($r);
2123 +
2124 + # if (aslide[i] > 0) {
2125 + if ($aslide[$i] > 0) {
2126 + # ge_p1p1_to_p3(&u,&t);
2127 + # ge_add(&t,&u,&Ai[aslide[i]/2]);
2128 + $u = self::ge_p1p1_to_p3($t);
2129 + $t = self::ge_add(
2130 + $u,
2131 + $Ai[(int) floor($aslide[$i] / 2)]
2132 + );
2133 + # } else if (aslide[i] < 0) {
2134 + } elseif ($aslide[$i] < 0) {
2135 + # ge_p1p1_to_p3(&u,&t);
2136 + # ge_sub(&t,&u,&Ai[(-aslide[i])/2]);
2137 + $u = self::ge_p1p1_to_p3($t);
2138 + $t = self::ge_sub(
2139 + $u,
2140 + $Ai[(int) floor(-$aslide[$i] / 2)]
2141 + );
2142 + }
2143 + /** @var array<int, ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp> $Bi */
2144 +
2145 + # if (bslide[i] > 0) {
2146 + if ($bslide[$i] > 0) {
2147 + # ge_p1p1_to_p3(&u,&t);
2148 + # ge_madd(&t,&u,&Bi[bslide[i]/2]);
2149 + $u = self::ge_p1p1_to_p3($t);
2150 + /** @var int $index */
2151 + $index = (int) floor($bslide[$i] / 2);
2152 + /** @var ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $thisB */
2153 + $thisB = $Bi[$index];
2154 + $t = self::ge_madd($t, $u, $thisB);
2155 + # } else if (bslide[i] < 0) {
2156 + } elseif ($bslide[$i] < 0) {
2157 + # ge_p1p1_to_p3(&u,&t);
2158 + # ge_msub(&t,&u,&Bi[(-bslide[i])/2]);
2159 + $u = self::ge_p1p1_to_p3($t);
2160 +
2161 + /** @var int $index */
2162 + $index = (int) floor(-$bslide[$i] / 2);
2163 +
2164 + /** @var ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $thisB */
2165 + $thisB = $Bi[$index];
2166 + $t = self::ge_msub($t, $u, $thisB);
2167 + }
2168 + # ge_p1p1_to_p2(r,&t);
2169 + $r = self::ge_p1p1_to_p2($t);
2170 + }
2171 + return $r;
2172 + }
2173 +
2174 + /**
2175 + * @internal You should not use this directly from another application
2176 + *
2177 + * @param string $a
2178 + * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P3
2179 + * @psalm-suppress MixedAssignment
2180 + * @psalm-suppress MixedOperand
2181 + * @throws SodiumException
2182 + * @throws TypeError
2183 + */
2184 + public static function ge_scalarmult_base($a)
2185 + {
2186 + /** @var array<int, int> $e */
2187 + $e = array();
2188 + $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1();
2189 +
2190 + for ($i = 0; $i < 32; ++$i) {
2191 + /** @var int $dbl */
2192 + $dbl = (int) $i << 1;
2193 + $e[$dbl] = (int) self::chrToInt($a[$i]) & 15;
2194 + $e[$dbl + 1] = (int) (self::chrToInt($a[$i]) >> 4) & 15;
2195 + }
2196 +
2197 + /** @var int $carry */
2198 + $carry = 0;
2199 + for ($i = 0; $i < 63; ++$i) {
2200 + $e[$i] += $carry;
2201 + $carry = $e[$i] + 8;
2202 + $carry >>= 4;
2203 + $e[$i] -= $carry << 4;
2204 + }
2205 +
2206 + /** @var array<int, int> $e */
2207 + $e[63] += (int) $carry;
2208 +
2209 + $h = self::ge_p3_0();
2210 +
2211 + for ($i = 1; $i < 64; $i += 2) {
2212 + $t = self::ge_select((int) floor($i / 2), (int) $e[$i]);
2213 + $r = self::ge_madd($r, $h, $t);
2214 + $h = self::ge_p1p1_to_p3($r);
2215 + }
2216 +
2217 + $r = self::ge_p3_dbl($h);
2218 +
2219 + $s = self::ge_p1p1_to_p2($r);
2220 + $r = self::ge_p2_dbl($s);
2221 + $s = self::ge_p1p1_to_p2($r);
2222 + $r = self::ge_p2_dbl($s);
2223 + $s = self::ge_p1p1_to_p2($r);
2224 + $r = self::ge_p2_dbl($s);
2225 +
2226 + $h = self::ge_p1p1_to_p3($r);
2227 +
2228 + for ($i = 0; $i < 64; $i += 2) {
2229 + $t = self::ge_select($i >> 1, (int) $e[$i]);
2230 + $r = self::ge_madd($r, $h, $t);
2231 + $h = self::ge_p1p1_to_p3($r);
2232 + }
2233 + return $h;
2234 + }
2235 +
2236 + /**
2237 + * Calculates (ab + c) mod l
2238 + * where l = 2^252 + 27742317777372353535851937790883648493
2239 + *
2240 + * @internal You should not use this directly from another application
2241 + *
2242 + * @param string $a
2243 + * @param string $b
2244 + * @param string $c
2245 + * @return string
2246 + * @throws SodiumException
2247 + * @throws TypeError
2248 + */
2249 + public static function sc_muladd($a, $b, $c)
2250 + {
2251 + $a0 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($a, 0, 3)));
2252 + $a1 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($a, 2, 4)) >> 5));
2253 + $a2 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($a, 5, 3)) >> 2));
2254 + $a3 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($a, 7, 4)) >> 7));
2255 + $a4 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($a, 10, 4)) >> 4));
2256 + $a5 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($a, 13, 3)) >> 1));
2257 + $a6 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($a, 15, 4)) >> 6));
2258 + $a7 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($a, 18, 3)) >> 3));
2259 + $a8 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($a, 21, 3)));
2260 + $a9 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($a, 23, 4)) >> 5));
2261 + $a10 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($a, 26, 3)) >> 2));
2262 + $a11 = ParagonIE_Sodium_Core32_Int64::fromInt(0x1fffffff & (self::load_4(self::substr($a, 28, 4)) >> 7));
2263 + $b0 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($b, 0, 3)));
2264 + $b1 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($b, 2, 4)) >> 5));
2265 + $b2 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($b, 5, 3)) >> 2));
2266 + $b3 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($b, 7, 4)) >> 7));
2267 + $b4 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($b, 10, 4)) >> 4));
2268 + $b5 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($b, 13, 3)) >> 1));
2269 + $b6 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($b, 15, 4)) >> 6));
2270 + $b7 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($b, 18, 3)) >> 3));
2271 + $b8 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($b, 21, 3)));
2272 + $b9 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($b, 23, 4)) >> 5));
2273 + $b10 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($b, 26, 3)) >> 2));
2274 + $b11 = ParagonIE_Sodium_Core32_Int64::fromInt(0x1fffffff & (self::load_4(self::substr($b, 28, 4)) >> 7));
2275 + $c0 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($c, 0, 3)));
2276 + $c1 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($c, 2, 4)) >> 5));
2277 + $c2 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($c, 5, 3)) >> 2));
2278 + $c3 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($c, 7, 4)) >> 7));
2279 + $c4 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($c, 10, 4)) >> 4));
2280 + $c5 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($c, 13, 3)) >> 1));
2281 + $c6 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($c, 15, 4)) >> 6));
2282 + $c7 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($c, 18, 3)) >> 3));
2283 + $c8 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($c, 21, 3)));
2284 + $c9 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($c, 23, 4)) >> 5));
2285 + $c10 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($c, 26, 3)) >> 2));
2286 + $c11 = ParagonIE_Sodium_Core32_Int64::fromInt(0x1fffffff & (self::load_4(self::substr($c, 28, 4)) >> 7));
2287 +
2288 + /* Can't really avoid the pyramid here: */
2289 + /**
2290 + * @var ParagonIE_Sodium_Core32_Int64 $s0
2291 + * @var ParagonIE_Sodium_Core32_Int64 $s1
2292 + * @var ParagonIE_Sodium_Core32_Int64 $s2
2293 + * @var ParagonIE_Sodium_Core32_Int64 $s3
2294 + * @var ParagonIE_Sodium_Core32_Int64 $s4
2295 + * @var ParagonIE_Sodium_Core32_Int64 $s5
2296 + * @var ParagonIE_Sodium_Core32_Int64 $s6
2297 + * @var ParagonIE_Sodium_Core32_Int64 $s7
2298 + * @var ParagonIE_Sodium_Core32_Int64 $s8
2299 + * @var ParagonIE_Sodium_Core32_Int64 $s9
2300 + * @var ParagonIE_Sodium_Core32_Int64 $s10
2301 + * @var ParagonIE_Sodium_Core32_Int64 $s11
2302 + * @var ParagonIE_Sodium_Core32_Int64 $s12
2303 + * @var ParagonIE_Sodium_Core32_Int64 $s13
2304 + * @var ParagonIE_Sodium_Core32_Int64 $s14
2305 + * @var ParagonIE_Sodium_Core32_Int64 $s15
2306 + * @var ParagonIE_Sodium_Core32_Int64 $s16
2307 + * @var ParagonIE_Sodium_Core32_Int64 $s17
2308 + * @var ParagonIE_Sodium_Core32_Int64 $s18
2309 + * @var ParagonIE_Sodium_Core32_Int64 $s19
2310 + * @var ParagonIE_Sodium_Core32_Int64 $s20
2311 + * @var ParagonIE_Sodium_Core32_Int64 $s21
2312 + * @var ParagonIE_Sodium_Core32_Int64 $s22
2313 + * @var ParagonIE_Sodium_Core32_Int64 $s23
2314 + */
2315 +
2316 + $s0 = $c0->addInt64($a0->mulInt64($b0, 24));
2317 + $s1 = $c1->addInt64($a0->mulInt64($b1, 24))->addInt64($a1->mulInt64($b0, 24));
2318 + $s2 = $c2->addInt64($a0->mulInt64($b2, 24))->addInt64($a1->mulInt64($b1, 24))->addInt64($a2->mulInt64($b0, 24));
2319 + $s3 = $c3->addInt64($a0->mulInt64($b3, 24))->addInt64($a1->mulInt64($b2, 24))->addInt64($a2->mulInt64($b1, 24))
2320 + ->addInt64($a3->mulInt64($b0, 24));
2321 + $s4 = $c4->addInt64($a0->mulInt64($b4, 24))->addInt64($a1->mulInt64($b3, 24))->addInt64($a2->mulInt64($b2, 24))
2322 + ->addInt64($a3->mulInt64($b1, 24))->addInt64($a4->mulInt64($b0, 24));
2323 + $s5 = $c5->addInt64($a0->mulInt64($b5, 24))->addInt64($a1->mulInt64($b4, 24))->addInt64($a2->mulInt64($b3, 24))
2324 + ->addInt64($a3->mulInt64($b2, 24))->addInt64($a4->mulInt64($b1, 24))->addInt64($a5->mulInt64($b0, 24));
2325 + $s6 = $c6->addInt64($a0->mulInt64($b6, 24))->addInt64($a1->mulInt64($b5, 24))->addInt64($a2->mulInt64($b4, 24))
2326 + ->addInt64($a3->mulInt64($b3, 24))->addInt64($a4->mulInt64($b2, 24))->addInt64($a5->mulInt64($b1, 24))
2327 + ->addInt64($a6->mulInt64($b0, 24));
2328 + $s7 = $c7->addInt64($a0->mulInt64($b7, 24))->addInt64($a1->mulInt64($b6, 24))->addInt64($a2->mulInt64($b5, 24))
2329 + ->addInt64($a3->mulInt64($b4, 24))->addInt64($a4->mulInt64($b3, 24))->addInt64($a5->mulInt64($b2, 24))
2330 + ->addInt64($a6->mulInt64($b1, 24))->addInt64($a7->mulInt64($b0, 24));
2331 + $s8 = $c8->addInt64($a0->mulInt64($b8, 24))->addInt64($a1->mulInt64($b7, 24))->addInt64($a2->mulInt64($b6, 24))
2332 + ->addInt64($a3->mulInt64($b5, 24))->addInt64($a4->mulInt64($b4, 24))->addInt64($a5->mulInt64($b3, 24))
2333 + ->addInt64($a6->mulInt64($b2, 24))->addInt64($a7->mulInt64($b1, 24))->addInt64($a8->mulInt64($b0, 24));
2334 + $s9 = $c9->addInt64($a0->mulInt64($b9, 24))->addInt64($a1->mulInt64($b8, 24))->addInt64($a2->mulInt64($b7, 24))
2335 + ->addInt64($a3->mulInt64($b6, 24))->addInt64($a4->mulInt64($b5, 24))->addInt64($a5->mulInt64($b4, 24))
2336 + ->addInt64($a6->mulInt64($b3, 24))->addInt64($a7->mulInt64($b2, 24))->addInt64($a8->mulInt64($b1, 24))
2337 + ->addInt64($a9->mulInt64($b0, 24));
2338 + $s10 = $c10->addInt64($a0->mulInt64($b10, 24))->addInt64($a1->mulInt64($b9, 24))->addInt64($a2->mulInt64($b8, 24))
2339 + ->addInt64($a3->mulInt64($b7, 24))->addInt64($a4->mulInt64($b6, 24))->addInt64($a5->mulInt64($b5, 24))
2340 + ->addInt64($a6->mulInt64($b4, 24))->addInt64($a7->mulInt64($b3, 24))->addInt64($a8->mulInt64($b2, 24))
2341 + ->addInt64($a9->mulInt64($b1, 24))->addInt64($a10->mulInt64($b0, 24));
2342 + $s11 = $c11->addInt64($a0->mulInt64($b11, 24))->addInt64($a1->mulInt64($b10, 24))->addInt64($a2->mulInt64($b9, 24))
2343 + ->addInt64($a3->mulInt64($b8, 24))->addInt64($a4->mulInt64($b7, 24))->addInt64($a5->mulInt64($b6, 24))
2344 + ->addInt64($a6->mulInt64($b5, 24))->addInt64($a7->mulInt64($b4, 24))->addInt64($a8->mulInt64($b3, 24))
2345 + ->addInt64($a9->mulInt64($b2, 24))->addInt64($a10->mulInt64($b1, 24))->addInt64($a11->mulInt64($b0, 24));
2346 + $s12 = $a1->mulInt64($b11, 24)->addInt64($a2->mulInt64($b10, 24))->addInt64($a3->mulInt64($b9, 24))
2347 + ->addInt64($a4->mulInt64($b8, 24))->addInt64($a5->mulInt64($b7, 24))->addInt64($a6->mulInt64($b6, 24))
2348 + ->addInt64($a7->mulInt64($b5, 24))->addInt64($a8->mulInt64($b4, 24))->addInt64($a9->mulInt64($b3, 24))
2349 + ->addInt64($a10->mulInt64($b2, 24))->addInt64($a11->mulInt64($b1, 24));
2350 + $s13 = $a2->mulInt64($b11, 24)->addInt64($a3->mulInt64($b10, 24))->addInt64($a4->mulInt64($b9, 24))
2351 + ->addInt64($a5->mulInt64($b8, 24))->addInt64($a6->mulInt64($b7, 24))->addInt64($a7->mulInt64($b6, 24))
2352 + ->addInt64($a8->mulInt64($b5, 24))->addInt64($a9->mulInt64($b4, 24))->addInt64($a10->mulInt64($b3, 24))
2353 + ->addInt64($a11->mulInt64($b2, 24));
2354 + $s14 = $a3->mulInt64($b11, 24)->addInt64($a4->mulInt64($b10, 24))->addInt64($a5->mulInt64($b9, 24))
2355 + ->addInt64($a6->mulInt64($b8, 24))->addInt64($a7->mulInt64($b7, 24))->addInt64($a8->mulInt64($b6, 24))
2356 + ->addInt64($a9->mulInt64($b5, 24))->addInt64($a10->mulInt64($b4, 24))->addInt64($a11->mulInt64($b3, 24));
2357 + $s15 = $a4->mulInt64($b11, 24)->addInt64($a5->mulInt64($b10, 24))->addInt64($a6->mulInt64($b9, 24))
2358 + ->addInt64($a7->mulInt64($b8, 24))->addInt64($a8->mulInt64($b7, 24))->addInt64($a9->mulInt64($b6, 24))
2359 + ->addInt64($a10->mulInt64($b5, 24))->addInt64($a11->mulInt64($b4, 24));
2360 + $s16 = $a5->mulInt64($b11, 24)->addInt64($a6->mulInt64($b10, 24))->addInt64($a7->mulInt64($b9, 24))
2361 + ->addInt64($a8->mulInt64($b8, 24))->addInt64($a9->mulInt64($b7, 24))->addInt64($a10->mulInt64($b6, 24))
2362 + ->addInt64($a11->mulInt64($b5, 24));
2363 + $s17 = $a6->mulInt64($b11, 24)->addInt64($a7->mulInt64($b10, 24))->addInt64($a8->mulInt64($b9, 24))
2364 + ->addInt64($a9->mulInt64($b8, 24))->addInt64($a10->mulInt64($b7, 24))->addInt64($a11->mulInt64($b6, 24));
2365 + $s18 = $a7->mulInt64($b11, 24)->addInt64($a8->mulInt64($b10, 24))->addInt64($a9->mulInt64($b9, 24))
2366 + ->addInt64($a10->mulInt64($b8, 24))->addInt64($a11->mulInt64($b7, 24));
2367 + $s19 = $a8->mulInt64($b11, 24)->addInt64($a9->mulInt64($b10, 24))->addInt64($a10->mulInt64($b9, 24))
2368 + ->addInt64($a11->mulInt64($b8, 24));
2369 + $s20 = $a9->mulInt64($b11, 24)->addInt64($a10->mulInt64($b10, 24))->addInt64($a11->mulInt64($b9, 24));
2370 + $s21 = $a10->mulInt64($b11, 24)->addInt64($a11->mulInt64($b10, 24));
2371 + $s22 = $a11->mulInt64($b11, 24);
2372 + $s23 = new ParagonIE_Sodium_Core32_Int64();
2373 +
2374 + $carry0 = $s0->addInt(1 << 20)->shiftRight(21);
2375 + $s1 = $s1->addInt64($carry0);
2376 + $s0 = $s0->subInt64($carry0->shiftLeft(21));
2377 + $carry2 = $s2->addInt(1 << 20)->shiftRight(21);
2378 + $s3 = $s3->addInt64($carry2);
2379 + $s2 = $s2->subInt64($carry2->shiftLeft(21));
2380 + $carry4 = $s4->addInt(1 << 20)->shiftRight(21);
2381 + $s5 = $s5->addInt64($carry4);
2382 + $s4 = $s4->subInt64($carry4->shiftLeft(21));
2383 + $carry6 = $s6->addInt(1 << 20)->shiftRight(21);
2384 + $s7 = $s7->addInt64($carry6);
2385 + $s6 = $s6->subInt64($carry6->shiftLeft(21));
2386 + $carry8 = $s8->addInt(1 << 20)->shiftRight(21);
2387 + $s9 = $s9->addInt64($carry8);
2388 + $s8 = $s8->subInt64($carry8->shiftLeft(21));
2389 + $carry10 = $s10->addInt(1 << 20)->shiftRight(21);
2390 + $s11 = $s11->addInt64($carry10);
2391 + $s10 = $s10->subInt64($carry10->shiftLeft(21));
2392 + $carry12 = $s12->addInt(1 << 20)->shiftRight(21);
2393 + $s13 = $s13->addInt64($carry12);
2394 + $s12 = $s12->subInt64($carry12->shiftLeft(21));
2395 + $carry14 = $s14->addInt(1 << 20)->shiftRight(21);
2396 + $s15 = $s15->addInt64($carry14);
2397 + $s14 = $s14->subInt64($carry14->shiftLeft(21));
2398 + $carry16 = $s16->addInt(1 << 20)->shiftRight(21);
2399 + $s17 = $s17->addInt64($carry16);
2400 + $s16 = $s16->subInt64($carry16->shiftLeft(21));
2401 + $carry18 = $s18->addInt(1 << 20)->shiftRight(21);
2402 + $s19 = $s19->addInt64($carry18);
2403 + $s18 = $s18->subInt64($carry18->shiftLeft(21));
2404 + $carry20 = $s20->addInt(1 << 20)->shiftRight(21);
2405 + $s21 = $s21->addInt64($carry20);
2406 + $s20 = $s20->subInt64($carry20->shiftLeft(21));
2407 + $carry22 = $s22->addInt(1 << 20)->shiftRight(21);
2408 + $s23 = $s23->addInt64($carry22);
2409 + $s22 = $s22->subInt64($carry22->shiftLeft(21));
2410 +
2411 + $carry1 = $s1->addInt(1 << 20)->shiftRight(21);
2412 + $s2 = $s2->addInt64($carry1);
2413 + $s1 = $s1->subInt64($carry1->shiftLeft(21));
2414 + $carry3 = $s3->addInt(1 << 20)->shiftRight(21);
2415 + $s4 = $s4->addInt64($carry3);
2416 + $s3 = $s3->subInt64($carry3->shiftLeft(21));
2417 + $carry5 = $s5->addInt(1 << 20)->shiftRight(21);
2418 + $s6 = $s6->addInt64($carry5);
2419 + $s5 = $s5->subInt64($carry5->shiftLeft(21));
2420 + $carry7 = $s7->addInt(1 << 20)->shiftRight(21);
2421 + $s8 = $s8->addInt64($carry7);
2422 + $s7 = $s7->subInt64($carry7->shiftLeft(21));
2423 + $carry9 = $s9->addInt(1 << 20)->shiftRight(21);
2424 + $s10 = $s10->addInt64($carry9);
2425 + $s9 = $s9->subInt64($carry9->shiftLeft(21));
2426 + $carry11 = $s11->addInt(1 << 20)->shiftRight(21);
2427 + $s12 = $s12->addInt64($carry11);
2428 + $s11 = $s11->subInt64($carry11->shiftLeft(21));
2429 + $carry13 = $s13->addInt(1 << 20)->shiftRight(21);
2430 + $s14 = $s14->addInt64($carry13);
2431 + $s13 = $s13->subInt64($carry13->shiftLeft(21));
2432 + $carry15 = $s15->addInt(1 << 20)->shiftRight(21);
2433 + $s16 = $s16->addInt64($carry15);
2434 + $s15 = $s15->subInt64($carry15->shiftLeft(21));
2435 + $carry17 = $s17->addInt(1 << 20)->shiftRight(21);
2436 + $s18 = $s18->addInt64($carry17);
2437 + $s17 = $s17->subInt64($carry17->shiftLeft(21));
2438 + $carry19 = $s19->addInt(1 << 20)->shiftRight(21);
2439 + $s20 = $s20->addInt64($carry19);
2440 + $s19 = $s19->subInt64($carry19->shiftLeft(21));
2441 + $carry21 = $s21->addInt(1 << 20)->shiftRight(21);
2442 + $s22 = $s22->addInt64($carry21);
2443 + $s21 = $s21->subInt64($carry21->shiftLeft(21));
2444 +
2445 + $s11 = $s11->addInt64($s23->mulInt(666643, 20));
2446 + $s12 = $s12->addInt64($s23->mulInt(470296, 19));
2447 + $s13 = $s13->addInt64($s23->mulInt(654183, 20));
2448 + $s14 = $s14->subInt64($s23->mulInt(997805, 20));
2449 + $s15 = $s15->addInt64($s23->mulInt(136657, 18));
2450 + $s16 = $s16->subInt64($s23->mulInt(683901, 20));
2451 +
2452 + $s10 = $s10->addInt64($s22->mulInt(666643, 20));
2453 + $s11 = $s11->addInt64($s22->mulInt(470296, 19));
2454 + $s12 = $s12->addInt64($s22->mulInt(654183, 20));
2455 + $s13 = $s13->subInt64($s22->mulInt(997805, 20));
2456 + $s14 = $s14->addInt64($s22->mulInt(136657, 18));
2457 + $s15 = $s15->subInt64($s22->mulInt(683901, 20));
2458 +
2459 + $s9 = $s9->addInt64($s21->mulInt(666643, 20));
2460 + $s10 = $s10->addInt64($s21->mulInt(470296, 19));
2461 + $s11 = $s11->addInt64($s21->mulInt(654183, 20));
2462 + $s12 = $s12->subInt64($s21->mulInt(997805, 20));
2463 + $s13 = $s13->addInt64($s21->mulInt(136657, 18));
2464 + $s14 = $s14->subInt64($s21->mulInt(683901, 20));
2465 +
2466 + $s8 = $s8->addInt64($s20->mulInt(666643, 20));
2467 + $s9 = $s9->addInt64($s20->mulInt(470296, 19));
2468 + $s10 = $s10->addInt64($s20->mulInt(654183, 20));
2469 + $s11 = $s11->subInt64($s20->mulInt(997805, 20));
2470 + $s12 = $s12->addInt64($s20->mulInt(136657, 18));
2471 + $s13 = $s13->subInt64($s20->mulInt(683901, 20));
2472 +
2473 + $s7 = $s7->addInt64($s19->mulInt(666643, 20));
2474 + $s8 = $s8->addInt64($s19->mulInt(470296, 19));
2475 + $s9 = $s9->addInt64($s19->mulInt(654183, 20));
2476 + $s10 = $s10->subInt64($s19->mulInt(997805, 20));
2477 + $s11 = $s11->addInt64($s19->mulInt(136657, 18));
2478 + $s12 = $s12->subInt64($s19->mulInt(683901, 20));
2479 +
2480 + $s6 = $s6->addInt64($s18->mulInt(666643, 20));
2481 + $s7 = $s7->addInt64($s18->mulInt(470296, 19));
2482 + $s8 = $s8->addInt64($s18->mulInt(654183, 20));
2483 + $s9 = $s9->subInt64($s18->mulInt(997805, 20));
2484 + $s10 = $s10->addInt64($s18->mulInt(136657, 18));
2485 + $s11 = $s11->subInt64($s18->mulInt(683901, 20));
2486 +
2487 + $carry6 = $s6->addInt(1 << 20)->shiftRight(21);
2488 + $s7 = $s7->addInt64($carry6);
2489 + $s6 = $s6->subInt64($carry6->shiftLeft(21));
2490 + $carry8 = $s8->addInt(1 << 20)->shiftRight(21);
2491 + $s9 = $s9->addInt64($carry8);
2492 + $s8 = $s8->subInt64($carry8->shiftLeft(21));
2493 + $carry10 = $s10->addInt(1 << 20)->shiftRight(21);
2494 + $s11 = $s11->addInt64($carry10);
2495 + $s10 = $s10->subInt64($carry10->shiftLeft(21));
2496 + $carry12 = $s12->addInt(1 << 20)->shiftRight(21);
2497 + $s13 = $s13->addInt64($carry12);
2498 + $s12 = $s12->subInt64($carry12->shiftLeft(21));
2499 + $carry14 = $s14->addInt(1 << 20)->shiftRight(21);
2500 + $s15 = $s15->addInt64($carry14);
2501 + $s14 = $s14->subInt64($carry14->shiftLeft(21));
2502 + $carry16 = $s16->addInt(1 << 20)->shiftRight(21);
2503 + $s17 = $s17->addInt64($carry16);
2504 + $s16 = $s16->subInt64($carry16->shiftLeft(21));
2505 +
2506 + $carry7 = $s7->addInt(1 << 20)->shiftRight(21);
2507 + $s8 = $s8->addInt64($carry7);
2508 + $s7 = $s7->subInt64($carry7->shiftLeft(21));
2509 + $carry9 = $s9->addInt(1 << 20)->shiftRight(21);
2510 + $s10 = $s10->addInt64($carry9);
2511 + $s9 = $s9->subInt64($carry9->shiftLeft(21));
2512 + $carry11 = $s11->addInt(1 << 20)->shiftRight(21);
2513 + $s12 = $s12->addInt64($carry11);
2514 + $s11 = $s11->subInt64($carry11->shiftLeft(21));
2515 + $carry13 = $s13->addInt(1 << 20)->shiftRight(21);
2516 + $s14 = $s14->addInt64($carry13);
2517 + $s13 = $s13->subInt64($carry13->shiftLeft(21));
2518 + $carry15 = $s15->addInt(1 << 20)->shiftRight(21);
2519 + $s16 = $s16->addInt64($carry15);
2520 + $s15 = $s15->subInt64($carry15->shiftLeft(21));
2521 +
2522 + $s5 = $s5->addInt64($s17->mulInt(666643, 20));
2523 + $s6 = $s6->addInt64($s17->mulInt(470296, 19));
2524 + $s7 = $s7->addInt64($s17->mulInt(654183, 20));
2525 + $s8 = $s8->subInt64($s17->mulInt(997805, 20));
2526 + $s9 = $s9->addInt64($s17->mulInt(136657, 18));
2527 + $s10 = $s10->subInt64($s17->mulInt(683901, 20));
2528 +
2529 + $s4 = $s4->addInt64($s16->mulInt(666643, 20));
2530 + $s5 = $s5->addInt64($s16->mulInt(470296, 19));
2531 + $s6 = $s6->addInt64($s16->mulInt(654183, 20));
2532 + $s7 = $s7->subInt64($s16->mulInt(997805, 20));
2533 + $s8 = $s8->addInt64($s16->mulInt(136657, 18));
2534 + $s9 = $s9->subInt64($s16->mulInt(683901, 20));
2535 +
2536 + $s3 = $s3->addInt64($s15->mulInt(666643, 20));
2537 + $s4 = $s4->addInt64($s15->mulInt(470296, 19));
2538 + $s5 = $s5->addInt64($s15->mulInt(654183, 20));
2539 + $s6 = $s6->subInt64($s15->mulInt(997805, 20));
2540 + $s7 = $s7->addInt64($s15->mulInt(136657, 18));
2541 + $s8 = $s8->subInt64($s15->mulInt(683901, 20));
2542 +
2543 + $s2 = $s2->addInt64($s14->mulInt(666643, 20));
2544 + $s3 = $s3->addInt64($s14->mulInt(470296, 19));
2545 + $s4 = $s4->addInt64($s14->mulInt(654183, 20));
2546 + $s5 = $s5->subInt64($s14->mulInt(997805, 20));
2547 + $s6 = $s6->addInt64($s14->mulInt(136657, 18));
2548 + $s7 = $s7->subInt64($s14->mulInt(683901, 20));
2549 +
2550 + $s1 = $s1->addInt64($s13->mulInt(666643, 20));
2551 + $s2 = $s2->addInt64($s13->mulInt(470296, 19));
2552 + $s3 = $s3->addInt64($s13->mulInt(654183, 20));
2553 + $s4 = $s4->subInt64($s13->mulInt(997805, 20));
2554 + $s5 = $s5->addInt64($s13->mulInt(136657, 18));
2555 + $s6 = $s6->subInt64($s13->mulInt(683901, 20));
2556 +
2557 + $s0 = $s0->addInt64($s12->mulInt(666643, 20));
2558 + $s1 = $s1->addInt64($s12->mulInt(470296, 19));
2559 + $s2 = $s2->addInt64($s12->mulInt(654183, 20));
2560 + $s3 = $s3->subInt64($s12->mulInt(997805, 20));
2561 + $s4 = $s4->addInt64($s12->mulInt(136657, 18));
2562 + $s5 = $s5->subInt64($s12->mulInt(683901, 20));
2563 + $s12 = new ParagonIE_Sodium_Core32_Int64();
2564 +
2565 + $carry0 = $s0->addInt(1 << 20)->shiftRight(21);
2566 + $s1 = $s1->addInt64($carry0);
2567 + $s0 = $s0->subInt64($carry0->shiftLeft(21));
2568 + $carry2 = $s2->addInt(1 << 20)->shiftRight(21);
2569 + $s3 = $s3->addInt64($carry2);
2570 + $s2 = $s2->subInt64($carry2->shiftLeft(21));
2571 + $carry4 = $s4->addInt(1 << 20)->shiftRight(21);
2572 + $s5 = $s5->addInt64($carry4);
2573 + $s4 = $s4->subInt64($carry4->shiftLeft(21));
2574 + $carry6 = $s6->addInt(1 << 20)->shiftRight(21);
2575 + $s7 = $s7->addInt64($carry6);
2576 + $s6 = $s6->subInt64($carry6->shiftLeft(21));
2577 + $carry8 = $s8->addInt(1 << 20)->shiftRight(21);
2578 + $s9 = $s9->addInt64($carry8);
2579 + $s8 = $s8->subInt64($carry8->shiftLeft(21));
2580 + $carry10 = $s10->addInt(1 << 20)->shiftRight(21);
2581 + $s11 = $s11->addInt64($carry10);
2582 + $s10 = $s10->subInt64($carry10->shiftLeft(21));
2583 +
2584 + $carry1 = $s1->addInt(1 << 20)->shiftRight(21);
2585 + $s2 = $s2->addInt64($carry1);
2586 + $s1 = $s1->subInt64($carry1->shiftLeft(21));
2587 + $carry3 = $s3->addInt(1 << 20)->shiftRight(21);
2588 + $s4 = $s4->addInt64($carry3);
2589 + $s3 = $s3->subInt64($carry3->shiftLeft(21));
2590 + $carry5 = $s5->addInt(1 << 20)->shiftRight(21);
2591 + $s6 = $s6->addInt64($carry5);
2592 + $s5 = $s5->subInt64($carry5->shiftLeft(21));
2593 + $carry7 = $s7->addInt(1 << 20)->shiftRight(21);
2594 + $s8 = $s8->addInt64($carry7);
2595 + $s7 = $s7->subInt64($carry7->shiftLeft(21));
2596 + $carry9 = $s9->addInt(1 << 20)->shiftRight(21);
2597 + $s10 = $s10->addInt64($carry9);
2598 + $s9 = $s9->subInt64($carry9->shiftLeft(21));
2599 + $carry11 = $s11->addInt(1 << 20)->shiftRight(21);
2600 + $s12 = $s12->addInt64($carry11);
2601 + $s11 = $s11->subInt64($carry11->shiftLeft(21));
2602 +
2603 + $s0 = $s0->addInt64($s12->mulInt(666643, 20));
2604 + $s1 = $s1->addInt64($s12->mulInt(470296, 19));
2605 + $s2 = $s2->addInt64($s12->mulInt(654183, 20));
2606 + $s3 = $s3->subInt64($s12->mulInt(997805, 20));
2607 + $s4 = $s4->addInt64($s12->mulInt(136657, 18));
2608 + $s5 = $s5->subInt64($s12->mulInt(683901, 20));
2609 + $s12 = new ParagonIE_Sodium_Core32_Int64();
2610 +
2611 + $carry0 = $s0->shiftRight(21);
2612 + $s1 = $s1->addInt64($carry0);
2613 + $s0 = $s0->subInt64($carry0->shiftLeft(21));
2614 + $carry1 = $s1->shiftRight(21);
2615 + $s2 = $s2->addInt64($carry1);
2616 + $s1 = $s1->subInt64($carry1->shiftLeft(21));
2617 + $carry2 = $s2->shiftRight(21);
2618 + $s3 = $s3->addInt64($carry2);
2619 + $s2 = $s2->subInt64($carry2->shiftLeft(21));
2620 + $carry3 = $s3->shiftRight(21);
2621 + $s4 = $s4->addInt64($carry3);
2622 + $s3 = $s3->subInt64($carry3->shiftLeft(21));
2623 + $carry4 = $s4->shiftRight(21);
2624 + $s5 = $s5->addInt64($carry4);
2625 + $s4 = $s4->subInt64($carry4->shiftLeft(21));
2626 + $carry5 = $s5->shiftRight(21);
2627 + $s6 = $s6->addInt64($carry5);
2628 + $s5 = $s5->subInt64($carry5->shiftLeft(21));
2629 + $carry6 = $s6->shiftRight(21);
2630 + $s7 = $s7->addInt64($carry6);
2631 + $s6 = $s6->subInt64($carry6->shiftLeft(21));
2632 + $carry7 = $s7->shiftRight(21);
2633 + $s8 = $s8->addInt64($carry7);
2634 + $s7 = $s7->subInt64($carry7->shiftLeft(21));
2635 + $carry8 = $s8->shiftRight(21);
2636 + $s9 = $s9->addInt64($carry8);
2637 + $s8 = $s8->subInt64($carry8->shiftLeft(21));
2638 + $carry9 = $s9->shiftRight(21);
2639 + $s10 = $s10->addInt64($carry9);
2640 + $s9 = $s9->subInt64($carry9->shiftLeft(21));
2641 + $carry10 = $s10->shiftRight(21);
2642 + $s11 = $s11->addInt64($carry10);
2643 + $s10 = $s10->subInt64($carry10->shiftLeft(21));
2644 + $carry11 = $s11->shiftRight(21);
2645 + $s12 = $s12->addInt64($carry11);
2646 + $s11 = $s11->subInt64($carry11->shiftLeft(21));
2647 +
2648 + $s0 = $s0->addInt64($s12->mulInt(666643, 20));
2649 + $s1 = $s1->addInt64($s12->mulInt(470296, 19));
2650 + $s2 = $s2->addInt64($s12->mulInt(654183, 20));
2651 + $s3 = $s3->subInt64($s12->mulInt(997805, 20));
2652 + $s4 = $s4->addInt64($s12->mulInt(136657, 18));
2653 + $s5 = $s5->subInt64($s12->mulInt(683901, 20));
2654 +
2655 + $carry0 = $s0->shiftRight(21);
2656 + $s1 = $s1->addInt64($carry0);
2657 + $s0 = $s0->subInt64($carry0->shiftLeft(21));
2658 + $carry1 = $s1->shiftRight(21);
2659 + $s2 = $s2->addInt64($carry1);
2660 + $s1 = $s1->subInt64($carry1->shiftLeft(21));
2661 + $carry2 = $s2->shiftRight(21);
2662 + $s3 = $s3->addInt64($carry2);
2663 + $s2 = $s2->subInt64($carry2->shiftLeft(21));
2664 + $carry3 = $s3->shiftRight(21);
2665 + $s4 = $s4->addInt64($carry3);
2666 + $s3 = $s3->subInt64($carry3->shiftLeft(21));
2667 + $carry4 = $s4->shiftRight(21);
2668 + $s5 = $s5->addInt64($carry4);
2669 + $s4 = $s4->subInt64($carry4->shiftLeft(21));
2670 + $carry5 = $s5->shiftRight(21);
2671 + $s6 = $s6->addInt64($carry5);
2672 + $s5 = $s5->subInt64($carry5->shiftLeft(21));
2673 + $carry6 = $s6->shiftRight(21);
2674 + $s7 = $s7->addInt64($carry6);
2675 + $s6 = $s6->subInt64($carry6->shiftLeft(21));
2676 + $carry7 = $s7->shiftRight(21);
2677 + $s8 = $s8->addInt64($carry7);
2678 + $s7 = $s7->subInt64($carry7->shiftLeft(21));
2679 + $carry8 = $s10->shiftRight(21);
2680 + $s9 = $s9->addInt64($carry8);
2681 + $s8 = $s8->subInt64($carry8->shiftLeft(21));
2682 + $carry9 = $s9->shiftRight(21);
2683 + $s10 = $s10->addInt64($carry9);
2684 + $s9 = $s9->subInt64($carry9->shiftLeft(21));
2685 + $carry10 = $s10->shiftRight(21);
2686 + $s11 = $s11->addInt64($carry10);
2687 + $s10 = $s10->subInt64($carry10->shiftLeft(21));
2688 +
2689 + $S0 = $s0->toInt();
2690 + $S1 = $s1->toInt();
2691 + $S2 = $s2->toInt();
2692 + $S3 = $s3->toInt();
2693 + $S4 = $s4->toInt();
2694 + $S5 = $s5->toInt();
2695 + $S6 = $s6->toInt();
2696 + $S7 = $s7->toInt();
2697 + $S8 = $s8->toInt();
2698 + $S9 = $s9->toInt();
2699 + $S10 = $s10->toInt();
2700 + $S11 = $s11->toInt();
2701 +
2702 + /**
2703 + * @var array<int, int>
2704 + */
2705 + $arr = array(
2706 + (int) (0xff & ($S0 >> 0)),
2707 + (int) (0xff & ($S0 >> 8)),
2708 + (int) (0xff & (($S0 >> 16) | ($S1 << 5))),
2709 + (int) (0xff & ($S1 >> 3)),
2710 + (int) (0xff & ($S1 >> 11)),
2711 + (int) (0xff & (($S1 >> 19) | ($S2 << 2))),
2712 + (int) (0xff & ($S2 >> 6)),
2713 + (int) (0xff & (($S2 >> 14) | ($S3 << 7))),
2714 + (int) (0xff & ($S3 >> 1)),
2715 + (int) (0xff & ($S3 >> 9)),
2716 + (int) (0xff & (($S3 >> 17) | ($S4 << 4))),
2717 + (int) (0xff & ($S4 >> 4)),
2718 + (int) (0xff & ($S4 >> 12)),
2719 + (int) (0xff & (($S4 >> 20) | ($S5 << 1))),
2720 + (int) (0xff & ($S5 >> 7)),
2721 + (int) (0xff & (($S5 >> 15) | ($S6 << 6))),
2722 + (int) (0xff & ($S6 >> 2)),
2723 + (int) (0xff & ($S6 >> 10)),
2724 + (int) (0xff & (($S6 >> 18) | ($S7 << 3))),
2725 + (int) (0xff & ($S7 >> 5)),
2726 + (int) (0xff & ($S7 >> 13)),
2727 + (int) (0xff & ($S8 >> 0)),
2728 + (int) (0xff & ($S8 >> 8)),
2729 + (int) (0xff & (($S8 >> 16) | ($S9 << 5))),
2730 + (int) (0xff & ($S9 >> 3)),
2731 + (int) (0xff & ($S9 >> 11)),
2732 + (int) (0xff & (($S9 >> 19) | ($S10 << 2))),
2733 + (int) (0xff & ($S10 >> 6)),
2734 + (int) (0xff & (($S10 >> 14) | ($S11 << 7))),
2735 + (int) (0xff & ($S11 >> 1)),
2736 + (int) (0xff & ($S11 >> 9)),
2737 + (int) (0xff & ($S11 >> 17))
2738 + );
2739 + return self::intArrayToString($arr);
2740 + }
2741 +
2742 + /**
2743 + * @internal You should not use this directly from another application
2744 + *
2745 + * @param string $s
2746 + * @return string
2747 + * @throws SodiumException
2748 + * @throws TypeError
2749 + */
2750 + public static function sc_reduce($s)
2751 + {
2752 + /**
2753 + * @var ParagonIE_Sodium_Core32_Int64 $s0
2754 + * @var ParagonIE_Sodium_Core32_Int64 $s1
2755 + * @var ParagonIE_Sodium_Core32_Int64 $s2
2756 + * @var ParagonIE_Sodium_Core32_Int64 $s3
2757 + * @var ParagonIE_Sodium_Core32_Int64 $s4
2758 + * @var ParagonIE_Sodium_Core32_Int64 $s5
2759 + * @var ParagonIE_Sodium_Core32_Int64 $s6
2760 + * @var ParagonIE_Sodium_Core32_Int64 $s7
2761 + * @var ParagonIE_Sodium_Core32_Int64 $s8
2762 + * @var ParagonIE_Sodium_Core32_Int64 $s9
2763 + * @var ParagonIE_Sodium_Core32_Int64 $s10
2764 + * @var ParagonIE_Sodium_Core32_Int64 $s11
2765 + * @var ParagonIE_Sodium_Core32_Int64 $s12
2766 + * @var ParagonIE_Sodium_Core32_Int64 $s13
2767 + * @var ParagonIE_Sodium_Core32_Int64 $s14
2768 + * @var ParagonIE_Sodium_Core32_Int64 $s15
2769 + * @var ParagonIE_Sodium_Core32_Int64 $s16
2770 + * @var ParagonIE_Sodium_Core32_Int64 $s17
2771 + * @var ParagonIE_Sodium_Core32_Int64 $s18
2772 + * @var ParagonIE_Sodium_Core32_Int64 $s19
2773 + * @var ParagonIE_Sodium_Core32_Int64 $s20
2774 + * @var ParagonIE_Sodium_Core32_Int64 $s21
2775 + * @var ParagonIE_Sodium_Core32_Int64 $s22
2776 + * @var ParagonIE_Sodium_Core32_Int64 $s23
2777 + */
2778 + $s0 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($s, 0, 3)));
2779 + $s1 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 2, 4)) >> 5));
2780 + $s2 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 5, 3)) >> 2));
2781 + $s3 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 7, 4)) >> 7));
2782 + $s4 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 10, 4)) >> 4));
2783 + $s5 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 13, 3)) >> 1));
2784 + $s6 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 15, 4)) >> 6));
2785 + $s7 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 18, 4)) >> 3));
2786 + $s8 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($s, 21, 3)));
2787 + $s9 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 23, 4)) >> 5));
2788 + $s10 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 26, 3)) >> 2));
2789 + $s11 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 28, 4)) >> 7));
2790 + $s12 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 31, 4)) >> 4));
2791 + $s13 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 34, 3)) >> 1));
2792 + $s14 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 36, 4)) >> 6));
2793 + $s15 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 39, 4)) >> 3));
2794 + $s16 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($s, 42, 3)));
2795 + $s17 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 44, 4)) >> 5));
2796 + $s18 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 47, 3)) >> 2));
2797 + $s19 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 49, 4)) >> 7));
2798 + $s20 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 52, 4)) >> 4));
2799 + $s21 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 55, 3)) >> 1));
2800 + $s22 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 57, 4)) >> 6));
2801 + $s23 = ParagonIE_Sodium_Core32_Int64::fromInt(0x1fffffff & (self::load_4(self::substr($s, 60, 4)) >> 3));
2802 +
2803 + $s11 = $s11->addInt64($s23->mulInt(666643, 20));
2804 + $s12 = $s12->addInt64($s23->mulInt(470296, 19));
2805 + $s13 = $s13->addInt64($s23->mulInt(654183, 20));
2806 + $s14 = $s14->subInt64($s23->mulInt(997805, 20));
2807 + $s15 = $s15->addInt64($s23->mulInt(136657, 18));
2808 + $s16 = $s16->subInt64($s23->mulInt(683901, 20));
2809 +
2810 + $s10 = $s10->addInt64($s22->mulInt(666643, 20));
2811 + $s11 = $s11->addInt64($s22->mulInt(470296, 19));
2812 + $s12 = $s12->addInt64($s22->mulInt(654183, 20));
2813 + $s13 = $s13->subInt64($s22->mulInt(997805, 20));
2814 + $s14 = $s14->addInt64($s22->mulInt(136657, 18));
2815 + $s15 = $s15->subInt64($s22->mulInt(683901, 20));
2816 +
2817 + $s9 = $s9->addInt64($s21->mulInt(666643, 20));
2818 + $s10 = $s10->addInt64($s21->mulInt(470296, 19));
2819 + $s11 = $s11->addInt64($s21->mulInt(654183, 20));
2820 + $s12 = $s12->subInt64($s21->mulInt(997805, 20));
2821 + $s13 = $s13->addInt64($s21->mulInt(136657, 18));
2822 + $s14 = $s14->subInt64($s21->mulInt(683901, 20));
2823 +
2824 + $s8 = $s8->addInt64($s20->mulInt(666643, 20));
2825 + $s9 = $s9->addInt64($s20->mulInt(470296, 19));
2826 + $s10 = $s10->addInt64($s20->mulInt(654183, 20));
2827 + $s11 = $s11->subInt64($s20->mulInt(997805, 20));
2828 + $s12 = $s12->addInt64($s20->mulInt(136657, 18));
2829 + $s13 = $s13->subInt64($s20->mulInt(683901, 20));
2830 +
2831 + $s7 = $s7->addInt64($s19->mulInt(666643, 20));
2832 + $s8 = $s8->addInt64($s19->mulInt(470296, 19));
2833 + $s9 = $s9->addInt64($s19->mulInt(654183, 20));
2834 + $s10 = $s10->subInt64($s19->mulInt(997805, 20));
2835 + $s11 = $s11->addInt64($s19->mulInt(136657, 18));
2836 + $s12 = $s12->subInt64($s19->mulInt(683901, 20));
2837 +
2838 + $s6 = $s6->addInt64($s18->mulInt(666643, 20));
2839 + $s7 = $s7->addInt64($s18->mulInt(470296, 19));
2840 + $s8 = $s8->addInt64($s18->mulInt(654183, 20));
2841 + $s9 = $s9->subInt64($s18->mulInt(997805, 20));
2842 + $s10 = $s10->addInt64($s18->mulInt(136657, 18));
2843 + $s11 = $s11->subInt64($s18->mulInt(683901, 20));
2844 +
2845 + $carry6 = $s6->addInt(1 << 20)->shiftRight(21);
2846 + $s7 = $s7->addInt64($carry6);
2847 + $s6 = $s6->subInt64($carry6->shiftLeft(21));
2848 + $carry8 = $s8->addInt(1 << 20)->shiftRight(21);
2849 + $s9 = $s9->addInt64($carry8);
2850 + $s8 = $s8->subInt64($carry8->shiftLeft(21));
2851 + $carry10 = $s10->addInt(1 << 20)->shiftRight(21);
2852 + $s11 = $s11->addInt64($carry10);
2853 + $s10 = $s10->subInt64($carry10->shiftLeft(21));
2854 + $carry12 = $s12->addInt(1 << 20)->shiftRight(21);
2855 + $s13 = $s13->addInt64($carry12);
2856 + $s12 = $s12->subInt64($carry12->shiftLeft(21));
2857 + $carry14 = $s14->addInt(1 << 20)->shiftRight(21);
2858 + $s15 = $s15->addInt64($carry14);
2859 + $s14 = $s14->subInt64($carry14->shiftLeft(21));
2860 + $carry16 = $s16->addInt(1 << 20)->shiftRight(21);
2861 + $s17 = $s17->addInt64($carry16);
2862 + $s16 = $s16->subInt64($carry16->shiftLeft(21));
2863 +
2864 + $carry7 = $s7->addInt(1 << 20)->shiftRight(21);
2865 + $s8 = $s8->addInt64($carry7);
2866 + $s7 = $s7->subInt64($carry7->shiftLeft(21));
2867 + $carry9 = $s9->addInt(1 << 20)->shiftRight(21);
2868 + $s10 = $s10->addInt64($carry9);
2869 + $s9 = $s9->subInt64($carry9->shiftLeft(21));
2870 + $carry11 = $s11->addInt(1 << 20)->shiftRight(21);
2871 + $s12 = $s12->addInt64($carry11);
2872 + $s11 = $s11->subInt64($carry11->shiftLeft(21));
2873 + $carry13 = $s13->addInt(1 << 20)->shiftRight(21);
2874 + $s14 = $s14->addInt64($carry13);
2875 + $s13 = $s13->subInt64($carry13->shiftLeft(21));
2876 + $carry15 = $s15->addInt(1 << 20)->shiftRight(21);
2877 + $s16 = $s16->addInt64($carry15);
2878 + $s15 = $s15->subInt64($carry15->shiftLeft(21));
2879 +
2880 + $s5 = $s5->addInt64($s17->mulInt(666643, 20));
2881 + $s6 = $s6->addInt64($s17->mulInt(470296, 19));
2882 + $s7 = $s7->addInt64($s17->mulInt(654183, 20));
2883 + $s8 = $s8->subInt64($s17->mulInt(997805, 20));
2884 + $s9 = $s9->addInt64($s17->mulInt(136657, 18));
2885 + $s10 = $s10->subInt64($s17->mulInt(683901, 20));
2886 +
2887 + $s4 = $s4->addInt64($s16->mulInt(666643, 20));
2888 + $s5 = $s5->addInt64($s16->mulInt(470296, 19));
2889 + $s6 = $s6->addInt64($s16->mulInt(654183, 20));
2890 + $s7 = $s7->subInt64($s16->mulInt(997805, 20));
2891 + $s8 = $s8->addInt64($s16->mulInt(136657, 18));
2892 + $s9 = $s9->subInt64($s16->mulInt(683901, 20));
2893 +
2894 + $s3 = $s3->addInt64($s15->mulInt(666643, 20));
2895 + $s4 = $s4->addInt64($s15->mulInt(470296, 19));
2896 + $s5 = $s5->addInt64($s15->mulInt(654183, 20));
2897 + $s6 = $s6->subInt64($s15->mulInt(997805, 20));
2898 + $s7 = $s7->addInt64($s15->mulInt(136657, 18));
2899 + $s8 = $s8->subInt64($s15->mulInt(683901, 20));
2900 +
2901 + $s2 = $s2->addInt64($s14->mulInt(666643, 20));
2902 + $s3 = $s3->addInt64($s14->mulInt(470296, 19));
2903 + $s4 = $s4->addInt64($s14->mulInt(654183, 20));
2904 + $s5 = $s5->subInt64($s14->mulInt(997805, 20));
2905 + $s6 = $s6->addInt64($s14->mulInt(136657, 18));
2906 + $s7 = $s7->subInt64($s14->mulInt(683901, 20));
2907 +
2908 + $s1 = $s1->addInt64($s13->mulInt(666643, 20));
2909 + $s2 = $s2->addInt64($s13->mulInt(470296, 19));
2910 + $s3 = $s3->addInt64($s13->mulInt(654183, 20));
2911 + $s4 = $s4->subInt64($s13->mulInt(997805, 20));
2912 + $s5 = $s5->addInt64($s13->mulInt(136657, 18));
2913 + $s6 = $s6->subInt64($s13->mulInt(683901, 20));
2914 +
2915 + $s0 = $s0->addInt64($s12->mulInt(666643, 20));
2916 + $s1 = $s1->addInt64($s12->mulInt(470296, 19));
2917 + $s2 = $s2->addInt64($s12->mulInt(654183, 20));
2918 + $s3 = $s3->subInt64($s12->mulInt(997805, 20));
2919 + $s4 = $s4->addInt64($s12->mulInt(136657, 18));
2920 + $s5 = $s5->subInt64($s12->mulInt(683901, 20));
2921 + $s12 = new ParagonIE_Sodium_Core32_Int64();
2922 +
2923 + $carry0 = $s0->addInt(1 << 20)->shiftRight(21);
2924 + $s1 = $s1->addInt64($carry0);
2925 + $s0 = $s0->subInt64($carry0->shiftLeft(21));
2926 + $carry2 = $s2->addInt(1 << 20)->shiftRight(21);
2927 + $s3 = $s3->addInt64($carry2);
2928 + $s2 = $s2->subInt64($carry2->shiftLeft(21));
2929 + $carry4 = $s4->addInt(1 << 20)->shiftRight(21);
2930 + $s5 = $s5->addInt64($carry4);
2931 + $s4 = $s4->subInt64($carry4->shiftLeft(21));
2932 + $carry6 = $s6->addInt(1 << 20)->shiftRight(21);
2933 + $s7 = $s7->addInt64($carry6);
2934 + $s6 = $s6->subInt64($carry6->shiftLeft(21));
2935 + $carry8 = $s8->addInt(1 << 20)->shiftRight(21);
2936 + $s9 = $s9->addInt64($carry8);
2937 + $s8 = $s8->subInt64($carry8->shiftLeft(21));
2938 + $carry10 = $s10->addInt(1 << 20)->shiftRight(21);
2939 + $s11 = $s11->addInt64($carry10);
2940 + $s10 = $s10->subInt64($carry10->shiftLeft(21));
2941 + $carry1 = $s1->addInt(1 << 20)->shiftRight(21);
2942 + $s2 = $s2->addInt64($carry1);
2943 + $s1 = $s1->subInt64($carry1->shiftLeft(21));
2944 + $carry3 = $s3->addInt(1 << 20)->shiftRight(21);
2945 + $s4 = $s4->addInt64($carry3);
2946 + $s3 = $s3->subInt64($carry3->shiftLeft(21));
2947 + $carry5 = $s5->addInt(1 << 20)->shiftRight(21);
2948 + $s6 = $s6->addInt64($carry5);
2949 + $s5 = $s5->subInt64($carry5->shiftLeft(21));
2950 + $carry7 = $s7->addInt(1 << 20)->shiftRight(21);
2951 + $s8 = $s8->addInt64($carry7);
2952 + $s7 = $s7->subInt64($carry7->shiftLeft(21));
2953 + $carry9 = $s9->addInt(1 << 20)->shiftRight(21);
2954 + $s10 = $s10->addInt64($carry9);
2955 + $s9 = $s9->subInt64($carry9->shiftLeft(21));
2956 + $carry11 = $s11->addInt(1 << 20)->shiftRight(21);
2957 + $s12 = $s12->addInt64($carry11);
2958 + $s11 = $s11->subInt64($carry11->shiftLeft(21));
2959 +
2960 + $s0 = $s0->addInt64($s12->mulInt(666643, 20));
2961 + $s1 = $s1->addInt64($s12->mulInt(470296, 19));
2962 + $s2 = $s2->addInt64($s12->mulInt(654183, 20));
2963 + $s3 = $s3->subInt64($s12->mulInt(997805, 20));
2964 + $s4 = $s4->addInt64($s12->mulInt(136657, 18));
2965 + $s5 = $s5->subInt64($s12->mulInt(683901, 20));
2966 + $s12 = new ParagonIE_Sodium_Core32_Int64();
2967 +
2968 + $carry0 = $s0->shiftRight(21);
2969 + $s1 = $s1->addInt64($carry0);
2970 + $s0 = $s0->subInt64($carry0->shiftLeft(21));
2971 + $carry1 = $s1->shiftRight(21);
2972 + $s2 = $s2->addInt64($carry1);
2973 + $s1 = $s1->subInt64($carry1->shiftLeft(21));
2974 + $carry2 = $s2->shiftRight(21);
2975 + $s3 = $s3->addInt64($carry2);
2976 + $s2 = $s2->subInt64($carry2->shiftLeft(21));
2977 + $carry3 = $s3->shiftRight(21);
2978 + $s4 = $s4->addInt64($carry3);
2979 + $s3 = $s3->subInt64($carry3->shiftLeft(21));
2980 + $carry4 = $s4->shiftRight(21);
2981 + $s5 = $s5->addInt64($carry4);
2982 + $s4 = $s4->subInt64($carry4->shiftLeft(21));
2983 + $carry5 = $s5->shiftRight(21);
2984 + $s6 = $s6->addInt64($carry5);
2985 + $s5 = $s5->subInt64($carry5->shiftLeft(21));
2986 + $carry6 = $s6->shiftRight(21);
2987 + $s7 = $s7->addInt64($carry6);
2988 + $s6 = $s6->subInt64($carry6->shiftLeft(21));
2989 + $carry7 = $s7->shiftRight(21);
2990 + $s8 = $s8->addInt64($carry7);
2991 + $s7 = $s7->subInt64($carry7->shiftLeft(21));
2992 + $carry8 = $s8->shiftRight(21);
2993 + $s9 = $s9->addInt64($carry8);
2994 + $s8 = $s8->subInt64($carry8->shiftLeft(21));
2995 + $carry9 = $s9->shiftRight(21);
2996 + $s10 = $s10->addInt64($carry9);
2997 + $s9 = $s9->subInt64($carry9->shiftLeft(21));
2998 + $carry10 = $s10->shiftRight(21);
2999 + $s11 = $s11->addInt64($carry10);
3000 + $s10 = $s10->subInt64($carry10->shiftLeft(21));
3001 + $carry11 = $s11->shiftRight(21);
3002 + $s12 = $s12->addInt64($carry11);
3003 + $s11 = $s11->subInt64($carry11->shiftLeft(21));
3004 +
3005 + $s0 = $s0->addInt64($s12->mulInt(666643, 20));
3006 + $s1 = $s1->addInt64($s12->mulInt(470296, 19));
3007 + $s2 = $s2->addInt64($s12->mulInt(654183, 20));
3008 + $s3 = $s3->subInt64($s12->mulInt(997805, 20));
3009 + $s4 = $s4->addInt64($s12->mulInt(136657, 18));
3010 + $s5 = $s5->subInt64($s12->mulInt(683901, 20));
3011 +
3012 + $carry0 = $s0->shiftRight(21);
3013 + $s1 = $s1->addInt64($carry0);
3014 + $s0 = $s0->subInt64($carry0->shiftLeft(21));
3015 + $carry1 = $s1->shiftRight(21);
3016 + $s2 = $s2->addInt64($carry1);
3017 + $s1 = $s1->subInt64($carry1->shiftLeft(21));
3018 + $carry2 = $s2->shiftRight(21);
3019 + $s3 = $s3->addInt64($carry2);
3020 + $s2 = $s2->subInt64($carry2->shiftLeft(21));
3021 + $carry3 = $s3->shiftRight(21);
3022 + $s4 = $s4->addInt64($carry3);
3023 + $s3 = $s3->subInt64($carry3->shiftLeft(21));
3024 + $carry4 = $s4->shiftRight(21);
3025 + $s5 = $s5->addInt64($carry4);
3026 + $s4 = $s4->subInt64($carry4->shiftLeft(21));
3027 + $carry5 = $s5->shiftRight(21);
3028 + $s6 = $s6->addInt64($carry5);
3029 + $s5 = $s5->subInt64($carry5->shiftLeft(21));
3030 + $carry6 = $s6->shiftRight(21);
3031 + $s7 = $s7->addInt64($carry6);
3032 + $s6 = $s6->subInt64($carry6->shiftLeft(21));
3033 + $carry7 = $s7->shiftRight(21);
3034 + $s8 = $s8->addInt64($carry7);
3035 + $s7 = $s7->subInt64($carry7->shiftLeft(21));
3036 + $carry8 = $s8->shiftRight(21);
3037 + $s9 = $s9->addInt64($carry8);
3038 + $s8 = $s8->subInt64($carry8->shiftLeft(21));
3039 + $carry9 = $s9->shiftRight(21);
3040 + $s10 = $s10->addInt64($carry9);
3041 + $s9 = $s9->subInt64($carry9->shiftLeft(21));
3042 + $carry10 = $s10->shiftRight(21);
3043 + $s11 = $s11->addInt64($carry10);
3044 + $s10 = $s10->subInt64($carry10->shiftLeft(21));
3045 +
3046 + $S0 = $s0->toInt32()->toInt();
3047 + $S1 = $s1->toInt32()->toInt();
3048 + $S2 = $s2->toInt32()->toInt();
3049 + $S3 = $s3->toInt32()->toInt();
3050 + $S4 = $s4->toInt32()->toInt();
3051 + $S5 = $s5->toInt32()->toInt();
3052 + $S6 = $s6->toInt32()->toInt();
3053 + $S7 = $s7->toInt32()->toInt();
3054 + $S8 = $s8->toInt32()->toInt();
3055 + $S9 = $s9->toInt32()->toInt();
3056 + $S10 = $s10->toInt32()->toInt();
3057 + $S11 = $s11->toInt32()->toInt();
3058 +
3059 + /**
3060 + * @var array<int, int>
3061 + */
3062 + $arr = array(
3063 + (int) ($S0 >> 0),
3064 + (int) ($S0 >> 8),
3065 + (int) (($S0 >> 16) | ($S1 << 5)),
3066 + (int) ($S1 >> 3),
3067 + (int) ($S1 >> 11),
3068 + (int) (($S1 >> 19) | ($S2 << 2)),
3069 + (int) ($S2 >> 6),
3070 + (int) (($S2 >> 14) | ($S3 << 7)),
3071 + (int) ($S3 >> 1),
3072 + (int) ($S3 >> 9),
3073 + (int) (($S3 >> 17) | ($S4 << 4)),
3074 + (int) ($S4 >> 4),
3075 + (int) ($S4 >> 12),
3076 + (int) (($S4 >> 20) | ($S5 << 1)),
3077 + (int) ($S5 >> 7),
3078 + (int) (($S5 >> 15) | ($S6 << 6)),
3079 + (int) ($S6 >> 2),
3080 + (int) ($S6 >> 10),
3081 + (int) (($S6 >> 18) | ($S7 << 3)),
3082 + (int) ($S7 >> 5),
3083 + (int) ($S7 >> 13),
3084 + (int) ($S8 >> 0),
3085 + (int) ($S8 >> 8),
3086 + (int) (($S8 >> 16) | ($S9 << 5)),
3087 + (int) ($S9 >> 3),
3088 + (int) ($S9 >> 11),
3089 + (int) (($S9 >> 19) | ($S10 << 2)),
3090 + (int) ($S10 >> 6),
3091 + (int) (($S10 >> 14) | ($S11 << 7)),
3092 + (int) ($S11 >> 1),
3093 + (int) ($S11 >> 9),
3094 + (int) $S11 >> 17
3095 + );
3096 + return self::intArrayToString($arr);
3097 + }
3098 +
3099 + /**
3100 + * multiply by the order of the main subgroup l = 2^252+27742317777372353535851937790883648493
3101 + *
3102 + * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A
3103 + * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P3
3104 + * @throws SodiumException
3105 + * @throws TypeError
3106 + */
3107 + public static function ge_mul_l(ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A)
3108 + {
3109 + $aslide = array(
3110 + 13, 0, 0, 0, 0, -1, 0, 0, 0, 0, -11, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0,
3111 + 0, 0, 0, -3, 0, 0, 0, 0, -13, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 3, 0,
3112 + 0, 0, 0, -13, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0,
3113 + 0, 0, 11, 0, 0, 0, 0, -13, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, -1,
3114 + 0, 0, 0, 0, 3, 0, 0, 0, 0, -11, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0,
3115 + 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 7, 0, 0, 0, 0, 5, 0, 0, 0, 0,
3116 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3117 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3118 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3119 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3120 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3121 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
3122 + );
3123 +
3124 + /** @var array<int, ParagonIE_Sodium_Core32_Curve25519_Ge_Cached> $Ai size 8 */
3125 + $Ai = array();
3126 +
3127 + # ge_p3_to_cached(&Ai[0], A);
3128 + $Ai[0] = self::ge_p3_to_cached($A);
3129 + # ge_p3_dbl(&t, A);
3130 + $t = self::ge_p3_dbl($A);
3131 + # ge_p1p1_to_p3(&A2, &t);
3132 + $A2 = self::ge_p1p1_to_p3($t);
3133 +
3134 + for ($i = 1; $i < 8; ++$i) {
3135 + # ge_add(&t, &A2, &Ai[0]);
3136 + $t = self::ge_add($A2, $Ai[$i - 1]);
3137 + # ge_p1p1_to_p3(&u, &t);
3138 + $u = self::ge_p1p1_to_p3($t);
3139 + # ge_p3_to_cached(&Ai[i], &u);
3140 + $Ai[$i] = self::ge_p3_to_cached($u);
3141 + }
3142 +
3143 + $r = self::ge_p3_0();
3144 + for ($i = 252; $i >= 0; --$i) {
3145 + $t = self::ge_p3_dbl($r);
3146 + if ($aslide[$i] > 0) {
3147 + # ge_p1p1_to_p3(&u, &t);
3148 + $u = self::ge_p1p1_to_p3($t);
3149 + # ge_add(&t, &u, &Ai[aslide[i] / 2]);
3150 + $t = self::ge_add($u, $Ai[(int)($aslide[$i] / 2)]);
3151 + } elseif ($aslide[$i] < 0) {
3152 + # ge_p1p1_to_p3(&u, &t);
3153 + $u = self::ge_p1p1_to_p3($t);
3154 + # ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]);
3155 + $t = self::ge_sub($u, $Ai[(int)(-$aslide[$i] / 2)]);
3156 + }
3157 + }
3158 + # ge_p1p1_to_p3(r, &t);
3159 + return self::ge_p1p1_to_p3($t);
3160 + }
3161 + }
3162 +