Scrypt Implementation (#3117)

* Scrypt implementation.

* Docs stuff.

* Make example just an example and not a doctest.

* Add changelog entry.

* Docs cleanup.

* Add more tests.

* Add multibackend tests.

* PEP8.

* Add docs about Scrypt parameters.

* Docs cleanup.

* Add AlreadyFinalized.
diff --git a/docs/hazmat/backends/interfaces.rst b/docs/hazmat/backends/interfaces.rst
index 14f72cf..b79bb23 100644
--- a/docs/hazmat/backends/interfaces.rst
+++ b/docs/hazmat/backends/interfaces.rst
@@ -652,3 +652,33 @@
 
         :returns: ``True`` if the given values of ``p`` and ``g`` are supported
             by this backend, otherwise ``False``.
+
+
+.. class:: ScryptBackend
+
+    .. versionadded:: 1.6
+
+    A backend with methods for using Scrypt.
+
+    The following backends implement this interface:
+
+    * :doc:`/hazmat/backends/openssl`
+
+    .. method:: derive_scrypt(self, key_material, salt, length, n, r, p)
+
+        :param bytes key_material: The key material to use as a basis for
+            the derived key. This is typically a password.
+
+        :param bytes salt: A salt.
+
+        :param int length: The desired length of the derived key.
+
+        :param int n: CPU/Memory cost parameter. It must be larger than 1 and be a
+            power of 2.
+
+        :param int r: Block size parameter.
+
+        :param int p: Parallelization parameter.
+
+        :return bytes: Derived key.
+
diff --git a/docs/hazmat/backends/openssl.rst b/docs/hazmat/backends/openssl.rst
index 8bc7dac..791aab3 100644
--- a/docs/hazmat/backends/openssl.rst
+++ b/docs/hazmat/backends/openssl.rst
@@ -24,6 +24,11 @@
     * :class:`~cryptography.hazmat.backends.interfaces.PEMSerializationBackend`
     * :class:`~cryptography.hazmat.backends.interfaces.X509Backend`
 
+    It also implements the following interface for OpenSSL versions ``1.1.0``
+    and above.
+
+    * :class:`~cryptography.hazmat.backends.interfaces.ScryptBackend`
+
     It also exposes the following:
 
     .. attribute:: name
diff --git a/docs/hazmat/primitives/key-derivation-functions.rst b/docs/hazmat/primitives/key-derivation-functions.rst
index 873e0ff..03260c0 100644
--- a/docs/hazmat/primitives/key-derivation-functions.rst
+++ b/docs/hazmat/primitives/key-derivation-functions.rst
@@ -737,6 +737,111 @@
         The counter iteration variable will be concatenated after
         the fixed input data.
 
+.. currentmodule:: cryptography.hazmat.primitives.kdf.scrypt
+
+.. class:: Scrypt(salt, length, n, r, p, backend)
+
+    .. versionadded:: 1.6
+
+    Scrypt is a KDF designed for password storage by Colin Percival to be
+    resistant against hardware-assisted attackers by having a tunable memory
+    cost. It is described in :rfc:`7914`.
+
+    This class conforms to the
+    :class:`~cryptography.hazmat.primitives.kdf.KeyDerivationFunction`
+    interface.
+
+    .. code-block:: python
+
+        >>> import os
+        >>> from cryptography.hazmat.primitives import hashes
+        >>> from cryptography.hazmat.primitives.kdf.scrypt import Scrypt
+        >>> from cryptography.hazmat.backends import default_backend
+        >>> backend = default_backend()
+        >>> salt = os.urandom(16)
+        >>> # derive
+        >>> kdf = Scrypt(
+        ...     salt=salt,
+        ...     length=64,
+        ...     n=1024,
+        ...     r=8,
+        ...     p=16,
+        ...     backend=backend
+        ... )
+        >>> key = kdf.derive(b"my great password")
+        >>> # verify
+        >>> kdf = Scrypt(
+        ...     salt=salt,
+        ...     length=64,
+        ...     n=1024,
+        ...     r=8,
+        ...     p=16,
+        ...     backend=backend
+        ... )
+        >>> kdf.verify(b"my great password", key)
+
+    :param bytes salt: A salt.
+    :param int length: The desired length of the derived key.
+    :param int n: CPU/Memory cost parameter. It must be larger than 1 and be a
+        power of 2.
+    :param int r: Block size parameter.
+    :param int p: Parallelization parameter.
+
+    The computational and memory cost of Scrypt can be adjusted by manipulating
+    the 3 parameters: n, r and p. In general, the memory cost of Scrypt is
+    affected by the values of both n and r while n also determines the number
+    of iterations performed. p increases the computational cost without
+    affecting memory usage. A more in-depth explanation of the 3 parameters can
+    be found `here`_.
+
+    :rfc:`7914` `recommends`_ values of r=8 and p=1 while scaling n to the
+    number appropriate for your system.
+
+    :param backend: An instance of
+        :class:`~cryptography.hazmat.backends.interfaces.ScryptBackend`.
+
+    :raises cryptography.exceptions.UnsupportedAlgorithm: This is raised if the
+        provided ``backend`` does not implement
+        :class:`~cryptography.hazmat.backends.interfaces.ScryptBackend`
+
+    :raises TypeError: This exception is raised if ``salt`` is not ``bytes``.
+
+    .. method:: derive(key_material)
+
+        :param bytes key_material: The input key material.
+        :return bytes: the derived key.
+        :raises TypeError: This exception is raised if ``key_material`` is not
+                           ``bytes``.
+        :raises cryptography.exceptions.AlreadyFinalized: This is raised when
+                                                          :meth:`derive` or
+                                                          :meth:`verify` is
+                                                          called more than
+                                                          once.
+
+        This generates and returns a new key from the supplied password.
+
+    .. method:: verify(key_material, expected_key)
+
+        :param bytes key_material: The input key material. This is the same as
+                                   ``key_material`` in :meth:`derive`.
+        :param bytes expected_key: The expected result of deriving a new key,
+                                   this is the same as the return value of
+                                   :meth:`derive`.
+        :raises cryptography.exceptions.InvalidKey: This is raised when the
+                                                    derived key does not match
+                                                    the expected key.
+        :raises cryptography.exceptions.AlreadyFinalized: This is raised when
+                                                          :meth:`derive` or
+                                                          :meth:`verify` is
+                                                          called more than
+                                                          once.
+
+        This checks whether deriving a new key from the supplied
+        ``key_material`` generates the same key as the ``expected_key``, and
+        raises an exception if they do not match. This can be used for
+        checking whether the password a user provides matches the stored derived
+        key.
+
 Interface
 ~~~~~~~~~
 
@@ -795,3 +900,5 @@
 .. _`key stretching`: https://en.wikipedia.org/wiki/Key_stretching
 .. _`HKDF`: https://en.wikipedia.org/wiki/HKDF
 .. _`HKDF paper`: https://eprint.iacr.org/2010/264
+.. _`here`: https://stackoverflow.com/a/30308723/1170681
+.. _`recommends`: https://tools.ietf.org/html/rfc7914#section-2