balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

SipHash.php (6613B)


      1 <?php
      2 
      3 if (class_exists('ParagonIE_Sodium_Core32_SipHash', false)) {
      4     return;
      5 }
      6 
      7 /**
      8  * Class ParagonIE_SodiumCompat_Core32_SipHash
      9  *
     10  * Only uses 32-bit arithmetic, while the original SipHash used 64-bit integers
     11  */
     12 class ParagonIE_Sodium_Core32_SipHash extends ParagonIE_Sodium_Core32_Util
     13 {
     14     /**
     15      * @internal You should not use this directly from another application
     16      *
     17      * @param array<int, ParagonIE_Sodium_Core32_Int64> $v
     18      * @return array<int, ParagonIE_Sodium_Core32_Int64>
     19      */
     20     public static function sipRound(array $v)
     21     {
     22         # v0 += v1;
     23         $v[0] = $v[0]->addInt64($v[1]);
     24 
     25         # v1 = ROTL(v1, 13);
     26         $v[1] = $v[1]->rotateLeft(13);
     27 
     28         #  v1 ^= v0;
     29         $v[1] = $v[1]->xorInt64($v[0]);
     30 
     31         #  v0=ROTL(v0,32);
     32         $v[0] = $v[0]->rotateLeft(32);
     33 
     34         # v2 += v3;
     35         $v[2] = $v[2]->addInt64($v[3]);
     36 
     37         # v3=ROTL(v3,16);
     38         $v[3] = $v[3]->rotateLeft(16);
     39 
     40         #  v3 ^= v2;
     41         $v[3] = $v[3]->xorInt64($v[2]);
     42 
     43         # v0 += v3;
     44         $v[0] = $v[0]->addInt64($v[3]);
     45 
     46         # v3=ROTL(v3,21);
     47         $v[3] = $v[3]->rotateLeft(21);
     48 
     49         # v3 ^= v0;
     50         $v[3] = $v[3]->xorInt64($v[0]);
     51 
     52         # v2 += v1;
     53         $v[2] = $v[2]->addInt64($v[1]);
     54 
     55         # v1=ROTL(v1,17);
     56         $v[1] = $v[1]->rotateLeft(17);
     57 
     58         #  v1 ^= v2;
     59         $v[1] = $v[1]->xorInt64($v[2]);
     60 
     61         # v2=ROTL(v2,32)
     62         $v[2] = $v[2]->rotateLeft(32);
     63 
     64         return $v;
     65     }
     66 
     67     /**
     68      * @internal You should not use this directly from another application
     69      *
     70      * @param string $in
     71      * @param string $key
     72      * @return string
     73      * @throws SodiumException
     74      * @throws TypeError
     75      */
     76     public static function sipHash24($in, $key)
     77     {
     78         $inlen = self::strlen($in);
     79 
     80         # /* "somepseudorandomlygeneratedbytes" */
     81         # u64 v0 = 0x736f6d6570736575ULL;
     82         # u64 v1 = 0x646f72616e646f6dULL;
     83         # u64 v2 = 0x6c7967656e657261ULL;
     84         # u64 v3 = 0x7465646279746573ULL;
     85         $v = array(
     86             new ParagonIE_Sodium_Core32_Int64(
     87                 array(0x736f, 0x6d65, 0x7073, 0x6575)
     88             ),
     89             new ParagonIE_Sodium_Core32_Int64(
     90                 array(0x646f, 0x7261, 0x6e64, 0x6f6d)
     91             ),
     92             new ParagonIE_Sodium_Core32_Int64(
     93                 array(0x6c79, 0x6765, 0x6e65, 0x7261)
     94             ),
     95             new ParagonIE_Sodium_Core32_Int64(
     96                 array(0x7465, 0x6462, 0x7974, 0x6573)
     97             )
     98         );
     99 
    100         # u64 k0 = LOAD64_LE( k );
    101         # u64 k1 = LOAD64_LE( k + 8 );
    102         $k = array(
    103             ParagonIE_Sodium_Core32_Int64::fromReverseString(
    104                 self::substr($key, 0, 8)
    105             ),
    106             ParagonIE_Sodium_Core32_Int64::fromReverseString(
    107                 self::substr($key, 8, 8)
    108             )
    109         );
    110 
    111         # b = ( ( u64 )inlen ) << 56;
    112         $b = new ParagonIE_Sodium_Core32_Int64(
    113             array(($inlen << 8) & 0xffff, 0, 0, 0)
    114         );
    115 
    116         # v3 ^= k1;
    117         $v[3] = $v[3]->xorInt64($k[1]);
    118         # v2 ^= k0;
    119         $v[2] = $v[2]->xorInt64($k[0]);
    120         # v1 ^= k1;
    121         $v[1] = $v[1]->xorInt64($k[1]);
    122         # v0 ^= k0;
    123         $v[0] = $v[0]->xorInt64($k[0]);
    124 
    125         $left = $inlen;
    126         # for ( ; in != end; in += 8 )
    127         while ($left >= 8) {
    128             # m = LOAD64_LE( in );
    129             $m = ParagonIE_Sodium_Core32_Int64::fromReverseString(
    130                 self::substr($in, 0, 8)
    131             );
    132 
    133             # v3 ^= m;
    134             $v[3] = $v[3]->xorInt64($m);
    135 
    136             # SIPROUND;
    137             # SIPROUND;
    138             $v = self::sipRound($v);
    139             $v = self::sipRound($v);
    140 
    141             # v0 ^= m;
    142             $v[0] = $v[0]->xorInt64($m);
    143 
    144             $in = self::substr($in, 8);
    145             $left -= 8;
    146         }
    147 
    148         # switch( left )
    149         #  {
    150         #     case 7: b |= ( ( u64 )in[ 6] )  << 48;
    151         #     case 6: b |= ( ( u64 )in[ 5] )  << 40;
    152         #     case 5: b |= ( ( u64 )in[ 4] )  << 32;
    153         #     case 4: b |= ( ( u64 )in[ 3] )  << 24;
    154         #     case 3: b |= ( ( u64 )in[ 2] )  << 16;
    155         #     case 2: b |= ( ( u64 )in[ 1] )  <<  8;
    156         #     case 1: b |= ( ( u64 )in[ 0] ); break;
    157         #     case 0: break;
    158         # }
    159         switch ($left) {
    160             case 7:
    161                 $b = $b->orInt64(
    162                     ParagonIE_Sodium_Core32_Int64::fromInts(
    163                         0, self::chrToInt($in[6]) << 16
    164                     )
    165                 );
    166             case 6:
    167                 $b = $b->orInt64(
    168                     ParagonIE_Sodium_Core32_Int64::fromInts(
    169                         0, self::chrToInt($in[5]) << 8
    170                     )
    171                 );
    172             case 5:
    173                 $b = $b->orInt64(
    174                     ParagonIE_Sodium_Core32_Int64::fromInts(
    175                         0, self::chrToInt($in[4])
    176                     )
    177                 );
    178             case 4:
    179                 $b = $b->orInt64(
    180                     ParagonIE_Sodium_Core32_Int64::fromInts(
    181                         self::chrToInt($in[3]) << 24, 0
    182                     )
    183                 );
    184             case 3:
    185                 $b = $b->orInt64(
    186                     ParagonIE_Sodium_Core32_Int64::fromInts(
    187                         self::chrToInt($in[2]) << 16, 0
    188                     )
    189                 );
    190             case 2:
    191                 $b = $b->orInt64(
    192                     ParagonIE_Sodium_Core32_Int64::fromInts(
    193                         self::chrToInt($in[1]) << 8, 0
    194                     )
    195                 );
    196             case 1:
    197                 $b = $b->orInt64(
    198                     ParagonIE_Sodium_Core32_Int64::fromInts(
    199                         self::chrToInt($in[0]), 0
    200                     )
    201                 );
    202             case 0:
    203                 break;
    204         }
    205 
    206         # v3 ^= b;
    207         $v[3] = $v[3]->xorInt64($b);
    208 
    209         # SIPROUND;
    210         # SIPROUND;
    211         $v = self::sipRound($v);
    212         $v = self::sipRound($v);
    213 
    214         # v0 ^= b;
    215         $v[0] = $v[0]->xorInt64($b);
    216 
    217         // Flip the lower 8 bits of v2 which is ($v[4], $v[5]) in our implementation
    218         # v2 ^= 0xff;
    219         $v[2]->limbs[3] ^= 0xff;
    220 
    221         # SIPROUND;
    222         # SIPROUND;
    223         # SIPROUND;
    224         # SIPROUND;
    225         $v = self::sipRound($v);
    226         $v = self::sipRound($v);
    227         $v = self::sipRound($v);
    228         $v = self::sipRound($v);
    229 
    230         # b = v0 ^ v1 ^ v2 ^ v3;
    231         # STORE64_LE( out, b );
    232         return $v[0]
    233             ->xorInt64($v[1])
    234             ->xorInt64($v[2])
    235             ->xorInt64($v[3])
    236             ->toReverseString();
    237     }
    238 }