2025-12-25 upload
This commit is contained in:
174
venv/Lib/site-packages/argon2/_utils.py
Normal file
174
venv/Lib/site-packages/argon2/_utils.py
Normal file
@@ -0,0 +1,174 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import platform
|
||||
import sys
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
from .exceptions import InvalidHashError, UnsupportedParametersError
|
||||
from .low_level import Type
|
||||
|
||||
|
||||
NoneType = type(None)
|
||||
|
||||
|
||||
def _check_types(**kw: Any) -> str | None:
|
||||
"""
|
||||
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(
|
||||
f"'{name}' must be a {types} (got {type(value).__name__})"
|
||||
)
|
||||
|
||||
if errors != []:
|
||||
return ", ".join(errors) + "."
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def _is_wasm() -> bool:
|
||||
return sys.platform == "emscripten" or platform.machine() in [
|
||||
"wasm32",
|
||||
"wasm64",
|
||||
]
|
||||
|
||||
|
||||
def _decoded_str_len(length: int) -> int:
|
||||
"""
|
||||
Compute how long an encoded string of length *l* becomes.
|
||||
"""
|
||||
rem = length % 4
|
||||
|
||||
if rem == 3:
|
||||
last_group_len = 2
|
||||
elif rem == 2:
|
||||
last_group_len = 1
|
||||
else:
|
||||
last_group_len = 0
|
||||
|
||||
return length // 4 * 3 + last_group_len
|
||||
|
||||
|
||||
@dataclass
|
||||
class Parameters:
|
||||
"""
|
||||
Argon2 hash parameters.
|
||||
|
||||
See :doc:`parameters` on how to pick them.
|
||||
|
||||
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
|
||||
"""
|
||||
|
||||
type: Type
|
||||
version: int
|
||||
salt_len: int
|
||||
hash_len: int
|
||||
time_cost: int
|
||||
memory_cost: int
|
||||
parallelism: int
|
||||
|
||||
__slots__ = (
|
||||
"hash_len",
|
||||
"memory_cost",
|
||||
"parallelism",
|
||||
"salt_len",
|
||||
"time_cost",
|
||||
"type",
|
||||
"version",
|
||||
)
|
||||
|
||||
|
||||
_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*.
|
||||
|
||||
Args:
|
||||
hash: An encoded Argon2 hash string.
|
||||
|
||||
Returns:
|
||||
The parameters used to create the hash.
|
||||
|
||||
.. 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 InvalidHashError
|
||||
|
||||
if parts[0]:
|
||||
raise InvalidHashError
|
||||
|
||||
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: # noqa: BLE001
|
||||
raise InvalidHashError from None
|
||||
|
||||
if sorted(kvs.keys()) != _REQUIRED_KEYS:
|
||||
raise InvalidHashError
|
||||
|
||||
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"],
|
||||
)
|
||||
|
||||
|
||||
def validate_params_for_platform(params: Parameters) -> None:
|
||||
"""
|
||||
Validate *params* against current platform.
|
||||
|
||||
Args:
|
||||
params: Parameters to be validated
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
if _is_wasm() and params.parallelism != 1:
|
||||
msg = "In WebAssembly environments `parallelism` must be 1."
|
||||
raise UnsupportedParametersError(msg)
|
||||
Reference in New Issue
Block a user