You are here

public static function ParagonIE_Sodium_Core_SipHash::sipHash24 in Automatic Updates 7

Same name and namespace in other branches
  1. 8 vendor/paragonie/sodium_compat/src/Core/SipHash.php \ParagonIE_Sodium_Core_SipHash::sipHash24()

Implements Siphash-2-4 using only 32-bit numbers.

When we split an int into two, the higher bits go to the lower index. e.g. 0xDEADBEEFAB10C92D becomes [ 0 => 0xDEADBEEF, 1 => 0xAB10C92D ].

@internal You should not use this directly from another application

Parameters

string $in:

string $key:

Return value

string

Throws

SodiumException

TypeError

1 call to ParagonIE_Sodium_Core_SipHash::sipHash24()
ParagonIE_Sodium_Compat::crypto_shorthash in vendor/paragonie/sodium_compat/src/Compat.php
Calculates a SipHash-2-4 hash of a message for a given key.

File

vendor/paragonie/sodium_compat/src/Core/SipHash.php, line 162

Class

ParagonIE_Sodium_Core_SipHash
Class ParagonIE_SodiumCompat_Core_SipHash

Code

public static function sipHash24($in, $key) {
  $inlen = self::strlen($in);

  # /* "somepseudorandomlygeneratedbytes" */

  # u64 v0 = 0x736f6d6570736575ULL;

  # u64 v1 = 0x646f72616e646f6dULL;

  # u64 v2 = 0x6c7967656e657261ULL;

  # u64 v3 = 0x7465646279746573ULL;
  $v = array(
    0x736f6d65,
    // 0
    0x70736575,
    // 1
    0x646f7261,
    // 2
    0x6e646f6d,
    // 3
    0x6c796765,
    // 4
    0x6e657261,
    // 5
    0x74656462,
    // 6
    0x79746573,
  );

  // v0 => $v[0], $v[1]
  // v1 => $v[2], $v[3]
  // v2 => $v[4], $v[5]
  // v3 => $v[6], $v[7]

  # u64 k0 = LOAD64_LE( k );

  # u64 k1 = LOAD64_LE( k + 8 );
  $k = array(
    self::load_4(self::substr($key, 4, 4)),
    self::load_4(self::substr($key, 0, 4)),
    self::load_4(self::substr($key, 12, 4)),
    self::load_4(self::substr($key, 8, 4)),
  );

  // k0 => $k[0], $k[1]
  // k1 => $k[2], $k[3]

  # b = ( ( u64 )inlen ) << 56;
  $b = array(
    $inlen << 24,
    0,
  );

  // See docblock for why the 0th index gets the higher bits.

  # v3 ^= k1;
  $v[6] ^= $k[2];
  $v[7] ^= $k[3];

  # v2 ^= k0;
  $v[4] ^= $k[0];
  $v[5] ^= $k[1];

  # v1 ^= k1;
  $v[2] ^= $k[2];
  $v[3] ^= $k[3];

  # v0 ^= k0;
  $v[0] ^= $k[0];
  $v[1] ^= $k[1];
  $left = $inlen;

  # for ( ; in != end; in += 8 )
  while ($left >= 8) {

    # m = LOAD64_LE( in );
    $m = array(
      self::load_4(self::substr($in, 4, 4)),
      self::load_4(self::substr($in, 0, 4)),
    );

    # v3 ^= m;
    $v[6] ^= $m[0];
    $v[7] ^= $m[1];

    # SIPROUND;

    # SIPROUND;
    $v = self::sipRound($v);
    $v = self::sipRound($v);

    # v0 ^= m;
    $v[0] ^= $m[0];
    $v[1] ^= $m[1];
    $in = self::substr($in, 8);
    $left -= 8;
  }

  # switch( left )

  #  {

  #     case 7: b |= ( ( u64 )in[ 6] )  << 48;

  #     case 6: b |= ( ( u64 )in[ 5] )  << 40;

  #     case 5: b |= ( ( u64 )in[ 4] )  << 32;

  #     case 4: b |= ( ( u64 )in[ 3] )  << 24;

  #     case 3: b |= ( ( u64 )in[ 2] )  << 16;

  #     case 2: b |= ( ( u64 )in[ 1] )  <<  8;

  #     case 1: b |= ( ( u64 )in[ 0] ); break;

  #     case 0: break;

  # }
  switch ($left) {
    case 7:
      $b[0] |= self::chrToInt($in[6]) << 16;
    case 6:
      $b[0] |= self::chrToInt($in[5]) << 8;
    case 5:
      $b[0] |= self::chrToInt($in[4]);
    case 4:
      $b[1] |= self::chrToInt($in[3]) << 24;
    case 3:
      $b[1] |= self::chrToInt($in[2]) << 16;
    case 2:
      $b[1] |= self::chrToInt($in[1]) << 8;
    case 1:
      $b[1] |= self::chrToInt($in[0]);
    case 0:
      break;
  }

  // See docblock for why the 0th index gets the higher bits.

  # v3 ^= b;
  $v[6] ^= $b[0];
  $v[7] ^= $b[1];

  # SIPROUND;

  # SIPROUND;
  $v = self::sipRound($v);
  $v = self::sipRound($v);

  # v0 ^= b;
  $v[0] ^= $b[0];
  $v[1] ^= $b[1];

  // Flip the lower 8 bits of v2 which is ($v[4], $v[5]) in our implementation

  # v2 ^= 0xff;
  $v[5] ^= 0xff;

  # SIPROUND;

  # SIPROUND;

  # SIPROUND;

  # SIPROUND;
  $v = self::sipRound($v);
  $v = self::sipRound($v);
  $v = self::sipRound($v);
  $v = self::sipRound($v);

  # b = v0 ^ v1 ^ v2 ^ v3;

  # STORE64_LE( out, b );
  return self::store32_le($v[1] ^ $v[3] ^ $v[5] ^ $v[7]) . self::store32_le($v[0] ^ $v[2] ^ $v[4] ^ $v[6]);
}