| 
<?phpdeclare(strict_types=1);
 
 /**
 * Class ParagonIE_Sodium_Core_SecretStream_State
 */
 class ParagonIE_Sodium_Core_SecretStream_State
 {
 protected string $key;
 protected int $counter;
 protected string $nonce;
 protected string $_pad;
 
 /**
 * ParagonIE_Sodium_Core_SecretStream_State constructor.
 * @param string $key
 * @param string|null $nonce
 */
 public function __construct(
 #[SensitiveParameter]
 string $key,
 ?string $nonce = null
 ) {
 $this->key = $key;
 $this->counter = 1;
 if (is_null($nonce)) {
 $nonce = str_repeat("\0", 12);
 }
 $this->nonce = str_pad($nonce, 12, "\0");
 $this->_pad = str_repeat("\0", 4);
 }
 
 /**
 * @return self
 */
 public function counterReset(): self
 {
 $this->counter = 1;
 $this->_pad = str_repeat("\0", 4);
 return $this;
 }
 
 /**
 * @return string
 */
 public function getKey(): string
 {
 return $this->key;
 }
 
 /**
 * @return string
 */
 public function getCounter(): string
 {
 return ParagonIE_Sodium_Core_Util::store32_le($this->counter);
 }
 
 /**
 * @return string
 */
 public function getNonce(): string
 {
 if (ParagonIE_Sodium_Core_Util::strlen($this->nonce) !== 12) {
 $this->nonce = str_pad($this->nonce, 12, "\0");
 }
 return $this->nonce;
 }
 
 /**
 * @return string
 */
 public function getCombinedNonce(): string
 {
 return $this->getCounter() .
 ParagonIE_Sodium_Core_Util::substr($this->getNonce(), 0, 8);
 }
 
 /**
 * @return self
 */
 public function incrementCounter(): self
 {
 ++$this->counter;
 return $this;
 }
 
 /**
 * @return bool
 */
 public function needsRekey(): bool
 {
 return ($this->counter & 0xffff) === 0;
 }
 
 /**
 * @param string $newKeyAndNonce
 * @return self
 */
 public function rekey(
 #[SensitiveParameter]
 string $newKeyAndNonce
 ): self {
 $this->key = ParagonIE_Sodium_Core_Util::substr($newKeyAndNonce, 0, 32);
 $this->nonce = str_pad(
 ParagonIE_Sodium_Core_Util::substr($newKeyAndNonce, 32),
 12,
 "\0"
 );
 return $this;
 }
 
 /**
 * @param string $str
 * @return self
 */
 public function xorNonce(
 #[SensitiveParameter]
 string $str
 ): self {
 $this->nonce = ParagonIE_Sodium_Core_Util::xorStrings(
 $this->getNonce(),
 str_pad(
 ParagonIE_Sodium_Core_Util::substr($str, 0, 8),
 12,
 "\0"
 )
 );
 return $this;
 }
 
 /**
 * @param string $string
 * @return self
 */
 public static function fromString(
 #[SensitiveParameter]
 string $string
 ): self {
 $state = new ParagonIE_Sodium_Core_SecretStream_State(
 ParagonIE_Sodium_Core_Util::substr($string, 0, 32)
 );
 $state->counter = ParagonIE_Sodium_Core_Util::load_4(
 ParagonIE_Sodium_Core_Util::substr($string, 32, 4)
 );
 $state->nonce = ParagonIE_Sodium_Core_Util::substr($string, 36, 12);
 $state->_pad = ParagonIE_Sodium_Core_Util::substr($string, 48, 8);
 return $state;
 }
 
 /**
 * @return string
 */
 public function toString(): string
 {
 return $this->key .
 $this->getCounter() .
 $this->nonce .
 $this->_pad;
 }
 }
 
 |