run:R W Run
8.04 KB
2026-03-11 16:18:52
R W Run
6.37 KB
2026-03-11 16:18:52
R W Run
error_log
📄State128L.php
1<?php
2
3if (class_exists('ParagonIE_Sodium_Core_AEGIS_State128L', false)) {
4 return;
5}
6
7if (!defined('SODIUM_COMPAT_AEGIS_C0')) {
8 define('SODIUM_COMPAT_AEGIS_C0', "\x00\x01\x01\x02\x03\x05\x08\x0d\x15\x22\x37\x59\x90\xe9\x79\x62");
9}
10if (!defined('SODIUM_COMPAT_AEGIS_C1')) {
11 define('SODIUM_COMPAT_AEGIS_C1', "\xdb\x3d\x18\x55\x6d\xc2\x2f\xf1\x20\x11\x31\x42\x73\xb5\x28\xdd");
12}
13
14class ParagonIE_Sodium_Core_AEGIS_State128L
15{
16 /** @var array<int, string> $state */
17 protected $state;
18 public function __construct()
19 {
20 $this->state = array_fill(0, 8, '');
21 }
22
23 /**
24 * @internal Only use this for unit tests!
25 * @return string[]
26 */
27 public function getState()
28 {
29 return array_values($this->state);
30 }
31
32 /**
33 * @param array $input
34 * @return self
35 * @throws SodiumException
36 *
37 * @internal Only for unit tests
38 */
39 public static function initForUnitTests(array $input)
40 {
41 if (count($input) < 8) {
42 throw new SodiumException('invalid input');
43 }
44 $state = new self();
45 for ($i = 0; $i < 8; ++$i) {
46 $state->state[$i] = $input[$i];
47 }
48 return $state;
49 }
50
51 /**
52 * @param string $key
53 * @param string $nonce
54 * @return self
55 */
56 public static function init($key, $nonce)
57 {
58 $state = new self();
59
60 // S0 = key ^ nonce
61 $state->state[0] = $key ^ $nonce;
62 // S1 = C1
63 $state->state[1] = SODIUM_COMPAT_AEGIS_C1;
64 // S2 = C0
65 $state->state[2] = SODIUM_COMPAT_AEGIS_C0;
66 // S3 = C1
67 $state->state[3] = SODIUM_COMPAT_AEGIS_C1;
68 // S4 = key ^ nonce
69 $state->state[4] = $key ^ $nonce;
70 // S5 = key ^ C0
71 $state->state[5] = $key ^ SODIUM_COMPAT_AEGIS_C0;
72 // S6 = key ^ C1
73 $state->state[6] = $key ^ SODIUM_COMPAT_AEGIS_C1;
74 // S7 = key ^ C0
75 $state->state[7] = $key ^ SODIUM_COMPAT_AEGIS_C0;
76
77 // Repeat(10, Update(nonce, key))
78 for ($i = 0; $i < 10; ++$i) {
79 $state->update($nonce, $key);
80 }
81 return $state;
82 }
83
84 /**
85 * @param string $ai
86 * @return self
87 */
88 public function absorb($ai)
89 {
90 if (ParagonIE_Sodium_Core_Util::strlen($ai) !== 32) {
91 throw new SodiumException('Input must be two AES blocks in size');
92 }
93 $t0 = ParagonIE_Sodium_Core_Util::substr($ai, 0, 16);
94 $t1 = ParagonIE_Sodium_Core_Util::substr($ai, 16, 16);
95 return $this->update($t0, $t1);
96 }
97
98
99 /**
100 * @param string $ci
101 * @return string
102 * @throws SodiumException
103 */
104 public function dec($ci)
105 {
106 if (ParagonIE_Sodium_Core_Util::strlen($ci) !== 32) {
107 throw new SodiumException('Input must be two AES blocks in size');
108 }
109
110 // z0 = S6 ^ S1 ^ (S2 & S3)
111 $z0 = $this->state[6]
112 ^ $this->state[1]
113 ^ ParagonIE_Sodium_Core_Util::andStrings($this->state[2], $this->state[3]);
114 // z1 = S2 ^ S5 ^ (S6 & S7)
115 $z1 = $this->state[2]
116 ^ $this->state[5]
117 ^ ParagonIE_Sodium_Core_Util::andStrings($this->state[6], $this->state[7]);
118
119 // t0, t1 = Split(xi, 128)
120 $t0 = ParagonIE_Sodium_Core_Util::substr($ci, 0, 16);
121 $t1 = ParagonIE_Sodium_Core_Util::substr($ci, 16, 16);
122
123 // out0 = t0 ^ z0
124 // out1 = t1 ^ z1
125 $out0 = $t0 ^ $z0;
126 $out1 = $t1 ^ $z1;
127
128 // Update(out0, out1)
129 // xi = out0 || out1
130 $this->update($out0, $out1);
131 return $out0 . $out1;
132 }
133
134 /**
135 * @param string $cn
136 * @return string
137 */
138 public function decPartial($cn)
139 {
140 $len = ParagonIE_Sodium_Core_Util::strlen($cn);
141
142 // z0 = S6 ^ S1 ^ (S2 & S3)
143 $z0 = $this->state[6]
144 ^ $this->state[1]
145 ^ ParagonIE_Sodium_Core_Util::andStrings($this->state[2], $this->state[3]);
146 // z1 = S2 ^ S5 ^ (S6 & S7)
147 $z1 = $this->state[2]
148 ^ $this->state[5]
149 ^ ParagonIE_Sodium_Core_Util::andStrings($this->state[6], $this->state[7]);
150
151 // t0, t1 = Split(ZeroPad(cn, 256), 128)
152 $cn = str_pad($cn, 32, "\0", STR_PAD_RIGHT);
153 $t0 = ParagonIE_Sodium_Core_Util::substr($cn, 0, 16);
154 $t1 = ParagonIE_Sodium_Core_Util::substr($cn, 16, 16);
155 // out0 = t0 ^ z0
156 // out1 = t1 ^ z1
157 $out0 = $t0 ^ $z0;
158 $out1 = $t1 ^ $z1;
159
160 // xn = Truncate(out0 || out1, |cn|)
161 $xn = ParagonIE_Sodium_Core_Util::substr($out0 . $out1, 0, $len);
162
163 // v0, v1 = Split(ZeroPad(xn, 256), 128)
164 $padded = str_pad($xn, 32, "\0", STR_PAD_RIGHT);
165 $v0 = ParagonIE_Sodium_Core_Util::substr($padded, 0, 16);
166 $v1 = ParagonIE_Sodium_Core_Util::substr($padded, 16, 16);
167 // Update(v0, v1)
168 $this->update($v0, $v1);
169
170 // return xn
171 return $xn;
172 }
173
174 /**
175 * @param string $xi
176 * @return string
177 * @throws SodiumException
178 */
179 public function enc($xi)
180 {
181 if (ParagonIE_Sodium_Core_Util::strlen($xi) !== 32) {
182 throw new SodiumException('Input must be two AES blocks in size');
183 }
184
185 // z0 = S6 ^ S1 ^ (S2 & S3)
186 $z0 = $this->state[6]
187 ^ $this->state[1]
188 ^ ParagonIE_Sodium_Core_Util::andStrings($this->state[2], $this->state[3]);
189 // z1 = S2 ^ S5 ^ (S6 & S7)
190 $z1 = $this->state[2]
191 ^ $this->state[5]
192 ^ ParagonIE_Sodium_Core_Util::andStrings($this->state[6], $this->state[7]);
193
194 // t0, t1 = Split(xi, 128)
195 $t0 = ParagonIE_Sodium_Core_Util::substr($xi, 0, 16);
196 $t1 = ParagonIE_Sodium_Core_Util::substr($xi, 16, 16);
197
198 // out0 = t0 ^ z0
199 // out1 = t1 ^ z1
200 $out0 = $t0 ^ $z0;
201 $out1 = $t1 ^ $z1;
202
203 // Update(t0, t1)
204 // ci = out0 || out1
205 $this->update($t0, $t1);
206
207 // return ci
208 return $out0 . $out1;
209 }
210
211 /**
212 * @param int $ad_len_bits
213 * @param int $msg_len_bits
214 * @return string
215 */
216 public function finalize($ad_len_bits, $msg_len_bits)
217 {
218 $encoded = ParagonIE_Sodium_Core_Util::store64_le($ad_len_bits) .
219 ParagonIE_Sodium_Core_Util::store64_le($msg_len_bits);
220 $t = $this->state[2] ^ $encoded;
221 for ($i = 0; $i < 7; ++$i) {
222 $this->update($t, $t);
223 }
224 return ($this->state[0] ^ $this->state[1] ^ $this->state[2] ^ $this->state[3]) .
225 ($this->state[4] ^ $this->state[5] ^ $this->state[6] ^ $this->state[7]);
226 }
227
228 /**
229 * @param string $m0
230 * @param string $m1
231 * @return self
232 */
233 public function update($m0, $m1)
234 {
235 /*
236 S'0 = AESRound(S7, S0 ^ M0)
237 S'1 = AESRound(S0, S1)
238 S'2 = AESRound(S1, S2)
239 S'3 = AESRound(S2, S3)
240 S'4 = AESRound(S3, S4 ^ M1)
241 S'5 = AESRound(S4, S5)
242 S'6 = AESRound(S5, S6)
243 S'7 = AESRound(S6, S7)
244 */
245 list($s_0, $s_1) = ParagonIE_Sodium_Core_AES::doubleRound(
246 $this->state[7], $this->state[0] ^ $m0,
247 $this->state[0], $this->state[1]
248 );
249
250 list($s_2, $s_3) = ParagonIE_Sodium_Core_AES::doubleRound(
251 $this->state[1], $this->state[2],
252 $this->state[2], $this->state[3]
253 );
254
255 list($s_4, $s_5) = ParagonIE_Sodium_Core_AES::doubleRound(
256 $this->state[3], $this->state[4] ^ $m1,
257 $this->state[4], $this->state[5]
258 );
259 list($s_6, $s_7) = ParagonIE_Sodium_Core_AES::doubleRound(
260 $this->state[5], $this->state[6],
261 $this->state[6], $this->state[7]
262 );
263
264 /*
265 S0 = S'0
266 S1 = S'1
267 S2 = S'2
268 S3 = S'3
269 S4 = S'4
270 S5 = S'5
271 S6 = S'6
272 S7 = S'7
273 */
274 $this->state[0] = $s_0;
275 $this->state[1] = $s_1;
276 $this->state[2] = $s_2;
277 $this->state[3] = $s_3;
278 $this->state[4] = $s_4;
279 $this->state[5] = $s_5;
280 $this->state[6] = $s_6;
281 $this->state[7] = $s_7;
282 return $this;
283 }
284}