Diff: STRATO-apps/wordpress_03/app/wp-includes/sodium_compat/src/Core32/Curve25519.php
Keine Baseline-Datei – Diff nur gegen leer.
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
+