CI_Encryption: Rename 'base64' parameter to 'raw_data' and add docs
diff --git a/system/libraries/Encryption.php b/system/libraries/Encryption.php
index e03e278..3a54098 100644
--- a/system/libraries/Encryption.php
+++ b/system/libraries/Encryption.php
@@ -698,7 +698,7 @@
 			'mode' => $params['mode'],
 			'key' => $params['key'],
 			'iv' => isset($params['iv']) ? $params['iv'] : NULL,
-			'base64' => isset($params['base64']) ? $params['base64'] : TRUE,
+			'base64' => isset($params['raw_data']) ? ! $params['raw_data'] : FALSE,
 			'hmac_digest' => $params['hmac_digest'],
 			'hmac_key' => $params['hmac_key']
 		);
@@ -825,8 +825,8 @@
 	 * @param	$key	Input key
 	 * @param	$digest	A SHA-2 hashing algorithm
 	 * @param	$salt	Optional salt
-	 * @param	$info	Optional context/application-specific info
 	 * @param	$length	Output length (defaults to the selected digest size)
+	 * @param	$info	Optional context/application-specific info
 	 * @return	string	A pseudo-random key
 	 */
 	public function hkdf($key, $digest = 'sha512', $salt = NULL, $length = NULL, $info = '')
diff --git a/tests/codeigniter/libraries/Encryption_test.php b/tests/codeigniter/libraries/Encryption_test.php
index 6bcf17b..54db2b4 100644
--- a/tests/codeigniter/libraries/Encryption_test.php
+++ b/tests/codeigniter/libraries/Encryption_test.php
@@ -151,20 +151,22 @@
 			'mode' => 'cbc',
 			'key' => str_repeat("\x0", 16),
 			'iv' => str_repeat("\x0", 16),
-			'base64' => FALSE,
+			'raw_data' => TRUE,
 			'hmac_key' => str_repeat("\x0", 16),
 			'hmac_digest' => 'sha256'
 		);
 
 		$output = $this->encryption->__get_params($params);
-		unset($output['handle']);
+		unset($output['handle'], $params['raw_data']);
+		$params['base64'] = FALSE;
 		$this->assertEquals($params, $output);
 
 		// HMAC disabled
 		unset($params['hmac_key'], $params['hmac_digest']);
-		$params['hmac'] = FALSE;
+		$params['hmac'] = $params['raw_data'] = FALSE;
 		$output = $this->encryption->__get_params($params);
-		unset($output['handle'], $params['hmac']);
+		unset($output['handle'], $params['hmac'], $params['raw_data']);
+		$params['base64'] = TRUE;
 		$params['hmac_digest'] = $params['hmac_key'] = NULL;
 		$this->assertEquals($params, $output);
 	}
diff --git a/user_guide_src/source/libraries/encryption.rst b/user_guide_src/source/libraries/encryption.rst
new file mode 100644
index 0000000..cedc8d3
--- /dev/null
+++ b/user_guide_src/source/libraries/encryption.rst
@@ -0,0 +1,555 @@
+##################
+Encryption Library
+##################
+
+The Encryption Library provides two-way data encryption. To do so in
+a cryptographically secure way, it utilizes PHP extensions that are
+unfortunately not always available on all systems.
+You must meet one of the following dependancies in order to use this
+library:
+
+- `OpenSSL <http://php.net/openssl>`_ (and PHP 5.3.3)
+- `MCrypt <http://php.net/mcrypt>`_ (and `MCRYPT_DEV_URANDOM` availability)
+
+If neither of the above dependancies is met, we simply cannot offer
+you a good enough implementation to meet the high standards required
+for proper cryptography.
+
+.. contents::
+  :local:
+
+.. raw:: html
+
+  <div class="custom-index container"></div>
+
+****************************
+Using the Encryption Library
+****************************
+
+Initializing the Class
+======================
+
+Like most other classes in CodeIgniter, the Encryption library is
+initialized in your controller using the ``$this->load->library()``
+method::
+
+	$this->load->library('encrypt');
+
+Once loaded, the Encryption library object will be available using::
+
+	$this->encrypt
+
+Default behavior
+================
+
+By default, the Encryption Library will use the AES-128 cipher in CBC
+mode, using your configured *encryption_key* and SHA512 HMAC authentication.
+
+.. note:: AES-128 is chosen both because it is proven to be strong and
+	because of its wide availability across different cryptographic
+	software and programming languages' APIs.
+
+However, the *encryption_key* is not used as is.
+
+If you are somewhat familiar with cryptography, you should already know
+that a HMAC also requires a secret key and using the same key for both
+encryption and authentication is a bad practice.
+
+Because of that, two separate keys are derived from your already configured
+*encryption_key*: one for encryption and one for authentication. This is
+done via a technique called `HMAC-based Key Derivation Function
+<http://en.wikipedia.org/wiki/HKDF>`_ (HKDF).
+
+Setting your encryption_key
+===========================
+
+An *encryption key* is a piece of information that controls the
+cryptographic process and permits a plain-text string to be encrypted,
+and afterwards - decrypted. It is the secret "ingredient" in the whole
+process that allows you to be the only one who is able to decrypt data
+that you've decided to hide from the eyes of the public.
+After one key is used to encrypt data, that same key provides the **only**
+means to decrypt it, so not only must you chose one carefully, but you
+must not lose it or you will also use the encrypted data.
+
+It must be noted that to ensure maximum security, such key *should* not
+only be as strong as possible, but also often changed. Such behavior
+however is rarely practical or possible to implement, and that is why
+CodeIgniter gives you the ability to configure a single key that is to be
+used (almost) every time.
+
+It goes without saying that you should guard your key carefully. Should
+someone gain access to your key, the data will be easily decrypted. If
+your server is not totally under your control it's impossible to ensure
+key security so you may want to think carefully before using it for
+anything that requires high security, like storing credit card numbers.
+
+Your encryption key should be as long as the encyption algorithm in use
+allows. For AES-128, that's 128 bits or 16 bytes (charcters) long. The
+key should be as random as possible and it should **not** be a simple
+text string.
+
+You will find a table below that shows the supported key lengths of
+different ciphers.
+
+The key can be either stored in your *application/config/config.php*, or
+you can design your own storage mechanism and pass the key dynamically
+when encrypting/decrypting.
+
+To save your key to your *application/config/config.php*, open the file
+and set::
+
+	$config['encryption_key'] = 'YOUR KEY';
+
+.. _ciphers-and-modes:
+
+Supported encryption ciphers and modes
+======================================
+
+.. note:: The terms 'cipher' and 'encryption algorithm' are interchangeable.
+
+Portable ciphers
+----------------
+
+Because MCrypt and OpenSSL (also called drivers throughout this document)
+each support different sets of encryption algorithms and often implement
+them in different ways, our Encryption library is designed to use them in
+a portable fashion, or in other words - it enables you to use them
+interchangeably, at least for the ciphers supported by both drivers.
+
+It is also implemented in a way that aims to match the standard
+implementations in other programming languages and libraries.
+
+Here's a list of the so called "portable" ciphers, where
+"CodeIgniter name" is the string value that you'd have to pass to the
+Encryption library to use that cipher:
+
+======================== ================== ============================ ===============================
+Cipher name              CodeIgniter name   Key lengths (bits / bytes)   Supported modes
+======================== ================== ============================ ===============================
+AES-128 / Rijndael-128   aes-128            128 / 16                     CBC, CTR, CFB, CFB8, OFB, ECB
+AES-192                  aes-192            192 / 24                     CBC, CTR, CFB, CFB8, OFB, ECB
+AES-256                  aes-256            256 / 32                     CBC, CTR, CFB, CFB8, OFB, ECB
+DES                      des                56 / 7                       CBC, CFB, CFB8, OFB, ECB
+TripleDES                tripledes          56 / 7, 112 / 14, 168 / 21   CBC, CFB, CFB8, OFB
+Blowfish                 blowfish           128-448 / 16-56              CBC, CFB, OFB, ECB
+CAST5 / CAST-128         cast5              40-128 / 5-16                CBC, CFB, OFB, ECB
+RC4 / ARCFour            rc4                40-2048 / 5-256              Stream
+======================== ================== ============================ ===============================
+
+.. important:: Because of how MCrypt works, if you fail to provide a key
+	with the appropriate length, you might end up using a different
+	algorithm than the one configured, so be really careful with that!
+
+.. note:: In case it isn't clear from the above table, Blowfish, CAST5
+	and RC4 support variable length keys. That is, any number in the
+	shown ranges is valid, although in bit terms that only happens
+	in 8-bit increments.
+
+.. note:: Even though CAST5 supports key lengths lower than 128 bits
+	(16 bytes), in fact they will just be zero-padded to the
+	maximum length, as specified in `RFC 2144
+	<http://tools.ietf.org/rfc/rfc2144.txt>`_.
+
+.. note:: Blowfish supports key lengths as small as 32 bits (4 bytes), but
+	our tests have shown that only lengths of 128 bits (16 bytes) or
+	higher are properly supported by both MCrypt and OpenSSL. It is
+	also a bad practice to use such low-length keys anyway.
+
+Driver-specific ciphers
+-----------------------
+
+As noted above, MCrypt and OpenSSL support different sets of encryption
+ciphers. For portability reasons and because we haven't tested them
+properly, we do not advise you to use the ones that are driver-specific,
+but regardless, here's a list of most of them:
+
+
+============== ========= ============================== =========================================
+Cipher name    Driver    Key lengths (bits / bytes)     Supported modes
+============== ========= ============================== =========================================
+AES-128        OpenSSL   128 / 16                       CBC, CTR, CFB, CFB8, OFB, ECB, GCM, XTS
+AES-192        OpenSSL   192 / 24                       CBC, CTR, CFB, CFB8, OFB, ECB, GCM, XTS
+AES-256        OpenSSL   256 / 32                       CBC, CTR, CFB, CFB8, OFB, ECB, GCM, XTS
+Rijndael-128   MCrypt    128 / 16, 192 / 24, 256 / 32   CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
+Rijndael-192   MCrypt    128 / 16, 192 / 24, 256 / 32   CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
+Rijndael-256   MCrypt    128 / 16, 192 / 24, 256 / 32   CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
+GOST           MCrypt    256 / 32                       CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
+Twofish        MCrypt    128 / 16, 192 / 24, 256 / 32   CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
+CAST-256       MCrypt    128 / 16, 192 / 24, 256 / 32   CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
+Loki97         MCrypt    128 / 16, 192 / 24, 256 / 32   CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
+SaferPlus      MCrypt    128 / 16, 192 / 24, 256 / 32   CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
+Serpent        MCrypt    128 / 16, 192 / 24, 256 / 32   CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
+XTEA           MCrypt    128 / 16                       CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
+RC2            MCrypt    8-1024 / 1-128                 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
+RC2            OpenSSL   8-1024 / 1-128                 CBC, CFB, OFB, ECB
+Camellia-128   OpenSSL   128 / 16                       CBC, CFB, CFB8, OFB, ECB
+Camellia-192   OpenSSL   192 / 24                       CBC, CFB, CFB8, OFB, ECB
+Camellia-256   OpenSSL   256 / 32                       CBC, CFB, CFB8, OFB, ECB
+Seed           OpenSSL   128 / 16                       CBC, CFB, OFB, ECB
+============== ========= ============================== =========================================
+
+.. note:: If you wish to use one of those ciphers, you'd have to pass
+	its name in lower-case to the Encryption library.
+
+.. note:: You've probably noticed that all AES cipers (and Rijndael-128)
+	are also listed in the portable ciphers list. This is because
+	drivers support different modes for these ciphers. Also, it is
+	important to note that AES-128 and Rijndael-128 are actually
+	the same cipher, but **only** when used with a 128-bit key.
+
+.. note:: RC2 is listed as supported by both MCrypt and OpenSSL.
+	However, both drivers implement them differently and they
+	are not portable. It is probably worth noting that we only
+	found one obscure source confirming that it is MCrypt that
+	is not properly implementing it.
+
+.. _encryption-modes:
+
+Encryption modes
+----------------
+
+Different modes of encryption have different characteristics and serve
+for different purposes. Some are stronger than others, some are faster
+and some offer extra features.
+We are not going in depth into that here, we'll leave that to the
+cryptography experts. The table below is to provide brief informational
+reference to our more experienced users. If you are a beginner, just
+stick to the CBC mode - it is widely accepted as strong and secure for
+general purposes.
+
+=========== ================== ================= ===================================================================================================================================================
+Mode name   CodeIgniter name   Driver support    Additional info
+=========== ================== ================= ===================================================================================================================================================
+CBC         cbc                MCrypt, OpenSSL   A safe default choice
+CTR         ctr                MCrypt, OpenSSL   Considered as theoretically better than CBC, but not as widely available
+CFB         cfb                MCrypt, OpenSSL   N/A
+CFB8        cfb8               MCrypt, OpenSSL   Same as CFB, but operates in 8-bit mode (not recommended).
+OFB         ofb                MCrypt, OpenSSL   N/A
+OFB8        ofb8               MCrypt            Same as OFB, but operates in 8-bit mode (not recommended).
+ECB         ecb                MCrypt, OpenSSL   Ignores IV (not recommended).
+GCM         gcm                OpenSSL           Provides authentication and therefore doesn't need a HMAC.
+XTS         xts                OpenSSL           Usually used for encrypting random access data such as RAM or hard-disk storage.
+Stream      stream             MCrypt, OpenSSL   This is not actually a mode, it just says that a stream cipher is being used. Required because of the general cipher+mode initialization process.
+=========== ================== ================= ===================================================================================================================================================
+
+Message Length
+==============
+
+It's probably important for you to know that an encrypted string is usually
+longer than the original, plain-text string (depending on the cipher).
+
+This is influenced by the cipher algorithm itself, the IV prepended to the
+cipher-text and (unless you are using GCM mode) the HMAC authentication
+message that is also prepended. Furthermore, the encrypted message is also
+Base64-encoded so that it is safe for storage and transmission, regardless
+of a possible character set in use.
+
+Keep this information in mind when selecting your data storage mechanism.
+Cookies, for example, can only hold 4K of information.
+
+.. _configuration:
+
+Configuring the library
+=======================
+
+For usability, performance, but also historical reasons tied to our old
+:doc:`Encrypt Class <encrypt>`, the Encryption library is designed to
+use repeatedly the same driver, encryption cipher, mode and key.
+
+As noted in the "Default behavior" section above, this means using an
+auto-detected driver (OpenSSL has a higher priority), the AES-128 ciper
+in CBC mode, and your ``$config['encryption_key']`` value.
+
+If you wish to change that however, you need to use the ``initialize()``
+method. It accepts an associative array of parameters, all of which are
+optional:
+
+======== ===============================================
+Option   Possible values
+======== ===============================================
+driver   'mcrypt', 'openssl'
+cipher   Cipher name (see :ref:`ciphers-and-modes`)
+mode     Encryption mode (see :ref:`encryption-modes`)
+key      Encryption key 
+======== ===============================================
+
+For example, if you were to change the encryption algorithm and
+mode to AES-256 in CTR mode, this is what you should do::
+
+	$this->encryption->initialize(
+		array(
+			'cipher' => 'aes-256',
+			'mode' => 'ctr',
+			'key' => '<a 32-character random string>'
+		)
+	);
+
+Note that we only mentioned that you want to change the ciper and mode,
+but we also included a key in the example. As previously noted, it is
+important that you choose a key with a proper size for the used algorithm.
+
+There's also the ability to change the driver, if for some reason you
+have both, but want to use MCrypt instead of OpenSSL::
+
+	// Switch to the MCrypt driver
+	$this->encryption->initialize(array('driver' => 'mcrypt'));
+
+	// Switch back to the OpenSSL driver
+	$this->encryption->initialize(array('driver' => 'openssl'));
+
+Encrypting and decrypting data
+==============================
+
+Encrypting and decrypting data with the already configured library
+settings is simple. As simple as just passing the string to the
+``encrypt()`` and/or ``decrypt()`` methods::
+
+	$plain_text = 'This is a plain-text message!';
+	$ciphertext = $this->encryption->encrypt($plain_text);
+
+	// Outputs: This is a plain-text message!
+	echo $this->encryption->decrypt($ciphertext);
+
+And that's it! The Encryption library will do everything necessary
+for the whole process to be cryptographically secure out-of-the-box.
+You don't need to worry about it.
+
+.. important:: Both methods will return FALSE in case of an error.
+	While for ``encrypt()`` this can only mean incorrect
+	configuration, you should always check the return value
+	of ``decrypt()`` in production code.
+
+How it works
+------------
+
+If you must know how the process works, here's what happens under
+the hood:
+
+- ``$this->encryption->encrypt($plain_text)``
+
+  #. Derive an encryption key and a HMAC key from your configured
+     *encryption_key* via HKDF, using the SHA-512 digest algorithm.
+
+  #. Generate a random initialization vector (IV).
+
+  #. Encrypt the data via AES-128 in CBC mode (or another previously
+     configured cipher and mode), using the above-mentioned derived
+     encryption key and IV.
+
+  #. Prepend said IV to the resulting cipher-text.
+
+  #. Base64-encode the resulting string, so that it can be safely
+     stored or transferred without worrying about character sets.
+
+  #. Create a SHA-512 HMAC authentication message using the derived
+     HMAC key to ensure data integrity and prepend it to the Base64
+     string.
+
+- ``$this->encryption->decrypt($ciphertext)``
+
+  #. Derive an encryption key and a HMAC key from your configured
+     *encryption_key* via HKDF, using the SHA-512 digest algorithm.
+     Because your configured *encryption_key* is the same, this
+     will produce the same result as in the ``encrypt()`` method
+     above - otherwise you won't be able to decrypt it.
+
+  #. Check if the string is long enough, separate the HMAC out of
+     it and validate if it is correct (this is done in a way that
+     prevents timing attacks agains it). Return FALSE if either of
+     the checks fails.
+
+  #. Base64-decode the string.
+
+  #. Separate the IV out of the cipher-text and decrypt the said
+     cipher-text using that IV and the derived encryption key.
+
+.. _custom-parameters:
+
+Using custom parameters
+-----------------------
+
+Let's say you have to interact with another system that is out
+of your control and uses another method to encrypt data. A
+method that will most certainly not match the above-described
+sequence and probably not use all of the steps either.
+
+The Encryption library allows you to change how its encryption
+and decryption processes work, so that you can easily tailor a
+custom solution for such situations.
+
+.. note:: It is possible to use the library in this way, without
+	setting an *encryption_key* in your configuration file.
+
+All you have to do is to pass an associative array with a few
+parameters to either the ``encrypt()`` or ``decrypt()`` method.
+Here's an example::
+
+	// Assume that we have $ciphertext, $key and $hmac_key
+	// from on outside source
+
+	$message = $this->encryption->decrypt(
+		$ciphertext,
+		array(
+			'cipher' => 'blowfish',
+			'mode' => 'cbc',
+			'key' => $key,
+			'hmac_digest' => 'sha256',
+			'hmac_key' => $hmac_key
+		)
+	);
+
+In the above example, we are decrypting a message that was encrypted
+using the Blowfish cipher in CBC mode and authenticated via a SHA-256
+HMAC.
+
+.. important:: Note that both 'key' and 'hmac_key' are used in this
+	example. When using custom parameters, encryption and HMAC keys
+	are not derived like the default behavior of the library is.
+
+Below is a list of the available options.
+
+However, unless you really need to and you know what you are doing,
+we advise you to not change the encryption process as this could
+impact security, so please do so with caution.
+
+============= =============== ============================= ======================================================
+Option        Default value   Mandatory / Optional          Description
+============= =============== ============================= ======================================================
+cipher        N/A             Yes                           Encryption algorithm (see :ref:`ciphers-and-modes`).
+mode          N/A             Yes                           Encryption mode (see :ref:`encryption-modes`).
+key           N/A             Yes                           Encryption key.
+iv            N/A             No                            Initialization vector (IV).
+                                                            If not provided it will be automatically generated
+                                                            during encryption and looked for during decryption.
+hmac          TRUE            No                            Whether to use a HMAC.
+                                                            Boolean. If set to FALSE, then *hmac_digest* and
+                                                            *hmac_key* will be ignored.
+hmac_digest   sha512          No                            HMAC message digest algorithm (see :ref:`digests`).
+hmac_key      N/A             Yes, unless *hmac* is FALSE   HMAC key.
+raw_data      FALSE           No                            Whether the cipher-text should be raw.
+                                                            Boolean. If set to TRUE, then Base64 encoding and
+                                                            decoding will not be performed and HMAC will not
+                                                            be a hexadecimal string.
+============= =============== ============================= ======================================================
+
+.. important:: ``encrypt()`` and ``decrypt()`` will return FALSE if
+	a mandatory parameter is not provided or if a provided
+	value is incorrect. This includes *hmac_key*, unless *hmac*
+	is set to FALSE.
+
+.. note:: If GCM mode is used, *hmac* will always be FALSE. This is
+	because GCM mode itself provides authentication.
+
+.. _digests:
+
+Supported HMAC authentication algorithms
+----------------------------------------
+
+For HMAC message authentication, the Encryption library supports
+usage of the SHA-2 family of algorithms:
+
+=========== ==================== ============================
+Algorithm   Raw length (bytes)   Hex-encoded length (bytes)
+=========== ==================== ============================
+sha512      64                   128
+sha384      48                   96
+sha256      32                   64
+sha224      28                   56
+=========== ==================== ============================
+
+The reason for not including other popular algorithms, such as
+MD5 or SHA1 is that they are no longer considered secure enough
+and as such, we don't want to encourage their usage.
+If you absolutely need to use them, it is easy to do so via PHP's
+native `hash_hmac() <http://php.net/hash_hmac()>`_ function.
+
+Stronger algorithms of course will be added in the future as they
+appear and become widely available.
+
+***************
+Class Reference
+***************
+
+.. class:: CI_Encryption
+
+	.. method:: initialize($params)
+
+		:param	array	$params: Configuration parameters
+		:returns:	CI_Encryption instance (method chaining)
+		:rtype:	CI_Encryption
+
+		Initializes (configures) the library to use a different
+		driver, cipher, mode or key.
+
+		Example::
+
+			$this->encryption->initialize(
+				array('mode' => 'ctr')
+			);
+
+		Please refer to the :ref:`configuration` section for detailed info.
+
+	.. method:: encrypt($data[, $params = NULL])
+
+		:param	string	$data: Data to encrypt
+		:param	array	$params: Optional parameters
+		:returns:	Encrypted data or FALSE on failure
+		:rtype:	string
+
+		Encrypts the input data and returns its ciphertext.
+
+		Example::
+
+			$ciphertext = $this->encryption->encrypt('My secret message');
+
+		Please refer to the :ref:`custom-parameters` section for information
+		on the optional parameters.
+
+	.. method:: decrypt($data[, $params = NULL])
+
+		:param	string	$data: Data to decrypt
+		:param	array	$params: Optional parameters
+		:returns:	Decrypted data or FALSE on failure
+		:rtype:	string
+
+		Decrypts the input data and returns it in plain-text.
+
+		Example::
+
+			echo $this->encryption->decrypt($ciphertext);
+
+		Please refer to the :ref:`custom-parameters` secrion for information
+		on the optional parameters.
+
+	.. method:: hkdf($key[, $digest = 'sha512'[, $salt = NULL[, $length = NULL[, $info = '']]]])
+
+		:param	string	$key: Input key material
+		:param	string	$digest: A SHA-2 family digest algorithm
+		:param	string	$salt: Optional salt
+		:param	int	$length: Optional output length
+		:param	string	$info: Optional context/application-specific info
+		:returns:	A pseudo-random key or FALSE on failure
+
+		Derives a key from another, presumably weaker key.
+
+		This method is used internally to derive an encryption and HMAC key
+		from your configured *encryption_key*.
+
+		It is publicly available due to its otherwise general purpose. It is
+		described in `RFC 5869 <https://tools.ietf.org/rfc/rfc5869.txt>`_.
+
+		However, as opposed to the description in RFC 5869, this implementation
+		doesn't support SHA1.
+
+		Example::
+
+			$hmac_key = $this->encryption->hkdf(
+				$key,
+				'sha512',
+				NULL,
+				NULL,
+				'authentication'
+			);
+
+			// $hmac_key is a pseudo-random key with a length of 64 bytes
\ No newline at end of file