run:R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
160.83 KB
2026-03-11 16:18:52
R W Run
53.68 KB
2026-03-11 16:18:52
R W Run
53.83 KB
2026-03-11 16:18:52
R W Run
53.53 KB
2026-03-11 16:18:52
R W Run
158 By
2026-03-11 16:18:52
R W Run
error_log
📄Crypto32.php
1<?php
2
3if (class_exists('ParagonIE_Sodium_Crypto32', false)) {
4 return;
5}
6
7/**
8 * Class ParagonIE_Sodium_Crypto
9 *
10 * ATTENTION!
11 *
12 * If you are using this library, you should be using
13 * ParagonIE_Sodium_Compat in your code, not this class.
14 */
15abstract class ParagonIE_Sodium_Crypto32
16{
17 const aead_chacha20poly1305_KEYBYTES = 32;
18 const aead_chacha20poly1305_NSECBYTES = 0;
19 const aead_chacha20poly1305_NPUBBYTES = 8;
20 const aead_chacha20poly1305_ABYTES = 16;
21
22 const aead_chacha20poly1305_IETF_KEYBYTES = 32;
23 const aead_chacha20poly1305_IETF_NSECBYTES = 0;
24 const aead_chacha20poly1305_IETF_NPUBBYTES = 12;
25 const aead_chacha20poly1305_IETF_ABYTES = 16;
26
27 const aead_xchacha20poly1305_IETF_KEYBYTES = 32;
28 const aead_xchacha20poly1305_IETF_NSECBYTES = 0;
29 const aead_xchacha20poly1305_IETF_NPUBBYTES = 24;
30 const aead_xchacha20poly1305_IETF_ABYTES = 16;
31
32 const box_curve25519xsalsa20poly1305_SEEDBYTES = 32;
33 const box_curve25519xsalsa20poly1305_PUBLICKEYBYTES = 32;
34 const box_curve25519xsalsa20poly1305_SECRETKEYBYTES = 32;
35 const box_curve25519xsalsa20poly1305_BEFORENMBYTES = 32;
36 const box_curve25519xsalsa20poly1305_NONCEBYTES = 24;
37 const box_curve25519xsalsa20poly1305_MACBYTES = 16;
38 const box_curve25519xsalsa20poly1305_BOXZEROBYTES = 16;
39 const box_curve25519xsalsa20poly1305_ZEROBYTES = 32;
40
41 const onetimeauth_poly1305_BYTES = 16;
42 const onetimeauth_poly1305_KEYBYTES = 32;
43
44 const secretbox_xsalsa20poly1305_KEYBYTES = 32;
45 const secretbox_xsalsa20poly1305_NONCEBYTES = 24;
46 const secretbox_xsalsa20poly1305_MACBYTES = 16;
47 const secretbox_xsalsa20poly1305_BOXZEROBYTES = 16;
48 const secretbox_xsalsa20poly1305_ZEROBYTES = 32;
49
50 const secretbox_xchacha20poly1305_KEYBYTES = 32;
51 const secretbox_xchacha20poly1305_NONCEBYTES = 24;
52 const secretbox_xchacha20poly1305_MACBYTES = 16;
53 const secretbox_xchacha20poly1305_BOXZEROBYTES = 16;
54 const secretbox_xchacha20poly1305_ZEROBYTES = 32;
55
56 const stream_salsa20_KEYBYTES = 32;
57
58 /**
59 * AEAD Decryption with ChaCha20-Poly1305
60 *
61 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
62 *
63 * @param string $message
64 * @param string $ad
65 * @param string $nonce
66 * @param string $key
67 * @return string
68 * @throws SodiumException
69 * @throws TypeError
70 */
71 public static function aead_chacha20poly1305_decrypt(
72 $message = '',
73 $ad = '',
74 $nonce = '',
75 $key = ''
76 ) {
77 /** @var int $len - Length of message (ciphertext + MAC) */
78 $len = ParagonIE_Sodium_Core32_Util::strlen($message);
79
80 /** @var int $clen - Length of ciphertext */
81 $clen = $len - self::aead_chacha20poly1305_ABYTES;
82
83 /** @var int $adlen - Length of associated data */
84 $adlen = ParagonIE_Sodium_Core32_Util::strlen($ad);
85
86 /** @var string $mac - Message authentication code */
87 $mac = ParagonIE_Sodium_Core32_Util::substr(
88 $message,
89 $clen,
90 self::aead_chacha20poly1305_ABYTES
91 );
92
93 /** @var string $ciphertext - The encrypted message (sans MAC) */
94 $ciphertext = ParagonIE_Sodium_Core32_Util::substr($message, 0, $clen);
95
96 /** @var string The first block of the chacha20 keystream, used as a poly1305 key */
97 $block0 = ParagonIE_Sodium_Core32_ChaCha20::stream(
98 32,
99 $nonce,
100 $key
101 );
102
103 /* Recalculate the Poly1305 authentication tag (MAC): */
104 $state = new ParagonIE_Sodium_Core32_Poly1305_State($block0);
105 try {
106 ParagonIE_Sodium_Compat::memzero($block0);
107 } catch (SodiumException $ex) {
108 $block0 = null;
109 }
110 $state->update($ad);
111 $state->update(ParagonIE_Sodium_Core32_Util::store64_le($adlen));
112 $state->update($ciphertext);
113 $state->update(ParagonIE_Sodium_Core32_Util::store64_le($clen));
114 $computed_mac = $state->finish();
115
116 /* Compare the given MAC with the recalculated MAC: */
117 if (!ParagonIE_Sodium_Core32_Util::verify_16($computed_mac, $mac)) {
118 throw new SodiumException('Invalid MAC');
119 }
120
121 // Here, we know that the MAC is valid, so we decrypt and return the plaintext
122 return ParagonIE_Sodium_Core32_ChaCha20::streamXorIc(
123 $ciphertext,
124 $nonce,
125 $key,
126 ParagonIE_Sodium_Core32_Util::store64_le(1)
127 );
128 }
129
130 /**
131 * AEAD Encryption with ChaCha20-Poly1305
132 *
133 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
134 *
135 * @param string $message
136 * @param string $ad
137 * @param string $nonce
138 * @param string $key
139 * @return string
140 * @throws SodiumException
141 * @throws TypeError
142 */
143 public static function aead_chacha20poly1305_encrypt(
144 $message = '',
145 $ad = '',
146 $nonce = '',
147 $key = ''
148 ) {
149 /** @var int $len - Length of the plaintext message */
150 $len = ParagonIE_Sodium_Core32_Util::strlen($message);
151
152 /** @var int $adlen - Length of the associated data */
153 $adlen = ParagonIE_Sodium_Core32_Util::strlen($ad);
154
155 /** @var string The first block of the chacha20 keystream, used as a poly1305 key */
156 $block0 = ParagonIE_Sodium_Core32_ChaCha20::stream(
157 32,
158 $nonce,
159 $key
160 );
161 $state = new ParagonIE_Sodium_Core32_Poly1305_State($block0);
162 try {
163 ParagonIE_Sodium_Compat::memzero($block0);
164 } catch (SodiumException $ex) {
165 $block0 = null;
166 }
167
168 /** @var string $ciphertext - Raw encrypted data */
169 $ciphertext = ParagonIE_Sodium_Core32_ChaCha20::streamXorIc(
170 $message,
171 $nonce,
172 $key,
173 ParagonIE_Sodium_Core32_Util::store64_le(1)
174 );
175
176 $state->update($ad);
177 $state->update(ParagonIE_Sodium_Core32_Util::store64_le($adlen));
178 $state->update($ciphertext);
179 $state->update(ParagonIE_Sodium_Core32_Util::store64_le($len));
180 return $ciphertext . $state->finish();
181 }
182
183 /**
184 * AEAD Decryption with ChaCha20-Poly1305, IETF mode (96-bit nonce)
185 *
186 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
187 *
188 * @param string $message
189 * @param string $ad
190 * @param string $nonce
191 * @param string $key
192 * @return string
193 * @throws SodiumException
194 * @throws TypeError
195 */
196 public static function aead_chacha20poly1305_ietf_decrypt(
197 $message = '',
198 $ad = '',
199 $nonce = '',
200 $key = ''
201 ) {
202 /** @var int $adlen - Length of associated data */
203 $adlen = ParagonIE_Sodium_Core32_Util::strlen($ad);
204
205 /** @var int $len - Length of message (ciphertext + MAC) */
206 $len = ParagonIE_Sodium_Core32_Util::strlen($message);
207
208 /** @var int $clen - Length of ciphertext */
209 $clen = $len - self::aead_chacha20poly1305_IETF_ABYTES;
210
211 /** @var string The first block of the chacha20 keystream, used as a poly1305 key */
212 $block0 = ParagonIE_Sodium_Core32_ChaCha20::ietfStream(
213 32,
214 $nonce,
215 $key
216 );
217
218 /** @var string $mac - Message authentication code */
219 $mac = ParagonIE_Sodium_Core32_Util::substr(
220 $message,
221 $len - self::aead_chacha20poly1305_IETF_ABYTES,
222 self::aead_chacha20poly1305_IETF_ABYTES
223 );
224
225 /** @var string $ciphertext - The encrypted message (sans MAC) */
226 $ciphertext = ParagonIE_Sodium_Core32_Util::substr(
227 $message,
228 0,
229 $len - self::aead_chacha20poly1305_IETF_ABYTES
230 );
231
232 /* Recalculate the Poly1305 authentication tag (MAC): */
233 $state = new ParagonIE_Sodium_Core32_Poly1305_State($block0);
234 try {
235 ParagonIE_Sodium_Compat::memzero($block0);
236 } catch (SodiumException $ex) {
237 $block0 = null;
238 }
239 $state->update($ad);
240 $state->update(str_repeat("\x00", ((0x10 - $adlen) & 0xf)));
241 $state->update($ciphertext);
242 $state->update(str_repeat("\x00", (0x10 - $clen) & 0xf));
243 $state->update(ParagonIE_Sodium_Core32_Util::store64_le($adlen));
244 $state->update(ParagonIE_Sodium_Core32_Util::store64_le($clen));
245 $computed_mac = $state->finish();
246
247 /* Compare the given MAC with the recalculated MAC: */
248 if (!ParagonIE_Sodium_Core32_Util::verify_16($computed_mac, $mac)) {
249 throw new SodiumException('Invalid MAC');
250 }
251
252 // Here, we know that the MAC is valid, so we decrypt and return the plaintext
253 return ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc(
254 $ciphertext,
255 $nonce,
256 $key,
257 ParagonIE_Sodium_Core32_Util::store64_le(1)
258 );
259 }
260
261 /**
262 * AEAD Encryption with ChaCha20-Poly1305, IETF mode (96-bit nonce)
263 *
264 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
265 *
266 * @param string $message
267 * @param string $ad
268 * @param string $nonce
269 * @param string $key
270 * @return string
271 * @throws SodiumException
272 * @throws TypeError
273 */
274 public static function aead_chacha20poly1305_ietf_encrypt(
275 $message = '',
276 $ad = '',
277 $nonce = '',
278 $key = ''
279 ) {
280 /** @var int $len - Length of the plaintext message */
281 $len = ParagonIE_Sodium_Core32_Util::strlen($message);
282
283 /** @var int $adlen - Length of the associated data */
284 $adlen = ParagonIE_Sodium_Core32_Util::strlen($ad);
285
286 /** @var string The first block of the chacha20 keystream, used as a poly1305 key */
287 $block0 = ParagonIE_Sodium_Core32_ChaCha20::ietfStream(
288 32,
289 $nonce,
290 $key
291 );
292 $state = new ParagonIE_Sodium_Core32_Poly1305_State($block0);
293 try {
294 ParagonIE_Sodium_Compat::memzero($block0);
295 } catch (SodiumException $ex) {
296 $block0 = null;
297 }
298
299 /** @var string $ciphertext - Raw encrypted data */
300 $ciphertext = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc(
301 $message,
302 $nonce,
303 $key,
304 ParagonIE_Sodium_Core32_Util::store64_le(1)
305 );
306
307 $state->update($ad);
308 $state->update(str_repeat("\x00", ((0x10 - $adlen) & 0xf)));
309 $state->update($ciphertext);
310 $state->update(str_repeat("\x00", ((0x10 - $len) & 0xf)));
311 $state->update(ParagonIE_Sodium_Core32_Util::store64_le($adlen));
312 $state->update(ParagonIE_Sodium_Core32_Util::store64_le($len));
313 return $ciphertext . $state->finish();
314 }
315
316 /**
317 * AEAD Decryption with ChaCha20-Poly1305, IETF mode (96-bit nonce)
318 *
319 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
320 *
321 * @param string $message
322 * @param string $ad
323 * @param string $nonce
324 * @param string $key
325 * @return string
326 * @throws SodiumException
327 * @throws TypeError
328 */
329 public static function aead_xchacha20poly1305_ietf_decrypt(
330 $message = '',
331 $ad = '',
332 $nonce = '',
333 $key = ''
334 ) {
335 $subkey = ParagonIE_Sodium_Core32_HChaCha20::hChaCha20(
336 ParagonIE_Sodium_Core32_Util::substr($nonce, 0, 16),
337 $key
338 );
339 $nonceLast = "\x00\x00\x00\x00" .
340 ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8);
341
342 return self::aead_chacha20poly1305_ietf_decrypt($message, $ad, $nonceLast, $subkey);
343 }
344
345 /**
346 * AEAD Encryption with ChaCha20-Poly1305, IETF mode (96-bit nonce)
347 *
348 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
349 *
350 * @param string $message
351 * @param string $ad
352 * @param string $nonce
353 * @param string $key
354 * @return string
355 * @throws SodiumException
356 * @throws TypeError
357 */
358 public static function aead_xchacha20poly1305_ietf_encrypt(
359 $message = '',
360 $ad = '',
361 $nonce = '',
362 $key = ''
363 ) {
364 $subkey = ParagonIE_Sodium_Core32_HChaCha20::hChaCha20(
365 ParagonIE_Sodium_Core32_Util::substr($nonce, 0, 16),
366 $key
367 );
368 $nonceLast = "\x00\x00\x00\x00" .
369 ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8);
370
371 return self::aead_chacha20poly1305_ietf_encrypt($message, $ad, $nonceLast, $subkey);
372 }
373
374 /**
375 * HMAC-SHA-512-256 (a.k.a. the leftmost 256 bits of HMAC-SHA-512)
376 *
377 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
378 *
379 * @param string $message
380 * @param string $key
381 * @return string
382 * @throws TypeError
383 */
384 public static function auth($message, $key)
385 {
386 return ParagonIE_Sodium_Core32_Util::substr(
387 hash_hmac('sha512', $message, $key, true),
388 0,
389 32
390 );
391 }
392
393 /**
394 * HMAC-SHA-512-256 validation. Constant-time via hash_equals().
395 *
396 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
397 *
398 * @param string $mac
399 * @param string $message
400 * @param string $key
401 * @return bool
402 * @throws SodiumException
403 * @throws TypeError
404 */
405 public static function auth_verify($mac, $message, $key)
406 {
407 return ParagonIE_Sodium_Core32_Util::hashEquals(
408 $mac,
409 self::auth($message, $key)
410 );
411 }
412
413 /**
414 * X25519 key exchange followed by XSalsa20Poly1305 symmetric encryption
415 *
416 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
417 *
418 * @param string $plaintext
419 * @param string $nonce
420 * @param string $keypair
421 * @return string
422 * @throws SodiumException
423 * @throws TypeError
424 */
425 public static function box($plaintext, $nonce, $keypair)
426 {
427 return self::secretbox(
428 $plaintext,
429 $nonce,
430 self::box_beforenm(
431 self::box_secretkey($keypair),
432 self::box_publickey($keypair)
433 )
434 );
435 }
436
437 /**
438 * X25519-XSalsa20-Poly1305 with one ephemeral X25519 keypair.
439 *
440 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
441 *
442 * @param string $message
443 * @param string $publicKey
444 * @return string
445 * @throws SodiumException
446 * @throws TypeError
447 */
448 public static function box_seal($message, $publicKey)
449 {
450 /** @var string $ephemeralKeypair */
451 $ephemeralKeypair = self::box_keypair();
452
453 /** @var string $ephemeralSK */
454 $ephemeralSK = self::box_secretkey($ephemeralKeypair);
455
456 /** @var string $ephemeralPK */
457 $ephemeralPK = self::box_publickey($ephemeralKeypair);
458
459 /** @var string $nonce */
460 $nonce = self::generichash(
461 $ephemeralPK . $publicKey,
462 '',
463 24
464 );
465
466 /** @var string $keypair - The combined keypair used in crypto_box() */
467 $keypair = self::box_keypair_from_secretkey_and_publickey($ephemeralSK, $publicKey);
468
469 /** @var string $ciphertext Ciphertext + MAC from crypto_box */
470 $ciphertext = self::box($message, $nonce, $keypair);
471 try {
472 ParagonIE_Sodium_Compat::memzero($ephemeralKeypair);
473 ParagonIE_Sodium_Compat::memzero($ephemeralSK);
474 ParagonIE_Sodium_Compat::memzero($nonce);
475 } catch (SodiumException $ex) {
476 $ephemeralKeypair = null;
477 $ephemeralSK = null;
478 $nonce = null;
479 }
480 return $ephemeralPK . $ciphertext;
481 }
482
483 /**
484 * Opens a message encrypted via box_seal().
485 *
486 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
487 *
488 * @param string $message
489 * @param string $keypair
490 * @return string
491 * @throws SodiumException
492 * @throws TypeError
493 */
494 public static function box_seal_open($message, $keypair)
495 {
496 /** @var string $ephemeralPK */
497 $ephemeralPK = ParagonIE_Sodium_Core32_Util::substr($message, 0, 32);
498
499 /** @var string $ciphertext (ciphertext + MAC) */
500 $ciphertext = ParagonIE_Sodium_Core32_Util::substr($message, 32);
501
502 /** @var string $secretKey */
503 $secretKey = self::box_secretkey($keypair);
504
505 /** @var string $publicKey */
506 $publicKey = self::box_publickey($keypair);
507
508 /** @var string $nonce */
509 $nonce = self::generichash(
510 $ephemeralPK . $publicKey,
511 '',
512 24
513 );
514
515 /** @var string $keypair */
516 $keypair = self::box_keypair_from_secretkey_and_publickey($secretKey, $ephemeralPK);
517
518 /** @var string $m */
519 $m = self::box_open($ciphertext, $nonce, $keypair);
520 try {
521 ParagonIE_Sodium_Compat::memzero($secretKey);
522 ParagonIE_Sodium_Compat::memzero($ephemeralPK);
523 ParagonIE_Sodium_Compat::memzero($nonce);
524 } catch (SodiumException $ex) {
525 $secretKey = null;
526 $ephemeralPK = null;
527 $nonce = null;
528 }
529 return $m;
530 }
531
532 /**
533 * Used by crypto_box() to get the crypto_secretbox() key.
534 *
535 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
536 *
537 * @param string $sk
538 * @param string $pk
539 * @return string
540 * @throws SodiumException
541 * @throws TypeError
542 */
543 public static function box_beforenm($sk, $pk)
544 {
545 return ParagonIE_Sodium_Core32_HSalsa20::hsalsa20(
546 str_repeat("\x00", 16),
547 self::scalarmult($sk, $pk)
548 );
549 }
550
551 /**
552 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
553 *
554 * @return string
555 * @throws Exception
556 * @throws SodiumException
557 * @throws TypeError
558 */
559 public static function box_keypair()
560 {
561 $sKey = random_bytes(32);
562 $pKey = self::scalarmult_base($sKey);
563 return $sKey . $pKey;
564 }
565
566 /**
567 * @param string $seed
568 * @return string
569 * @throws SodiumException
570 * @throws TypeError
571 */
572 public static function box_seed_keypair($seed)
573 {
574 $sKey = ParagonIE_Sodium_Core32_Util::substr(
575 hash('sha512', $seed, true),
576 0,
577 32
578 );
579 $pKey = self::scalarmult_base($sKey);
580 return $sKey . $pKey;
581 }
582
583 /**
584 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
585 *
586 * @param string $sKey
587 * @param string $pKey
588 * @return string
589 * @throws TypeError
590 */
591 public static function box_keypair_from_secretkey_and_publickey($sKey, $pKey)
592 {
593 return ParagonIE_Sodium_Core32_Util::substr($sKey, 0, 32) .
594 ParagonIE_Sodium_Core32_Util::substr($pKey, 0, 32);
595 }
596
597 /**
598 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
599 *
600 * @param string $keypair
601 * @return string
602 * @throws RangeException
603 * @throws TypeError
604 */
605 public static function box_secretkey($keypair)
606 {
607 if (ParagonIE_Sodium_Core32_Util::strlen($keypair) !== 64) {
608 throw new RangeException(
609 'Must be ParagonIE_Sodium_Compat::CRYPTO_BOX_KEYPAIRBYTES bytes long.'
610 );
611 }
612 return ParagonIE_Sodium_Core32_Util::substr($keypair, 0, 32);
613 }
614
615 /**
616 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
617 *
618 * @param string $keypair
619 * @return string
620 * @throws RangeException
621 * @throws TypeError
622 */
623 public static function box_publickey($keypair)
624 {
625 if (ParagonIE_Sodium_Core32_Util::strlen($keypair) !== ParagonIE_Sodium_Compat::CRYPTO_BOX_KEYPAIRBYTES) {
626 throw new RangeException(
627 'Must be ParagonIE_Sodium_Compat::CRYPTO_BOX_KEYPAIRBYTES bytes long.'
628 );
629 }
630 return ParagonIE_Sodium_Core32_Util::substr($keypair, 32, 32);
631 }
632
633 /**
634 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
635 *
636 * @param string $sKey
637 * @return string
638 * @throws RangeException
639 * @throws SodiumException
640 * @throws TypeError
641 */
642 public static function box_publickey_from_secretkey($sKey)
643 {
644 if (ParagonIE_Sodium_Core32_Util::strlen($sKey) !== ParagonIE_Sodium_Compat::CRYPTO_BOX_SECRETKEYBYTES) {
645 throw new RangeException(
646 'Must be ParagonIE_Sodium_Compat::CRYPTO_BOX_SECRETKEYBYTES bytes long.'
647 );
648 }
649 return self::scalarmult_base($sKey);
650 }
651
652 /**
653 * Decrypt a message encrypted with box().
654 *
655 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
656 *
657 * @param string $ciphertext
658 * @param string $nonce
659 * @param string $keypair
660 * @return string
661 * @throws SodiumException
662 * @throws TypeError
663 */
664 public static function box_open($ciphertext, $nonce, $keypair)
665 {
666 return self::secretbox_open(
667 $ciphertext,
668 $nonce,
669 self::box_beforenm(
670 self::box_secretkey($keypair),
671 self::box_publickey($keypair)
672 )
673 );
674 }
675
676 /**
677 * Calculate a BLAKE2b hash.
678 *
679 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
680 *
681 * @param string $message
682 * @param string|null $key
683 * @param int $outlen
684 * @return string
685 * @throws RangeException
686 * @throws SodiumException
687 * @throws TypeError
688 */
689 public static function generichash($message, $key = '', $outlen = 32)
690 {
691 // This ensures that ParagonIE_Sodium_Core32_BLAKE2b::$iv is initialized
692 ParagonIE_Sodium_Core32_BLAKE2b::pseudoConstructor();
693
694 $k = null;
695 if (!empty($key)) {
696 /** @var SplFixedArray $k */
697 $k = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($key);
698 if ($k->count() > ParagonIE_Sodium_Core32_BLAKE2b::KEYBYTES) {
699 throw new RangeException('Invalid key size');
700 }
701 }
702
703 /** @var SplFixedArray $in */
704 $in = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($message);
705
706 /** @var SplFixedArray $ctx */
707 $ctx = ParagonIE_Sodium_Core32_BLAKE2b::init($k, $outlen);
708 ParagonIE_Sodium_Core32_BLAKE2b::update($ctx, $in, $in->count());
709
710 /** @var SplFixedArray $out */
711 $out = new SplFixedArray($outlen);
712 $out = ParagonIE_Sodium_Core32_BLAKE2b::finish($ctx, $out);
713
714 /** @var array<int, int> */
715 $outArray = $out->toArray();
716 return ParagonIE_Sodium_Core32_Util::intArrayToString($outArray);
717 }
718
719 /**
720 * Finalize a BLAKE2b hashing context, returning the hash.
721 *
722 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
723 *
724 * @param string $ctx
725 * @param int $outlen
726 * @return string
727 * @throws SodiumException
728 * @throws TypeError
729 */
730 public static function generichash_final($ctx, $outlen = 32)
731 {
732 if (!is_string($ctx)) {
733 throw new TypeError('Context must be a string');
734 }
735 $out = new SplFixedArray($outlen);
736
737 /** @var SplFixedArray $context */
738 $context = ParagonIE_Sodium_Core32_BLAKE2b::stringToContext($ctx);
739
740 /** @var SplFixedArray $out */
741 $out = ParagonIE_Sodium_Core32_BLAKE2b::finish($context, $out);
742
743 /** @var array<int, int> */
744 $outArray = $out->toArray();
745 return ParagonIE_Sodium_Core32_Util::intArrayToString($outArray);
746 }
747
748 /**
749 * Initialize a hashing context for BLAKE2b.
750 *
751 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
752 *
753 * @param string $key
754 * @param int $outputLength
755 * @return string
756 * @throws RangeException
757 * @throws SodiumException
758 * @throws TypeError
759 */
760 public static function generichash_init($key = '', $outputLength = 32)
761 {
762 // This ensures that ParagonIE_Sodium_Core32_BLAKE2b::$iv is initialized
763 ParagonIE_Sodium_Core32_BLAKE2b::pseudoConstructor();
764
765 $k = null;
766 if (!empty($key)) {
767 $k = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($key);
768 if ($k->count() > ParagonIE_Sodium_Core32_BLAKE2b::KEYBYTES) {
769 throw new RangeException('Invalid key size');
770 }
771 }
772
773 /** @var SplFixedArray $ctx */
774 $ctx = ParagonIE_Sodium_Core32_BLAKE2b::init($k, $outputLength);
775
776 return ParagonIE_Sodium_Core32_BLAKE2b::contextToString($ctx);
777 }
778
779 /**
780 * Initialize a hashing context for BLAKE2b.
781 *
782 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
783 *
784 * @param string $key
785 * @param int $outputLength
786 * @param string $salt
787 * @param string $personal
788 * @return string
789 * @throws RangeException
790 * @throws SodiumException
791 * @throws TypeError
792 */
793 public static function generichash_init_salt_personal(
794 $key = '',
795 $outputLength = 32,
796 $salt = '',
797 $personal = ''
798 ) {
799 // This ensures that ParagonIE_Sodium_Core32_BLAKE2b::$iv is initialized
800 ParagonIE_Sodium_Core32_BLAKE2b::pseudoConstructor();
801
802 $k = null;
803 if (!empty($key)) {
804 $k = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($key);
805 if ($k->count() > ParagonIE_Sodium_Core32_BLAKE2b::KEYBYTES) {
806 throw new RangeException('Invalid key size');
807 }
808 }
809 if (!empty($salt)) {
810 $s = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($salt);
811 } else {
812 $s = null;
813 }
814 if (!empty($salt)) {
815 $p = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($personal);
816 } else {
817 $p = null;
818 }
819
820 /** @var SplFixedArray $ctx */
821 $ctx = ParagonIE_Sodium_Core32_BLAKE2b::init($k, $outputLength, $s, $p);
822
823 return ParagonIE_Sodium_Core32_BLAKE2b::contextToString($ctx);
824 }
825
826 /**
827 * Update a hashing context for BLAKE2b with $message
828 *
829 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
830 *
831 * @param string $ctx
832 * @param string $message
833 * @return string
834 * @throws SodiumException
835 * @throws TypeError
836 */
837 public static function generichash_update($ctx, $message)
838 {
839 // This ensures that ParagonIE_Sodium_Core32_BLAKE2b::$iv is initialized
840 ParagonIE_Sodium_Core32_BLAKE2b::pseudoConstructor();
841
842 /** @var SplFixedArray $context */
843 $context = ParagonIE_Sodium_Core32_BLAKE2b::stringToContext($ctx);
844
845 /** @var SplFixedArray $in */
846 $in = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($message);
847
848 ParagonIE_Sodium_Core32_BLAKE2b::update($context, $in, $in->count());
849
850 return ParagonIE_Sodium_Core32_BLAKE2b::contextToString($context);
851 }
852
853 /**
854 * Libsodium's crypto_kx().
855 *
856 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
857 *
858 * @param string $my_sk
859 * @param string $their_pk
860 * @param string $client_pk
861 * @param string $server_pk
862 * @return string
863 * @throws SodiumException
864 * @throws TypeError
865 */
866 public static function keyExchange($my_sk, $their_pk, $client_pk, $server_pk)
867 {
868 return self::generichash(
869 self::scalarmult($my_sk, $their_pk) .
870 $client_pk .
871 $server_pk
872 );
873 }
874
875 /**
876 * ECDH over Curve25519
877 *
878 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
879 *
880 * @param string $sKey
881 * @param string $pKey
882 * @return string
883 *
884 * @throws SodiumException
885 * @throws TypeError
886 */
887 public static function scalarmult($sKey, $pKey)
888 {
889 $q = ParagonIE_Sodium_Core32_X25519::crypto_scalarmult_curve25519_ref10($sKey, $pKey);
890 self::scalarmult_throw_if_zero($q);
891 return $q;
892 }
893
894 /**
895 * ECDH over Curve25519, using the basepoint.
896 * Used to get a secret key from a public key.
897 *
898 * @param string $secret
899 * @return string
900 *
901 * @throws SodiumException
902 * @throws TypeError
903 */
904 public static function scalarmult_base($secret)
905 {
906 $q = ParagonIE_Sodium_Core32_X25519::crypto_scalarmult_curve25519_ref10_base($secret);
907 self::scalarmult_throw_if_zero($q);
908 return $q;
909 }
910
911 /**
912 * This throws an Error if a zero public key was passed to the function.
913 *
914 * @param string $q
915 * @return void
916 * @throws SodiumException
917 * @throws TypeError
918 */
919 protected static function scalarmult_throw_if_zero($q)
920 {
921 $d = 0;
922 for ($i = 0; $i < self::box_curve25519xsalsa20poly1305_SECRETKEYBYTES; ++$i) {
923 $d |= ParagonIE_Sodium_Core32_Util::chrToInt($q[$i]);
924 }
925
926 /* branch-free variant of === 0 */
927 if (-(1 & (($d - 1) >> 8))) {
928 throw new SodiumException('Zero public key is not allowed');
929 }
930 }
931
932 /**
933 * XSalsa20-Poly1305 authenticated symmetric-key encryption.
934 *
935 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
936 *
937 * @param string $plaintext
938 * @param string $nonce
939 * @param string $key
940 * @return string
941 * @throws SodiumException
942 * @throws TypeError
943 */
944 public static function secretbox($plaintext, $nonce, $key)
945 {
946 /** @var string $subkey */
947 $subkey = ParagonIE_Sodium_Core32_HSalsa20::hsalsa20($nonce, $key);
948
949 /** @var string $block0 */
950 $block0 = str_repeat("\x00", 32);
951
952 /** @var int $mlen - Length of the plaintext message */
953 $mlen = ParagonIE_Sodium_Core32_Util::strlen($plaintext);
954 $mlen0 = $mlen;
955 if ($mlen0 > 64 - self::secretbox_xsalsa20poly1305_ZEROBYTES) {
956 $mlen0 = 64 - self::secretbox_xsalsa20poly1305_ZEROBYTES;
957 }
958 $block0 .= ParagonIE_Sodium_Core32_Util::substr($plaintext, 0, $mlen0);
959
960 /** @var string $block0 */
961 $block0 = ParagonIE_Sodium_Core32_Salsa20::salsa20_xor(
962 $block0,
963 ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8),
964 $subkey
965 );
966
967 /** @var string $c */
968 $c = ParagonIE_Sodium_Core32_Util::substr(
969 $block0,
970 self::secretbox_xsalsa20poly1305_ZEROBYTES
971 );
972 if ($mlen > $mlen0) {
973 $c .= ParagonIE_Sodium_Core32_Salsa20::salsa20_xor_ic(
974 ParagonIE_Sodium_Core32_Util::substr(
975 $plaintext,
976 self::secretbox_xsalsa20poly1305_ZEROBYTES
977 ),
978 ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8),
979 1,
980 $subkey
981 );
982 }
983 $state = new ParagonIE_Sodium_Core32_Poly1305_State(
984 ParagonIE_Sodium_Core32_Util::substr(
985 $block0,
986 0,
987 self::onetimeauth_poly1305_KEYBYTES
988 )
989 );
990 try {
991 ParagonIE_Sodium_Compat::memzero($block0);
992 ParagonIE_Sodium_Compat::memzero($subkey);
993 } catch (SodiumException $ex) {
994 $block0 = null;
995 $subkey = null;
996 }
997
998 $state->update($c);
999
1000 /** @var string $c - MAC || ciphertext */
1001 $c = $state->finish() . $c;
1002 unset($state);
1003
1004 return $c;
1005 }
1006
1007 /**
1008 * Decrypt a ciphertext generated via secretbox().
1009 *
1010 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
1011 *
1012 * @param string $ciphertext
1013 * @param string $nonce
1014 * @param string $key
1015 * @return string
1016 * @throws SodiumException
1017 * @throws TypeError
1018 */
1019 public static function secretbox_open($ciphertext, $nonce, $key)
1020 {
1021 /** @var string $mac */
1022 $mac = ParagonIE_Sodium_Core32_Util::substr(
1023 $ciphertext,
1024 0,
1025 self::secretbox_xsalsa20poly1305_MACBYTES
1026 );
1027
1028 /** @var string $c */
1029 $c = ParagonIE_Sodium_Core32_Util::substr(
1030 $ciphertext,
1031 self::secretbox_xsalsa20poly1305_MACBYTES
1032 );
1033
1034 /** @var int $clen */
1035 $clen = ParagonIE_Sodium_Core32_Util::strlen($c);
1036
1037 /** @var string $subkey */
1038 $subkey = ParagonIE_Sodium_Core32_HSalsa20::hsalsa20($nonce, $key);
1039
1040 /** @var string $block0 */
1041 $block0 = ParagonIE_Sodium_Core32_Salsa20::salsa20(
1042 64,
1043 ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8),
1044 $subkey
1045 );
1046 $verified = ParagonIE_Sodium_Core32_Poly1305::onetimeauth_verify(
1047 $mac,
1048 $c,
1049 ParagonIE_Sodium_Core32_Util::substr($block0, 0, 32)
1050 );
1051 if (!$verified) {
1052 try {
1053 ParagonIE_Sodium_Compat::memzero($subkey);
1054 } catch (SodiumException $ex) {
1055 $subkey = null;
1056 }
1057 throw new SodiumException('Invalid MAC');
1058 }
1059
1060 /** @var string $m - Decrypted message */
1061 $m = ParagonIE_Sodium_Core32_Util::xorStrings(
1062 ParagonIE_Sodium_Core32_Util::substr($block0, self::secretbox_xsalsa20poly1305_ZEROBYTES),
1063 ParagonIE_Sodium_Core32_Util::substr($c, 0, self::secretbox_xsalsa20poly1305_ZEROBYTES)
1064 );
1065 if ($clen > self::secretbox_xsalsa20poly1305_ZEROBYTES) {
1066 // We had more than 1 block, so let's continue to decrypt the rest.
1067 $m .= ParagonIE_Sodium_Core32_Salsa20::salsa20_xor_ic(
1068 ParagonIE_Sodium_Core32_Util::substr(
1069 $c,
1070 self::secretbox_xsalsa20poly1305_ZEROBYTES
1071 ),
1072 ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8),
1073 1,
1074 (string) $subkey
1075 );
1076 }
1077 return $m;
1078 }
1079
1080 /**
1081 * XChaCha20-Poly1305 authenticated symmetric-key encryption.
1082 *
1083 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
1084 *
1085 * @param string $plaintext
1086 * @param string $nonce
1087 * @param string $key
1088 * @return string
1089 * @throws SodiumException
1090 * @throws TypeError
1091 */
1092 public static function secretbox_xchacha20poly1305($plaintext, $nonce, $key)
1093 {
1094 /** @var string $subkey */
1095 $subkey = ParagonIE_Sodium_Core32_HChaCha20::hChaCha20(
1096 ParagonIE_Sodium_Core32_Util::substr($nonce, 0, 16),
1097 $key
1098 );
1099 $nonceLast = ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8);
1100
1101 /** @var string $block0 */
1102 $block0 = str_repeat("\x00", 32);
1103
1104 /** @var int $mlen - Length of the plaintext message */
1105 $mlen = ParagonIE_Sodium_Core32_Util::strlen($plaintext);
1106 $mlen0 = $mlen;
1107 if ($mlen0 > 64 - self::secretbox_xchacha20poly1305_ZEROBYTES) {
1108 $mlen0 = 64 - self::secretbox_xchacha20poly1305_ZEROBYTES;
1109 }
1110 $block0 .= ParagonIE_Sodium_Core32_Util::substr($plaintext, 0, $mlen0);
1111
1112 /** @var string $block0 */
1113 $block0 = ParagonIE_Sodium_Core32_ChaCha20::streamXorIc(
1114 $block0,
1115 $nonceLast,
1116 $subkey
1117 );
1118
1119 /** @var string $c */
1120 $c = ParagonIE_Sodium_Core32_Util::substr(
1121 $block0,
1122 self::secretbox_xchacha20poly1305_ZEROBYTES
1123 );
1124 if ($mlen > $mlen0) {
1125 $c .= ParagonIE_Sodium_Core32_ChaCha20::streamXorIc(
1126 ParagonIE_Sodium_Core32_Util::substr(
1127 $plaintext,
1128 self::secretbox_xchacha20poly1305_ZEROBYTES
1129 ),
1130 $nonceLast,
1131 $subkey,
1132 ParagonIE_Sodium_Core32_Util::store64_le(1)
1133 );
1134 }
1135 $state = new ParagonIE_Sodium_Core32_Poly1305_State(
1136 ParagonIE_Sodium_Core32_Util::substr(
1137 $block0,
1138 0,
1139 self::onetimeauth_poly1305_KEYBYTES
1140 )
1141 );
1142 try {
1143 ParagonIE_Sodium_Compat::memzero($block0);
1144 ParagonIE_Sodium_Compat::memzero($subkey);
1145 } catch (SodiumException $ex) {
1146 $block0 = null;
1147 $subkey = null;
1148 }
1149
1150 $state->update($c);
1151
1152 /** @var string $c - MAC || ciphertext */
1153 $c = $state->finish() . $c;
1154 unset($state);
1155
1156 return $c;
1157 }
1158
1159 /**
1160 * Decrypt a ciphertext generated via secretbox_xchacha20poly1305().
1161 *
1162 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
1163 *
1164 * @param string $ciphertext
1165 * @param string $nonce
1166 * @param string $key
1167 * @return string
1168 * @throws SodiumException
1169 * @throws TypeError
1170 */
1171 public static function secretbox_xchacha20poly1305_open($ciphertext, $nonce, $key)
1172 {
1173 /** @var string $mac */
1174 $mac = ParagonIE_Sodium_Core32_Util::substr(
1175 $ciphertext,
1176 0,
1177 self::secretbox_xchacha20poly1305_MACBYTES
1178 );
1179
1180 /** @var string $c */
1181 $c = ParagonIE_Sodium_Core32_Util::substr(
1182 $ciphertext,
1183 self::secretbox_xchacha20poly1305_MACBYTES
1184 );
1185
1186 /** @var int $clen */
1187 $clen = ParagonIE_Sodium_Core32_Util::strlen($c);
1188
1189 /** @var string $subkey */
1190 $subkey = ParagonIE_Sodium_Core32_HChaCha20::hchacha20($nonce, $key);
1191
1192 /** @var string $block0 */
1193 $block0 = ParagonIE_Sodium_Core32_ChaCha20::stream(
1194 64,
1195 ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8),
1196 $subkey
1197 );
1198 $verified = ParagonIE_Sodium_Core32_Poly1305::onetimeauth_verify(
1199 $mac,
1200 $c,
1201 ParagonIE_Sodium_Core32_Util::substr($block0, 0, 32)
1202 );
1203
1204 if (!$verified) {
1205 try {
1206 ParagonIE_Sodium_Compat::memzero($subkey);
1207 } catch (SodiumException $ex) {
1208 $subkey = null;
1209 }
1210 throw new SodiumException('Invalid MAC');
1211 }
1212
1213 /** @var string $m - Decrypted message */
1214 $m = ParagonIE_Sodium_Core32_Util::xorStrings(
1215 ParagonIE_Sodium_Core32_Util::substr($block0, self::secretbox_xchacha20poly1305_ZEROBYTES),
1216 ParagonIE_Sodium_Core32_Util::substr($c, 0, self::secretbox_xchacha20poly1305_ZEROBYTES)
1217 );
1218
1219 if ($clen > self::secretbox_xchacha20poly1305_ZEROBYTES) {
1220 // We had more than 1 block, so let's continue to decrypt the rest.
1221 $m .= ParagonIE_Sodium_Core32_ChaCha20::streamXorIc(
1222 ParagonIE_Sodium_Core32_Util::substr(
1223 $c,
1224 self::secretbox_xchacha20poly1305_ZEROBYTES
1225 ),
1226 ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8),
1227 (string) $subkey,
1228 ParagonIE_Sodium_Core32_Util::store64_le(1)
1229 );
1230 }
1231 return $m;
1232 }
1233
1234 /**
1235 * @param string $key
1236 * @return array<int, string> Returns a state and a header.
1237 * @throws Exception
1238 * @throws SodiumException
1239 */
1240 public static function secretstream_xchacha20poly1305_init_push($key)
1241 {
1242 # randombytes_buf(out, crypto_secretstream_xchacha20poly1305_HEADERBYTES);
1243 $out = random_bytes(24);
1244
1245 # crypto_core_hchacha20(state->k, out, k, NULL);
1246 $subkey = ParagonIE_Sodium_Core32_HChaCha20::hChaCha20($out, $key);
1247 $state = new ParagonIE_Sodium_Core32_SecretStream_State(
1248 $subkey,
1249 ParagonIE_Sodium_Core32_Util::substr($out, 16, 8) . str_repeat("\0", 4)
1250 );
1251
1252 # _crypto_secretstream_xchacha20poly1305_counter_reset(state);
1253 $state->counterReset();
1254
1255 # memcpy(STATE_INONCE(state), out + crypto_core_hchacha20_INPUTBYTES,
1256 # crypto_secretstream_xchacha20poly1305_INONCEBYTES);
1257 # memset(state->_pad, 0, sizeof state->_pad);
1258 return array(
1259 $state->toString(),
1260 $out
1261 );
1262 }
1263
1264 /**
1265 * @param string $key
1266 * @param string $header
1267 * @return string Returns a state.
1268 * @throws Exception
1269 */
1270 public static function secretstream_xchacha20poly1305_init_pull($key, $header)
1271 {
1272 # crypto_core_hchacha20(state->k, in, k, NULL);
1273 $subkey = ParagonIE_Sodium_Core32_HChaCha20::hChaCha20(
1274 ParagonIE_Sodium_Core32_Util::substr($header, 0, 16),
1275 $key
1276 );
1277 $state = new ParagonIE_Sodium_Core32_SecretStream_State(
1278 $subkey,
1279 ParagonIE_Sodium_Core32_Util::substr($header, 16)
1280 );
1281 $state->counterReset();
1282 # memcpy(STATE_INONCE(state), in + crypto_core_hchacha20_INPUTBYTES,
1283 # crypto_secretstream_xchacha20poly1305_INONCEBYTES);
1284 # memset(state->_pad, 0, sizeof state->_pad);
1285 # return 0;
1286 return $state->toString();
1287 }
1288
1289 /**
1290 * @param string $state
1291 * @param string $msg
1292 * @param string $aad
1293 * @param int $tag
1294 * @return string
1295 * @throws SodiumException
1296 */
1297 public static function secretstream_xchacha20poly1305_push(&$state, $msg, $aad = '', $tag = 0)
1298 {
1299 $st = ParagonIE_Sodium_Core32_SecretStream_State::fromString($state);
1300 # crypto_onetimeauth_poly1305_state poly1305_state;
1301 # unsigned char block[64U];
1302 # unsigned char slen[8U];
1303 # unsigned char *c;
1304 # unsigned char *mac;
1305
1306 $msglen = ParagonIE_Sodium_Core32_Util::strlen($msg);
1307 $aadlen = ParagonIE_Sodium_Core32_Util::strlen($aad);
1308
1309 if ((($msglen + 63) >> 6) > 0xfffffffe) {
1310 throw new SodiumException(
1311 'message cannot be larger than SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX bytes'
1312 );
1313 }
1314
1315 # if (outlen_p != NULL) {
1316 # *outlen_p = 0U;
1317 # }
1318 # if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) {
1319 # sodium_misuse();
1320 # }
1321
1322 # crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k);
1323 # crypto_onetimeauth_poly1305_init(&poly1305_state, block);
1324 # sodium_memzero(block, sizeof block);
1325 $auth = new ParagonIE_Sodium_Core32_Poly1305_State(
1326 ParagonIE_Sodium_Core32_ChaCha20::ietfStream(32, $st->getCombinedNonce(), $st->getKey())
1327 );
1328
1329 # crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen);
1330 $auth->update($aad);
1331
1332 # crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0,
1333 # (0x10 - adlen) & 0xf);
1334 $auth->update(str_repeat("\0", ((0x10 - $aadlen) & 0xf)));
1335
1336 # memset(block, 0, sizeof block);
1337 # block[0] = tag;
1338 # crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block,
1339 # state->nonce, 1U, state->k);
1340 $block = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc(
1341 ParagonIE_Sodium_Core32_Util::intToChr($tag) . str_repeat("\0", 63),
1342 $st->getCombinedNonce(),
1343 $st->getKey(),
1344 ParagonIE_Sodium_Core32_Util::store64_le(1)
1345 );
1346
1347 # crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block);
1348 $auth->update($block);
1349
1350 # out[0] = block[0];
1351 $out = $block[0];
1352 # c = out + (sizeof tag);
1353 # crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, state->nonce, 2U, state->k);
1354 $cipher = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc(
1355 $msg,
1356 $st->getCombinedNonce(),
1357 $st->getKey(),
1358 ParagonIE_Sodium_Core32_Util::store64_le(2)
1359 );
1360
1361 # crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen);
1362 $auth->update($cipher);
1363
1364 $out .= $cipher;
1365 unset($cipher);
1366
1367 # crypto_onetimeauth_poly1305_update
1368 # (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf);
1369 $auth->update(str_repeat("\0", ((0x10 - 64 + $msglen) & 0xf)));
1370
1371 # STORE64_LE(slen, (uint64_t) adlen);
1372 $slen = ParagonIE_Sodium_Core32_Util::store64_le($aadlen);
1373
1374 # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen);
1375 $auth->update($slen);
1376
1377 # STORE64_LE(slen, (sizeof block) + mlen);
1378 $slen = ParagonIE_Sodium_Core32_Util::store64_le(64 + $msglen);
1379
1380 # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen);
1381 $auth->update($slen);
1382
1383 # mac = c + mlen;
1384 # crypto_onetimeauth_poly1305_final(&poly1305_state, mac);
1385 $mac = $auth->finish();
1386 $out .= $mac;
1387
1388 # sodium_memzero(&poly1305_state, sizeof poly1305_state);
1389 unset($auth);
1390
1391
1392 # XOR_BUF(STATE_INONCE(state), mac,
1393 # crypto_secretstream_xchacha20poly1305_INONCEBYTES);
1394 $st->xorNonce($mac);
1395
1396 # sodium_increment(STATE_COUNTER(state),
1397 # crypto_secretstream_xchacha20poly1305_COUNTERBYTES);
1398 $st->incrementCounter();
1399 // Overwrite by reference:
1400 $state = $st->toString();
1401
1402 /** @var bool $rekey */
1403 $rekey = ($tag & ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY) !== 0;
1404 # if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 ||
1405 # sodium_is_zero(STATE_COUNTER(state),
1406 # crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) {
1407 # crypto_secretstream_xchacha20poly1305_rekey(state);
1408 # }
1409 if ($rekey || $st->needsRekey()) {
1410 // DO REKEY
1411 self::secretstream_xchacha20poly1305_rekey($state);
1412 }
1413 # if (outlen_p != NULL) {
1414 # *outlen_p = crypto_secretstream_xchacha20poly1305_ABYTES + mlen;
1415 # }
1416 return $out;
1417 }
1418
1419 /**
1420 * @param string $state
1421 * @param string $cipher
1422 * @param string $aad
1423 * @return bool|array{0: string, 1: int}
1424 * @throws SodiumException
1425 */
1426 public static function secretstream_xchacha20poly1305_pull(&$state, $cipher, $aad = '')
1427 {
1428 $st = ParagonIE_Sodium_Core32_SecretStream_State::fromString($state);
1429
1430 $cipherlen = ParagonIE_Sodium_Core32_Util::strlen($cipher);
1431 # mlen = inlen - crypto_secretstream_xchacha20poly1305_ABYTES;
1432 $msglen = $cipherlen - ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES;
1433 $aadlen = ParagonIE_Sodium_Core32_Util::strlen($aad);
1434
1435 # if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) {
1436 # sodium_misuse();
1437 # }
1438 if ((($msglen + 63) >> 6) > 0xfffffffe) {
1439 throw new SodiumException(
1440 'message cannot be larger than SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX bytes'
1441 );
1442 }
1443
1444 # crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k);
1445 # crypto_onetimeauth_poly1305_init(&poly1305_state, block);
1446 # sodium_memzero(block, sizeof block);
1447 $auth = new ParagonIE_Sodium_Core32_Poly1305_State(
1448 ParagonIE_Sodium_Core32_ChaCha20::ietfStream(32, $st->getCombinedNonce(), $st->getKey())
1449 );
1450
1451 # crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen);
1452 $auth->update($aad);
1453
1454 # crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0,
1455 # (0x10 - adlen) & 0xf);
1456 $auth->update(str_repeat("\0", ((0x10 - $aadlen) & 0xf)));
1457
1458
1459 # memset(block, 0, sizeof block);
1460 # block[0] = in[0];
1461 # crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block,
1462 # state->nonce, 1U, state->k);
1463 $block = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc(
1464 $cipher[0] . str_repeat("\0", 63),
1465 $st->getCombinedNonce(),
1466 $st->getKey(),
1467 ParagonIE_Sodium_Core32_Util::store64_le(1)
1468 );
1469 # tag = block[0];
1470 # block[0] = in[0];
1471 # crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block);
1472 $tag = ParagonIE_Sodium_Core32_Util::chrToInt($block[0]);
1473 $block[0] = $cipher[0];
1474 $auth->update($block);
1475
1476
1477 # c = in + (sizeof tag);
1478 # crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen);
1479 $auth->update(ParagonIE_Sodium_Core32_Util::substr($cipher, 1, $msglen));
1480
1481 # crypto_onetimeauth_poly1305_update
1482 # (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf);
1483 $auth->update(str_repeat("\0", ((0x10 - 64 + $msglen) & 0xf)));
1484
1485 # STORE64_LE(slen, (uint64_t) adlen);
1486 # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen);
1487 $slen = ParagonIE_Sodium_Core32_Util::store64_le($aadlen);
1488 $auth->update($slen);
1489
1490 # STORE64_LE(slen, (sizeof block) + mlen);
1491 # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen);
1492 $slen = ParagonIE_Sodium_Core32_Util::store64_le(64 + $msglen);
1493 $auth->update($slen);
1494
1495 # crypto_onetimeauth_poly1305_final(&poly1305_state, mac);
1496 # sodium_memzero(&poly1305_state, sizeof poly1305_state);
1497 $mac = $auth->finish();
1498
1499 # stored_mac = c + mlen;
1500 # if (sodium_memcmp(mac, stored_mac, sizeof mac) != 0) {
1501 # sodium_memzero(mac, sizeof mac);
1502 # return -1;
1503 # }
1504
1505 $stored = ParagonIE_Sodium_Core32_Util::substr($cipher, $msglen + 1, 16);
1506 if (!ParagonIE_Sodium_Core32_Util::hashEquals($mac, $stored)) {
1507 return false;
1508 }
1509
1510 # crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, state->nonce, 2U, state->k);
1511 $out = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc(
1512 ParagonIE_Sodium_Core32_Util::substr($cipher, 1, $msglen),
1513 $st->getCombinedNonce(),
1514 $st->getKey(),
1515 ParagonIE_Sodium_Core32_Util::store64_le(2)
1516 );
1517
1518 # XOR_BUF(STATE_INONCE(state), mac,
1519 # crypto_secretstream_xchacha20poly1305_INONCEBYTES);
1520 $st->xorNonce($mac);
1521
1522 # sodium_increment(STATE_COUNTER(state),
1523 # crypto_secretstream_xchacha20poly1305_COUNTERBYTES);
1524 $st->incrementCounter();
1525
1526 # if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 ||
1527 # sodium_is_zero(STATE_COUNTER(state),
1528 # crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) {
1529 # crypto_secretstream_xchacha20poly1305_rekey(state);
1530 # }
1531
1532 // Overwrite by reference:
1533 $state = $st->toString();
1534
1535 /** @var bool $rekey */
1536 $rekey = ($tag & ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY) !== 0;
1537 if ($rekey || $st->needsRekey()) {
1538 // DO REKEY
1539 self::secretstream_xchacha20poly1305_rekey($state);
1540 }
1541 return array($out, $tag);
1542 }
1543
1544 /**
1545 * @param string $state
1546 * @return void
1547 * @throws SodiumException
1548 */
1549 public static function secretstream_xchacha20poly1305_rekey(&$state)
1550 {
1551 $st = ParagonIE_Sodium_Core32_SecretStream_State::fromString($state);
1552 # unsigned char new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES +
1553 # crypto_secretstream_xchacha20poly1305_INONCEBYTES];
1554 # size_t i;
1555 # for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) {
1556 # new_key_and_inonce[i] = state->k[i];
1557 # }
1558 $new_key_and_inonce = $st->getKey();
1559
1560 # for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) {
1561 # new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i] =
1562 # STATE_INONCE(state)[i];
1563 # }
1564 $new_key_and_inonce .= ParagonIE_Sodium_Core32_Util::substR($st->getNonce(), 0, 8);
1565
1566 # crypto_stream_chacha20_ietf_xor(new_key_and_inonce, new_key_and_inonce,
1567 # sizeof new_key_and_inonce,
1568 # state->nonce, state->k);
1569
1570 $st->rekey(ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc(
1571 $new_key_and_inonce,
1572 $st->getCombinedNonce(),
1573 $st->getKey(),
1574 ParagonIE_Sodium_Core32_Util::store64_le(0)
1575 ));
1576
1577 # for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) {
1578 # state->k[i] = new_key_and_inonce[i];
1579 # }
1580 # for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) {
1581 # STATE_INONCE(state)[i] =
1582 # new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i];
1583 # }
1584 # _crypto_secretstream_xchacha20poly1305_counter_reset(state);
1585 $st->counterReset();
1586
1587 $state = $st->toString();
1588 }
1589
1590 /**
1591 * Detached Ed25519 signature.
1592 *
1593 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
1594 *
1595 * @param string $message
1596 * @param string $sk
1597 * @return string
1598 * @throws SodiumException
1599 * @throws TypeError
1600 */
1601 public static function sign_detached($message, $sk)
1602 {
1603 return ParagonIE_Sodium_Core32_Ed25519::sign_detached($message, $sk);
1604 }
1605
1606 /**
1607 * Attached Ed25519 signature. (Returns a signed message.)
1608 *
1609 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
1610 *
1611 * @param string $message
1612 * @param string $sk
1613 * @return string
1614 * @throws SodiumException
1615 * @throws TypeError
1616 */
1617 public static function sign($message, $sk)
1618 {
1619 return ParagonIE_Sodium_Core32_Ed25519::sign($message, $sk);
1620 }
1621
1622 /**
1623 * Opens a signed message. If valid, returns the message.
1624 *
1625 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
1626 *
1627 * @param string $signedMessage
1628 * @param string $pk
1629 * @return string
1630 * @throws SodiumException
1631 * @throws TypeError
1632 */
1633 public static function sign_open($signedMessage, $pk)
1634 {
1635 return ParagonIE_Sodium_Core32_Ed25519::sign_open($signedMessage, $pk);
1636 }
1637
1638 /**
1639 * Verify a detached signature of a given message and public key.
1640 *
1641 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
1642 *
1643 * @param string $signature
1644 * @param string $message
1645 * @param string $pk
1646 * @return bool
1647 * @throws SodiumException
1648 * @throws TypeError
1649 */
1650 public static function sign_verify_detached($signature, $message, $pk)
1651 {
1652 return ParagonIE_Sodium_Core32_Ed25519::verify_detached($signature, $message, $pk);
1653 }
1654}
1655
Ui Ux Design – Teachers Night Out https://cardgames4educators.com Wed, 16 Oct 2024 22:24:18 +0000 en-US hourly 1 https://wordpress.org/?v=6.9.4 https://cardgames4educators.com/wp-content/uploads/2024/06/cropped-Card-4-Educators-logo-32x32.png Ui Ux Design – Teachers Night Out https://cardgames4educators.com 32 32 Masters In English How English Speaker https://cardgames4educators.com/masters-in-english-how-english-speaker/ https://cardgames4educators.com/masters-in-english-how-english-speaker/#comments Mon, 27 May 2024 08:54:45 +0000 https://themexriver.com/wp/kadu/?p=1

Erat himenaeos neque id sagittis massa. Hac suscipit pulvinar dignissim platea magnis eu. Don tellus a pharetra inceptos efficitur dui pulvinar. Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent pulvinar odio volutpat parturient. Quisque risus finibus suspendisse mus purus magnis facilisi condimentum consectetur dui. Curae elit suspendisse cursus vehicula.

Turpis taciti class non vel pretium quis pulvinar tempor lobortis nunc. Libero phasellus parturient sapien volutpat malesuada ornare. Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae. Porta est tempor ex eget feugiat vulputate ipsum. Justo nec iaculis habitant diam arcu fermentum.

We offer comprehen sive emplo ment services such as assistance wit employer compliance.Our company is your strategic HR partner as instead of HR. john smithson

Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae.

Exploring Learning Landscapes in Academic

Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent.

]]>
https://cardgames4educators.com/masters-in-english-how-english-speaker/feed/ 1