run:R W Run
12.61 KB
2026-03-11 16:18:52
R W Run
error_log
📄State.php
1<?php
2
3if (class_exists('ParagonIE_Sodium_Core_Poly1305_State', false)) {
4 return;
5}
6
7/**
8 * Class ParagonIE_Sodium_Core_Poly1305_State
9 */
10class ParagonIE_Sodium_Core_Poly1305_State extends ParagonIE_Sodium_Core_Util
11{
12 /**
13 * @var array<int, int>
14 */
15 protected $buffer = array();
16
17 /**
18 * @var bool
19 */
20 protected $final = false;
21
22 /**
23 * @var array<int, int>
24 */
25 public $h;
26
27 /**
28 * @var int
29 */
30 protected $leftover = 0;
31
32 /**
33 * @var int[]
34 */
35 public $r;
36
37 /**
38 * @var int[]
39 */
40 public $pad;
41
42 /**
43 * ParagonIE_Sodium_Core_Poly1305_State constructor.
44 *
45 * @internal You should not use this directly from another application
46 *
47 * @param string $key
48 * @throws InvalidArgumentException
49 * @throws TypeError
50 */
51 public function __construct($key = '')
52 {
53 if (self::strlen($key) < 32) {
54 throw new InvalidArgumentException(
55 'Poly1305 requires a 32-byte key'
56 );
57 }
58 /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
59 $this->r = array(
60 (int) ((self::load_4(self::substr($key, 0, 4))) & 0x3ffffff),
61 (int) ((self::load_4(self::substr($key, 3, 4)) >> 2) & 0x3ffff03),
62 (int) ((self::load_4(self::substr($key, 6, 4)) >> 4) & 0x3ffc0ff),
63 (int) ((self::load_4(self::substr($key, 9, 4)) >> 6) & 0x3f03fff),
64 (int) ((self::load_4(self::substr($key, 12, 4)) >> 8) & 0x00fffff)
65 );
66
67 /* h = 0 */
68 $this->h = array(0, 0, 0, 0, 0);
69
70 /* save pad for later */
71 $this->pad = array(
72 self::load_4(self::substr($key, 16, 4)),
73 self::load_4(self::substr($key, 20, 4)),
74 self::load_4(self::substr($key, 24, 4)),
75 self::load_4(self::substr($key, 28, 4)),
76 );
77
78 $this->leftover = 0;
79 $this->final = false;
80 }
81
82 /**
83 * Zero internal buffer upon destruction
84 */
85 public function __destruct()
86 {
87 $this->r[0] ^= $this->r[0];
88 $this->r[1] ^= $this->r[1];
89 $this->r[2] ^= $this->r[2];
90 $this->r[3] ^= $this->r[3];
91 $this->r[4] ^= $this->r[4];
92 $this->h[0] ^= $this->h[0];
93 $this->h[1] ^= $this->h[1];
94 $this->h[2] ^= $this->h[2];
95 $this->h[3] ^= $this->h[3];
96 $this->h[4] ^= $this->h[4];
97 $this->pad[0] ^= $this->pad[0];
98 $this->pad[1] ^= $this->pad[1];
99 $this->pad[2] ^= $this->pad[2];
100 $this->pad[3] ^= $this->pad[3];
101 $this->leftover = 0;
102 $this->final = true;
103 }
104
105 /**
106 * @internal You should not use this directly from another application
107 *
108 * @param string $message
109 * @return self
110 * @throws SodiumException
111 * @throws TypeError
112 */
113 public function update($message = '')
114 {
115 $bytes = self::strlen($message);
116 if ($bytes < 1) {
117 return $this;
118 }
119
120 /* handle leftover */
121 if ($this->leftover) {
122 $want = ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE - $this->leftover;
123 if ($want > $bytes) {
124 $want = $bytes;
125 }
126 for ($i = 0; $i < $want; ++$i) {
127 $mi = self::chrToInt($message[$i]);
128 $this->buffer[$this->leftover + $i] = $mi;
129 }
130 // We snip off the leftmost bytes.
131 $message = self::substr($message, $want);
132 $bytes = self::strlen($message);
133 $this->leftover += $want;
134 if ($this->leftover < ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
135 // We still don't have enough to run $this->blocks()
136 return $this;
137 }
138
139 $this->blocks(
140 self::intArrayToString($this->buffer),
141 ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE
142 );
143 $this->leftover = 0;
144 }
145
146 /* process full blocks */
147 if ($bytes >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
148 /** @var int $want */
149 $want = $bytes & ~(ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE - 1);
150 if ($want >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
151 $block = self::substr($message, 0, $want);
152 if (self::strlen($block) >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
153 $this->blocks($block, $want);
154 $message = self::substr($message, $want);
155 $bytes = self::strlen($message);
156 }
157 }
158 }
159
160 /* store leftover */
161 if ($bytes) {
162 for ($i = 0; $i < $bytes; ++$i) {
163 $mi = self::chrToInt($message[$i]);
164 $this->buffer[$this->leftover + $i] = $mi;
165 }
166 $this->leftover = (int) $this->leftover + $bytes;
167 }
168 return $this;
169 }
170
171 /**
172 * @internal You should not use this directly from another application
173 *
174 * @param string $message
175 * @param int $bytes
176 * @return self
177 * @throws TypeError
178 */
179 public function blocks($message, $bytes)
180 {
181 if (self::strlen($message) < 16) {
182 $message = str_pad($message, 16, "\x00", STR_PAD_RIGHT);
183 }
184 /** @var int $hibit */
185 $hibit = $this->final ? 0 : 1 << 24; /* 1 << 128 */
186 $r0 = (int) $this->r[0];
187 $r1 = (int) $this->r[1];
188 $r2 = (int) $this->r[2];
189 $r3 = (int) $this->r[3];
190 $r4 = (int) $this->r[4];
191
192 $s1 = self::mul($r1, 5, 3);
193 $s2 = self::mul($r2, 5, 3);
194 $s3 = self::mul($r3, 5, 3);
195 $s4 = self::mul($r4, 5, 3);
196
197 $h0 = $this->h[0];
198 $h1 = $this->h[1];
199 $h2 = $this->h[2];
200 $h3 = $this->h[3];
201 $h4 = $this->h[4];
202
203 while ($bytes >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
204 /* h += m[i] */
205 $h0 += self::load_4(self::substr($message, 0, 4)) & 0x3ffffff;
206 $h1 += (self::load_4(self::substr($message, 3, 4)) >> 2) & 0x3ffffff;
207 $h2 += (self::load_4(self::substr($message, 6, 4)) >> 4) & 0x3ffffff;
208 $h3 += (self::load_4(self::substr($message, 9, 4)) >> 6) & 0x3ffffff;
209 $h4 += (self::load_4(self::substr($message, 12, 4)) >> 8) | $hibit;
210
211 /* h *= r */
212 $d0 = (
213 self::mul($h0, $r0, 27) +
214 self::mul($s4, $h1, 27) +
215 self::mul($s3, $h2, 27) +
216 self::mul($s2, $h3, 27) +
217 self::mul($s1, $h4, 27)
218 );
219
220 $d1 = (
221 self::mul($h0, $r1, 27) +
222 self::mul($h1, $r0, 27) +
223 self::mul($s4, $h2, 27) +
224 self::mul($s3, $h3, 27) +
225 self::mul($s2, $h4, 27)
226 );
227
228 $d2 = (
229 self::mul($h0, $r2, 27) +
230 self::mul($h1, $r1, 27) +
231 self::mul($h2, $r0, 27) +
232 self::mul($s4, $h3, 27) +
233 self::mul($s3, $h4, 27)
234 );
235
236 $d3 = (
237 self::mul($h0, $r3, 27) +
238 self::mul($h1, $r2, 27) +
239 self::mul($h2, $r1, 27) +
240 self::mul($h3, $r0, 27) +
241 self::mul($s4, $h4, 27)
242 );
243
244 $d4 = (
245 self::mul($h0, $r4, 27) +
246 self::mul($h1, $r3, 27) +
247 self::mul($h2, $r2, 27) +
248 self::mul($h3, $r1, 27) +
249 self::mul($h4, $r0, 27)
250 );
251
252 /* (partial) h %= p */
253 /** @var int $c */
254 $c = $d0 >> 26;
255 /** @var int $h0 */
256 $h0 = $d0 & 0x3ffffff;
257 $d1 += $c;
258
259 /** @var int $c */
260 $c = $d1 >> 26;
261 /** @var int $h1 */
262 $h1 = $d1 & 0x3ffffff;
263 $d2 += $c;
264
265 /** @var int $c */
266 $c = $d2 >> 26;
267 /** @var int $h2 */
268 $h2 = $d2 & 0x3ffffff;
269 $d3 += $c;
270
271 /** @var int $c */
272 $c = $d3 >> 26;
273 /** @var int $h3 */
274 $h3 = $d3 & 0x3ffffff;
275 $d4 += $c;
276
277 /** @var int $c */
278 $c = $d4 >> 26;
279 /** @var int $h4 */
280 $h4 = $d4 & 0x3ffffff;
281 $h0 += (int) self::mul($c, 5, 3);
282
283 /** @var int $c */
284 $c = $h0 >> 26;
285 /** @var int $h0 */
286 $h0 &= 0x3ffffff;
287 $h1 += $c;
288
289 // Chop off the left 32 bytes.
290 $message = self::substr(
291 $message,
292 ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE
293 );
294 $bytes -= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE;
295 }
296
297 $this->h = array(
298 (int) ($h0 & 0xffffffff),
299 (int) ($h1 & 0xffffffff),
300 (int) ($h2 & 0xffffffff),
301 (int) ($h3 & 0xffffffff),
302 (int) ($h4 & 0xffffffff)
303 );
304 return $this;
305 }
306
307 /**
308 * @internal You should not use this directly from another application
309 *
310 * @return string
311 * @throws TypeError
312 */
313 public function finish()
314 {
315 /* process the remaining block */
316 if ($this->leftover) {
317 $i = $this->leftover;
318 $this->buffer[$i++] = 1;
319 for (; $i < ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE; ++$i) {
320 $this->buffer[$i] = 0;
321 }
322 $this->final = true;
323 $this->blocks(
324 self::substr(
325 self::intArrayToString($this->buffer),
326 0,
327 ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE
328 ),
329 ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE
330 );
331 }
332
333 $h0 = (int) $this->h[0];
334 $h1 = (int) $this->h[1];
335 $h2 = (int) $this->h[2];
336 $h3 = (int) $this->h[3];
337 $h4 = (int) $this->h[4];
338
339 /** @var int $c */
340 $c = $h1 >> 26;
341 /** @var int $h1 */
342 $h1 &= 0x3ffffff;
343 /** @var int $h2 */
344 $h2 += $c;
345 /** @var int $c */
346 $c = $h2 >> 26;
347 /** @var int $h2 */
348 $h2 &= 0x3ffffff;
349 $h3 += $c;
350 /** @var int $c */
351 $c = $h3 >> 26;
352 $h3 &= 0x3ffffff;
353 $h4 += $c;
354 /** @var int $c */
355 $c = $h4 >> 26;
356 $h4 &= 0x3ffffff;
357 /** @var int $h0 */
358 $h0 += self::mul($c, 5, 3);
359 /** @var int $c */
360 $c = $h0 >> 26;
361 /** @var int $h0 */
362 $h0 &= 0x3ffffff;
363 /** @var int $h1 */
364 $h1 += $c;
365
366 /* compute h + -p */
367 /** @var int $g0 */
368 $g0 = $h0 + 5;
369 /** @var int $c */
370 $c = $g0 >> 26;
371 /** @var int $g0 */
372 $g0 &= 0x3ffffff;
373
374 /** @var int $g1 */
375 $g1 = $h1 + $c;
376 /** @var int $c */
377 $c = $g1 >> 26;
378 $g1 &= 0x3ffffff;
379
380 /** @var int $g2 */
381 $g2 = $h2 + $c;
382 /** @var int $c */
383 $c = $g2 >> 26;
384 /** @var int $g2 */
385 $g2 &= 0x3ffffff;
386
387 /** @var int $g3 */
388 $g3 = $h3 + $c;
389 /** @var int $c */
390 $c = $g3 >> 26;
391 /** @var int $g3 */
392 $g3 &= 0x3ffffff;
393
394 /** @var int $g4 */
395 $g4 = ($h4 + $c - (1 << 26)) & 0xffffffff;
396
397 /* select h if h < p, or h + -p if h >= p */
398 /** @var int $mask */
399 $mask = ($g4 >> 31) - 1;
400
401 $g0 &= $mask;
402 $g1 &= $mask;
403 $g2 &= $mask;
404 $g3 &= $mask;
405 $g4 &= $mask;
406
407 /** @var int $mask */
408 $mask = ~$mask & 0xffffffff;
409 /** @var int $h0 */
410 $h0 = ($h0 & $mask) | $g0;
411 /** @var int $h1 */
412 $h1 = ($h1 & $mask) | $g1;
413 /** @var int $h2 */
414 $h2 = ($h2 & $mask) | $g2;
415 /** @var int $h3 */
416 $h3 = ($h3 & $mask) | $g3;
417 /** @var int $h4 */
418 $h4 = ($h4 & $mask) | $g4;
419
420 /* h = h % (2^128) */
421 /** @var int $h0 */
422 $h0 = (($h0) | ($h1 << 26)) & 0xffffffff;
423 /** @var int $h1 */
424 $h1 = (($h1 >> 6) | ($h2 << 20)) & 0xffffffff;
425 /** @var int $h2 */
426 $h2 = (($h2 >> 12) | ($h3 << 14)) & 0xffffffff;
427 /** @var int $h3 */
428 $h3 = (($h3 >> 18) | ($h4 << 8)) & 0xffffffff;
429
430 /* mac = (h + pad) % (2^128) */
431 $f = (int) ($h0 + $this->pad[0]);
432 $h0 = (int) $f;
433 $f = (int) ($h1 + $this->pad[1] + ($f >> 32));
434 $h1 = (int) $f;
435 $f = (int) ($h2 + $this->pad[2] + ($f >> 32));
436 $h2 = (int) $f;
437 $f = (int) ($h3 + $this->pad[3] + ($f >> 32));
438 $h3 = (int) $f;
439
440 return self::store32_le($h0 & 0xffffffff) .
441 self::store32_le($h1 & 0xffffffff) .
442 self::store32_le($h2 & 0xffffffff) .
443 self::store32_le($h3 & 0xffffffff);
444 }
445}
446