API Reference

argon2_cffi comes with an high-level API and hopefully reasonable defaults for Argon2 parameters that result in a verification time of 40–50ms on recent-ish hardware.


The current memory requirement is set to rather conservative 100 MB. However, in memory constrained environments like Docker containers that can lead to problems. One possible non-obvious symptom are apparent freezes that are caused by swapping.

Please check Choosing Parameters for more details.

Unless you have any special needs, all you need to know is:

>>> from argon2 import PasswordHasher
>>> ph = PasswordHasher()
>>> hash = ph.hash("s3kr3tp4ssw0rd")
>>> hash  
>>> ph.verify(hash, "s3kr3tp4ssw0rd")
>>> ph.check_needs_rehash(hash)
>>> ph.verify(hash, "t0t411ywr0ng")
Traceback (most recent call last):
argon2.exceptions.VerifyMismatchError: The password does not match the supplied hash

A login function could thus look like this:

import argon2

ph = argon2.PasswordHasher()

def login(db, user, password):
    hash = db.get_password_hash_for_user(user)

    # Verify password, raises exception if wrong.
    ph.verify(hash, password)

    # Now that we have the cleartext password,
    # check the hash's parameters and if outdated,
    # rehash the user's password in the database.
    if ph.check_needs_rehash(hash):
        db.set_password_hash_for_user(user, ph.hash(password))

While the PasswordHasher class has the aspiration to be good to use out of the box, it has all the parametrization you’ll need:

class argon2.PasswordHasher(time_cost=2, memory_cost=102400, parallelism=8, hash_len=16, salt_len=16, encoding='utf-8', type=<Type.ID: 2>)

High level class to hash passwords with sensible defaults.

Uses Argon2id 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.

  • time_cost (int) – Defines the amount of computation realized and therefore the execution time, given in number of iterations.
  • memory_cost (int) – Defines the memory usage, given in kibibytes.
  • parallelism (int) – Defines the number of parallel threads (changes the resulting hash value).
  • hash_len (int) – Length of the hash in bytes.
  • salt_len (int) – Length of random salt to be generated for each password.
  • encoding (str) – The Argon2 C library expects bytes. So if hash() or verify() are passed an unicode string, it will be encoded using this encoding.
  • type (Type) – Argon2 type to use. Only change for interoperability with legacy systems.

New in version 16.0.0.

Changed in version 18.2.0: Switch from Argon2i to Argon2id based on the recommendation by the current RFC draft.

Changed in version 18.2.0: Changed default memory_cost to 100 MiB and default parallelism to 8.

Changed in version 18.2.0: verify now will determine the type of hash.

Changed in version 18.3.0: The Argon2 type is configurable now.


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.

Return type:bool

New in version 18.2.0.


Hash password and return an encoded hash.

Parameters:password (bytes or unicode) – Password to hash.
Raises:argon2.exceptions.HashingError – If hashing fails.
Return type:unicode
verify(hash, password)

Verify that password matches hash.


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.

  • hash (bytes or unicode) – An encoded hash as returned from PasswordHasher.hash().
  • password (bytes or unicode) – The password to verify.

True on success, raise VerificationError otherwise.

Return type:


Changed in version 16.1.0: Raise VerifyMismatchError on mismatches instead of its more generic superclass.

New in version 18.2.0: Hash type agility.

If you don’t specify any parameters, the following constants are used:


You can see their values in PasswordHasher.


exception argon2.exceptions.VerificationError

Verification failed.

You can find the original error message from Argon2 in args[0].

exception argon2.exceptions.VerifyMismatchError

The secret does not match the hash.

Subclass of argon2.exceptions.VerificationError.

New in version 16.1.0.

exception argon2.exceptions.HashingError

Raised if hashing failed.

You can find the original error message from Argon2 in args[0].

exception argon2.exceptions.InvalidHash

Raised if the hash is invalid before passing it to Argon2.

New in version 18.2.0.



Extract parameters from an encoded hash.

Parameters:params (str) – An encoded Argon2 hash string.
Return type:Parameters

New in version 18.2.0.

class argon2.Parameters(type, version, salt_len, hash_len, time_cost, memory_cost, parallelism)

Argon2 hash parameters.

See Choosing Parameters on how to pick them.

  • type (Type) – Hash type.
  • version (int) – Argon2 version.
  • salt_len (int) – Length of the salt in bytes.
  • hash_len (int) – Length of the hash in bytes.
  • time_cost (int) – Time cost in iterations.
  • memory_cost (int) – Memory cost in kibibytes.
  • parallelism (int) – Number of parallel threads.

New in version 18.2.0.

Low Level

Low-level functions if you want to build your own higher level abstractions.


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.

class argon2.low_level.Type

Enum of Argon2 variants.

Please see Choosing Parameters on how to pick one.

D = 0

Argon2d 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 = 1

Argon2i uses data-independent memory access. Argon2i is slower as it makes more passes over the memory to protect from tradeoff attacks.

ID = 2

Argon2id 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.

New in version 16.3.0.

argon2.low_level.ARGON2_VERSION = 19

The latest version of the Argon2 algorithm that is supported (and used by default).

New in version 16.1.0.

argon2.low_level.hash_secret(secret, salt, time_cost, memory_cost, parallelism, hash_len, type, version=19)

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.

  • secret (bytes) – Secret to hash.
  • salt (bytes) – A salt. Should be random and different for each secret.
  • type (Type) – Which Argon2 variant to use.
  • version (int) – Which Argon2 version to use.

For an explanation of the Argon2 parameters see PasswordHasher.

Return type:bytes
Raises:argon2.exceptions.HashingError – If hashing fails.

New in version 16.0.0.

>>> import argon2
>>> argon2.low_level.hash_secret(
...     b"secret", b"somesalt",
...     time_cost=1, memory_cost=8, parallelism=1, hash_len=64, type=argon2.low_level.Type.D
... )
argon2.low_level.verify_secret(hash, secret, type)

Verify whether secret is correct for hash of type.

  • hash (bytes) – An encoded Argon2 hash as returned by hash_secret().
  • secret (bytes) – The secret to verify whether it matches the one in hash.
  • type (Type) – Type for hash.

True on success, raise VerificationError otherwise.

Return type:


New in version 16.0.0.

Changed in version 16.1.0: Raise VerifyMismatchError on mismatches instead of its more generic superclass.

The raw hash can also be computed:

argon2.low_level.hash_secret_raw(secret, salt, time_cost, memory_cost, parallelism, hash_len, type, version=19)

Hash password and return a raw hash.

This function takes the same parameters as hash_secret().

New in version 16.0.0.

>>> argon2.low_level.hash_secret_raw(
...     b"secret", b"somesalt",
...     time_cost=1, memory_cost=8, parallelism=1, hash_len=8, type=argon2.low_level.Type.D
... )

The super low-level argon2_core() function is exposed too if you need access to very specific options:

argon2.low_level.core(context, type)

Direct binding to the argon2_ctx function.


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.

  • context – A CFFI Argon2 context object (i.e. an struct Argon2_Context/argon2_context).
  • type (int) – Which Argon2 variant to use. You can use the value field of Type’s fields.
Return type:



An Argon2 error code. Can be transformed into a string using error_to_str().

New in version 16.0.0.

In order to use core(), you need access to argon2_cffi’s FFI objects. Therefore it is OK to use argon2.low_level.ffi and argon2.low_level.lib when working with it:

>>> from argon2.low_level import ARGON2_VERSION, Type, core, ffi, lib
>>> pwd = b"secret"
>>> salt = b"12345678"
>>> hash_len = 8
>>> # Make sure you keep FFI objects alive until *after* the core call!
>>> cout = ffi.new("uint8_t[]", hash_len)
>>> cpwd = ffi.new("uint8_t[]", pwd)
>>> csalt = ffi.new("uint8_t[]", salt)
>>> ctx = ffi.new(
...     "argon2_context *", dict(
...         version=ARGON2_VERSION,
...         out=cout, outlen=hash_len,
...         pwd=cpwd, pwdlen=len(pwd),
...         salt=csalt, saltlen=len(salt),
...         secret=ffi.NULL, secretlen=0,
...         ad=ffi.NULL, adlen=0,
...         t_cost=1,
...         m_cost=8,
...         lanes=1, threads=1,
...         allocate_cbk=ffi.NULL, free_cbk=ffi.NULL,
...         flags=lib.ARGON2_DEFAULT_FLAGS,
...     )
... )
>>> ctx
<cdata 'struct Argon2_Context *' owning 120 bytes>
>>> core(ctx, Type.D.value)
>>> out = bytes(ffi.buffer(ctx.out, ctx.outlen))
>>> out
>>> out == argon2.low_level.hash_secret_raw(pwd, salt, 1, 8, 1, 8, Type.D)

All constants and types on argon2.low_level.lib are guaranteed to stay as long they are not altered by Argon2 itself.


Convert an Argon2 error code into a native string.

Parameters:error (int) – An Argon2 error code as returned by core().
Return type:str

New in version 16.0.0.

Deprecated APIs

These APIs are from the first release of argon2_cffi and proved to live in an unfortunate mid-level. On one hand they have defaults and check parameters but on the other hand they only consume byte strings.

Therefore the decision has been made to replace them by a high-level (argon2.PasswordHasher) and a low-level (argon2.low_level) solution. There are no immediate plans to remove them though.

argon2.hash_password(password, salt=None, time_cost=2, memory_cost=102400, parallelism=8, hash_len=16, type=<Type.I: 1>)

Legacy alias for hash_secret() with default parameters.

Deprecated since version 16.0.0: Use argon2.PasswordHasher for passwords.

argon2.hash_password_raw(password, salt=None, time_cost=2, memory_cost=102400, parallelism=8, hash_len=16, type=<Type.I: 1>)

Legacy alias for hash_secret_raw() with default parameters.

Deprecated since version 16.0.0: Use argon2.PasswordHasher for passwords.

argon2.verify_password(hash, password, type=<Type.I: 1>)

Legacy alias for verify_secret() with default parameters.

Deprecated since version 16.0.0: Use argon2.PasswordHasher for passwords.