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