1<?php
2
3if (class_exists('ParagonIE_Sodium_Core_HSalsa20', false)) {
4 return;
5}
6
7/**
8 * Class ParagonIE_Sodium_Core_HSalsa20
9 */
10abstract class ParagonIE_Sodium_Core_HSalsa20 extends ParagonIE_Sodium_Core_Salsa20
11{
12 /**
13 * Calculate an hsalsa20 hash of a single block
14 *
15 * HSalsa20 doesn't have a counter and will never be used for more than
16 * one block (used to derive a subkey for xsalsa20).
17 *
18 * @internal You should not use this directly from another application
19 *
20 * @param string $in
21 * @param string $k
22 * @param string|null $c
23 * @return string
24 * @throws TypeError
25 */
26 public static function hsalsa20($in, $k, $c = null)
27 {
28 if ($c === null) {
29 $x0 = 0x61707865;
30 $x5 = 0x3320646e;
31 $x10 = 0x79622d32;
32 $x15 = 0x6b206574;
33 } else {
34 $x0 = self::load_4(self::substr($c, 0, 4));
35 $x5 = self::load_4(self::substr($c, 4, 4));
36 $x10 = self::load_4(self::substr($c, 8, 4));
37 $x15 = self::load_4(self::substr($c, 12, 4));
38 }
39 $x1 = self::load_4(self::substr($k, 0, 4));
40 $x2 = self::load_4(self::substr($k, 4, 4));
41 $x3 = self::load_4(self::substr($k, 8, 4));
42 $x4 = self::load_4(self::substr($k, 12, 4));
43 $x11 = self::load_4(self::substr($k, 16, 4));
44 $x12 = self::load_4(self::substr($k, 20, 4));
45 $x13 = self::load_4(self::substr($k, 24, 4));
46 $x14 = self::load_4(self::substr($k, 28, 4));
47 $x6 = self::load_4(self::substr($in, 0, 4));
48 $x7 = self::load_4(self::substr($in, 4, 4));
49 $x8 = self::load_4(self::substr($in, 8, 4));
50 $x9 = self::load_4(self::substr($in, 12, 4));
51
52 for ($i = self::ROUNDS; $i > 0; $i -= 2) {
53 $x4 ^= self::rotate($x0 + $x12, 7);
54 $x8 ^= self::rotate($x4 + $x0, 9);
55 $x12 ^= self::rotate($x8 + $x4, 13);
56 $x0 ^= self::rotate($x12 + $x8, 18);
57 $x9 ^= self::rotate($x5 + $x1, 7);
58 $x13 ^= self::rotate($x9 + $x5, 9);
59 $x1 ^= self::rotate($x13 + $x9, 13);
60 $x5 ^= self::rotate($x1 + $x13, 18);
61 $x14 ^= self::rotate($x10 + $x6, 7);
62 $x2 ^= self::rotate($x14 + $x10, 9);
63 $x6 ^= self::rotate($x2 + $x14, 13);
64 $x10 ^= self::rotate($x6 + $x2, 18);
65 $x3 ^= self::rotate($x15 + $x11, 7);
66 $x7 ^= self::rotate($x3 + $x15, 9);
67 $x11 ^= self::rotate($x7 + $x3, 13);
68 $x15 ^= self::rotate($x11 + $x7, 18);
69 $x1 ^= self::rotate($x0 + $x3, 7);
70 $x2 ^= self::rotate($x1 + $x0, 9);
71 $x3 ^= self::rotate($x2 + $x1, 13);
72 $x0 ^= self::rotate($x3 + $x2, 18);
73 $x6 ^= self::rotate($x5 + $x4, 7);
74 $x7 ^= self::rotate($x6 + $x5, 9);
75 $x4 ^= self::rotate($x7 + $x6, 13);
76 $x5 ^= self::rotate($x4 + $x7, 18);
77 $x11 ^= self::rotate($x10 + $x9, 7);
78 $x8 ^= self::rotate($x11 + $x10, 9);
79 $x9 ^= self::rotate($x8 + $x11, 13);
80 $x10 ^= self::rotate($x9 + $x8, 18);
81 $x12 ^= self::rotate($x15 + $x14, 7);
82 $x13 ^= self::rotate($x12 + $x15, 9);
83 $x14 ^= self::rotate($x13 + $x12, 13);
84 $x15 ^= self::rotate($x14 + $x13, 18);
85 }
86
87 return self::store32_le($x0) .
88 self::store32_le($x5) .
89 self::store32_le($x10) .
90 self::store32_le($x15) .
91 self::store32_le($x6) .
92 self::store32_le($x7) .
93 self::store32_le($x8) .
94 self::store32_le($x9);
95 }
96}
97