CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-argon2-cffi

Argon2 password hashing algorithm for Python with secure defaults and multiple variants

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

low-level.mddocs/

Low-Level Functions

Direct access to Argon2 C library functions for advanced users who need fine-grained control over hashing parameters, raw hash outputs, or custom implementations.

Warning: This is a "Hazardous Materials" module. Only use if you're absolutely sure you know what you're doing, as this module contains many potential pitfalls.

Capabilities

Secret Hashing (Encoded)

Hash secrets and return encoded hash strings that contain all parameters and salt information.

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 verify_secret() as it
    contains all parameters and the salt.
    
    Args:
        secret: Secret to hash (must be bytes)
        salt: Salt bytes (should be random and different for each secret)
        time_cost: Number of iterations
        memory_cost: Memory usage in kibibytes
        parallelism: Number of parallel threads
        hash_len: Length of hash output in bytes
        type: Argon2 variant (Type.I, Type.D, or Type.ID)
        version: Argon2 version number (default: latest)
    
    Returns:
        Encoded Argon2 hash as bytes
    
    Raises:
        argon2.exceptions.HashingError: If hashing fails
    """

Usage Example

from argon2.low_level import hash_secret, Type
import os

# Prepare inputs
secret = b"my_secret_data"
salt = os.urandom(16)  # 16-byte random salt

# Hash with Argon2id
encoded_hash = hash_secret(
    secret=secret,
    salt=salt,
    time_cost=3,
    memory_cost=65536,  # 64 MiB
    parallelism=4,
    hash_len=32,
    type=Type.ID
)

print(encoded_hash.decode('ascii'))
# Output: $argon2id$v=19$m=65536,t=3,p=4$base64salt$base64hash

Secret Hashing (Raw)

Hash secrets and return raw hash bytes without encoding or parameter information.

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 secret and return a raw hash.
    
    Returns only the hash bytes without encoding or parameter information.
    Takes the same parameters as hash_secret().
    
    Args:
        secret: Secret to hash (must be bytes)
        salt: Salt bytes
        time_cost: Number of iterations
        memory_cost: Memory usage in kibibytes
        parallelism: Number of parallel threads
        hash_len: Length of hash output in bytes
        type: Argon2 variant
        version: Argon2 version number
    
    Returns:
        Raw hash bytes (length = hash_len)
    
    Raises:
        argon2.exceptions.HashingError: If hashing fails
    """

Usage Example

from argon2.low_level import hash_secret_raw, Type
import os

# Get raw hash bytes for custom processing
raw_hash = hash_secret_raw(
    secret=b"my_secret",
    salt=os.urandom(16),
    time_cost=2,
    memory_cost=102400,  # 100 MiB
    parallelism=8,
    hash_len=64,        # 64-byte output
    type=Type.ID
)

print(f"Raw hash length: {len(raw_hash)} bytes")
print(f"Raw hash (hex): {raw_hash.hex()}")

Secret Verification

Verify secrets against encoded hashes with specified Argon2 type.

def verify_secret(hash: bytes, secret: bytes, type: Type) -> Literal[True]:
    """
    Verify whether secret is correct for hash of specified type.
    
    Args:
        hash: Encoded Argon2 hash (from hash_secret())
        secret: Secret to verify (must be bytes)
        type: Argon2 type used for the hash
    
    Returns:
        True if secret matches hash
    
    Raises:
        argon2.exceptions.VerifyMismatchError: Secret doesn't match hash
        argon2.exceptions.VerificationError: Verification failed for other reasons
    """

Usage Example

from argon2.low_level import hash_secret, verify_secret, Type

# Hash a secret
secret = b"my_secret_password"
salt = os.urandom(16)
hash_bytes = hash_secret(
    secret, salt, 3, 65536, 4, 32, Type.ID
)

# Later, verify the secret
try:
    result = verify_secret(hash_bytes, secret, Type.ID)
    print("Verification successful!")
except argon2.exceptions.VerifyMismatchError:
    print("Secret doesn't match!")

Direct C Library Access

Direct binding to the Argon2 C library's core function for maximum control.

def core(context: Any, type: int) -> int:
    """
    Direct binding to the argon2_ctx function.
    
    WARNING: This is strictly advanced functionality working on raw C data
    structures. All parameter validation and memory management is your
    responsibility. The context structure can change with any release.
    
    Args:
        context: CFFI Argon2 context object (struct Argon2_Context)
        type: Argon2 type value (use Type enum's .value attribute)
    
    Returns:
        Argon2 error code (0 = success)
    """

Error Code Conversion

Convert Argon2 C library error codes to human-readable strings.

def error_to_str(error: int) -> str:
    """
    Convert an Argon2 error code into a native string.
    
    Args:
        error: Argon2 error code (from core() function)
    
    Returns:
        Human-readable error description
    """

Usage Example

from argon2.low_level import core, error_to_str

# Advanced usage with direct C library access
try:
    # ... setup context object ...
    error_code = core(context, type_value)
    if error_code != 0:  # ARGON2_OK = 0
        error_msg = error_to_str(error_code)
        print(f"Argon2 error: {error_msg}")
except Exception as e:
    print(f"Failed: {e}")

Constants

ARGON2_VERSION: int
"""
The latest version of the Argon2 algorithm that is supported
and used by default.
"""

ffi: Any
"""
Foreign function interface (CFFI) object for direct C library access.
Provides access to C data structures and functions.
"""

Types

class Type(Enum):
    """
    Enum of Argon2 variants.
    
    D: Argon2d - Uses data-dependent memory access patterns.
       Faster but vulnerable to side-channel attacks.
       
    I: Argon2i - Uses data-independent memory access patterns.
       Slower but resistant to side-channel attacks.
       
    ID: Argon2id - Hybrid approach using both patterns.
        Recommended for most use cases.
    """
    D = ...   # Argon2d (data-dependent)
    I = ...   # Argon2i (data-independent)  
    ID = ...  # Argon2id (hybrid, recommended)

Platform Considerations

WebAssembly Limitations

When running in WebAssembly environments (detected automatically), parallelism must be set to 1:

# This will work in WebAssembly
hash_secret(secret, salt, 3, 65536, 1, 32, Type.ID)  # parallelism=1

# This will raise UnsupportedParametersError in WebAssembly
hash_secret(secret, salt, 3, 65536, 4, 32, Type.ID)  # parallelism=4

Memory Considerations

Memory cost is specified in kibibytes (1024 bytes). Large values may cause issues on memory-constrained systems:

# Conservative memory usage (64 MiB)
hash_secret(secret, salt, 3, 65536, 4, 32, Type.ID)

# High memory usage (2 GiB) - ensure system has sufficient RAM
hash_secret(secret, salt, 1, 2097152, 4, 32, Type.ID)

Install with Tessl CLI

npx tessl i tessl/pypi-argon2-cffi

docs

exceptions.md

index.md

low-level.md

password-hasher.md

profiles.md

tile.json