mirror of
https://github.com/aykhans/AzSuicideDataVisualization.git
synced 2025-07-01 14:07:48 +00:00
first commit
This commit is contained in:
51
.venv/Lib/site-packages/argon2/__init__.py
Normal file
51
.venv/Lib/site-packages/argon2/__init__.py
Normal file
@ -0,0 +1,51 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
"""
|
||||
The secure Argon2 password hashing algorithm.
|
||||
"""
|
||||
|
||||
from . import exceptions, low_level, profiles
|
||||
from ._legacy import hash_password, hash_password_raw, verify_password
|
||||
from ._password_hasher import (
|
||||
DEFAULT_HASH_LENGTH,
|
||||
DEFAULT_MEMORY_COST,
|
||||
DEFAULT_PARALLELISM,
|
||||
DEFAULT_RANDOM_SALT_LENGTH,
|
||||
DEFAULT_TIME_COST,
|
||||
PasswordHasher,
|
||||
)
|
||||
from ._utils import Parameters, extract_parameters
|
||||
from .low_level import Type
|
||||
|
||||
|
||||
__version__ = "21.3.0"
|
||||
|
||||
__title__ = "argon2-cffi"
|
||||
__description__ = (__doc__ or "").strip()
|
||||
__url__ = "https://argon2-cffi.readthedocs.io/"
|
||||
__uri__ = __url__
|
||||
|
||||
__author__ = "Hynek Schlawack"
|
||||
__email__ = "hs@ox.cx"
|
||||
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2015 " + __author__
|
||||
|
||||
|
||||
__all__ = [
|
||||
"DEFAULT_HASH_LENGTH",
|
||||
"DEFAULT_MEMORY_COST",
|
||||
"DEFAULT_PARALLELISM",
|
||||
"DEFAULT_RANDOM_SALT_LENGTH",
|
||||
"DEFAULT_TIME_COST",
|
||||
"Parameters",
|
||||
"PasswordHasher",
|
||||
"Type",
|
||||
"exceptions",
|
||||
"extract_parameters",
|
||||
"hash_password",
|
||||
"hash_password_raw",
|
||||
"low_level",
|
||||
"profiles",
|
||||
"verify_password",
|
||||
]
|
97
.venv/Lib/site-packages/argon2/__main__.py
Normal file
97
.venv/Lib/site-packages/argon2/__main__.py
Normal file
@ -0,0 +1,97 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import timeit
|
||||
|
||||
from typing import List
|
||||
|
||||
from . import (
|
||||
DEFAULT_HASH_LENGTH,
|
||||
DEFAULT_MEMORY_COST,
|
||||
DEFAULT_PARALLELISM,
|
||||
DEFAULT_TIME_COST,
|
||||
PasswordHasher,
|
||||
profiles,
|
||||
)
|
||||
|
||||
|
||||
def main(argv: List[str]) -> None:
|
||||
parser = argparse.ArgumentParser(description="Benchmark Argon2.")
|
||||
parser.add_argument(
|
||||
"-n", type=int, default=100, help="Number of iterations to measure."
|
||||
)
|
||||
parser.add_argument(
|
||||
"-t", type=int, help="`time_cost`", default=DEFAULT_TIME_COST
|
||||
)
|
||||
parser.add_argument(
|
||||
"-m", type=int, help="`memory_cost`", default=DEFAULT_MEMORY_COST
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p", type=int, help="`parallelism`", default=DEFAULT_PARALLELISM
|
||||
)
|
||||
parser.add_argument(
|
||||
"-l", type=int, help="`hash_length`", default=DEFAULT_HASH_LENGTH
|
||||
)
|
||||
parser.add_argument(
|
||||
"--profile",
|
||||
type=str,
|
||||
help="A profile from `argon2.profiles. Takes precendence.",
|
||||
default=None,
|
||||
)
|
||||
|
||||
args = parser.parse_args(argv[1:])
|
||||
|
||||
password = b"secret"
|
||||
if args.profile:
|
||||
ph = PasswordHasher.from_parameters(
|
||||
getattr(profiles, args.profile.upper())
|
||||
)
|
||||
else:
|
||||
ph = PasswordHasher(
|
||||
time_cost=args.t,
|
||||
memory_cost=args.m,
|
||||
parallelism=args.p,
|
||||
hash_len=args.l,
|
||||
)
|
||||
hash = ph.hash(password)
|
||||
|
||||
params = {
|
||||
"time_cost": (ph.time_cost, "iterations"),
|
||||
"memory_cost": (ph.memory_cost, "KiB"),
|
||||
"parallelism": (ph.parallelism, "threads"),
|
||||
"hash_len": (ph.hash_len, "bytes"),
|
||||
}
|
||||
|
||||
print("Running Argon2id %d times with:" % (args.n,))
|
||||
|
||||
for k, v in sorted(params.items()):
|
||||
print("%s: %d %s" % (k, v[0], v[1]))
|
||||
|
||||
print("\nMeasuring...")
|
||||
duration = timeit.timeit(
|
||||
"ph.verify({hash!r}, {password!r})".format(
|
||||
hash=hash, password=password
|
||||
),
|
||||
setup="""\
|
||||
from argon2 import PasswordHasher, Type
|
||||
|
||||
ph = PasswordHasher(
|
||||
time_cost={time_cost!r},
|
||||
memory_cost={memory_cost!r},
|
||||
parallelism={parallelism!r},
|
||||
hash_len={hash_len!r},
|
||||
)
|
||||
gc.enable()""".format(
|
||||
time_cost=args.t,
|
||||
memory_cost=args.m,
|
||||
parallelism=args.p,
|
||||
hash_len=args.l,
|
||||
),
|
||||
number=args.n,
|
||||
)
|
||||
print(f"\n{duration / args.n * 1000:.1f}ms per password verification")
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
main(sys.argv)
|
75
.venv/Lib/site-packages/argon2/_legacy.py
Normal file
75
.venv/Lib/site-packages/argon2/_legacy.py
Normal file
@ -0,0 +1,75 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
"""
|
||||
Legacy mid-level functions.
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from ._password_hasher import (
|
||||
DEFAULT_HASH_LENGTH,
|
||||
DEFAULT_MEMORY_COST,
|
||||
DEFAULT_PARALLELISM,
|
||||
DEFAULT_RANDOM_SALT_LENGTH,
|
||||
DEFAULT_TIME_COST,
|
||||
)
|
||||
from ._typing import Literal
|
||||
from .low_level import Type, hash_secret, hash_secret_raw, verify_secret
|
||||
|
||||
|
||||
def hash_password(
|
||||
password: bytes,
|
||||
salt: Optional[bytes] = None,
|
||||
time_cost: int = DEFAULT_TIME_COST,
|
||||
memory_cost: int = DEFAULT_MEMORY_COST,
|
||||
parallelism: int = DEFAULT_PARALLELISM,
|
||||
hash_len: int = DEFAULT_HASH_LENGTH,
|
||||
type: Type = Type.I,
|
||||
) -> bytes:
|
||||
"""
|
||||
Legacy alias for :func:`hash_secret` with default parameters.
|
||||
|
||||
.. deprecated:: 16.0.0
|
||||
Use :class:`argon2.PasswordHasher` for passwords.
|
||||
"""
|
||||
if salt is None:
|
||||
salt = os.urandom(DEFAULT_RANDOM_SALT_LENGTH)
|
||||
return hash_secret(
|
||||
password, salt, time_cost, memory_cost, parallelism, hash_len, type
|
||||
)
|
||||
|
||||
|
||||
def hash_password_raw(
|
||||
password: bytes,
|
||||
salt: Optional[bytes] = None,
|
||||
time_cost: int = DEFAULT_TIME_COST,
|
||||
memory_cost: int = DEFAULT_MEMORY_COST,
|
||||
parallelism: int = DEFAULT_PARALLELISM,
|
||||
hash_len: int = DEFAULT_HASH_LENGTH,
|
||||
type: Type = Type.I,
|
||||
) -> bytes:
|
||||
"""
|
||||
Legacy alias for :func:`hash_secret_raw` with default parameters.
|
||||
|
||||
.. deprecated:: 16.0.0
|
||||
Use :class:`argon2.PasswordHasher` for passwords.
|
||||
"""
|
||||
if salt is None:
|
||||
salt = os.urandom(DEFAULT_RANDOM_SALT_LENGTH)
|
||||
return hash_secret_raw(
|
||||
password, salt, time_cost, memory_cost, parallelism, hash_len, type
|
||||
)
|
||||
|
||||
|
||||
def verify_password(
|
||||
hash: bytes, password: bytes, type: Type = Type.I
|
||||
) -> Literal[True]:
|
||||
"""
|
||||
Legacy alias for :func:`verify_secret` with default parameters.
|
||||
|
||||
.. deprecated:: 16.0.0
|
||||
Use :class:`argon2.PasswordHasher` for passwords.
|
||||
"""
|
||||
return verify_secret(hash, password, type)
|
235
.venv/Lib/site-packages/argon2/_password_hasher.py
Normal file
235
.venv/Lib/site-packages/argon2/_password_hasher.py
Normal file
@ -0,0 +1,235 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
import os
|
||||
|
||||
from typing import Union
|
||||
|
||||
from ._typing import Literal
|
||||
from ._utils import Parameters, _check_types, extract_parameters
|
||||
from .exceptions import InvalidHash
|
||||
from .low_level import Type, hash_secret, verify_secret
|
||||
from .profiles import RFC_9106_LOW_MEMORY
|
||||
|
||||
|
||||
DEFAULT_RANDOM_SALT_LENGTH = RFC_9106_LOW_MEMORY.salt_len
|
||||
DEFAULT_HASH_LENGTH = RFC_9106_LOW_MEMORY.hash_len
|
||||
DEFAULT_TIME_COST = RFC_9106_LOW_MEMORY.time_cost
|
||||
DEFAULT_MEMORY_COST = RFC_9106_LOW_MEMORY.memory_cost
|
||||
DEFAULT_PARALLELISM = RFC_9106_LOW_MEMORY.parallelism
|
||||
|
||||
|
||||
def _ensure_bytes(s: Union[bytes, str], encoding: str) -> bytes:
|
||||
"""
|
||||
Ensure *s* is a bytes string. Encode using *encoding* if it isn't.
|
||||
"""
|
||||
if isinstance(s, bytes):
|
||||
return s
|
||||
return s.encode(encoding)
|
||||
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
: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.
|
||||
|
||||
.. versionadded:: 16.0.0
|
||||
.. versionchanged:: 18.2.0
|
||||
Switch from Argon2i to Argon2id based on the recommendation by the
|
||||
current RFC draft. See also :doc:`parameters`.
|
||||
.. versionchanged:: 18.2.0
|
||||
Changed default *memory_cost* to 100 MiB and default *parallelism* to 8.
|
||||
.. versionchanged:: 18.2.0 ``verify`` now will determine the type of hash.
|
||||
.. versionchanged:: 18.3.0 The *Argon2* type is configurable now.
|
||||
.. versionadded:: 21.2.0 :meth:`from_parameters`
|
||||
.. versionchanged:: 21.2.0
|
||||
Changed defaults to :data:`argon2.profiles.RFC_9106_LOW_MEMORY`.
|
||||
|
||||
.. _salt: https://en.wikipedia.org/wiki/Salt_(cryptography)
|
||||
.. _kibibytes: https://en.wikipedia.org/wiki/Binary_prefix#kibi
|
||||
"""
|
||||
__slots__ = ["_parameters", "encoding"]
|
||||
|
||||
_parameters: Parameters
|
||||
encoding: str
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
time_cost: int = DEFAULT_TIME_COST,
|
||||
memory_cost: int = DEFAULT_MEMORY_COST,
|
||||
parallelism: int = DEFAULT_PARALLELISM,
|
||||
hash_len: int = DEFAULT_HASH_LENGTH,
|
||||
salt_len: int = DEFAULT_RANDOM_SALT_LENGTH,
|
||||
encoding: str = "utf-8",
|
||||
type: Type = Type.ID,
|
||||
):
|
||||
e = _check_types(
|
||||
time_cost=(time_cost, int),
|
||||
memory_cost=(memory_cost, int),
|
||||
parallelism=(parallelism, int),
|
||||
hash_len=(hash_len, int),
|
||||
salt_len=(salt_len, int),
|
||||
encoding=(encoding, str),
|
||||
type=(type, Type),
|
||||
)
|
||||
if e:
|
||||
raise TypeError(e)
|
||||
|
||||
# Cache a Parameters object for check_needs_rehash.
|
||||
self._parameters = Parameters(
|
||||
type=type,
|
||||
version=19,
|
||||
salt_len=salt_len,
|
||||
hash_len=hash_len,
|
||||
time_cost=time_cost,
|
||||
memory_cost=memory_cost,
|
||||
parallelism=parallelism,
|
||||
)
|
||||
self.encoding = encoding
|
||||
|
||||
@classmethod
|
||||
def from_parameters(cls, params: Parameters) -> "PasswordHasher":
|
||||
"""
|
||||
Construct a `PasswordHasher` from *params*.
|
||||
|
||||
.. versionadded:: 21.2.0
|
||||
"""
|
||||
ph = cls()
|
||||
ph._parameters = params
|
||||
|
||||
return ph
|
||||
|
||||
@property
|
||||
def time_cost(self) -> int:
|
||||
return self._parameters.time_cost
|
||||
|
||||
@property
|
||||
def memory_cost(self) -> int:
|
||||
return self._parameters.memory_cost
|
||||
|
||||
@property
|
||||
def parallelism(self) -> int:
|
||||
return self._parameters.parallelism
|
||||
|
||||
@property
|
||||
def hash_len(self) -> int:
|
||||
return self._parameters.hash_len
|
||||
|
||||
@property
|
||||
def salt_len(self) -> int:
|
||||
return self._parameters.salt_len
|
||||
|
||||
@property
|
||||
def type(self) -> Type:
|
||||
return self._parameters.type
|
||||
|
||||
def hash(self, password: Union[str, bytes]) -> str:
|
||||
"""
|
||||
Hash *password* and return an encoded hash.
|
||||
|
||||
:param password: Password to hash.
|
||||
:type password: ``bytes`` or ``str``
|
||||
|
||||
:raises argon2.exceptions.HashingError: If hashing fails.
|
||||
|
||||
:rtype: str
|
||||
"""
|
||||
return hash_secret(
|
||||
secret=_ensure_bytes(password, self.encoding),
|
||||
salt=os.urandom(self.salt_len),
|
||||
time_cost=self.time_cost,
|
||||
memory_cost=self.memory_cost,
|
||||
parallelism=self.parallelism,
|
||||
hash_len=self.hash_len,
|
||||
type=self.type,
|
||||
).decode("ascii")
|
||||
|
||||
_header_to_type = {
|
||||
b"$argon2i$": Type.I,
|
||||
b"$argon2d$": Type.D,
|
||||
b"$argon2id": Type.ID,
|
||||
}
|
||||
|
||||
def verify(
|
||||
self, hash: Union[str, bytes], password: Union[str, bytes]
|
||||
) -> Literal[True]:
|
||||
"""
|
||||
Verify that *password* matches *hash*.
|
||||
|
||||
.. warning::
|
||||
|
||||
It is assumed that the caller is in full control of the hash. No
|
||||
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``
|
||||
|
||||
:param password: The password to verify.
|
||||
:type password: ``bytes`` or ``str``
|
||||
|
||||
: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.InvalidHash: If *hash* is so clearly
|
||||
invalid, that it couldn't be passed to *Argon2*.
|
||||
|
||||
:return: ``True`` on success, raise
|
||||
:exc:`~argon2.exceptions.VerificationError` otherwise.
|
||||
:rtype: bool
|
||||
|
||||
.. versionchanged:: 16.1.0
|
||||
Raise :exc:`~argon2.exceptions.VerifyMismatchError` on mismatches
|
||||
instead of its more generic superclass.
|
||||
.. versionadded:: 18.2.0 Hash type agility.
|
||||
"""
|
||||
hash = _ensure_bytes(hash, "ascii")
|
||||
try:
|
||||
hash_type = self._header_to_type[hash[:9]]
|
||||
except (IndexError, KeyError, LookupError):
|
||||
raise InvalidHash()
|
||||
|
||||
return verify_secret(
|
||||
hash, _ensure_bytes(password, self.encoding), hash_type
|
||||
)
|
||||
|
||||
def check_needs_rehash(self, hash: str) -> bool:
|
||||
"""
|
||||
Check whether *hash* was created using the instance's parameters.
|
||||
|
||||
Whenever your *Argon2* parameters -- or *argon2-cffi*'s defaults! --
|
||||
change, you should rehash your passwords at the next opportunity. The
|
||||
common approach is to do that whenever a user logs in, since that
|
||||
should be the only time when you have access to the cleartext
|
||||
password.
|
||||
|
||||
Therefore it's best practice to check -- and if necessary rehash --
|
||||
passwords after each successful authentication.
|
||||
|
||||
:rtype: bool
|
||||
|
||||
.. versionadded:: 18.2.0
|
||||
"""
|
||||
return self._parameters != extract_parameters(hash)
|
13
.venv/Lib/site-packages/argon2/_typing.py
Normal file
13
.venv/Lib/site-packages/argon2/_typing.py
Normal file
@ -0,0 +1,13 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
# try/except ImportError does NOT work.
|
||||
# c.f. https://github.com/python/mypy/issues/8520
|
||||
if sys.version_info >= (3, 8):
|
||||
from typing import Literal
|
||||
else:
|
||||
from typing_extensions import Literal
|
||||
|
||||
__all__ = ["Literal"]
|
140
.venv/Lib/site-packages/argon2/_utils.py
Normal file
140
.venv/Lib/site-packages/argon2/_utils.py
Normal file
@ -0,0 +1,140 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Optional
|
||||
|
||||
from .exceptions import InvalidHash
|
||||
from .low_level import Type
|
||||
|
||||
|
||||
NoneType = type(None)
|
||||
|
||||
|
||||
def _check_types(**kw: Any) -> Optional[str]:
|
||||
"""
|
||||
Check each ``name: (value, types)`` in *kw*.
|
||||
|
||||
Returns a human-readable string of all violations or `None``.
|
||||
"""
|
||||
errors = []
|
||||
for name, (value, types) in kw.items():
|
||||
if not isinstance(value, types):
|
||||
if isinstance(types, tuple):
|
||||
types = ", or ".join(t.__name__ for t in types)
|
||||
else:
|
||||
types = types.__name__
|
||||
errors.append(
|
||||
"'{name}' must be a {type} (got {actual})".format(
|
||||
name=name, type=types, actual=type(value).__name__
|
||||
)
|
||||
)
|
||||
|
||||
if errors != []:
|
||||
return ", ".join(errors) + "."
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def _decoded_str_len(l: int) -> int:
|
||||
"""
|
||||
Compute how long an encoded string of length *l* becomes.
|
||||
"""
|
||||
rem = l % 4
|
||||
|
||||
if rem == 3:
|
||||
last_group_len = 2
|
||||
elif rem == 2:
|
||||
last_group_len = 1
|
||||
else:
|
||||
last_group_len = 0
|
||||
|
||||
return l // 4 * 3 + last_group_len
|
||||
|
||||
|
||||
@dataclass
|
||||
class Parameters:
|
||||
"""
|
||||
Argon2 hash 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.
|
||||
|
||||
.. versionadded:: 18.2.0
|
||||
"""
|
||||
|
||||
type: Type
|
||||
version: int
|
||||
salt_len: int
|
||||
hash_len: int
|
||||
time_cost: int
|
||||
memory_cost: int
|
||||
parallelism: int
|
||||
|
||||
__slots__ = [
|
||||
"type",
|
||||
"version",
|
||||
"salt_len",
|
||||
"hash_len",
|
||||
"time_cost",
|
||||
"memory_cost",
|
||||
"parallelism",
|
||||
]
|
||||
|
||||
|
||||
_NAME_TO_TYPE = {"argon2id": Type.ID, "argon2i": Type.I, "argon2d": Type.D}
|
||||
_REQUIRED_KEYS = sorted(("v", "m", "t", "p"))
|
||||
|
||||
|
||||
def extract_parameters(hash: str) -> Parameters:
|
||||
"""
|
||||
Extract parameters from an encoded *hash*.
|
||||
|
||||
:param str params: An encoded Argon2 hash string.
|
||||
|
||||
:rtype: Parameters
|
||||
|
||||
.. versionadded:: 18.2.0
|
||||
"""
|
||||
parts = hash.split("$")
|
||||
|
||||
# Backwards compatibility for Argon v1.2 hashes
|
||||
if len(parts) == 5:
|
||||
parts.insert(2, "v=18")
|
||||
|
||||
if len(parts) != 6:
|
||||
raise InvalidHash
|
||||
|
||||
if parts[0] != "":
|
||||
raise InvalidHash
|
||||
|
||||
try:
|
||||
type = _NAME_TO_TYPE[parts[1]]
|
||||
|
||||
kvs = {
|
||||
k: int(v)
|
||||
for k, v in (
|
||||
s.split("=") for s in [parts[2]] + parts[3].split(",")
|
||||
)
|
||||
}
|
||||
except Exception:
|
||||
raise InvalidHash
|
||||
|
||||
if sorted(kvs.keys()) != _REQUIRED_KEYS:
|
||||
raise InvalidHash
|
||||
|
||||
return Parameters(
|
||||
type=type,
|
||||
salt_len=_decoded_str_len(len(parts[4])),
|
||||
hash_len=_decoded_str_len(len(parts[5])),
|
||||
version=kvs["v"],
|
||||
time_cost=kvs["t"],
|
||||
memory_cost=kvs["m"],
|
||||
parallelism=kvs["p"],
|
||||
)
|
43
.venv/Lib/site-packages/argon2/exceptions.py
Normal file
43
.venv/Lib/site-packages/argon2/exceptions.py
Normal file
@ -0,0 +1,43 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
class Argon2Error(Exception):
|
||||
"""
|
||||
Superclass of all argon2 exceptions.
|
||||
|
||||
Never thrown directly.
|
||||
"""
|
||||
|
||||
|
||||
class VerificationError(Argon2Error):
|
||||
"""
|
||||
Verification failed.
|
||||
|
||||
You can find the original error message from Argon2 in ``args[0]``.
|
||||
"""
|
||||
|
||||
|
||||
class VerifyMismatchError(VerificationError):
|
||||
"""
|
||||
The secret does not match the hash.
|
||||
|
||||
Subclass of :exc:`argon2.exceptions.VerificationError`.
|
||||
|
||||
.. versionadded:: 16.1.0
|
||||
"""
|
||||
|
||||
|
||||
class HashingError(Argon2Error):
|
||||
"""
|
||||
Raised if hashing failed.
|
||||
|
||||
You can find the original error message from Argon2 in ``args[0]``.
|
||||
"""
|
||||
|
||||
|
||||
class InvalidHash(ValueError):
|
||||
"""
|
||||
Raised if the hash is invalid before passing it to Argon2.
|
||||
|
||||
.. versionadded:: 18.2.0
|
||||
"""
|
255
.venv/Lib/site-packages/argon2/low_level.py
Normal file
255
.venv/Lib/site-packages/argon2/low_level.py
Normal file
@ -0,0 +1,255 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
"""
|
||||
Low-level functions if you want to build your own higher level abstractions.
|
||||
|
||||
.. warning::
|
||||
This is a "Hazardous Materials" module. You should **ONLY** use it if
|
||||
you're 100% absolutely sure that you know what you’re doing because this
|
||||
module is full of land mines, dragons, and dinosaurs with laser guns.
|
||||
"""
|
||||
|
||||
from enum import Enum
|
||||
from typing import Any
|
||||
|
||||
from _argon2_cffi_bindings import ffi, lib
|
||||
|
||||
from ._typing import Literal
|
||||
from .exceptions import HashingError, VerificationError, VerifyMismatchError
|
||||
|
||||
|
||||
__all__ = [
|
||||
"ARGON2_VERSION",
|
||||
"Type",
|
||||
"ffi",
|
||||
"hash_secret",
|
||||
"hash_secret_raw",
|
||||
"verify_secret",
|
||||
]
|
||||
|
||||
ARGON2_VERSION = lib.ARGON2_VERSION_NUMBER
|
||||
"""
|
||||
The latest version of the Argon2 algorithm that is supported (and used by
|
||||
default).
|
||||
|
||||
.. versionadded:: 16.1.0
|
||||
"""
|
||||
|
||||
|
||||
class Type(Enum):
|
||||
"""
|
||||
Enum of Argon2 variants.
|
||||
|
||||
Please see :doc:`parameters` on how to pick one.
|
||||
"""
|
||||
|
||||
D = lib.Argon2_d
|
||||
r"""
|
||||
Argon2\ **d** is faster and uses data-depending memory access, which makes
|
||||
it less suitable for hashing secrets and more suitable for cryptocurrencies
|
||||
and applications with no threats from side-channel timing attacks.
|
||||
"""
|
||||
I = lib.Argon2_i
|
||||
r"""
|
||||
Argon2\ **i** uses data-independent memory access. Argon2i is slower as
|
||||
it makes more passes over the memory to protect from tradeoff attacks.
|
||||
"""
|
||||
ID = lib.Argon2_id
|
||||
r"""
|
||||
Argon2\ **id** is a hybrid of Argon2i and Argon2d, using a combination of
|
||||
data-depending and data-independent memory accesses, which gives some of
|
||||
Argon2i's resistance to side-channel cache timing attacks and much of
|
||||
Argon2d's resistance to GPU cracking attacks.
|
||||
|
||||
That makes it the preferred type for password hashing and password-based
|
||||
key derivation.
|
||||
|
||||
.. versionadded:: 16.3.0
|
||||
"""
|
||||
|
||||
|
||||
def hash_secret(
|
||||
secret: bytes,
|
||||
salt: bytes,
|
||||
time_cost: int,
|
||||
memory_cost: int,
|
||||
parallelism: int,
|
||||
hash_len: int,
|
||||
type: Type,
|
||||
version: int = ARGON2_VERSION,
|
||||
) -> bytes:
|
||||
"""
|
||||
Hash *secret* and return an **encoded** hash.
|
||||
|
||||
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.
|
||||
|
||||
For an explanation of the Argon2 parameters see :class:`PasswordHasher`.
|
||||
|
||||
:rtype: bytes
|
||||
|
||||
:raises argon2.exceptions.HashingError: If hashing fails.
|
||||
|
||||
.. versionadded:: 16.0.0
|
||||
|
||||
.. _salt: https://en.wikipedia.org/wiki/Salt_(cryptography)
|
||||
.. _kibibytes: https://en.wikipedia.org/wiki/Binary_prefix#kibi
|
||||
"""
|
||||
size = (
|
||||
lib.argon2_encodedlen(
|
||||
time_cost,
|
||||
memory_cost,
|
||||
parallelism,
|
||||
len(salt),
|
||||
hash_len,
|
||||
type.value,
|
||||
)
|
||||
+ 1
|
||||
)
|
||||
buf = ffi.new("char[]", size)
|
||||
rv = lib.argon2_hash(
|
||||
time_cost,
|
||||
memory_cost,
|
||||
parallelism,
|
||||
ffi.new("uint8_t[]", secret),
|
||||
len(secret),
|
||||
ffi.new("uint8_t[]", salt),
|
||||
len(salt),
|
||||
ffi.NULL,
|
||||
hash_len,
|
||||
buf,
|
||||
size,
|
||||
type.value,
|
||||
version,
|
||||
)
|
||||
if rv != lib.ARGON2_OK:
|
||||
raise HashingError(error_to_str(rv))
|
||||
|
||||
return ffi.string(buf)
|
||||
|
||||
|
||||
def hash_secret_raw(
|
||||
secret: bytes,
|
||||
salt: bytes,
|
||||
time_cost: int,
|
||||
memory_cost: int,
|
||||
parallelism: int,
|
||||
hash_len: int,
|
||||
type: Type,
|
||||
version: int = ARGON2_VERSION,
|
||||
) -> bytes:
|
||||
"""
|
||||
Hash *password* and return a **raw** hash.
|
||||
|
||||
This function takes the same parameters as :func:`hash_secret`.
|
||||
|
||||
.. versionadded:: 16.0.0
|
||||
"""
|
||||
buf = ffi.new("uint8_t[]", hash_len)
|
||||
|
||||
rv = lib.argon2_hash(
|
||||
time_cost,
|
||||
memory_cost,
|
||||
parallelism,
|
||||
ffi.new("uint8_t[]", secret),
|
||||
len(secret),
|
||||
ffi.new("uint8_t[]", salt),
|
||||
len(salt),
|
||||
buf,
|
||||
hash_len,
|
||||
ffi.NULL,
|
||||
0,
|
||||
type.value,
|
||||
version,
|
||||
)
|
||||
if rv != lib.ARGON2_OK:
|
||||
raise HashingError(error_to_str(rv))
|
||||
|
||||
return bytes(ffi.buffer(buf, hash_len))
|
||||
|
||||
|
||||
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
|
||||
: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.
|
||||
|
||||
:return: ``True`` on success, raise
|
||||
:exc:`~argon2.exceptions.VerificationError` otherwise.
|
||||
:rtype: bool
|
||||
|
||||
.. versionadded:: 16.0.0
|
||||
.. versionchanged:: 16.1.0
|
||||
Raise :exc:`~argon2.exceptions.VerifyMismatchError` on mismatches
|
||||
instead of its more generic superclass.
|
||||
"""
|
||||
rv = lib.argon2_verify(
|
||||
ffi.new("char[]", hash),
|
||||
ffi.new("uint8_t[]", secret),
|
||||
len(secret),
|
||||
type.value,
|
||||
)
|
||||
if rv == lib.ARGON2_OK:
|
||||
return True
|
||||
elif rv == lib.ARGON2_VERIFY_MISMATCH:
|
||||
raise VerifyMismatchError(error_to_str(rv))
|
||||
else:
|
||||
raise VerificationError(error_to_str(rv))
|
||||
|
||||
|
||||
def core(context: Any, type: int) -> int:
|
||||
"""
|
||||
Direct binding to the ``argon2_ctx`` function.
|
||||
|
||||
.. warning::
|
||||
This is a strictly advanced function working on raw C data structures.
|
||||
Both *Argon2*'s and *argon2-cffi*'s higher-level bindings do a lot of
|
||||
sanity checks and housekeeping work that *you* are now responsible for
|
||||
(e.g. clearing buffers). The structure of the *context* object can,
|
||||
has, and will change with *any* release!
|
||||
|
||||
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.
|
||||
|
||||
:rtype: int
|
||||
:return: An *Argon2* error code. Can be transformed into a string using
|
||||
:func:`error_to_str`.
|
||||
|
||||
.. versionadded:: 16.0.0
|
||||
"""
|
||||
return lib.argon2_ctx(context, type)
|
||||
|
||||
|
||||
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`.
|
||||
|
||||
:rtype: str
|
||||
|
||||
.. versionadded:: 16.0.0
|
||||
"""
|
||||
msg = ffi.string(lib.argon2_error_message(error))
|
||||
msg = msg.decode("ascii")
|
||||
return msg
|
58
.venv/Lib/site-packages/argon2/profiles.py
Normal file
58
.venv/Lib/site-packages/argon2/profiles.py
Normal file
@ -0,0 +1,58 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
"""
|
||||
This module offers access to standardized parameters that you can load using
|
||||
:meth:`PasswordHasher.from_parameters()`. See the `source code
|
||||
<https://github.com/hynek/argon2-cffi/blob/main/src/argon2/profiles.py>`_ for
|
||||
concrete values and :doc:`parameters` for more information.
|
||||
|
||||
.. versionadded:: 21.2.0
|
||||
"""
|
||||
|
||||
from ._utils import Parameters
|
||||
from .low_level import Type
|
||||
|
||||
|
||||
# FIRST RECOMMENDED option per RFC 9106.
|
||||
RFC_9106_HIGH_MEMORY = Parameters(
|
||||
type=Type.ID,
|
||||
version=19,
|
||||
salt_len=16,
|
||||
hash_len=32,
|
||||
time_cost=1,
|
||||
memory_cost=2097152, # 2 GiB
|
||||
parallelism=4,
|
||||
)
|
||||
|
||||
# SECOND RECOMMENDED option per RFC 9106.
|
||||
RFC_9106_LOW_MEMORY = Parameters(
|
||||
type=Type.ID,
|
||||
version=19,
|
||||
salt_len=16,
|
||||
hash_len=32,
|
||||
time_cost=3,
|
||||
memory_cost=65536, # 64 MiB
|
||||
parallelism=4,
|
||||
)
|
||||
|
||||
# The pre-RFC defaults in argon2-cffi 18.2.0 - 21.1.0.
|
||||
PRE_21_2 = Parameters(
|
||||
type=Type.ID,
|
||||
version=19,
|
||||
salt_len=16,
|
||||
hash_len=16,
|
||||
time_cost=2,
|
||||
memory_cost=102400, # 100 MiB
|
||||
parallelism=8,
|
||||
)
|
||||
|
||||
# Only for testing!
|
||||
CHEAPEST = Parameters(
|
||||
type=Type.ID,
|
||||
version=19,
|
||||
salt_len=8,
|
||||
hash_len=4,
|
||||
time_cost=1,
|
||||
memory_cost=8,
|
||||
parallelism=1,
|
||||
)
|
0
.venv/Lib/site-packages/argon2/py.typed
Normal file
0
.venv/Lib/site-packages/argon2/py.typed
Normal file
Reference in New Issue
Block a user