130 } |
130 } |
131 if (!is_numeric($y[1])) { |
131 if (!is_numeric($y[1])) { |
132 throw new SodiumException('y[1] is not an integer'); |
132 throw new SodiumException('y[1] is not an integer'); |
133 } |
133 } |
134 return self::new64( |
134 return self::new64( |
135 (int) ($x[0] ^ $y[0]), |
135 (int) (($x[0] ^ $y[0]) & 0xffffffff), |
136 (int) ($x[1] ^ $y[1]) |
136 (int) (($x[1] ^ $y[1]) & 0xffffffff) |
137 ); |
137 ); |
138 } |
138 } |
139 |
139 |
140 /** |
140 /** |
141 * @internal You should not use this directly from another application |
141 * @internal You should not use this directly from another application |
297 * @psalm-suppress MixedArrayAccess |
297 * @psalm-suppress MixedArrayAccess |
298 * @psalm-suppress MixedArrayAssignment |
298 * @psalm-suppress MixedArrayAssignment |
299 */ |
299 */ |
300 protected static function context() |
300 protected static function context() |
301 { |
301 { |
302 $ctx = new SplFixedArray(5); |
302 $ctx = new SplFixedArray(6); |
303 $ctx[0] = new SplFixedArray(8); // h |
303 $ctx[0] = new SplFixedArray(8); // h |
304 $ctx[1] = new SplFixedArray(2); // t |
304 $ctx[1] = new SplFixedArray(2); // t |
305 $ctx[2] = new SplFixedArray(2); // f |
305 $ctx[2] = new SplFixedArray(2); // f |
306 $ctx[3] = new SplFixedArray(256); // buf |
306 $ctx[3] = new SplFixedArray(256); // buf |
307 $ctx[4] = 0; // buflen |
307 $ctx[4] = 0; // buflen |
|
308 $ctx[5] = 0; // last_node (uint8_t) |
308 |
309 |
309 for ($i = 8; $i--;) { |
310 for ($i = 8; $i--;) { |
310 $ctx[0][$i] = self::$iv[$i]; |
311 $ctx[0][$i] = self::$iv[$i]; |
311 } |
312 } |
312 for ($i = 256; $i--;) { |
313 for ($i = 256; $i--;) { |
548 /** |
549 /** |
549 * @internal You should not use this directly from another application |
550 * @internal You should not use this directly from another application |
550 * |
551 * |
551 * @param SplFixedArray|null $key |
552 * @param SplFixedArray|null $key |
552 * @param int $outlen |
553 * @param int $outlen |
|
554 * @param SplFixedArray|null $salt |
|
555 * @param SplFixedArray|null $personal |
553 * @return SplFixedArray |
556 * @return SplFixedArray |
554 * @throws SodiumException |
557 * @throws SodiumException |
555 * @throws TypeError |
558 * @throws TypeError |
556 * @psalm-suppress MixedArgument |
559 * @psalm-suppress MixedArgument |
557 * @psalm-suppress MixedAssignment |
560 * @psalm-suppress MixedAssignment |
558 * @psalm-suppress MixedArrayAccess |
561 * @psalm-suppress MixedArrayAccess |
559 * @psalm-suppress MixedArrayAssignment |
562 * @psalm-suppress MixedArrayAssignment |
560 * @psalm-suppress MixedArrayOffset |
563 * @psalm-suppress MixedArrayOffset |
561 */ |
564 */ |
562 public static function init($key = null, $outlen = 64) |
565 public static function init( |
563 { |
566 $key = null, |
|
567 $outlen = 64, |
|
568 $salt = null, |
|
569 $personal = null |
|
570 ) { |
564 self::pseudoConstructor(); |
571 self::pseudoConstructor(); |
565 $klen = 0; |
572 $klen = 0; |
566 |
573 |
567 if ($key !== null) { |
574 if ($key !== null) { |
568 if (count($key) > 64) { |
575 if (count($key) > 64) { |
576 } |
583 } |
577 |
584 |
578 $ctx = self::context(); |
585 $ctx = self::context(); |
579 |
586 |
580 $p = new SplFixedArray(64); |
587 $p = new SplFixedArray(64); |
|
588 // Zero our param buffer... |
581 for ($i = 64; --$i;) { |
589 for ($i = 64; --$i;) { |
582 $p[$i] = 0; |
590 $p[$i] = 0; |
583 } |
591 } |
584 |
592 |
585 $p[0] = $outlen; // digest_length |
593 $p[0] = $outlen; // digest_length |
586 $p[1] = $klen; // key_length |
594 $p[1] = $klen; // key_length |
587 $p[2] = 1; // fanout |
595 $p[2] = 1; // fanout |
588 $p[3] = 1; // depth |
596 $p[3] = 1; // depth |
589 |
597 |
|
598 if ($salt instanceof SplFixedArray) { |
|
599 // salt: [32] through [47] |
|
600 for ($i = 0; $i < 16; ++$i) { |
|
601 $p[32 + $i] = (int) $salt[$i]; |
|
602 } |
|
603 } |
|
604 if ($personal instanceof SplFixedArray) { |
|
605 // personal: [48] through [63] |
|
606 for ($i = 0; $i < 16; ++$i) { |
|
607 $p[48 + $i] = (int) $personal[$i]; |
|
608 } |
|
609 } |
|
610 |
590 $ctx[0][0] = self::xor64( |
611 $ctx[0][0] = self::xor64( |
591 $ctx[0][0], |
612 $ctx[0][0], |
592 self::load64($p, 0) |
613 self::load64($p, 0) |
593 ); |
614 ); |
|
615 if ($salt instanceof SplFixedArray || $personal instanceof SplFixedArray) { |
|
616 // We need to do what blake2b_init_param() does: |
|
617 for ($i = 1; $i < 8; ++$i) { |
|
618 $ctx[0][$i] = self::xor64( |
|
619 $ctx[0][$i], |
|
620 self::load64($p, $i << 3) |
|
621 ); |
|
622 } |
|
623 } |
594 |
624 |
595 if ($klen > 0 && $key instanceof SplFixedArray) { |
625 if ($klen > 0 && $key instanceof SplFixedArray) { |
596 $block = new SplFixedArray(128); |
626 $block = new SplFixedArray(128); |
597 for ($i = 128; $i--;) { |
627 for ($i = 128; $i--;) { |
598 $block[$i] = 0; |
628 $block[$i] = 0; |
599 } |
629 } |
600 for ($i = $klen; $i--;) { |
630 for ($i = $klen; $i--;) { |
601 $block[$i] = $key[$i]; |
631 $block[$i] = $key[$i]; |
602 } |
632 } |
603 self::update($ctx, $block, 128); |
633 self::update($ctx, $block, 128); |
|
634 $ctx[4] = 128; |
604 } |
635 } |
605 |
636 |
606 return $ctx; |
637 return $ctx; |
607 } |
638 } |
608 |
639 |
691 self::intToChr(($ctx4 >> 40) & 0xff), |
722 self::intToChr(($ctx4 >> 40) & 0xff), |
692 self::intToChr(($ctx4 >> 48) & 0xff), |
723 self::intToChr(($ctx4 >> 48) & 0xff), |
693 self::intToChr(($ctx4 >> 56) & 0xff) |
724 self::intToChr(($ctx4 >> 56) & 0xff) |
694 )); |
725 )); |
695 # uint8_t last_node; |
726 # uint8_t last_node; |
696 return $str . "\x00"; |
727 return $str . self::intToChr($ctx[5]) . str_repeat("\x00", 23); |
697 } |
728 } |
698 |
729 |
699 /** |
730 /** |
700 * Creates an SplFixedArray containing other SplFixedArray elements, from |
731 * Creates an SplFixedArray containing other SplFixedArray elements, from |
701 * a string (compatible with \Sodium\crypto_generichash_{init, update, final}) |
732 * a string (compatible with \Sodium\crypto_generichash_{init, update, final}) |
744 } |
775 } |
745 |
776 |
746 # uint8_t buf[2 * 128]; |
777 # uint8_t buf[2 * 128]; |
747 $ctx[3] = self::stringToSplFixedArray(self::substr($string, 96, 256)); |
778 $ctx[3] = self::stringToSplFixedArray(self::substr($string, 96, 256)); |
748 |
779 |
749 |
|
750 # uint8_t buf[2 * 128]; |
780 # uint8_t buf[2 * 128]; |
751 $int = 0; |
781 $int = 0; |
752 for ($i = 0; $i < 8; ++$i) { |
782 for ($i = 0; $i < 8; ++$i) { |
753 $int |= self::chrToInt($string[352 + $i]) << ($i << 3); |
783 $int |= self::chrToInt($string[352 + $i]) << ($i << 3); |
754 } |
784 } |