wp/wp-includes/sodium_compat/src/Core32/X25519.php
changeset 9 177826044cd9
child 16 a86126ab1dd4
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
       
     1 <?php
       
     2 
       
     3 if (class_exists('ParagonIE_Sodium_Core32_X25519', false)) {
       
     4     return;
       
     5 }
       
     6 
       
     7 /**
       
     8  * Class ParagonIE_Sodium_Core32_X25519
       
     9  */
       
    10 abstract class ParagonIE_Sodium_Core32_X25519 extends ParagonIE_Sodium_Core32_Curve25519
       
    11 {
       
    12     /**
       
    13      * Alters the objects passed to this method in place.
       
    14      *
       
    15      * @internal You should not use this directly from another application
       
    16      *
       
    17      * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
       
    18      * @param ParagonIE_Sodium_Core32_Curve25519_Fe $g
       
    19      * @param int $b
       
    20      * @return void
       
    21      * @throws SodiumException
       
    22      * @throws TypeError
       
    23      * @psalm-suppress MixedMethodCall
       
    24      */
       
    25     public static function fe_cswap(
       
    26         ParagonIE_Sodium_Core32_Curve25519_Fe $f,
       
    27         ParagonIE_Sodium_Core32_Curve25519_Fe $g,
       
    28         $b = 0
       
    29     ) {
       
    30         $f0 = (int) $f[0]->toInt();
       
    31         $f1 = (int) $f[1]->toInt();
       
    32         $f2 = (int) $f[2]->toInt();
       
    33         $f3 = (int) $f[3]->toInt();
       
    34         $f4 = (int) $f[4]->toInt();
       
    35         $f5 = (int) $f[5]->toInt();
       
    36         $f6 = (int) $f[6]->toInt();
       
    37         $f7 = (int) $f[7]->toInt();
       
    38         $f8 = (int) $f[8]->toInt();
       
    39         $f9 = (int) $f[9]->toInt();
       
    40         $g0 = (int) $g[0]->toInt();
       
    41         $g1 = (int) $g[1]->toInt();
       
    42         $g2 = (int) $g[2]->toInt();
       
    43         $g3 = (int) $g[3]->toInt();
       
    44         $g4 = (int) $g[4]->toInt();
       
    45         $g5 = (int) $g[5]->toInt();
       
    46         $g6 = (int) $g[6]->toInt();
       
    47         $g7 = (int) $g[7]->toInt();
       
    48         $g8 = (int) $g[8]->toInt();
       
    49         $g9 = (int) $g[9]->toInt();
       
    50         $b = -$b;
       
    51         /** @var int $x0 */
       
    52         $x0 = ($f0 ^ $g0) & $b;
       
    53         /** @var int $x1 */
       
    54         $x1 = ($f1 ^ $g1) & $b;
       
    55         /** @var int $x2 */
       
    56         $x2 = ($f2 ^ $g2) & $b;
       
    57         /** @var int $x3 */
       
    58         $x3 = ($f3 ^ $g3) & $b;
       
    59         /** @var int $x4 */
       
    60         $x4 = ($f4 ^ $g4) & $b;
       
    61         /** @var int $x5 */
       
    62         $x5 = ($f5 ^ $g5) & $b;
       
    63         /** @var int $x6 */
       
    64         $x6 = ($f6 ^ $g6) & $b;
       
    65         /** @var int $x7 */
       
    66         $x7 = ($f7 ^ $g7) & $b;
       
    67         /** @var int $x8 */
       
    68         $x8 = ($f8 ^ $g8) & $b;
       
    69         /** @var int $x9 */
       
    70         $x9 = ($f9 ^ $g9) & $b;
       
    71         $f[0] = ParagonIE_Sodium_Core32_Int32::fromInt($f0 ^ $x0);
       
    72         $f[1] = ParagonIE_Sodium_Core32_Int32::fromInt($f1 ^ $x1);
       
    73         $f[2] = ParagonIE_Sodium_Core32_Int32::fromInt($f2 ^ $x2);
       
    74         $f[3] = ParagonIE_Sodium_Core32_Int32::fromInt($f3 ^ $x3);
       
    75         $f[4] = ParagonIE_Sodium_Core32_Int32::fromInt($f4 ^ $x4);
       
    76         $f[5] = ParagonIE_Sodium_Core32_Int32::fromInt($f5 ^ $x5);
       
    77         $f[6] = ParagonIE_Sodium_Core32_Int32::fromInt($f6 ^ $x6);
       
    78         $f[7] = ParagonIE_Sodium_Core32_Int32::fromInt($f7 ^ $x7);
       
    79         $f[8] = ParagonIE_Sodium_Core32_Int32::fromInt($f8 ^ $x8);
       
    80         $f[9] = ParagonIE_Sodium_Core32_Int32::fromInt($f9 ^ $x9);
       
    81         $g[0] = ParagonIE_Sodium_Core32_Int32::fromInt($g0 ^ $x0);
       
    82         $g[1] = ParagonIE_Sodium_Core32_Int32::fromInt($g1 ^ $x1);
       
    83         $g[2] = ParagonIE_Sodium_Core32_Int32::fromInt($g2 ^ $x2);
       
    84         $g[3] = ParagonIE_Sodium_Core32_Int32::fromInt($g3 ^ $x3);
       
    85         $g[4] = ParagonIE_Sodium_Core32_Int32::fromInt($g4 ^ $x4);
       
    86         $g[5] = ParagonIE_Sodium_Core32_Int32::fromInt($g5 ^ $x5);
       
    87         $g[6] = ParagonIE_Sodium_Core32_Int32::fromInt($g6 ^ $x6);
       
    88         $g[7] = ParagonIE_Sodium_Core32_Int32::fromInt($g7 ^ $x7);
       
    89         $g[8] = ParagonIE_Sodium_Core32_Int32::fromInt($g8 ^ $x8);
       
    90         $g[9] = ParagonIE_Sodium_Core32_Int32::fromInt($g9 ^ $x9);
       
    91     }
       
    92 
       
    93     /**
       
    94      * @internal You should not use this directly from another application
       
    95      *
       
    96      * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
       
    97      * @return ParagonIE_Sodium_Core32_Curve25519_Fe
       
    98      * @throws SodiumException
       
    99      * @throws TypeError
       
   100      * @psalm-suppress MixedAssignment
       
   101      * @psalm-suppress MixedMethodCall
       
   102      */
       
   103     public static function fe_mul121666(ParagonIE_Sodium_Core32_Curve25519_Fe $f)
       
   104     {
       
   105         /** @var array<int, ParagonIE_Sodium_Core32_Int64> $h */
       
   106         $h = array();
       
   107         for ($i = 0; $i < 10; ++$i) {
       
   108             $h[$i] = $f[$i]->toInt64()->mulInt(121666, 17);
       
   109         }
       
   110 
       
   111         $carry9 = $h[9]->addInt(1 << 24)->shiftRight(25);
       
   112         $h[0] = $h[0]->addInt64($carry9->mulInt(19, 5));
       
   113         $h[9] = $h[9]->subInt64($carry9->shiftLeft(25));
       
   114 
       
   115         $carry1 = $h[1]->addInt(1 << 24)->shiftRight(25);
       
   116         $h[2] = $h[2]->addInt64($carry1);
       
   117         $h[1] = $h[1]->subInt64($carry1->shiftLeft(25));
       
   118 
       
   119         $carry3 = $h[3]->addInt(1 << 24)->shiftRight(25);
       
   120         $h[4] = $h[4]->addInt64($carry3);
       
   121         $h[3] = $h[3]->subInt64($carry3->shiftLeft(25));
       
   122 
       
   123         $carry5 = $h[5]->addInt(1 << 24)->shiftRight(25);
       
   124         $h[6] = $h[6]->addInt64($carry5);
       
   125         $h[5] = $h[5]->subInt64($carry5->shiftLeft(25));
       
   126 
       
   127         $carry7 = $h[7]->addInt(1 << 24)->shiftRight(25);
       
   128         $h[8] = $h[8]->addInt64($carry7);
       
   129         $h[7] = $h[7]->subInt64($carry7->shiftLeft(25));
       
   130 
       
   131         $carry0 = $h[0]->addInt(1 << 25)->shiftRight(26);
       
   132         $h[1] = $h[1]->addInt64($carry0);
       
   133         $h[0] = $h[0]->subInt64($carry0->shiftLeft(26));
       
   134 
       
   135         $carry2 = $h[2]->addInt(1 << 25)->shiftRight(26);
       
   136         $h[3] = $h[3]->addInt64($carry2);
       
   137         $h[2] = $h[2]->subInt64($carry2->shiftLeft(26));
       
   138 
       
   139         $carry4 = $h[4]->addInt(1 << 25)->shiftRight(26);
       
   140         $h[5] = $h[5]->addInt64($carry4);
       
   141         $h[4] = $h[4]->subInt64($carry4->shiftLeft(26));
       
   142 
       
   143         $carry6 = $h[6]->addInt(1 << 25)->shiftRight(26);
       
   144         $h[7] = $h[7]->addInt64($carry6);
       
   145         $h[6] = $h[6]->subInt64($carry6->shiftLeft(26));
       
   146 
       
   147         $carry8 = $h[8]->addInt(1 << 25)->shiftRight(26);
       
   148         $h[9] = $h[9]->addInt64($carry8);
       
   149         $h[8] = $h[8]->subInt64($carry8->shiftLeft(26));
       
   150 
       
   151         for ($i = 0; $i < 10; ++$i) {
       
   152             $h[$i] = $h[$i]->toInt32();
       
   153         }
       
   154         /** @var array<int, ParagonIE_Sodium_Core32_Int32> $h */
       
   155         return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray($h);
       
   156     }
       
   157 
       
   158     /**
       
   159      * @internal You should not use this directly from another application
       
   160      *
       
   161      * Inline comments preceded by # are from libsodium's ref10 code.
       
   162      *
       
   163      * @param string $n
       
   164      * @param string $p
       
   165      * @return string
       
   166      * @throws SodiumException
       
   167      * @throws TypeError
       
   168      */
       
   169     public static function crypto_scalarmult_curve25519_ref10($n, $p)
       
   170     {
       
   171         # for (i = 0;i < 32;++i) e[i] = n[i];
       
   172         $e = '' . $n;
       
   173         # e[0] &= 248;
       
   174         $e[0] = self::intToChr(
       
   175             self::chrToInt($e[0]) & 248
       
   176         );
       
   177         # e[31] &= 127;
       
   178         # e[31] |= 64;
       
   179         $e[31] = self::intToChr(
       
   180             (self::chrToInt($e[31]) & 127) | 64
       
   181         );
       
   182         # fe_frombytes(x1,p);
       
   183         $x1 = self::fe_frombytes($p);
       
   184         # fe_1(x2);
       
   185         $x2 = self::fe_1();
       
   186         # fe_0(z2);
       
   187         $z2 = self::fe_0();
       
   188         # fe_copy(x3,x1);
       
   189         $x3 = self::fe_copy($x1);
       
   190         # fe_1(z3);
       
   191         $z3 = self::fe_1();
       
   192 
       
   193         # swap = 0;
       
   194         /** @var int $swap */
       
   195         $swap = 0;
       
   196 
       
   197         # for (pos = 254;pos >= 0;--pos) {
       
   198         for ($pos = 254; $pos >= 0; --$pos) {
       
   199             # b = e[pos / 8] >> (pos & 7);
       
   200             /** @var int $b */
       
   201             $b = self::chrToInt(
       
   202                     $e[(int) floor($pos / 8)]
       
   203                 ) >> ($pos & 7);
       
   204             # b &= 1;
       
   205             $b &= 1;
       
   206 
       
   207             # swap ^= b;
       
   208             $swap ^= $b;
       
   209 
       
   210             # fe_cswap(x2,x3,swap);
       
   211             self::fe_cswap($x2, $x3, $swap);
       
   212 
       
   213             # fe_cswap(z2,z3,swap);
       
   214             self::fe_cswap($z2, $z3, $swap);
       
   215 
       
   216             # swap = b;
       
   217             /** @var int $swap */
       
   218             $swap = $b;
       
   219 
       
   220             # fe_sub(tmp0,x3,z3);
       
   221             $tmp0 = self::fe_sub($x3, $z3);
       
   222 
       
   223             # fe_sub(tmp1,x2,z2);
       
   224             $tmp1 = self::fe_sub($x2, $z2);
       
   225 
       
   226             # fe_add(x2,x2,z2);
       
   227             $x2 = self::fe_add($x2, $z2);
       
   228 
       
   229             # fe_add(z2,x3,z3);
       
   230             $z2 = self::fe_add($x3, $z3);
       
   231 
       
   232             # fe_mul(z3,tmp0,x2);
       
   233             $z3 = self::fe_mul($tmp0, $x2);
       
   234 
       
   235             # fe_mul(z2,z2,tmp1);
       
   236             $z2 = self::fe_mul($z2, $tmp1);
       
   237 
       
   238             # fe_sq(tmp0,tmp1);
       
   239             $tmp0 = self::fe_sq($tmp1);
       
   240 
       
   241             # fe_sq(tmp1,x2);
       
   242             $tmp1 = self::fe_sq($x2);
       
   243 
       
   244             # fe_add(x3,z3,z2);
       
   245             $x3 = self::fe_add($z3, $z2);
       
   246 
       
   247             # fe_sub(z2,z3,z2);
       
   248             $z2 = self::fe_sub($z3, $z2);
       
   249 
       
   250             # fe_mul(x2,tmp1,tmp0);
       
   251             $x2 = self::fe_mul($tmp1, $tmp0);
       
   252 
       
   253             # fe_sub(tmp1,tmp1,tmp0);
       
   254             $tmp1 = self::fe_sub($tmp1, $tmp0);
       
   255 
       
   256             # fe_sq(z2,z2);
       
   257             $z2 = self::fe_sq($z2);
       
   258 
       
   259             # fe_mul121666(z3,tmp1);
       
   260             $z3 = self::fe_mul121666($tmp1);
       
   261 
       
   262             # fe_sq(x3,x3);
       
   263             $x3 = self::fe_sq($x3);
       
   264 
       
   265             # fe_add(tmp0,tmp0,z3);
       
   266             $tmp0 = self::fe_add($tmp0, $z3);
       
   267 
       
   268             # fe_mul(z3,x1,z2);
       
   269             $z3 = self::fe_mul($x1, $z2);
       
   270 
       
   271             # fe_mul(z2,tmp1,tmp0);
       
   272             $z2 = self::fe_mul($tmp1, $tmp0);
       
   273         }
       
   274 
       
   275         # fe_cswap(x2,x3,swap);
       
   276         self::fe_cswap($x2, $x3, $swap);
       
   277 
       
   278         # fe_cswap(z2,z3,swap);
       
   279         self::fe_cswap($z2, $z3, $swap);
       
   280 
       
   281         # fe_invert(z2,z2);
       
   282         $z2 = self::fe_invert($z2);
       
   283 
       
   284         # fe_mul(x2,x2,z2);
       
   285         $x2 = self::fe_mul($x2, $z2);
       
   286         # fe_tobytes(q,x2);
       
   287         return (string) self::fe_tobytes($x2);
       
   288     }
       
   289 
       
   290     /**
       
   291      * @internal You should not use this directly from another application
       
   292      *
       
   293      * @param ParagonIE_Sodium_Core32_Curve25519_Fe $edwardsY
       
   294      * @param ParagonIE_Sodium_Core32_Curve25519_Fe $edwardsZ
       
   295      * @return ParagonIE_Sodium_Core32_Curve25519_Fe
       
   296      * @throws SodiumException
       
   297      * @throws TypeError
       
   298      */
       
   299     public static function edwards_to_montgomery(
       
   300         ParagonIE_Sodium_Core32_Curve25519_Fe $edwardsY,
       
   301         ParagonIE_Sodium_Core32_Curve25519_Fe $edwardsZ
       
   302     ) {
       
   303         $tempX = self::fe_add($edwardsZ, $edwardsY);
       
   304         $tempZ = self::fe_sub($edwardsZ, $edwardsY);
       
   305         $tempZ = self::fe_invert($tempZ);
       
   306         return self::fe_mul($tempX, $tempZ);
       
   307     }
       
   308 
       
   309     /**
       
   310      * @internal You should not use this directly from another application
       
   311      *
       
   312      * @param string $n
       
   313      * @return string
       
   314      * @throws SodiumException
       
   315      * @throws TypeError
       
   316      */
       
   317     public static function crypto_scalarmult_curve25519_ref10_base($n)
       
   318     {
       
   319         # for (i = 0;i < 32;++i) e[i] = n[i];
       
   320         $e = '' . $n;
       
   321 
       
   322         # e[0] &= 248;
       
   323         $e[0] = self::intToChr(
       
   324             self::chrToInt($e[0]) & 248
       
   325         );
       
   326 
       
   327         # e[31] &= 127;
       
   328         # e[31] |= 64;
       
   329         $e[31] = self::intToChr(
       
   330             (self::chrToInt($e[31]) & 127) | 64
       
   331         );
       
   332 
       
   333         $A = self::ge_scalarmult_base($e);
       
   334         if (
       
   335             !($A->Y instanceof ParagonIE_Sodium_Core32_Curve25519_Fe)
       
   336                 ||
       
   337             !($A->Z instanceof ParagonIE_Sodium_Core32_Curve25519_Fe)
       
   338         ) {
       
   339             throw new TypeError('Null points encountered');
       
   340         }
       
   341         $pk = self::edwards_to_montgomery($A->Y, $A->Z);
       
   342         return self::fe_tobytes($pk);
       
   343     }
       
   344 }