Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
low_level.py254 linesDownload Raw Back to argon2
1# SPDX-License-Identifier: MIT2 3"""4Low-level functions if you want to build your own higher level abstractions.5 6.. warning::7    This is a "Hazardous Materials" module.  You should **ONLY** use it if8    you're 100% absolutely sure that you know what you're doing because this9    module is full of land mines, dragons, and dinosaurs with laser guns.10"""11 12from __future__ import annotations13 14from enum import Enum15from typing import Any, Literal16 17from _argon2_cffi_bindings import ffi, lib18 19from .exceptions import HashingError, VerificationError, VerifyMismatchError20 21 22__all__ = [23    "ARGON2_VERSION",24    "Type",25    "ffi",26    "hash_secret",27    "hash_secret_raw",28    "verify_secret",29]30 31ARGON2_VERSION = lib.ARGON2_VERSION_NUMBER32"""33The latest version of the Argon2 algorithm that is supported (and used by34default).35 36.. versionadded:: 16.1.037"""38 39 40class Type(Enum):41    """42    Enum of Argon2 variants.43 44    Please see :doc:`parameters` on how to pick one.45    """46 47    D = lib.Argon2_d48    I = lib.Argon2_i  # noqa: E74149    ID = lib.Argon2_id50 51 52def hash_secret(53    secret: bytes,54    salt: bytes,55    time_cost: int,56    memory_cost: int,57    parallelism: int,58    hash_len: int,59    type: Type,60    version: int = ARGON2_VERSION,61) -> bytes:62    """63    Hash *secret* and return an **encoded** hash.64 65    An encoded hash can be directly passed into :func:`verify_secret` as it66    contains all parameters and the salt.67 68    Args:69        secret: Secret to hash.70 71        salt: A salt_. Should be random and different for each secret.72 73        type: Which Argon2 variant to use.74 75        version: Which Argon2 version to use.76 77    For an explanation of the Argon2 parameters see78    :class:`argon2.PasswordHasher`.79 80    Returns:81        An encoded Argon2 hash.82 83    Raises:84        argon2.exceptions.HashingError: If hashing fails.85 86    .. versionadded:: 16.0.087 88    .. _salt: https://en.wikipedia.org/wiki/Salt_(cryptography)89    """90    size = (91        lib.argon2_encodedlen(92            time_cost,93            memory_cost,94            parallelism,95            len(salt),96            hash_len,97            type.value,98        )99        + 1100    )101    buf = ffi.new("char[]", size)102    rv = lib.argon2_hash(103        time_cost,104        memory_cost,105        parallelism,106        ffi.new("uint8_t[]", secret),107        len(secret),108        ffi.new("uint8_t[]", salt),109        len(salt),110        ffi.NULL,111        hash_len,112        buf,113        size,114        type.value,115        version,116    )117    if rv != lib.ARGON2_OK:118        raise HashingError(error_to_str(rv))119 120    return ffi.string(buf)  # type: ignore[no-any-return]121 122 123def hash_secret_raw(124    secret: bytes,125    salt: bytes,126    time_cost: int,127    memory_cost: int,128    parallelism: int,129    hash_len: int,130    type: Type,131    version: int = ARGON2_VERSION,132) -> bytes:133    """134    Hash *password* and return a **raw** hash.135 136    This function takes the same parameters as :func:`hash_secret`.137 138    .. versionadded:: 16.0.0139    """140    buf = ffi.new("uint8_t[]", hash_len)141 142    rv = lib.argon2_hash(143        time_cost,144        memory_cost,145        parallelism,146        ffi.new("uint8_t[]", secret),147        len(secret),148        ffi.new("uint8_t[]", salt),149        len(salt),150        buf,151        hash_len,152        ffi.NULL,153        0,154        type.value,155        version,156    )157    if rv != lib.ARGON2_OK:158        raise HashingError(error_to_str(rv))159 160    return bytes(ffi.buffer(buf, hash_len))161 162 163def verify_secret(hash: bytes, secret: bytes, type: Type) -> Literal[True]:164    """165    Verify whether *secret* is correct for *hash* of *type*.166 167    Args:168        hash:169            An encoded Argon2 hash as returned by :func:`hash_secret`.170 171        secret:172            The secret to verify whether it matches the one in *hash*.173 174        type: Type for *hash*.175 176    Raises:177        argon2.exceptions.VerifyMismatchError:178            If verification fails because *hash* is not valid for *secret* of179            *type*.180 181        argon2.exceptions.VerificationError:182            If verification fails for other reasons.183 184    Returns:185        ``True`` on success, raise :exc:`~argon2.exceptions.VerificationError`186        otherwise.187 188    .. versionadded:: 16.0.0189    .. versionchanged:: 16.1.0190        Raise :exc:`~argon2.exceptions.VerifyMismatchError` on mismatches191        instead of its more generic superclass.192    """193    rv = lib.argon2_verify(194        ffi.new("char[]", hash),195        ffi.new("uint8_t[]", secret),196        len(secret),197        type.value,198    )199 200    if rv == lib.ARGON2_OK:201        return True202 203    if rv == lib.ARGON2_VERIFY_MISMATCH:204        raise VerifyMismatchError(error_to_str(rv))205 206    raise VerificationError(error_to_str(rv))207 208 209def core(context: Any, type: int) -> int:210    """211    Direct binding to the ``argon2_ctx`` function.212 213    .. warning::214        This is a strictly advanced function working on raw C data structures.215        Both Argon2's and *argon2-cffi*'s higher-level bindings do a lot of216        sanity checks and housekeeping work that *you* are now responsible for217        (e.g. clearing buffers). The structure of the *context* object can,218        has, and will change with *any* release!219 220        Use at your own peril; *argon2-cffi* does *not* use this binding221        itself.222 223    Args:224        context:225            A CFFI Argon2 context object (i.e. an ``struct Argon2_Context`` /226            ``argon2_context``).227 228        type:229            Which Argon2 variant to use.  You can use the ``value`` field of230            :class:`Type`'s fields.231 232    Returns:233        An Argon2 error code.  Can be transformed into a string using234        :func:`error_to_str`.235 236    .. versionadded:: 16.0.0237    """238    return lib.argon2_ctx(context, type)  # type: ignore[no-any-return]239 240 241def error_to_str(error: int) -> str:242    """243    Convert an Argon2 error code into a native string.244 245    Args:246        error: An Argon2 error code as returned by :func:`core`.247 248    Returns:249        A human-readable string describing the error.250 251    .. versionadded:: 16.0.0252    """253    return ffi.string(lib.argon2_error_message(error)).decode("ascii")  # type: ignore[no-any-return]254 
codekingpro/portable-devtools · Team Ai