Diff: STRATO-apps/wordpress_03/app/wp-includes/sodium_compat/src/Core/BLAKE2b.php
Keine Baseline-Datei – Diff nur gegen leer.
1
-
1
+
<?php
2
+
3
+
if (class_exists('ParagonIE_Sodium_Core_BLAKE2b', false)) {
4
+
return;
5
+
}
6
+
7
+
/**
8
+
* Class ParagonIE_Sodium_Core_BLAKE2b
9
+
*
10
+
* Based on the work of Devi Mandiri in devi/salt.
11
+
*/
12
+
abstract class ParagonIE_Sodium_Core_BLAKE2b extends ParagonIE_Sodium_Core_Util
13
+
{
14
+
/**
15
+
* @var SplFixedArray
16
+
*/
17
+
protected static $iv;
18
+
19
+
/**
20
+
* @var array<int, array<int, int>>
21
+
*/
22
+
protected static $sigma = array(
23
+
array( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15),
24
+
array( 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3),
25
+
array( 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4),
26
+
array( 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8),
27
+
array( 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13),
28
+
array( 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9),
29
+
array( 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11),
30
+
array( 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10),
31
+
array( 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5),
32
+
array( 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0),
33
+
array( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15),
34
+
array( 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3)
35
+
);
36
+
37
+
const BLOCKBYTES = 128;
38
+
const OUTBYTES = 64;
39
+
const KEYBYTES = 64;
40
+
41
+
/**
42
+
* Turn two 32-bit integers into a fixed array representing a 64-bit integer.
43
+
*
44
+
* @internal You should not use this directly from another application
45
+
*
46
+
* @param int $high
47
+
* @param int $low
48
+
* @return SplFixedArray
49
+
* @psalm-suppress MixedAssignment
50
+
*/
51
+
public static function new64($high, $low)
52
+
{
53
+
if (PHP_INT_SIZE === 4) {
54
+
throw new SodiumException("Error, use 32-bit");
55
+
}
56
+
$i64 = new SplFixedArray(2);
57
+
$i64[0] = $high & 0xffffffff;
58
+
$i64[1] = $low & 0xffffffff;
59
+
return $i64;
60
+
}
61
+
62
+
/**
63
+
* Convert an arbitrary number into an SplFixedArray of two 32-bit integers
64
+
* that represents a 64-bit integer.
65
+
*
66
+
* @internal You should not use this directly from another application
67
+
*
68
+
* @param int $num
69
+
* @return SplFixedArray
70
+
*/
71
+
protected static function to64($num)
72
+
{
73
+
list($hi, $lo) = self::numericTo64BitInteger($num);
74
+
return self::new64($hi, $lo);
75
+
}
76
+
77
+
/**
78
+
* Adds two 64-bit integers together, returning their sum as a SplFixedArray
79
+
* containing two 32-bit integers (representing a 64-bit integer).
80
+
*
81
+
* @internal You should not use this directly from another application
82
+
*
83
+
* @param SplFixedArray $x
84
+
* @param SplFixedArray $y
85
+
* @return SplFixedArray
86
+
* @psalm-suppress MixedArgument
87
+
* @psalm-suppress MixedAssignment
88
+
* @psalm-suppress MixedOperand
89
+
*/
90
+
protected static function add64($x, $y)
91
+
{
92
+
if (PHP_INT_SIZE === 4) {
93
+
throw new SodiumException("Error, use 32-bit");
94
+
}
95
+
$l = ($x[1] + $y[1]) & 0xffffffff;
96
+
return self::new64(
97
+
(int) ($x[0] + $y[0] + (
98
+
($l < $x[1]) ? 1 : 0
99
+
)),
100
+
(int) $l
101
+
);
102
+
}
103
+
104
+
/**
105
+
* @internal You should not use this directly from another application
106
+
*
107
+
* @param SplFixedArray $x
108
+
* @param SplFixedArray $y
109
+
* @param SplFixedArray $z
110
+
* @return SplFixedArray
111
+
*/
112
+
protected static function add364($x, $y, $z)
113
+
{
114
+
return self::add64($x, self::add64($y, $z));
115
+
}
116
+
117
+
/**
118
+
* @internal You should not use this directly from another application
119
+
*
120
+
* @param SplFixedArray $x
121
+
* @param SplFixedArray $y
122
+
* @return SplFixedArray
123
+
* @throws SodiumException
124
+
* @throws TypeError
125
+
*/
126
+
protected static function xor64(SplFixedArray $x, SplFixedArray $y)
127
+
{
128
+
if (PHP_INT_SIZE === 4) {
129
+
throw new SodiumException("Error, use 32-bit");
130
+
}
131
+
if (!is_numeric($x[0])) {
132
+
throw new SodiumException('x[0] is not an integer');
133
+
}
134
+
if (!is_numeric($x[1])) {
135
+
throw new SodiumException('x[1] is not an integer');
136
+
}
137
+
if (!is_numeric($y[0])) {
138
+
throw new SodiumException('y[0] is not an integer');
139
+
}
140
+
if (!is_numeric($y[1])) {
141
+
throw new SodiumException('y[1] is not an integer');
142
+
}
143
+
return self::new64(
144
+
(int) (($x[0] ^ $y[0]) & 0xffffffff),
145
+
(int) (($x[1] ^ $y[1]) & 0xffffffff)
146
+
);
147
+
}
148
+
149
+
/**
150
+
* @internal You should not use this directly from another application
151
+
*
152
+
* @param SplFixedArray $x
153
+
* @param int $c
154
+
* @return SplFixedArray
155
+
* @psalm-suppress MixedAssignment
156
+
*/
157
+
public static function rotr64($x, $c)
158
+
{
159
+
if (PHP_INT_SIZE === 4) {
160
+
throw new SodiumException("Error, use 32-bit");
161
+
}
162
+
if ($c >= 64) {
163
+
$c %= 64;
164
+
}
165
+
if ($c >= 32) {
166
+
/** @var int $tmp */
167
+
$tmp = $x[0];
168
+
$x[0] = $x[1];
169
+
$x[1] = $tmp;
170
+
$c -= 32;
171
+
}
172
+
if ($c === 0) {
173
+
return $x;
174
+
}
175
+
176
+
$l0 = 0;
177
+
$c = 64 - $c;
178
+
179
+
/** @var int $c */
180
+
if ($c < 32) {
181
+
$h0 = ((int) ($x[0]) << $c) | (
182
+
(
183
+
(int) ($x[1]) & ((1 << $c) - 1)
184
+
<<
185
+
(32 - $c)
186
+
) >> (32 - $c)
187
+
);
188
+
$l0 = (int) ($x[1]) << $c;
189
+
} else {
190
+
$h0 = (int) ($x[1]) << ($c - 32);
191
+
}
192
+
193
+
$h1 = 0;
194
+
$c1 = 64 - $c;
195
+
196
+
if ($c1 < 32) {
197
+
$h1 = (int) ($x[0]) >> $c1;
198
+
$l1 = ((int) ($x[1]) >> $c1) | ((int) ($x[0]) & ((1 << $c1) - 1)) << (32 - $c1);
199
+
} else {
200
+
$l1 = (int) ($x[0]) >> ($c1 - 32);
201
+
}
202
+
203
+
return self::new64($h0 | $h1, $l0 | $l1);
204
+
}
205
+
206
+
/**
207
+
* @internal You should not use this directly from another application
208
+
*
209
+
* @param SplFixedArray $x
210
+
* @return int
211
+
* @psalm-suppress MixedOperand
212
+
*/
213
+
protected static function flatten64($x)
214
+
{
215
+
return (int) ($x[0] * 4294967296 + $x[1]);
216
+
}
217
+
218
+
/**
219
+
* @internal You should not use this directly from another application
220
+
*
221
+
* @param SplFixedArray $x
222
+
* @param int $i
223
+
* @return SplFixedArray
224
+
* @psalm-suppress MixedArgument
225
+
* @psalm-suppress MixedArrayOffset
226
+
*/
227
+
protected static function load64(SplFixedArray $x, $i)
228
+
{
229
+
/** @var int $l */
230
+
$l = (int) ($x[$i])
231
+
| ((int) ($x[$i+1]) << 8)
232
+
| ((int) ($x[$i+2]) << 16)
233
+
| ((int) ($x[$i+3]) << 24);
234
+
/** @var int $h */
235
+
$h = (int) ($x[$i+4])
236
+
| ((int) ($x[$i+5]) << 8)
237
+
| ((int) ($x[$i+6]) << 16)
238
+
| ((int) ($x[$i+7]) << 24);
239
+
return self::new64($h, $l);
240
+
}
241
+
242
+
/**
243
+
* @internal You should not use this directly from another application
244
+
*
245
+
* @param SplFixedArray $x
246
+
* @param int $i
247
+
* @param SplFixedArray $u
248
+
* @return void
249
+
* @psalm-suppress MixedAssignment
250
+
*/
251
+
protected static function store64(SplFixedArray $x, $i, SplFixedArray $u)
252
+
{
253
+
$maxLength = $x->getSize() - 1;
254
+
for ($j = 0; $j < 8; ++$j) {
255
+
/*
256
+
[0, 1, 2, 3, 4, 5, 6, 7]
257
+
... becomes ...
258
+
[0, 0, 0, 0, 1, 1, 1, 1]
259
+
*/
260
+
/** @var int $uIdx */
261
+
$uIdx = ((7 - $j) & 4) >> 2;
262
+
$x[$i] = ((int) ($u[$uIdx]) & 0xff);
263
+
if (++$i > $maxLength) {
264
+
return;
265
+
}
266
+
/** @psalm-suppress MixedOperand */
267
+
$u[$uIdx] >>= 8;
268
+
}
269
+
}
270
+
271
+
/**
272
+
* This just sets the $iv static variable.
273
+
*
274
+
* @internal You should not use this directly from another application
275
+
*
276
+
* @return void
277
+
*/
278
+
public static function pseudoConstructor()
279
+
{
280
+
static $called = false;
281
+
if ($called) {
282
+
return;
283
+
}
284
+
self::$iv = new SplFixedArray(8);
285
+
self::$iv[0] = self::new64(0x6a09e667, 0xf3bcc908);
286
+
self::$iv[1] = self::new64(0xbb67ae85, 0x84caa73b);
287
+
self::$iv[2] = self::new64(0x3c6ef372, 0xfe94f82b);
288
+
self::$iv[3] = self::new64(0xa54ff53a, 0x5f1d36f1);
289
+
self::$iv[4] = self::new64(0x510e527f, 0xade682d1);
290
+
self::$iv[5] = self::new64(0x9b05688c, 0x2b3e6c1f);
291
+
self::$iv[6] = self::new64(0x1f83d9ab, 0xfb41bd6b);
292
+
self::$iv[7] = self::new64(0x5be0cd19, 0x137e2179);
293
+
294
+
$called = true;
295
+
}
296
+
297
+
/**
298
+
* Returns a fresh BLAKE2 context.
299
+
*
300
+
* @internal You should not use this directly from another application
301
+
*
302
+
* @return SplFixedArray
303
+
* @psalm-suppress MixedAssignment
304
+
* @psalm-suppress MixedArrayAccess
305
+
* @psalm-suppress MixedArrayAssignment
306
+
*/
307
+
protected static function context()
308
+
{
309
+
$ctx = new SplFixedArray(6);
310
+
$ctx[0] = new SplFixedArray(8); // h
311
+
$ctx[1] = new SplFixedArray(2); // t
312
+
$ctx[2] = new SplFixedArray(2); // f
313
+
$ctx[3] = new SplFixedArray(256); // buf
314
+
$ctx[4] = 0; // buflen
315
+
$ctx[5] = 0; // last_node (uint8_t)
316
+
317
+
for ($i = 8; $i--;) {
318
+
$ctx[0][$i] = self::$iv[$i];
319
+
}
320
+
for ($i = 256; $i--;) {
321
+
$ctx[3][$i] = 0;
322
+
}
323
+
324
+
$zero = self::new64(0, 0);
325
+
$ctx[1][0] = $zero;
326
+
$ctx[1][1] = $zero;
327
+
$ctx[2][0] = $zero;
328
+
$ctx[2][1] = $zero;
329
+
330
+
return $ctx;
331
+
}
332
+
333
+
/**
334
+
* @internal You should not use this directly from another application
335
+
*
336
+
* @param SplFixedArray $ctx
337
+
* @param SplFixedArray $buf
338
+
* @return void
339
+
* @throws SodiumException
340
+
* @throws TypeError
341
+
* @psalm-suppress MixedArgument
342
+
* @psalm-suppress MixedAssignment
343
+
* @psalm-suppress MixedArrayAccess
344
+
* @psalm-suppress MixedArrayAssignment
345
+
* @psalm-suppress MixedArrayOffset
346
+
*/
347
+
protected static function compress(SplFixedArray $ctx, SplFixedArray $buf)
348
+
{
349
+
$m = new SplFixedArray(16);
350
+
$v = new SplFixedArray(16);
351
+
352
+
for ($i = 16; $i--;) {
353
+
$m[$i] = self::load64($buf, $i << 3);
354
+
}
355
+
356
+
for ($i = 8; $i--;) {
357
+
$v[$i] = $ctx[0][$i];
358
+
}
359
+
360
+
$v[ 8] = self::$iv[0];
361
+
$v[ 9] = self::$iv[1];
362
+
$v[10] = self::$iv[2];
363
+
$v[11] = self::$iv[3];
364
+
365
+
$v[12] = self::xor64($ctx[1][0], self::$iv[4]);
366
+
$v[13] = self::xor64($ctx[1][1], self::$iv[5]);
367
+
$v[14] = self::xor64($ctx[2][0], self::$iv[6]);
368
+
$v[15] = self::xor64($ctx[2][1], self::$iv[7]);
369
+
370
+
for ($r = 0; $r < 12; ++$r) {
371
+
$v = self::G($r, 0, 0, 4, 8, 12, $v, $m);
372
+
$v = self::G($r, 1, 1, 5, 9, 13, $v, $m);
373
+
$v = self::G($r, 2, 2, 6, 10, 14, $v, $m);
374
+
$v = self::G($r, 3, 3, 7, 11, 15, $v, $m);
375
+
$v = self::G($r, 4, 0, 5, 10, 15, $v, $m);
376
+
$v = self::G($r, 5, 1, 6, 11, 12, $v, $m);
377
+
$v = self::G($r, 6, 2, 7, 8, 13, $v, $m);
378
+
$v = self::G($r, 7, 3, 4, 9, 14, $v, $m);
379
+
}
380
+
381
+
for ($i = 8; $i--;) {
382
+
$ctx[0][$i] = self::xor64(
383
+
$ctx[0][$i], self::xor64($v[$i], $v[$i+8])
384
+
);
385
+
}
386
+
}
387
+
388
+
/**
389
+
* @internal You should not use this directly from another application
390
+
*
391
+
* @param int $r
392
+
* @param int $i
393
+
* @param int $a
394
+
* @param int $b
395
+
* @param int $c
396
+
* @param int $d
397
+
* @param SplFixedArray $v
398
+
* @param SplFixedArray $m
399
+
* @return SplFixedArray
400
+
* @throws SodiumException
401
+
* @throws TypeError
402
+
* @psalm-suppress MixedArgument
403
+
* @psalm-suppress MixedArrayOffset
404
+
*/
405
+
public static function G($r, $i, $a, $b, $c, $d, SplFixedArray $v, SplFixedArray $m)
406
+
{
407
+
$v[$a] = self::add364($v[$a], $v[$b], $m[self::$sigma[$r][$i << 1]]);
408
+
$v[$d] = self::rotr64(self::xor64($v[$d], $v[$a]), 32);
409
+
$v[$c] = self::add64($v[$c], $v[$d]);
410
+
$v[$b] = self::rotr64(self::xor64($v[$b], $v[$c]), 24);
411
+
$v[$a] = self::add364($v[$a], $v[$b], $m[self::$sigma[$r][($i << 1) + 1]]);
412
+
$v[$d] = self::rotr64(self::xor64($v[$d], $v[$a]), 16);
413
+
$v[$c] = self::add64($v[$c], $v[$d]);
414
+
$v[$b] = self::rotr64(self::xor64($v[$b], $v[$c]), 63);
415
+
return $v;
416
+
}
417
+
418
+
/**
419
+
* @internal You should not use this directly from another application
420
+
*
421
+
* @param SplFixedArray $ctx
422
+
* @param int $inc
423
+
* @return void
424
+
* @throws SodiumException
425
+
* @psalm-suppress MixedArgument
426
+
* @psalm-suppress MixedArrayAccess
427
+
* @psalm-suppress MixedArrayAssignment
428
+
*/
429
+
public static function increment_counter($ctx, $inc)
430
+
{
431
+
if ($inc < 0) {
432
+
throw new SodiumException('Increasing by a negative number makes no sense.');
433
+
}
434
+
$t = self::to64($inc);
435
+
# S->t is $ctx[1] in our implementation
436
+
437
+
# S->t[0] = ( uint64_t )( t >> 0 );
438
+
$ctx[1][0] = self::add64($ctx[1][0], $t);
439
+
440
+
# S->t[1] += ( S->t[0] < inc );
441
+
if (self::flatten64($ctx[1][0]) < $inc) {
442
+
$ctx[1][1] = self::add64($ctx[1][1], self::to64(1));
443
+
}
444
+
}
445
+
446
+
/**
447
+
* @internal You should not use this directly from another application
448
+
*
449
+
* @param SplFixedArray $ctx
450
+
* @param SplFixedArray $p
451
+
* @param int $plen
452
+
* @return void
453
+
* @throws SodiumException
454
+
* @throws TypeError
455
+
* @psalm-suppress MixedArgument
456
+
* @psalm-suppress MixedAssignment
457
+
* @psalm-suppress MixedArrayAccess
458
+
* @psalm-suppress MixedArrayAssignment
459
+
* @psalm-suppress MixedArrayOffset
460
+
* @psalm-suppress MixedOperand
461
+
*/
462
+
public static function update(SplFixedArray $ctx, SplFixedArray $p, $plen)
463
+
{
464
+
self::pseudoConstructor();
465
+
466
+
$offset = 0;
467
+
while ($plen > 0) {
468
+
$left = $ctx[4];
469
+
$fill = 256 - $left;
470
+
471
+
if ($plen > $fill) {
472
+
# memcpy( S->buf + left, in, fill ); /* Fill buffer */
473
+
for ($i = $fill; $i--;) {
474
+
$ctx[3][$i + $left] = $p[$i + $offset];
475
+
}
476
+
477
+
# S->buflen += fill;
478
+
$ctx[4] += $fill;
479
+
480
+
# blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
481
+
self::increment_counter($ctx, 128);
482
+
483
+
# blake2b_compress( S, S->buf ); /* Compress */
484
+
self::compress($ctx, $ctx[3]);
485
+
486
+
# memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); /* Shift buffer left */
487
+
for ($i = 128; $i--;) {
488
+
$ctx[3][$i] = $ctx[3][$i + 128];
489
+
}
490
+
491
+
# S->buflen -= BLAKE2B_BLOCKBYTES;
492
+
$ctx[4] -= 128;
493
+
494
+
# in += fill;
495
+
$offset += $fill;
496
+
497
+
# inlen -= fill;
498
+
$plen -= $fill;
499
+
} else {
500
+
for ($i = $plen; $i--;) {
501
+
$ctx[3][$i + $left] = $p[$i + $offset];
502
+
}
503
+
$ctx[4] += $plen;
504
+
$offset += $plen;
505
+
$plen -= $plen;
506
+
}
507
+
}
508
+
}
509
+
510
+
/**
511
+
* @internal You should not use this directly from another application
512
+
*
513
+
* @param SplFixedArray $ctx
514
+
* @param SplFixedArray $out
515
+
* @return SplFixedArray
516
+
* @throws SodiumException
517
+
* @throws TypeError
518
+
* @psalm-suppress MixedArgument
519
+
* @psalm-suppress MixedAssignment
520
+
* @psalm-suppress MixedArrayAccess
521
+
* @psalm-suppress MixedArrayAssignment
522
+
* @psalm-suppress MixedArrayOffset
523
+
* @psalm-suppress MixedOperand
524
+
*/
525
+
public static function finish(SplFixedArray $ctx, SplFixedArray $out)
526
+
{
527
+
self::pseudoConstructor();
528
+
if ($ctx[4] > 128) {
529
+
self::increment_counter($ctx, 128);
530
+
self::compress($ctx, $ctx[3]);
531
+
$ctx[4] -= 128;
532
+
if ($ctx[4] > 128) {
533
+
throw new SodiumException('Failed to assert that buflen <= 128 bytes');
534
+
}
535
+
for ($i = $ctx[4]; $i--;) {
536
+
$ctx[3][$i] = $ctx[3][$i + 128];
537
+
}
538
+
}
539
+
540
+
self::increment_counter($ctx, $ctx[4]);
541
+
$ctx[2][0] = self::new64(0xffffffff, 0xffffffff);
542
+
543
+
for ($i = 256 - $ctx[4]; $i--;) {
544
+
$ctx[3][$i+$ctx[4]] = 0;
545
+
}
546
+
547
+
self::compress($ctx, $ctx[3]);
548
+
549
+
$i = (int) (($out->getSize() - 1) / 8);
550
+
for (; $i >= 0; --$i) {
551
+
self::store64($out, $i << 3, $ctx[0][$i]);
552
+
}
553
+
return $out;
554
+
}
555
+
556
+
/**
557
+
* @internal You should not use this directly from another application
558
+
*
559
+
* @param SplFixedArray|null $key
560
+
* @param int $outlen
561
+
* @param SplFixedArray|null $salt
562
+
* @param SplFixedArray|null $personal
563
+
* @return SplFixedArray
564
+
* @throws SodiumException
565
+
* @throws TypeError
566
+
* @psalm-suppress MixedArgument
567
+
* @psalm-suppress MixedAssignment
568
+
* @psalm-suppress MixedArrayAccess
569
+
* @psalm-suppress MixedArrayAssignment
570
+
* @psalm-suppress MixedArrayOffset
571
+
*/
572
+
public static function init(
573
+
$key = null,
574
+
$outlen = 64,
575
+
$salt = null,
576
+
$personal = null
577
+
) {
578
+
self::pseudoConstructor();
579
+
$klen = 0;
580
+
581
+
if ($key !== null) {
582
+
if (count($key) > 64) {
583
+
throw new SodiumException('Invalid key size');
584
+
}
585
+
$klen = count($key);
586
+
}
587
+
588
+
if ($outlen > 64) {
589
+
throw new SodiumException('Invalid output size');
590
+
}
591
+
592
+
$ctx = self::context();
593
+
594
+
$p = new SplFixedArray(64);
595
+
// Zero our param buffer...
596
+
for ($i = 64; --$i;) {
597
+
$p[$i] = 0;
598
+
}
599
+
600
+
$p[0] = $outlen; // digest_length
601
+
$p[1] = $klen; // key_length
602
+
$p[2] = 1; // fanout
603
+
$p[3] = 1; // depth
604
+
605
+
if ($salt instanceof SplFixedArray) {
606
+
// salt: [32] through [47]
607
+
for ($i = 0; $i < 16; ++$i) {
608
+
$p[32 + $i] = (int) $salt[$i];
609
+
}
610
+
}
611
+
if ($personal instanceof SplFixedArray) {
612
+
// personal: [48] through [63]
613
+
for ($i = 0; $i < 16; ++$i) {
614
+
$p[48 + $i] = (int) $personal[$i];
615
+
}
616
+
}
617
+
618
+
$ctx[0][0] = self::xor64(
619
+
$ctx[0][0],
620
+
self::load64($p, 0)
621
+
);
622
+
if ($salt instanceof SplFixedArray || $personal instanceof SplFixedArray) {
623
+
// We need to do what blake2b_init_param() does:
624
+
for ($i = 1; $i < 8; ++$i) {
625
+
$ctx[0][$i] = self::xor64(
626
+
$ctx[0][$i],
627
+
self::load64($p, $i << 3)
628
+
);
629
+
}
630
+
}
631
+
632
+
if ($klen > 0 && $key instanceof SplFixedArray) {
633
+
$block = new SplFixedArray(128);
634
+
for ($i = 128; $i--;) {
635
+
$block[$i] = 0;
636
+
}
637
+
for ($i = $klen; $i--;) {
638
+
$block[$i] = $key[$i];
639
+
}
640
+
self::update($ctx, $block, 128);
641
+
$ctx[4] = 128;
642
+
}
643
+
644
+
return $ctx;
645
+
}
646
+
647
+
/**
648
+
* Convert a string into an SplFixedArray of integers
649
+
*
650
+
* @internal You should not use this directly from another application
651
+
*
652
+
* @param string $str
653
+
* @return SplFixedArray
654
+
* @psalm-suppress MixedArgumentTypeCoercion
655
+
*/
656
+
public static function stringToSplFixedArray($str = '')
657
+
{
658
+
$values = unpack('C*', $str);
659
+
return SplFixedArray::fromArray(array_values($values));
660
+
}
661
+
662
+
/**
663
+
* Convert an SplFixedArray of integers into a string
664
+
*
665
+
* @internal You should not use this directly from another application
666
+
*
667
+
* @param SplFixedArray $a
668
+
* @return string
669
+
* @throws TypeError
670
+
*/
671
+
public static function SplFixedArrayToString(SplFixedArray $a)
672
+
{
673
+
/**
674
+
* @var array<int, int|string> $arr
675
+
*/
676
+
$arr = $a->toArray();
677
+
$c = $a->count();
678
+
array_unshift($arr, str_repeat('C', $c));
679
+
return (string) (call_user_func_array('pack', $arr));
680
+
}
681
+
682
+
/**
683
+
* @internal You should not use this directly from another application
684
+
*
685
+
* @param SplFixedArray $ctx
686
+
* @return string
687
+
* @throws TypeError
688
+
* @psalm-suppress MixedArgument
689
+
* @psalm-suppress MixedAssignment
690
+
* @psalm-suppress MixedArrayAccess
691
+
* @psalm-suppress MixedArrayAssignment
692
+
* @psalm-suppress MixedArrayOffset
693
+
* @psalm-suppress MixedMethodCall
694
+
*/
695
+
public static function contextToString(SplFixedArray $ctx)
696
+
{
697
+
$str = '';
698
+
/** @var array<int, array<int, int>> $ctxA */
699
+
$ctxA = $ctx[0]->toArray();
700
+
701
+
# uint64_t h[8];
702
+
for ($i = 0; $i < 8; ++$i) {
703
+
$str .= self::store32_le($ctxA[$i][1]);
704
+
$str .= self::store32_le($ctxA[$i][0]);
705
+
}
706
+
707
+
# uint64_t t[2];
708
+
# uint64_t f[2];
709
+
for ($i = 1; $i < 3; ++$i) {
710
+
$ctxA = $ctx[$i]->toArray();
711
+
$str .= self::store32_le($ctxA[0][1]);
712
+
$str .= self::store32_le($ctxA[0][0]);
713
+
$str .= self::store32_le($ctxA[1][1]);
714
+
$str .= self::store32_le($ctxA[1][0]);
715
+
}
716
+
717
+
# uint8_t buf[2 * 128];
718
+
$str .= self::SplFixedArrayToString($ctx[3]);
719
+
720
+
/** @var int $ctx4 */
721
+
$ctx4 = (int) $ctx[4];
722
+
723
+
# size_t buflen;
724
+
$str .= implode('', array(
725
+
self::intToChr($ctx4 & 0xff),
726
+
self::intToChr(($ctx4 >> 8) & 0xff),
727
+
self::intToChr(($ctx4 >> 16) & 0xff),
728
+
self::intToChr(($ctx4 >> 24) & 0xff),
729
+
self::intToChr(($ctx4 >> 32) & 0xff),
730
+
self::intToChr(($ctx4 >> 40) & 0xff),
731
+
self::intToChr(($ctx4 >> 48) & 0xff),
732
+
self::intToChr(($ctx4 >> 56) & 0xff)
733
+
));
734
+
# uint8_t last_node;
735
+
return $str . self::intToChr($ctx[5]) . str_repeat("\x00", 23);
736
+
}
737
+
738
+
/**
739
+
* Creates an SplFixedArray containing other SplFixedArray elements, from
740
+
* a string (compatible with \Sodium\crypto_generichash_{init, update, final})
741
+
*
742
+
* @internal You should not use this directly from another application
743
+
*
744
+
* @param string $string
745
+
* @return SplFixedArray
746
+
* @throws SodiumException
747
+
* @throws TypeError
748
+
* @psalm-suppress MixedArrayAssignment
749
+
*/
750
+
public static function stringToContext($string)
751
+
{
752
+
$ctx = self::context();
753
+
754
+
# uint64_t h[8];
755
+
for ($i = 0; $i < 8; ++$i) {
756
+
$ctx[0][$i] = SplFixedArray::fromArray(
757
+
array(
758
+
self::load_4(
759
+
self::substr($string, (($i << 3) + 4), 4)
760
+
),
761
+
self::load_4(
762
+
self::substr($string, (($i << 3) + 0), 4)
763
+
)
764
+
)
765
+
);
766
+
}
767
+
768
+
# uint64_t t[2];
769
+
# uint64_t f[2];
770
+
for ($i = 1; $i < 3; ++$i) {
771
+
$ctx[$i][1] = SplFixedArray::fromArray(
772
+
array(
773
+
self::load_4(self::substr($string, 76 + (($i - 1) << 4), 4)),
774
+
self::load_4(self::substr($string, 72 + (($i - 1) << 4), 4))
775
+
)
776
+
);
777
+
$ctx[$i][0] = SplFixedArray::fromArray(
778
+
array(
779
+
self::load_4(self::substr($string, 68 + (($i - 1) << 4), 4)),
780
+
self::load_4(self::substr($string, 64 + (($i - 1) << 4), 4))
781
+
)
782
+
);
783
+
}
784
+
785
+
# uint8_t buf[2 * 128];
786
+
$ctx[3] = self::stringToSplFixedArray(self::substr($string, 96, 256));
787
+
788
+
# uint8_t buf[2 * 128];
789
+
$int = 0;
790
+
for ($i = 0; $i < 8; ++$i) {
791
+
$int |= self::chrToInt($string[352 + $i]) << ($i << 3);
792
+
}
793
+
$ctx[4] = $int;
794
+
795
+
return $ctx;
796
+
}
797
+
}
798
+