summaryrefslogtreecommitdiffstats
path: root/vendor/paragonie/sodium_compat/src/Core32/Poly1305/State.php
diff options
context:
space:
mode:
authorAnton Luka Šijanec <anton@sijanec.eu>2022-01-11 12:35:47 +0100
committerAnton Luka Šijanec <anton@sijanec.eu>2022-01-11 12:35:47 +0100
commit19985dbb8c0aa66dc4bf7905abc1148de909097d (patch)
tree2cd5a5d20d7e80fc2a51adf60d838d8a2c40999e /vendor/paragonie/sodium_compat/src/Core32/Poly1305/State.php
download1ka-19985dbb8c0aa66dc4bf7905abc1148de909097d.tar
1ka-19985dbb8c0aa66dc4bf7905abc1148de909097d.tar.gz
1ka-19985dbb8c0aa66dc4bf7905abc1148de909097d.tar.bz2
1ka-19985dbb8c0aa66dc4bf7905abc1148de909097d.tar.lz
1ka-19985dbb8c0aa66dc4bf7905abc1148de909097d.tar.xz
1ka-19985dbb8c0aa66dc4bf7905abc1148de909097d.tar.zst
1ka-19985dbb8c0aa66dc4bf7905abc1148de909097d.zip
Diffstat (limited to 'vendor/paragonie/sodium_compat/src/Core32/Poly1305/State.php')
-rw-r--r--vendor/paragonie/sodium_compat/src/Core32/Poly1305/State.php451
1 files changed, 451 insertions, 0 deletions
diff --git a/vendor/paragonie/sodium_compat/src/Core32/Poly1305/State.php b/vendor/paragonie/sodium_compat/src/Core32/Poly1305/State.php
new file mode 100644
index 0000000..d80e1ff
--- /dev/null
+++ b/vendor/paragonie/sodium_compat/src/Core32/Poly1305/State.php
@@ -0,0 +1,451 @@
+<?php
+
+if (class_exists('ParagonIE_Sodium_Core32_Poly1305_State', false)) {
+ return;
+}
+
+/**
+ * Class ParagonIE_Sodium_Core32_Poly1305_State
+ */
+class ParagonIE_Sodium_Core32_Poly1305_State extends ParagonIE_Sodium_Core32_Util
+{
+ /**
+ * @var array<int, int>
+ */
+ protected $buffer = array();
+
+ /**
+ * @var bool
+ */
+ protected $final = false;
+
+ /**
+ * @var array<int, ParagonIE_Sodium_Core32_Int32>
+ */
+ public $h;
+
+ /**
+ * @var int
+ */
+ protected $leftover = 0;
+
+ /**
+ * @var array<int, ParagonIE_Sodium_Core32_Int32>
+ */
+ public $r;
+
+ /**
+ * @var array<int, ParagonIE_Sodium_Core32_Int64>
+ */
+ public $pad;
+
+ /**
+ * ParagonIE_Sodium_Core32_Poly1305_State constructor.
+ *
+ * @internal You should not use this directly from another application
+ *
+ * @param string $key
+ * @throws InvalidArgumentException
+ * @throws SodiumException
+ * @throws TypeError
+ */
+ public function __construct($key = '')
+ {
+ if (self::strlen($key) < 32) {
+ throw new InvalidArgumentException(
+ 'Poly1305 requires a 32-byte key'
+ );
+ }
+ /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
+ $this->r = array(
+ // st->r[0] = ...
+ ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 0, 4))
+ ->setUnsignedInt(true)
+ ->mask(0x3ffffff),
+ // st->r[1] = ...
+ ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 3, 4))
+ ->setUnsignedInt(true)
+ ->shiftRight(2)
+ ->mask(0x3ffff03),
+ // st->r[2] = ...
+ ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 6, 4))
+ ->setUnsignedInt(true)
+ ->shiftRight(4)
+ ->mask(0x3ffc0ff),
+ // st->r[3] = ...
+ ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 9, 4))
+ ->setUnsignedInt(true)
+ ->shiftRight(6)
+ ->mask(0x3f03fff),
+ // st->r[4] = ...
+ ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 12, 4))
+ ->setUnsignedInt(true)
+ ->shiftRight(8)
+ ->mask(0x00fffff)
+ );
+
+ /* h = 0 */
+ $this->h = array(
+ new ParagonIE_Sodium_Core32_Int32(array(0, 0), true),
+ new ParagonIE_Sodium_Core32_Int32(array(0, 0), true),
+ new ParagonIE_Sodium_Core32_Int32(array(0, 0), true),
+ new ParagonIE_Sodium_Core32_Int32(array(0, 0), true),
+ new ParagonIE_Sodium_Core32_Int32(array(0, 0), true)
+ );
+
+ /* save pad for later */
+ $this->pad = array(
+ ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 16, 4))
+ ->setUnsignedInt(true)->toInt64(),
+ ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 20, 4))
+ ->setUnsignedInt(true)->toInt64(),
+ ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 24, 4))
+ ->setUnsignedInt(true)->toInt64(),
+ ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 28, 4))
+ ->setUnsignedInt(true)->toInt64(),
+ );
+
+ $this->leftover = 0;
+ $this->final = false;
+ }
+
+ /**
+ * @internal You should not use this directly from another application
+ *
+ * @param string $message
+ * @return self
+ * @throws SodiumException
+ * @throws TypeError
+ */
+ public function update($message = '')
+ {
+ $bytes = self::strlen($message);
+
+ /* handle leftover */
+ if ($this->leftover) {
+ /** @var int $want */
+ $want = ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE - $this->leftover;
+ if ($want > $bytes) {
+ $want = $bytes;
+ }
+ for ($i = 0; $i < $want; ++$i) {
+ $mi = self::chrToInt($message[$i]);
+ $this->buffer[$this->leftover + $i] = $mi;
+ }
+ // We snip off the leftmost bytes.
+ $message = self::substr($message, $want);
+ $bytes = self::strlen($message);
+ $this->leftover += $want;
+ if ($this->leftover < ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) {
+ // We still don't have enough to run $this->blocks()
+ return $this;
+ }
+
+ $this->blocks(
+ self::intArrayToString($this->buffer),
+ ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE
+ );
+ $this->leftover = 0;
+ }
+
+ /* process full blocks */
+ if ($bytes >= ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) {
+ /** @var int $want */
+ $want = $bytes & ~(ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE - 1);
+ if ($want >= ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) {
+ /** @var string $block */
+ $block = self::substr($message, 0, $want);
+ if (self::strlen($block) >= ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) {
+ $this->blocks($block, $want);
+ $message = self::substr($message, $want);
+ $bytes = self::strlen($message);
+ }
+ }
+ }
+
+ /* store leftover */
+ if ($bytes) {
+ for ($i = 0; $i < $bytes; ++$i) {
+ $mi = self::chrToInt($message[$i]);
+ $this->buffer[$this->leftover + $i] = $mi;
+ }
+ $this->leftover = (int) $this->leftover + $bytes;
+ }
+ return $this;
+ }
+
+ /**
+ * @internal You should not use this directly from another application
+ *
+ * @param string $message
+ * @param int $bytes
+ * @return self
+ * @throws SodiumException
+ * @throws TypeError
+ */
+ public function blocks($message, $bytes)
+ {
+ if (self::strlen($message) < 16) {
+ $message = str_pad($message, 16, "\x00", STR_PAD_RIGHT);
+ }
+ $hibit = ParagonIE_Sodium_Core32_Int32::fromInt((int) ($this->final ? 0 : 1 << 24)); /* 1 << 128 */
+ $hibit->setUnsignedInt(true);
+ $zero = new ParagonIE_Sodium_Core32_Int64(array(0, 0, 0, 0), true);
+ /**
+ * @var ParagonIE_Sodium_Core32_Int64 $d0
+ * @var ParagonIE_Sodium_Core32_Int64 $d1
+ * @var ParagonIE_Sodium_Core32_Int64 $d2
+ * @var ParagonIE_Sodium_Core32_Int64 $d3
+ * @var ParagonIE_Sodium_Core32_Int64 $d4
+ * @var ParagonIE_Sodium_Core32_Int64 $r0
+ * @var ParagonIE_Sodium_Core32_Int64 $r1
+ * @var ParagonIE_Sodium_Core32_Int64 $r2
+ * @var ParagonIE_Sodium_Core32_Int64 $r3
+ * @var ParagonIE_Sodium_Core32_Int64 $r4
+ *
+ * @var ParagonIE_Sodium_Core32_Int32 $h0
+ * @var ParagonIE_Sodium_Core32_Int32 $h1
+ * @var ParagonIE_Sodium_Core32_Int32 $h2
+ * @var ParagonIE_Sodium_Core32_Int32 $h3
+ * @var ParagonIE_Sodium_Core32_Int32 $h4
+ */
+ $r0 = $this->r[0]->toInt64();
+ $r1 = $this->r[1]->toInt64();
+ $r2 = $this->r[2]->toInt64();
+ $r3 = $this->r[3]->toInt64();
+ $r4 = $this->r[4]->toInt64();
+
+ $s1 = $r1->toInt64()->mulInt(5, 3);
+ $s2 = $r2->toInt64()->mulInt(5, 3);
+ $s3 = $r3->toInt64()->mulInt(5, 3);
+ $s4 = $r4->toInt64()->mulInt(5, 3);
+
+ $h0 = $this->h[0];
+ $h1 = $this->h[1];
+ $h2 = $this->h[2];
+ $h3 = $this->h[3];
+ $h4 = $this->h[4];
+
+ while ($bytes >= ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) {
+ /* h += m[i] */
+ $h0 = $h0->addInt32(
+ ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 0, 4))
+ ->mask(0x3ffffff)
+ )->toInt64();
+ $h1 = $h1->addInt32(
+ ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 3, 4))
+ ->shiftRight(2)
+ ->mask(0x3ffffff)
+ )->toInt64();
+ $h2 = $h2->addInt32(
+ ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 6, 4))
+ ->shiftRight(4)
+ ->mask(0x3ffffff)
+ )->toInt64();
+ $h3 = $h3->addInt32(
+ ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 9, 4))
+ ->shiftRight(6)
+ ->mask(0x3ffffff)
+ )->toInt64();
+ $h4 = $h4->addInt32(
+ ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 12, 4))
+ ->shiftRight(8)
+ ->orInt32($hibit)
+ )->toInt64();
+
+ /* h *= r */
+ $d0 = $zero
+ ->addInt64($h0->mulInt64($r0, 25))
+ ->addInt64($s4->mulInt64($h1, 26))
+ ->addInt64($s3->mulInt64($h2, 26))
+ ->addInt64($s2->mulInt64($h3, 26))
+ ->addInt64($s1->mulInt64($h4, 26));
+
+ $d1 = $zero
+ ->addInt64($h0->mulInt64($r1, 25))
+ ->addInt64($h1->mulInt64($r0, 25))
+ ->addInt64($s4->mulInt64($h2, 26))
+ ->addInt64($s3->mulInt64($h3, 26))
+ ->addInt64($s2->mulInt64($h4, 26));
+
+ $d2 = $zero
+ ->addInt64($h0->mulInt64($r2, 25))
+ ->addInt64($h1->mulInt64($r1, 25))
+ ->addInt64($h2->mulInt64($r0, 25))
+ ->addInt64($s4->mulInt64($h3, 26))
+ ->addInt64($s3->mulInt64($h4, 26));
+
+ $d3 = $zero
+ ->addInt64($h0->mulInt64($r3, 25))
+ ->addInt64($h1->mulInt64($r2, 25))
+ ->addInt64($h2->mulInt64($r1, 25))
+ ->addInt64($h3->mulInt64($r0, 25))
+ ->addInt64($s4->mulInt64($h4, 26));
+
+ $d4 = $zero
+ ->addInt64($h0->mulInt64($r4, 25))
+ ->addInt64($h1->mulInt64($r3, 25))
+ ->addInt64($h2->mulInt64($r2, 25))
+ ->addInt64($h3->mulInt64($r1, 25))
+ ->addInt64($h4->mulInt64($r0, 25));
+
+ /* (partial) h %= p */
+ $c = $d0->shiftRight(26);
+ $h0 = $d0->toInt32()->mask(0x3ffffff);
+ $d1 = $d1->addInt64($c);
+
+ $c = $d1->shiftRight(26);
+ $h1 = $d1->toInt32()->mask(0x3ffffff);
+ $d2 = $d2->addInt64($c);
+
+ $c = $d2->shiftRight(26);
+ $h2 = $d2->toInt32()->mask(0x3ffffff);
+ $d3 = $d3->addInt64($c);
+
+ $c = $d3->shiftRight(26);
+ $h3 = $d3->toInt32()->mask(0x3ffffff);
+ $d4 = $d4->addInt64($c);
+
+ $c = $d4->shiftRight(26);
+ $h4 = $d4->toInt32()->mask(0x3ffffff);
+ $h0 = $h0->addInt32($c->toInt32()->mulInt(5, 3));
+
+ $c = $h0->shiftRight(26);
+ $h0 = $h0->mask(0x3ffffff);
+ $h1 = $h1->addInt32($c);
+
+ // Chop off the left 32 bytes.
+ $message = self::substr(
+ $message,
+ ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE
+ );
+ $bytes -= ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE;
+ }
+
+ /** @var array<int, ParagonIE_Sodium_Core32_Int32> $h */
+ $this->h = array($h0, $h1, $h2, $h3, $h4);
+ return $this;
+ }
+
+ /**
+ * @internal You should not use this directly from another application
+ *
+ * @return string
+ * @throws SodiumException
+ * @throws TypeError
+ */
+ public function finish()
+ {
+ /* process the remaining block */
+ if ($this->leftover) {
+ $i = $this->leftover;
+ $this->buffer[$i++] = 1;
+ for (; $i < ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE; ++$i) {
+ $this->buffer[$i] = 0;
+ }
+ $this->final = true;
+ $this->blocks(
+ self::substr(
+ self::intArrayToString($this->buffer),
+ 0,
+ ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE
+ ),
+ $b = ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE
+ );
+ }
+
+ /**
+ * @var ParagonIE_Sodium_Core32_Int32 $f
+ * @var ParagonIE_Sodium_Core32_Int32 $g0
+ * @var ParagonIE_Sodium_Core32_Int32 $g1
+ * @var ParagonIE_Sodium_Core32_Int32 $g2
+ * @var ParagonIE_Sodium_Core32_Int32 $g3
+ * @var ParagonIE_Sodium_Core32_Int32 $g4
+ * @var ParagonIE_Sodium_Core32_Int32 $h0
+ * @var ParagonIE_Sodium_Core32_Int32 $h1
+ * @var ParagonIE_Sodium_Core32_Int32 $h2
+ * @var ParagonIE_Sodium_Core32_Int32 $h3
+ * @var ParagonIE_Sodium_Core32_Int32 $h4
+ */
+ $h0 = $this->h[0];
+ $h1 = $this->h[1];
+ $h2 = $this->h[2];
+ $h3 = $this->h[3];
+ $h4 = $this->h[4];
+
+ $c = $h1->shiftRight(26); # $c = $h1 >> 26;
+ $h1 = $h1->mask(0x3ffffff); # $h1 &= 0x3ffffff;
+
+ $h2 = $h2->addInt32($c); # $h2 += $c;
+ $c = $h2->shiftRight(26); # $c = $h2 >> 26;
+ $h2 = $h2->mask(0x3ffffff); # $h2 &= 0x3ffffff;
+
+ $h3 = $h3->addInt32($c); # $h3 += $c;
+ $c = $h3->shiftRight(26); # $c = $h3 >> 26;
+ $h3 = $h3->mask(0x3ffffff); # $h3 &= 0x3ffffff;
+
+ $h4 = $h4->addInt32($c); # $h4 += $c;
+ $c = $h4->shiftRight(26); # $c = $h4 >> 26;
+ $h4 = $h4->mask(0x3ffffff); # $h4 &= 0x3ffffff;
+
+ $h0 = $h0->addInt32($c->mulInt(5, 3)); # $h0 += self::mul($c, 5);
+ $c = $h0->shiftRight(26); # $c = $h0 >> 26;
+ $h0 = $h0->mask(0x3ffffff); # $h0 &= 0x3ffffff;
+ $h1 = $h1->addInt32($c); # $h1 += $c;
+
+ /* compute h + -p */
+ $g0 = $h0->addInt(5);
+ $c = $g0->shiftRight(26);
+ $g0 = $g0->mask(0x3ffffff);
+ $g1 = $h1->addInt32($c);
+ $c = $g1->shiftRight(26);
+ $g1 = $g1->mask(0x3ffffff);
+ $g2 = $h2->addInt32($c);
+ $c = $g2->shiftRight(26);
+ $g2 = $g2->mask(0x3ffffff);
+ $g3 = $h3->addInt32($c);
+ $c = $g3->shiftRight(26);
+ $g3 = $g3->mask(0x3ffffff);
+ $g4 = $h4->addInt32($c)->subInt(1 << 26);
+
+ # $mask = ($g4 >> 31) - 1;
+ /* select h if h < p, or h + -p if h >= p */
+ $mask = (int) (($g4->toInt() >> 31) + 1);
+
+ $g0 = $g0->mask($mask);
+ $g1 = $g1->mask($mask);
+ $g2 = $g2->mask($mask);
+ $g3 = $g3->mask($mask);
+ $g4 = $g4->mask($mask);
+
+ /** @var int $mask */
+ $mask = (~$mask) & 0xffffffff;
+
+ $h0 = $h0->mask($mask)->orInt32($g0);
+ $h1 = $h1->mask($mask)->orInt32($g1);
+ $h2 = $h2->mask($mask)->orInt32($g2);
+ $h3 = $h3->mask($mask)->orInt32($g3);
+ $h4 = $h4->mask($mask)->orInt32($g4);
+
+ /* h = h % (2^128) */
+ $h0 = $h0->orInt32($h1->shiftLeft(26));
+ $h1 = $h1->shiftRight(6)->orInt32($h2->shiftLeft(20));
+ $h2 = $h2->shiftRight(12)->orInt32($h3->shiftLeft(14));
+ $h3 = $h3->shiftRight(18)->orInt32($h4->shiftLeft(8));
+
+ /* mac = (h + pad) % (2^128) */
+ $f = $h0->toInt64()->addInt64($this->pad[0]);
+ $h0 = $f->toInt32();
+ $f = $h1->toInt64()->addInt64($this->pad[1])->addInt($h0->overflow);
+ $h1 = $f->toInt32();
+ $f = $h2->toInt64()->addInt64($this->pad[2])->addInt($h1->overflow);
+ $h2 = $f->toInt32();
+ $f = $h3->toInt64()->addInt64($this->pad[3])->addInt($h2->overflow);
+ $h3 = $f->toInt32();
+
+ return $h0->toReverseString() .
+ $h1->toReverseString() .
+ $h2->toReverseString() .
+ $h3->toReverseString();
+ }
+}