protected function encryptData($value)
    {
        if (is_null($this->cryptokey)) {
            throw InvalidSetupException::nullSecret();
        }
        try {
            $serialized = serialize($value);
        } catch (\Error $e) {
            throw InvalidArgumentException::serializeFailed($e->getMessage());
        }
        $oldnonce = $this->nonce;
        if (is_null($this->nonce)) {
            // both IETF ChaCha20 and AES256GCM use 12 bytes for nonce
            $this->nonce = random_bytes(12);
        } else {
            sodium_increment($this->nonce);
        }
        if ($oldnonce === $this->nonce) {
            // This should never ever happen
            throw InvalidSetupException::nonceIncrementError();
        }
        $obj = new \stdClass;
        $obj->nonce = $this->nonce;
        if ($this->aesgcm) {
            $obj->ciphertext = sodium_crypto_aead_aes256gcm_encrypt(
                $serialized,
                $obj->nonce,
                $obj->nonce,
                $this->cryptokey
            );
        } else {
            $obj->ciphertext = sodium_crypto_aead_chacha20poly1305_ietf_encrypt(
                $serialized,
                $obj->nonce,
                $obj->nonce,
                $this->cryptokey
            );
        }
        sodium_memzero($serialized);
        // RESEARCH - How to zero out non-string? I don't believe recast
        //  will do it it properly
        if (is_string($value)) {
            sodium_memzero($value);
        }
        return $obj;
    }