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