diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 031142e..cd0cd69 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -106,16 +106,22 @@ But it's way more comfortable to run it locally and *git* catching avoidable err ## Code - Obey [PEP 8](https://www.python.org/dev/peps/pep-0008/) and [PEP 257](https://www.python.org/dev/peps/pep-0257/). - We use the `"""`-on-separate-lines style for docstrings: + We use the `"""`-on-separate-lines style for docstrings and [Napoleon](https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html) for parsing them: ```python - def func(x): + def func(x: str, y: bool) -> int: """ Do something. - :param str x: A very important parameter. + Parameters: + x: A very important parameter. - :rtype: str + y: + Another important parameter whose description is too long for one + line, therefore it starts on the next line. + + Returns: + Something! """ ``` - If you add or change public APIs, tag the docstring using `.. versionadded:: 16.0.0 WHAT` or `.. versionchanged:: 16.2.0 WHAT`. diff --git a/docs/argon2.md b/docs/argon2.md index fe5cbe6..1ee3e76 100644 --- a/docs/argon2.md +++ b/docs/argon2.md @@ -18,7 +18,7 @@ Argon2**d**'s strength is the resistance against [time–memory trade-offs], whi Accordingly, Argon2**i** was originally considered the correct choice for password hashing and password-based key derivation. In practice it turned out that a *combination* of d and i -- that combines their strengths -- is the better choice. -And so Argon2**id** was born and is now considered the *main variant* (and the only variant required by the RFC to be implemented). +And so Argon2**id** was born and is now considered the *main variant* -- and the only variant required by the RFC to be implemented. ## Why “just use bcrypt” Is Not the Best Answer (Anymore) diff --git a/docs/installation.md b/docs/installation.md index 27e9f89..89c5862 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -13,10 +13,10 @@ But since *argon2-cffi* depends on [argon2-cffi-bindings] that vendors Argon2's The C code is known to compile and work on all common platforms (including x86, ARM, and PPC). On x86, an [SSE2]-optimized version is used. -If something goes wrong, please try to update your *cffi*, *pip* and *setuptools* packages first: +If something goes wrong, please try to update your *pip* package first: ```console -$ python -Im pip install -U cffi pip setuptools +$ python -Im pip install -U pip ``` Overall this should be the safest bet because *argon2-cffi* has been specifically tested against the vendored version. @@ -25,7 +25,7 @@ Overall this should be the safest bet because *argon2-cffi* has been specificall ### Wheels Binary [wheels](https://pythonwheels.com) for macOS, Windows, and Linux are provided on [PyPI] by [argon2-cffi-bindings]. -With a recent-enough *pip* and *setuptools*, they should be used automatically. +With a recent-enough *pip* they should be used automatically. ### Source Distribution @@ -50,8 +50,12 @@ This approach can lead to problems around your build chain and you can run into **It is your own responsibility to deal with these risks if you choose this path.** -Available since version 18.1.0. -The `--no-binary` option value changed in 21.2.0 due to the outsourcing of the binary bindings. +:::{versionadded} 18.1.0 +::: + +:::{versionchanged} 21.2.0 +The `--no-binary` option value changed due to the outsourcing of the binary bindings. +::: ## Override Automatic SSE2 Detection @@ -65,7 +69,8 @@ Therefore you can use the `ARGON2_CFFI_USE_SSE2` environment variable to control - If you set it to `0`, *argon2-cffi* will build **without** SSE2 support. - If you set it to anything else, it will be ignored and *argon2-cffi* will try to guess. -Available since version 20.1.0. +:::{versionadded} 20.1.0 +::: [argon2-cffi-bindings]: https://github.com/hynek/argon2-cffi-bindings [cffi environment]: https://cffi.readthedocs.io/en/latest/installation.html diff --git a/src/argon2/_password_hasher.py b/src/argon2/_password_hasher.py index 2b945c6..e3286ee 100644 --- a/src/argon2/_password_hasher.py +++ b/src/argon2/_password_hasher.py @@ -33,27 +33,36 @@ class PasswordHasher: r""" High level class to hash passwords with sensible defaults. - Uses Argon2\ **id** by default and always uses a random salt_ for hashing. - But it can verify any type of Argon2 as long as the hash is correctly - encoded. + Uses Argon2\ **id** by default and uses a random salt_ for hashing. But it + can verify any type of Argon2 as long as the hash is correctly encoded. The reason for this being a class is both for convenience to carry parameters and to verify the parameters only *once*. Any unnecessary - slowdown when hashing is a tangible advantage for a brute force attacker. + slowdown when hashing is a tangible advantage for a brute-force attacker. - :param int time_cost: Defines the amount of computation realized and - therefore the execution time, given in number of iterations. - :param int memory_cost: Defines the memory usage, given in kibibytes_. - :param int parallelism: Defines the number of parallel threads (*changes* - the resulting hash value). - :param int hash_len: Length of the hash in bytes. - :param int salt_len: Length of random salt to be generated for each - password. - :param str encoding: The Argon2 C library expects bytes. So if - :meth:`hash` or :meth:`verify` are passed a ``str``, it will be - encoded using this encoding. - :param Type type: Argon2 type to use. Only change for interoperability - with legacy systems. + Parameters: + time_cost: + Defines the amount of computation realized and therefore the + execution time, given in number of iterations. + + memory_cost: Defines the memory usage, given in kibibytes_. + + parallelism: + Defines the number of parallel threads (*changes* the resulting + hash value). + + hash_len: Length of the hash in bytes. + + salt_len: Length of random salt to be generated for each password. + + encoding: + The Argon2 C library expects bytes. So if :meth:`hash` or + :meth:`verify` are passed a ``str``, it will be encoded using this + encoding. + + type: + Argon2 type to use. Only change for interoperability with legacy + systems. .. versionadded:: 16.0.0 .. versionchanged:: 18.2.0 @@ -114,6 +123,9 @@ class PasswordHasher: """ Construct a `PasswordHasher` from *params*. + Returns: + A `PasswordHasher` instance with the parameters from *params*. + .. versionadded:: 21.2.0 """ ph = cls() @@ -150,7 +162,6 @@ class PasswordHasher: Hash *password* and return an encoded hash. Parameters: - password: Password to hash. salt: If None, a random salt is securely created. @@ -161,11 +172,9 @@ class PasswordHasher: you are doing. Raises: - argon2.exceptions.HashingError: If hashing fails. Returns: - Hashed *password*. .. versionadded:: 23.1.0 *salt* parameter @@ -198,23 +207,25 @@ class PasswordHasher: other parsing than the determination of the hash type is done by *argon2-cffi*. - :param hash: An encoded hash as returned from - :meth:`PasswordHasher.hash`. - :type hash: ``bytes`` or ``str`` + Parameters: + hash: An encoded hash as returned from :meth:`PasswordHasher.hash`. - :param password: The password to verify. - :type password: ``bytes`` or ``str`` + password: The password to verify. - :raises argon2.exceptions.VerifyMismatchError: If verification fails - because *hash* is not valid for *password*. - :raises argon2.exceptions.VerificationError: If verification fails for - other reasons. - :raises argon2.exceptions.InvalidHashError: If *hash* is so clearly - invalid, that it couldn't be passed to Argon2. + Raises: + argon2.exceptions.VerifyMismatchError: + If verification fails because *hash* is not valid for + *password*. - :return: ``True`` on success, raise - :exc:`~argon2.exceptions.VerificationError` otherwise. - :rtype: bool + argon2.exceptions.VerificationError: + If verification fails for other reasons. + + argon2.exceptions.InvalidHashError: + If *hash* is so clearly invalid, that it couldn't be passed to + Argon2. + + Returns: + ``True`` on success, otherwise an exception is raised. .. versionchanged:: 16.1.0 Raise :exc:`~argon2.exceptions.VerifyMismatchError` on mismatches @@ -244,7 +255,11 @@ class PasswordHasher: Therefore it's best practice to check -- and if necessary rehash -- passwords after each successful authentication. - :rtype: bool + Parameters: + hash: An encoded Argon2 password hash. + + Returns: + Whether *hash* was created using the instance's parameters. .. versionadded:: 18.2.0 """ diff --git a/src/argon2/_utils.py b/src/argon2/_utils.py index 53e9425..baa48cf 100644 --- a/src/argon2/_utils.py +++ b/src/argon2/_utils.py @@ -58,13 +58,20 @@ class Parameters: See :doc:`parameters` on how to pick them. - :ivar Type type: Hash type. - :ivar int version: Argon2 version. - :ivar int salt_len: Length of the salt in bytes. - :ivar int hash_len: Length of the hash in bytes. - :ivar int time_cost: Time cost in iterations. - :ivar int memory_cost: Memory cost in kibibytes. - :ivar int parallelism: Number of parallel threads. + Attributes: + type: Hash type. + + version: Argon2 version. + + salt_len: Length of the salt in bytes. + + hash_len: Length of the hash in bytes. + + time_cost: Time cost in iterations. + + memory_cost: Memory cost in kibibytes. + + parallelism: Number of parallel threads. .. versionadded:: 18.2.0 """ @@ -96,9 +103,11 @@ def extract_parameters(hash: str) -> Parameters: """ Extract parameters from an encoded *hash*. - :param str params: An encoded Argon2 hash string. + Parameters: + hash: An encoded Argon2 hash string. - :rtype: Parameters + Returns: + The parameters used to create the hash. .. versionadded:: 18.2.0 """ diff --git a/src/argon2/low_level.py b/src/argon2/low_level.py index ce2dfa7..ab9a53c 100644 --- a/src/argon2/low_level.py +++ b/src/argon2/low_level.py @@ -66,18 +66,24 @@ def hash_secret( An encoded hash can be directly passed into :func:`verify_secret` as it contains all parameters and the salt. - :param bytes secret: Secret to hash. - :param bytes salt: A salt_. Should be random and different for each - secret. - :param Type type: Which Argon2 variant to use. - :param int version: Which Argon2 version to use. + Parameters: + secret: Secret to hash. + + salt: + A salt_. Should be random and different for each secret. + + type: Which Argon2 variant to use. + + version: Which Argon2 version to use. For an explanation of the Argon2 parameters see :class:`argon2.PasswordHasher`. - :rtype: bytes + Returns: + An encoded Argon2 hash. - :raises argon2.exceptions.HashingError: If hashing fails. + Raises: + argon2.exceptions.HashingError: If hashing fails. .. versionadded:: 16.0.0 @@ -160,20 +166,28 @@ def verify_secret(hash: bytes, secret: bytes, type: Type) -> Literal[True]: """ Verify whether *secret* is correct for *hash* of *type*. - :param bytes hash: An encoded Argon2 hash as returned by + Parameters: + hash: + An encoded Argon2 hash as returned by :func:`hash_secret`. - :param bytes secret: The secret to verify whether it matches the one - in *hash*. - :param Type type: Type for *hash*. - :raises argon2.exceptions.VerifyMismatchError: If verification fails - because *hash* is not valid for *secret* of *type*. - :raises argon2.exceptions.VerificationError: If verification fails for - other reasons. + secret: + The secret to verify whether it matches the one + in *hash*. - :return: ``True`` on success, raise + type: Type for *hash*. + + Raises: + argon2.exceptions.VerifyMismatchError: + If verification fails + because *hash* is not valid for *secret* of *type*. + argon2.exceptions.VerificationError: + If verification fails for + other reasons. + + Returns: + ``True`` on success, raise :exc:`~argon2.exceptions.VerificationError` otherwise. - :rtype: bool .. versionadded:: 16.0.0 .. versionchanged:: 16.1.0 @@ -210,13 +224,17 @@ def core(context: Any, type: int) -> int: Use at your own peril; *argon2-cffi* does *not* use this binding itself. - :param context: A CFFI Argon2 context object (i.e. an ``struct - Argon2_Context`` / ``argon2_context``). - :param int type: Which Argon2 variant to use. You can use the ``value`` - field of :class:`Type`'s fields. + Parameters: + context: + A CFFI Argon2 context object (i.e. an ``struct Argon2_Context`` / + ``argon2_context``). - :rtype: int - :return: An Argon2 error code. Can be transformed into a string using + type: + Which Argon2 variant to use. You can use the ``value`` field of + :class:`Type`'s fields. + + Returns: + An Argon2 error code. Can be transformed into a string using :func:`error_to_str`. .. versionadded:: 16.0.0 @@ -228,9 +246,11 @@ def error_to_str(error: int) -> str: """ Convert an Argon2 error code into a native string. - :param int error: An Argon2 error code as returned by :func:`core`. + Parameters: + error: An Argon2 error code as returned by :func:`core`. - :rtype: str + Returns: + A human-readable string describing the error. .. versionadded:: 16.0.0 """