private function _gctr(string $ICB, string $X, string $K): string
    {
        // if data is an empty string, return an empty string
        if ("" == $X) {
            return "";
        }
        // number of blocks
        $n = ceil(strlen($X) / 16);
        $CB = $ICB;
        $Y = "";
        for ($i = 0; $i < $n - 1; ++$i) {
            // plaintext block
            $xi = substr($X, $i << 4, 16);
            // encrypt block and append to Y
            $Y .= $xi ^ $this->_cipher->encrypt($CB, $K);
            // increment counter block
            $CB = self::_inc32($CB);
        }
        // final block
        $xn = substr($X, $i << 4);
        // XOR against partial block
        $Y .= $xn ^ substr($this->_cipher->encrypt($CB, $K), 0, strlen($xn));
        return $Y;
    }