.\" This file is dual-licensed.  Choose whichever you want.
.\"
.\" The first licence is a regular 2-clause BSD licence.  The second licence
.\" is the CC-0 from Creative Commons. It is intended to release Monocypher
.\" to the public domain.  The BSD licence serves as a fallback option.
.\"
.\" SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
.\"
.\" ----------------------------------------------------------------------------
.\"
.\" Copyright (c) 2017-2019 Loup Vaillant
.\" Copyright (c) 2018 Michael Savage
.\" Copyright (c) 2017, 2019-2020 Fabio Scotoni
.\" All rights reserved.
.\"
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions are
.\" met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\"    notice, this list of conditions and the following disclaimer.
.\"
.\" 2. Redistributions in binary form must reproduce the above copyright
.\"    notice, this list of conditions and the following disclaimer in the
.\"    documentation and/or other materials provided with the
.\"    distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
.\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
.\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
.\" HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
.\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" ----------------------------------------------------------------------------
.\"
.\" Written in 2017-2020 by Loup Vaillant, Michael Savage and Fabio Scotoni
.\"
.\" To the extent possible under law, the author(s) have dedicated all copyright
.\" and related neighboring rights to this software to the public domain
.\" worldwide.  This software is distributed without any warranty.
.\"
.\" You should have received a copy of the CC0 Public Domain Dedication along
.\" with this software.  If not, see
.\" <https://creativecommons.org/publicdomain/zero/1.0/>
.\"
.Dd April 8, 2020
.Dt CRYPTO_ARGON2I 3MONOCYPHER
.Os
.Sh NAME
.Nm crypto_argon2i
.Nd password key derivation
.Sh SYNOPSIS
.In monocypher.h
.Ft void
.Fo crypto_argon2i
.Fa "uint8_t *hash"
.Fa "uint32_t hash_size"
.Fa "void *work_area"
.Fa "uint32_t nb_blocks"
.Fa "uint32_t nb_iterations"
.Fa "const uint8_t *password"
.Fa "uint32_t password_size"
.Fa "const uint8_t *salt"
.Fa "uint32_t salt_size"
.Fc
.Ft void
.Fo crypto_argon2i_general
.Fa "uint8_t *hash"
.Fa "uint32_t hash_size"
.Fa "void *work_area"
.Fa "uint32_t nb_blocks"
.Fa "uint32_t nb_iterations"
.Fa "const uint8_t *password"
.Fa "uint32_t password_size"
.Fa "const uint8_t *salt"
.Fa "uint32_t salt_size"
.Fa "const uint8_t *key"
.Fa "uint32_t key_size"
.Fa "const uint8_t *ad"
.Fa "uint32_t ad_size"
.Fc
.Sh DESCRIPTION
Argon2i is a resource intensive password key derivation scheme
optimised for the typical x86-like processor.
It runs in constant time with respect to the contents of the password.
.Pp
Typical applications are password checking (for online services), and
key derivation (for encryption).
Derived keys can be used to encrypt, for example, private keys or
password databases.
.Pp
The version provided by Monocypher has no threading support, so the
degree of parallelism is limited to 1.
This is considered good enough for most purposes.
.Pp
The arguments to
.Fn crypto_argon2i
are:
.Bl -tag -width Ds
.It Fa hash
The output hash.
.It Fa hash_size
Length of
.Fa hash ,
in bytes.
This argument should be set to 32 or 64 for compatibility with the
.Fn crypto_verify*
constant time comparison functions.
.It Fa work_area
Temporary buffer for the algorithm, allocated by the caller.
It must be
.Fa nb_blocks
× 1024 bytes big, and suitably aligned for 64-bit integers.
If you are not sure how to allocate that buffer, just use
.Fn malloc .
.Pp
The work area is automatically wiped by
.Fn crypto_argon2i .
.It Fa nb_blocks
The number of blocks for the work area.
Must be at least 8.
A value of 100000 (one hundred megabytes) is a good starting point.
If the computation takes too long, reduce this number.
If it is too fast, increase this number.
If it is still too fast with all available memory, increase
.Fa nb_iterations .
.It Fa nb_iterations
The number of iterations.
It must be at least 1.
A value of 3 is
.Em strongly
recommended;
any value lower than 3 enables significantly more efficient attacks.
.It Fa password
The password to hash.
It should be wiped with
.Xr crypto_wipe 3monocypher
after being hashed.
.It Fa password_size
Length of
.Fa password ,
in bytes.
.It Fa salt
A password salt.
This should be filled with random bytes, generated separately for each
password to be hashed.
See
.Xr intro 3monocypher
for advice about generating random bytes (use the operating system's
random number generator).
.It Fa salt_size
Length of
.Fa salt ,
in bytes.
Must be at least 8.
16 is recommended.
.El
.Pp
The output hash must not overlap with the work area, or it will be
wiped along with it.
Any other overlap is permitted.
.Pp
Use
.Xr crypto_verify16 3monocypher ,
.Xr crypto_verify32 3monocypher
or
.Xr crypto_verify64 3monocypher
to compare password hashes to prevent timing attacks.
.Pp
To select the
.Fa nb_blocks
and
.Fa nb_iterations
parameters, it should first be decided how long the computation should
take.
For user authentication, values somewhere between half a second
(convenient) and several seconds (paranoid) are recommended.
The computation should use as much memory as can be spared.
.Pp
Since parameter selection depends on your hardware, some trial and error
will be required in order to determine the ideal settings.
Three iterations and 100000 blocks (that is, one hundred megabytes of
memory) is a good starting point.
Adjust
.Fa nb_blocks
first.
If using all available memory is not slow enough, increase
.Fa nb_iterations .
.Pp
.Fn crypto_argon2i_general
is a variant of
.Fn crypto_argon2i
that supports keyed hashing and hashing of additional data.
The additional arguments are:
.Bl -tag -width Ds
.It Fa key
A key to use in the hash.
Can be
.Dv NULL
if
.Fa key_size
is zero.
The key is generally not needed, but it does have some uses.
In the context of password derivation, it would be stored separately
from the password database, and would remain secret even if an
attacker were to steal the database.
Note that changing the key requires rehashing the user's password,
which is only possible upon user login.
.It Fa key_size
Length of
.Fa key ,
in bytes.
Must be zero if there is no key.
.It Fa ad
Additional data.
This is additional data that goes into the hash, similar to the
authenticated encryption with authenticated data (AEAD) construction in
.Xr crypto_lock_aead 3monocypher .
This most likely has no practical application but is exposed for the
sake of completeness.
This parameter may be
.Dv NULL
if
.Fa ad_size
is zero.
.It Fa ad_size
Length of
.Fa ad ,
in bytes.
Must be zero if there is no additional data.
.El
.Sh RETURN VALUES
These functions return nothing.
.Sh EXAMPLES
The following example assumes the existence of
.Fn arc4random_buf ,
which fills the given buffer with cryptographically secure random bytes.
If
.Fn arc4random_buf
does not exist on your system, see
.Xr intro 3monocypher
for advice about how to generate cryptographically secure random bytes.
.Pp
This example shows how to hash a password with the recommended baseline
parameters:
.Bd -literal -offset indent
uint8_t        hash[32];                    /* Output hash     */
char          *password = "Okay Password!"; /* User's password */
uint32_t       password_size = 14;          /* Password length */
uint8_t        salt[16];                    /* Random salt     */
const uint32_t nb_blocks = 100000;          /* 100 megabytes   */
const uint32_t nb_iterations = 3;           /* 3 iterations    */
void *work_area = malloc(nb_blocks * 1024); /* Work area       */
if (work_area == NULL) {
    /* Handle malloc() failure */
    /* Wipe secrets if they are no longer needed */
    crypto_wipe(password, password_size);
} else {
    arc4random_buf(salt, 16);
    crypto_argon2i(hash, 32,
                   work_area, nb_blocks, nb_iterations,
                   (uint8_t *)password, password_size,
                   salt, 16);
    /* Wipe secrets if they are no longer needed */
    crypto_wipe(password, password_size);
    free(work_area);
}
.Ed
.Sh SEE ALSO
.Xr crypto_lock 3monocypher ,
.Xr crypto_verify16 3monocypher ,
.Xr crypto_wipe 3monocypher ,
.Xr intro 3monocypher
.Sh STANDARDS
These functions implement Argon2i.
An RFC draft is being maintained.
.Sh HISTORY
The
.Fn crypto_argon2i_general
function first appeared in Monocypher 0.1 but was called
.Fn crypto_argon2i ;
it was renamed to its current name in Monocypher 1.1.0.
The current
.Fn crypto_argon2i
first appeared in Monocypher 1.1.0.
.Sh CAVEATS
Any deviation from the specified input and output length ranges results
in
.Sy undefined behaviour .
Make sure your inputs are correct.
