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